/* Back-office styles. One plain file, linked with a cache-busting stamp from the layout,
   so nothing has to be built on deploy and a change is never served stale.
   No framework: every screen is server-rendered HTML. */

/* --- tokens --- */
:root {
    --ink: #14161a;
    --quiet: #6a7076;
    --faint: #9aa0a6;
    --line: #dcdfe3;
    --page: #eef0f2;
    --header: #f4f5f7;
    --card: #ffffff;
    --accent: #14161a;
    --bad: #b3261e;
    --good: #1a7f43;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;

    --radius: 8px;

    /* The bar across the top. The toast sits below it, so both read this. */
    --topbar: 56px;
}

* { box-sizing: border-box }

html { -webkit-text-size-adjust: 100% }

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font: 14px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

h1, h2 { margin: 0; font-weight: 600; letter-spacing: -0.01em }
h1 { font-size: 20px }
h2 { font-size: 14px }

a { color: var(--ink) }

/* Focus is its own state, never carried by a colour change alone, so keyboard use
   survives any later restyling of the control itself. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- controls --- */
button {
    font: inherit;
    font-weight: 500;
    padding: 9px 16px;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    cursor: pointer;
    transition: opacity .12s ease;
}

button:hover { opacity: .88 }

input[type="email"],
input[type="password"],
input[type="search"],
input[type="text"] {
    font: inherit;
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: #fff;
    color: var(--ink);
}

input::placeholder { color: var(--faint) }

/* --- top bar --- */
.topbar {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    padding: 0 var(--space-6);
    height: var(--topbar);
    background: var(--card);
    border-bottom: 1px solid var(--line);
}

.topbar-name {
    font-weight: 600;
    text-decoration: none;
    letter-spacing: -0.01em;
}

.topbar-links { display: flex; gap: var(--space-5); flex: 1 }

.topbar-links a {
    color: var(--quiet);
    text-decoration: none;
    padding: 4px 0;
    border-bottom: 2px solid transparent;
}

.topbar-links a:hover { color: var(--ink) }
.topbar-links a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink) }

.topbar-signout { display: flex; align-items: center; gap: var(--space-4); margin: 0 }
/* The name is the way into My account, so it reads as something to press. */
.topbar-person { color: var(--quiet); text-decoration: none; padding: 4px 2px }
.topbar-person:hover { color: var(--ink) }
.topbar-person[aria-current="page"] { color: var(--ink); font-weight: 600 }

.topbar-signout button {
    background: none;
    color: var(--quiet);
    border-color: var(--line);
    padding: 6px 12px;
}

.topbar-signout button:hover { color: var(--ink); border-color: var(--faint); opacity: 1 }

/* --- page --- */
.page { max-width: 960px; margin: 0 auto; padding: var(--space-4) var(--space-6) var(--space-7) }

/* A screen whose value is the width of its table asks for this. 960px is right for
   reading; a nine-column stock list truncates every column at it. 1300px is what the
   old Stock Level screen uses, so the rows break in the same places staff are used to. */
.page-wide { max-width: 1640px }

.page-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.page-count { color: var(--quiet); margin: 0 }
/* A control belonging to the whole screen, at the far end of its heading. */
.page-head-action { margin-left: auto }
.empty { color: var(--quiet); margin: 0; padding: var(--space-6); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius) }

/* --- panels --- */
.panel {
    max-width: 460px;
    padding: var(--space-5);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.panel + .panel { margin-top: var(--space-4) }
/* Panels side by side where there is room, stacked where there is not. The carrier
   screens have three of them and a column of stacked 460px cards on a 1640px page
   reads as one narrow strip against a lot of nothing. */
.panel-row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: flex-start }
.panel-row .panel { flex: 1 1 320px; margin-top: 0 }
/* .panel + .panel stacks them; inside a row the gap does that instead. */
.panel-row .panel + .panel { margin-top: 0 }

.panel h2 { margin-bottom: var(--space-4) }

/* --- forms --- */
.field { margin-bottom: var(--space-4) }
.field:last-of-type { margin-bottom: 0 }
.field > label { display: block; margin-bottom: var(--space-2); color: var(--quiet); font-size: 13px }

/* A choice sits beside a typed value, so it has to look like one. Scoped to .field
   rather than to select: the ship form has selects of its own that are styled where
   they stand. */
.field select {
    font: inherit;
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: #fff;
    color: var(--ink);
}

.field-hint { color: var(--quiet); font-size: 13px; margin: var(--space-2) 0 0 }
.field-error { color: var(--bad); font-size: 13px; margin: var(--space-2) 0 0 }

.form-foot { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 1px solid var(--line) }

/* --- carrier screens --- */
/* The key on its own line: the names are long enough that the 140px first column of
   .detail pushes the answer off the card. */
.secret-state { margin: 0 0 var(--space-3); font-size: 13px; line-height: 1.7 }
.secret-state code { display: block; color: var(--quiet); font-size: 12px }
.secret-state .secret-set { color: var(--good) }
.secret-state .secret-missing { color: var(--bad) }

/* A heading that follows a form needs the gap a panel would have given it. */
form + .section-heading { margin-top: var(--space-6) }
.form-foot .field-hint { margin: 0 0 var(--space-3) }

.notice {
    padding: var(--space-3) var(--space-4);
    margin: 0 0 var(--space-4);
    max-width: 460px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--card);
    color: var(--quiet);
    font-size: 13px;
}

/* --- definition list, label beside value --- */
.detail { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: var(--space-3) var(--space-4); margin: 0 }
.detail dt { color: var(--quiet); font-size: 13px }
.detail dd { margin: 0 }

/* --- sign in --- */
.signin { max-width: 380px; margin: 14vh auto 0; padding: var(--space-6); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius) }
.signin h1 { margin-bottom: var(--space-5); font-size: 17px }
.signin-remember { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-4) 0 0; color: var(--quiet); font-size: 13px }
.signin-remember input { margin: 0 }
.signin button { width: 100%; margin-top: var(--space-5) }

/* --- search --- */
.search { display: flex; gap: var(--space-2); align-items: center; margin-bottom: var(--space-4) }
.search input { width: 260px }
.search a { color: var(--quiet); font-size: 13px; margin-left: var(--space-2) }

/* --- tables: every list screen shares one look, and adds its own rules after --- */
.orders {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}

.orders th, .orders td { padding: var(--space-3) var(--space-4); text-align: left }
.orders th { color: var(--quiet); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .07em; background: var(--header) }
.orders th, .orders tbody td { border-bottom: 1px solid var(--line) }
.orders thead th { border-bottom-color: var(--faint) }
.orders tbody tr:last-child td { border-bottom: none }
.orders tbody tr:hover { background: #f8f9fa }
.orders .right { text-align: right; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" }

/* --- tabs --- */
/* Two levels, deliberately unalike: the five sections read as tabs along a rule, the two
   inside Overview as a segmented control, so a glance tells you which level you are on.
   A tab is a link, and the global rule underlines links, so that is turned off here. */
.tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0 0 var(--space-3); border-bottom: 1px solid var(--line) }
.tab { padding: var(--space-2) var(--space-4); font-size: 13px; font-weight: 500; color: var(--quiet); text-decoration: none; border-bottom: 2px solid transparent; transition: color .12s ease, border-color .12s ease }
a.tab:hover { color: var(--ink) }
.tab[aria-current="page"] { color: var(--ink); font-weight: 600; border-bottom-color: var(--ink) }
/* Named but not built. Shown so the screen has the shape staff already know. */
.tab[aria-disabled="true"] { opacity: .38; cursor: default }

.tabs-sub {
    display: inline-flex;
    gap: 2px;
    margin: 0 0 var(--space-3);
    padding: 3px;
    background: #eff1f3;
    border: none;
    border-radius: 7px;
}

.tabs-sub .tab { padding: 5px var(--space-4); border-bottom: none; border-radius: 5px }
.tabs-sub .tab[aria-current="page"] { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(17, 24, 28, .1) }
.tabs-sub a.tab:hover:not([aria-current="page"]) { background: rgba(255, 255, 255, .55) }

.section-heading { margin: 0 0 var(--space-1); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--faint) }

.note { margin: 0 0 var(--space-4); padding: var(--space-3) var(--space-4); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); color: var(--quiet); font-size: 13px }

/* --- table tools --- */
.table-tools { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2) }
/* Matched to the fields inside the rows, so the band above the table is not taller than
   it needs to be. A sign-in field can be generous; a filter above 1.140 rows cannot. */
.table-tools input { flex: 1; max-width: 22rem; height: 32px; padding: 0 12px; border-color: var(--faint) }
.table-count { margin: 0; color: var(--quiet); font-size: 13px; white-space: nowrap }

/* Only there while a column is sorted, because that is the only time it means anything. */
.reset-sorting { display: none; padding: 5px 10px; font-size: 12px; font-weight: 500; background: var(--card); color: var(--quiet); border: 1px solid var(--line); border-radius: 5px; cursor: pointer; white-space: nowrap }
.reset-sorting.is-shown { display: inline-block }
.reset-sorting:hover { color: var(--ink); border-color: var(--faint); opacity: 1 }

/* --- the stock tables, fabrics and foams --- */
/* Headings stay in view while the catalogue scrolls; overflow on the shared table rule
   would clip a sticky cell, so this one scrolls the page instead.
   The table sizes itself to its contents, as the old screen's does. A fixed layout with
   shares of the page truncated every column: Roll got 58px, 32 of which was padding, and
   showed "1...". */
.stock-table { overflow: visible }
/* The heading follows the page down. A shadow rather than a border, so it reads as
   sitting above the rows once they start passing under it. */
.stock-table th { position: sticky; top: 0; z-index: 1; box-shadow: inset 0 -1px 0 var(--faint) }

/* Tighter than the shared table rule. 16px each side is right for a five-column list and
   wrong for a ten-column one: it spends 320px of the page on gaps. */
/* Centred, as the old screen is. The two name columns stay left: they are the longest
   thing on the row and centring a wrapped name leaves it ragged on both sides. */
.stock-table th, .stock-table td { padding: var(--space-2) var(--space-2); white-space: nowrap; vertical-align: middle; text-align: center }
.stock-table .column-production-name, .stock-table .column-public-name,
.stock-table td:nth-child(2), .stock-table td:nth-child(3) { text-align: left }
/* Those two are the fabrics overview's name columns. Every cell on the stock tabs is centred. */
#materials-ordered td, #missing-materials td { text-align: center }
.stock-table .right { text-align: center }

/* The two name columns take whatever the table has left over; everything else is as
   narrow as its content. */
.stock-table .column-production-name, .stock-table .column-public-name { width: 50% }

/* And they are the only two allowed to wrap. A foam's public name runs to "Ryg
   standardskum - Skra (Dybde: Bund 20cm - Top 10cm, Hojde: 45cm)"; held on one line it
   pushes the table past the page and the History column off the edge. The old screen
   wraps this column too. */
.stock-table .column-production-name, .stock-table .column-public-name,
.stock-table td:nth-child(2), .stock-table td:nth-child(3) { white-space: normal }

.stock-table .supplier, .stock-table .type { color: var(--quiet); font-size: 13px }
.stock-table .production-name { font-weight: 600; letter-spacing: -0.005em }

/* The old screen reddens a figure at zero as well as below it. */
.stock-table .none-left { color: #b42318; font-weight: 600 }
.stock-table .not-built { color: var(--quiet); font-size: 12px; opacity: .5 }

/* --- editing a row --- */
/* Sized to their content, so a dropdown does not stretch the table and a price field is
   only as wide as a price. Tall enough to hit without aiming, and outlined clearly enough
   to read as a field: a pale 3px control on a white row reads as text somebody left
   lying there, and the old screen's do not. */
.stock-table select, .stock-table input[type="number"] {
    /* One height for both. A select and a number input size themselves differently from
       the same padding, so the height is stated rather than inferred, or they sit at two
       heights in the same row. */
    height: 30px;
    padding: 0 8px;
    font: inherit;
    font-size: 13px;
    line-height: 28px;
    border: 1px solid var(--faint);
    border-radius: 5px;
    background: var(--card);
    color: var(--ink);
    vertical-align: middle;
}

.stock-table select:hover, .stock-table input[type="number"]:hover { border-color: var(--quiet) }

.stock-table input[type="number"] { width: 6rem; text-align: right; font-variant-numeric: tabular-nums }

/* The gap goes on the spinner, not on the field. Padding moves the spinner inward with
   the text, because it sits at the right edge of the content box rather than the border
   box, so the figure ends up touching it wherever it lands. */
.stock-table input[type="number"]::-webkit-inner-spin-button { margin-left: 8px }
.stock-table input[type="number"]::-webkit-outer-spin-button { margin-left: 8px }
.stock-table .save { text-align: center }
/* The global button rule paints white on the accent colour. These sit on white, so the
   colour has to be reset too, not only the background: overriding half a rule leaves the
   other half painting. */
.stock-table .save button {
    height: 30px;
    padding: 0 10px;
    font-size: 13px;
    line-height: 1.3;
    cursor: pointer;
    border: 1px solid var(--ink);
    border-radius: 5px;
    background: var(--ink);
    color: #fff;
}

.stock-table .save button:hover { opacity: .85 }

/* Stacked, one under the other, as they are on the old screen. */
/* Filled, as they are on the old screen, so they read as buttons rather than as words in
   a box. Every one of these sets its own colour: the global rule paints white on the
   accent, and overriding half a rule leaves the other half painting. */
.history-button {
    display: block;
    width: 100%;
    min-width: 4.25rem;
    margin-bottom: 3px;
    padding: 4px 8px;
    font-size: 12px;
    font-weight: 500;
    border: 1px solid #2f4b6b;
    border-radius: 5px;
    background: #2f4b6b;
    color: #fff;
    cursor: pointer;
}

.history-button:last-child { margin-bottom: 0 }
.history-button:hover:not(:disabled) { opacity: .85 }
.history-button:disabled { background: var(--card); border-color: var(--line); color: var(--faint); cursor: default }

/* A save is a toast: green, centred at the top of the window, no wider than its own text,
   and over the page rather than in it. Saving a row on the Fabrics overview returns to
   that row, which on 1.140 of them is far below where a message in the flow would sit.
   Fixed rather than sticky, so it holds no space and nothing shifts when it leaves.
   assets: notes.js takes it away after six seconds, or on a click. */
.note-done {
    position: fixed;
    top: calc(var(--topbar) + var(--space-3));
    left: 50%;
    transform: translateX(-50%);
    z-index: 30;
    width: max-content;
    max-width: min(90vw, 40rem);
    margin: 0;
    border-color: var(--good);
    background: #f2fbf5;
    color: #14663a;
    box-shadow: 0 4px 16px rgb(20 22 26 / 14%);
    cursor: pointer;
    transition: opacity .3s ease, transform .3s ease;
}

/* Must match the FADE in notes.js. */
.note-done.is-going {
    opacity: 0;
    transform: translateX(-50%) translateY(-8px);
    pointer-events: none;
}

/* A refusal stays where the form is and is not taken away: it says why nothing saved,
   and it is read at whatever pace. Pinned so it is visible from anywhere in a long
   table, which sticky can do here because .topbar scrolls away rather than being fixed.
   No wider than its own words, and centred, as the green one is. */
.note-warn {
    position: sticky;
    top: var(--space-3);
    z-index: 15;
    width: max-content;
    max-width: min(90vw, 40rem);
    margin: 0 auto var(--space-4);
    border-color: #eccaca;
    background: #fdf3f3;
    color: #a12d2d;
    box-shadow: 0 2px 10px rgb(20 22 26 / 8%);
}

/* A warning that belongs to the page rather than one that just arrived. .note-warn is
   a toast - sticky, sized to its text, shadowed - and every one of those has to be
   undone here or a standing banner floats down the page as it scrolls. */
.note-warn.note-standing {
    position: static;
    width: auto;
    max-width: none;
    margin: 0 0 var(--space-4);
    box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
    .note-done { transition: none }
}

/* The field the page is complaining about. */
.is-wrong { outline: 2px solid #d0453f; outline-offset: -1px }

/* --- Add Fabrics summary --- */
/* What Add Fabrics is about to do, in the shape the old screen shows it: the material,
   then a green line for what arrives and a red one for what leaves. Modal, because it is
   the last thing read before the shelf moves.
   assets: adding-materials.js */
.summary-panel {
    width: min(460px, 92vw); margin: auto; padding: var(--space-5);
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card); color: var(--ink)
}
.summary-panel::backdrop { background: rgb(17 24 28 / 35%) }
.summary-panel h2 { margin: 0 0 var(--space-4); font-size: 15px }
.changed-material { margin-bottom: var(--space-3); font-size: 13px }
.changed-material:last-child { margin-bottom: 0 }
/* The Logs panel's colours, so material arriving reads the same everywhere. */
.changed-material .arriving { color: #00b300 }
.changed-material .leaving { color: #b42318 }
.summary-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4) }

/* --- pieces toggle --- */
/* Sits under the Stock figure, as it does on the old screen. */
/* Full width of the Stock column, under the figure it belongs to. */
.pieces-toggle { display: block; width: 100%; min-width: 5.5rem; margin-top: 4px; padding: 2px 6px; font-size: 11px; font-weight: 500; text-align: center; background: var(--page); color: var(--quiet); border: 1px solid var(--line); border-radius: 4px; cursor: pointer }
.pieces-toggle[aria-expanded="true"] { background: var(--ink); color: #fff; border-color: var(--ink) }
/* A card pinned beside the button that opened it. Fixed, so the table's own scrolling
   cannot clip it, and hidden with opacity rather than display so it can be animated. */
#pieces-card {
    position: fixed;
    z-index: 20;
    max-width: 28rem;
    padding: var(--space-3) var(--space-4);
    background: var(--card);
    border: 1px solid var(--faint);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(17, 24, 28, .14);
    font-size: 12px;
    opacity: 0;
    transform: translateY(-4px) scale(.98);
    transform-origin: top left;
    pointer-events: none;
    transition: opacity .14s ease, transform .14s ease;
}

#pieces-card.is-open { opacity: 1; transform: none; pointer-events: auto }

/* Somebody who has asked not to be animated still gets the card, just without the move. */
@media (prefers-reduced-motion: reduce) {
    #pieces-card { transition: none }
}

/* Three to a row, always. Flowing them filled each line by width instead, and since a
   piece carrying a reference is nearly twice as wide as one without, the rows held two,
   then three, then two. A column that moves cannot be read down. */
.pieces {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3) var(--space-4);
}

.pieces span { white-space: nowrap }

/* Under the metres rather than beside them, which is what keeps every cell the same
   narrow width whether or not the piece came in on a reference. */
.pieces-reference { display: block; color: var(--quiet) }
.pieces-none { color: var(--quiet) }

/* --- history panel --- */
/* A dialog, so the browser handles the overlay, focus and Escape rather than this doing
   it by hand and getting one of the three wrong. */
#stock-panel { width: min(1100px, 92vw); max-height: 86vh; padding: var(--space-4) var(--space-5) var(--space-5); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden }

/* Only when open. A dialog is hidden by display:none in the browser's own stylesheet, and
   an unconditional display here would override that and show it shut. */
#stock-panel[open] { display: flex; flex-direction: column }

/* The note panel opens under the button that asked for it, not in the middle of the
   screen. Position comes from missing-materials.js; the fade is here. Keep the .16s in
   step with FADE in that file, or the panel leaves the top layer before it has faded. */
.stock-panel {
    position: fixed; margin: 0; width: min(330px, 92vw); padding: var(--space-4);
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card); color: var(--ink);
    box-shadow: 0 14px 32px rgba(17, 24, 28, .18);
    opacity: 0; transform: translateY(-6px) scale(.985);
    transition: opacity .16s ease, transform .16s ease;
}
.stock-panel.is-open { opacity: 1; transform: none }
.stock-panel::backdrop { background: rgba(17, 24, 28, .12) }
.stock-panel h2 { margin: 0 0 var(--space-1); font-size: 14px }
.stock-panel .muted { margin: 0 0 var(--space-3) }
.stock-panel .field { margin: 0 }
.stock-panel label { display: block; margin-bottom: var(--space-1); font-size: 12px; color: var(--quiet) }
.stock-panel textarea {
    width: 100%; font: inherit; font-size: 13px; padding: var(--space-2);
    border: 1px solid var(--line); border-radius: var(--radius); resize: vertical
}
.stock-panel .panel-actions { display: flex; gap: var(--space-2); margin-top: var(--space-3) }

@media (prefers-reduced-motion: reduce) {
    .stock-panel { transition: none }
}
#stock-panel::backdrop { background: rgba(17, 24, 28, .35) }
/* In the corner rather than on a row of its own, which cost the panel a line before it
   said anything. Absolute, not floated: floated it shortens the title's line, and a title
   centred in what is left of a line sits left of the box. A dialog is the containing block,
   and only the body below scrolls, so Close stays in reach of a log 180 rows long. */
.panel-bar { position: absolute; top: var(--space-4); right: var(--space-4); z-index: 1 }
.panel-close {
    display: flex; align-items: center; justify-content: center; width: 28px; height: 28px;
    padding: 0; font-size: 18px; line-height: 1; background: #fff; color: var(--quiet);
    border: 1px solid var(--line); border-radius: var(--radius)
}
.panel-close:hover { color: var(--ink) }
#stock-panel-body { overflow: auto }

/* Centred, as the old panel is: the summary is read as a heading, not as the start of the
   table. Title and figures share one line; the padding keeps a long title off the Close
   button in the corner, and is on both sides so the centre stays the box's centre. */
.panel-head {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: var(--space-2) var(--space-3); padding: 0 44px; margin-bottom: var(--space-3)
}
.panel-head h2 { margin: 0; font-size: 17px }
/* Its own line: a fabric can be on eight pieces, and they do not belong beside the title. */
.panel-pieces { flex-basis: 100%; margin: 0; font-size: 13px; text-align: center }
.panel-totals { margin: 0; padding: var(--space-1) var(--space-3); border: 1px solid var(--faint); border-radius: var(--radius); font-size: 13px }

.history-table td, .history-table th { padding: 6px var(--space-2); font-size: 12px; text-align: center }
.history-table th { text-align: center }
.history-table .right { text-align: center }
.history-table .date { white-space: nowrap }
.history-table .log-sentence { white-space: normal; text-align: left }

/* Material leaving and arriving, in the old panel's own colours. */
.history-table .moved-out { color: #b42318; font-weight: 600 }
.history-table .moved-in { color: #00b300; font-weight: 600 }

.sortable { cursor: pointer; user-select: none }
.sortable:hover { color: var(--ink) }
/* An arrow only while it is sorted, so a third click clearing it is visible. */
.sortable::after { content: " \2195"; font-size: 10px; opacity: 0; transition: opacity .12s ease }
.sortable:hover::after { opacity: .35 }
.sortable[aria-sort]::after { content: " \2191"; opacity: 1 }
.sortable[aria-sort="descending"]::after { content: " \2193"; opacity: 1 }
.sortable[aria-sort] { color: var(--ink) }

/* A fabric the shop no longer sells. Still shown, because the stock is real and can
   still be cut, but it should not compete with the fabrics in the catalogue. */

.tag { margin-left: var(--space-2); color: var(--quiet); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap }

/* --- pager --- */
.pager { display: flex; gap: var(--space-4); align-items: center; margin-top: var(--space-4); color: var(--quiet); font-size: 13px }

/* --- timelog: the list of people --- */
.notice-wide { max-width: none }
.notice-problem { color: var(--bad); border-color: var(--bad) }

.people { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-3) }

/* A whole card is one target: this is tapped on a shared screen, often not with a
   fingertip. No left border, the status carries itself. */
.person {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-4) var(--space-5);
    min-height: 96px;
    justify-content: center;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    text-decoration: none;
    transition: border-color .12s ease, background .12s ease;
}

.person:hover { border-color: var(--faint); background: #fcfcfd }

.person-name { font-weight: 600; font-size: 15px }
.person-today { color: var(--faint); font-size: 12px; font-variant-numeric: tabular-nums }
.person-open { color: #1e8e3e }

/* The status is the one coloured thing, on the word itself, so colour is never the only
   signal: the word says the same. */
.person-status { font-size: 13px; color: var(--quiet) }
.person-working .person-status, .person-status-working { color: #1e8e3e; font-weight: 500 }
.person-on_break .person-status, .person-status-on_break { color: #b06a00; font-weight: 500 }
.person-on_holiday .person-status, .person-status-on_holiday { color: #1a56c4; font-weight: 500 }
.person-on_sick_leave .person-status, .person-status-on_sick_leave { color: var(--bad); font-weight: 500 }

/* --- timelog: one person --- */
.person-head { display: flex; align-items: baseline; gap: var(--space-4); margin-bottom: var(--space-3) }
.back { color: var(--quiet); font-size: 13px; text-decoration: none }
.back:hover { color: var(--ink) }
.back::before { content: "\2190"; margin-right: var(--space-1) }

.person-summary { margin: 0 0 var(--space-5); color: var(--quiet); font-size: 13px }
.person-summary strong { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums }

/* A grid rather than a wrapping row, so the buttons line up in columns instead of
   ragging across whatever width the window happens to be. */
.actions { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-3) }
/* The form is the grid cell; the button has to be told to fill it, or every button
   sizes to its own label and the column edges go ragged. */
.actions form { margin: 0; display: flex }
.actions .action { flex: 1 }
.actions-rule { grid-column: 1 / -1; height: 0; margin: var(--space-2) 0; border: none; border-top: 1px solid var(--line) }

/* Big enough to hit on a shared tablet without looking. */
/* One height for all of them, whether the label wraps to two lines or not. */
.action { padding: 16px 20px; font-size: 15px; min-height: 56px; text-align: center }

/* Disabled rather than removed, so a person's button never moves under them. */
.action:disabled { background: var(--page); color: var(--faint); border-color: var(--line); cursor: not-allowed; opacity: 1 }
.action:disabled:hover { opacity: 1 }

.empty code { font-size: 13px; background: var(--page); padding: 2px 6px; border-radius: 4px }

/* --- correction --- */
/* Same width as the action buttons below it, so the column has one edge. */
.correction {
    margin-bottom: var(--space-6);
    padding: var(--space-5);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.correction h2 { margin-bottom: var(--space-3) }
.correction > p { margin: 0 0 var(--space-5); color: var(--quiet); font-size: 13px; max-width: 70ch }

/* Label, field and button on one line, sitting on a common baseline. */
.correction form { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; margin: 0 }
.correction-field { display: flex; flex-direction: column; gap: var(--space-2) }
.correction-field label { color: var(--quiet); font-size: 13px }

.correction input[type="datetime-local"] {
    font: inherit;
    width: auto;
    min-width: 240px;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: #fff;
    color: var(--ink);
}

.correction button { padding: 9px 16px }
.correction .field-error { margin-top: var(--space-3) }

/* --- history --- */
.section { margin: var(--space-7) 0 var(--space-3); font-size: 14px }
/* nothing to cap: the table fills the page */

/* --- products: pairing a Shopify product with ours --- */

.muted { color: var(--quiet); font-size: 13px }

.pill { display: inline-block; padding: 1px var(--space-2); border-radius: var(--radius); font-size: 12px }
.pill-quiet { background: var(--header); color: var(--quiet) }
.pill-warn { background: #fdf3f3; color: #a12d2d; border: 1px solid #eccaca }

.column-suggestion { white-space: nowrap }
.column-suggestion form { display: flex; align-items: center; gap: var(--space-2) }

/* Sits beside the search box, so it must not read as the main action. */
.btn-quiet { background: transparent; border-color: var(--line); color: inherit }
.btn-quiet:hover { background: var(--header) }

/* --- missing materials --- */

.missing-head { display: flex; align-items: baseline; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-3) }
.supplier-summary { margin: 0; font-size: 13px; line-height: 1.8 }
.supplier-total { white-space: nowrap }
.supplier-divider { margin: 0 var(--space-2); color: var(--quiet) }
.supplier-summary .is-short { color: #a12d2d; font-weight: 600 }

/* Bordered and centred, as the screen this replaces is. It must fit the page: the two
   columns that can take the space are the reference and the delivery date. */
.missing-materials { border: 1px solid var(--line); table-layout: fixed; width: 100% }
.missing-materials th,
.missing-materials td { border: 1px solid var(--line); text-align: center; vertical-align: middle; padding: var(--space-2) }
/* Headings read as words and wrap onto a second line rather than being cut off. */
.missing-materials th {
    background: var(--header); font-size: 13px; font-weight: 600; white-space: normal; line-height: 1.3;
    /* Words, not shouting. The shared .orders th sets uppercase and letter-spacing. */
    text-transform: none; letter-spacing: 0; color: var(--ink)
}

/* Every column is fixed except the production name, which takes whatever is left. The
   buttons had width:auto and so soaked up the whole surplus. */
.missing-materials col.pick { width: 42px }
.missing-materials col.order { width: 118px }
.missing-materials col.metres { width: 104px }
.missing-materials col.reference { width: 188px }
.missing-materials col.supplier { width: 112px }
.missing-materials col.production { width: auto }
.missing-materials col.stock { width: 96px }
.missing-materials col.needed { width: 96px }
.missing-materials col.delivery { width: 142px }
.missing-materials col.actions { width: 232px }

/* Materials arrived but missing carries the same column classes and different content:
   a unit beside the figure, an arrival date, and three buttons rather than one. */
.arrived-missing col.stock { width: 112px }
/* Meters Required holds four things stacked, so it is the one column that wraps. */
.arrived-missing col.needed { width: 210px }
.arrived-missing col.submit { width: 116px }
.arrived-missing col.actions { width: 106px }
/* Below this the buttons no longer fit their columns and start crossing the border, so
   the page scrolls instead of the cells breaking. */
.arrived-missing { min-width: 1180px }
.arrived-missing .required-cell { white-space: normal; line-height: 1.4 }
.arrived-missing .entered-date, .arrived-missing .still-missing { margin-top: var(--space-2); font-size: 11px }
/* The old badge, in its own words. No icon font: a cross is a character. */
.arrived-missing .out-of-stock {
    display: inline-block; margin-top: var(--space-2); padding: 2px var(--space-2);
    border-radius: var(--radius); background: #b42318; color: #fff; font-size: 11px; font-weight: 600
}
/* The row is #FF8A65, and the quiet grey is not readable on it. */
#materials-ordered tr.is-overdue .muted { color: #5c2110 }

/* A fixed column only holds if its contents wrap and cannot paint outside it. */
.missing-materials td { overflow-wrap: anywhere; overflow: hidden }

.missing-materials tr.supplier-headline td {
    padding: var(--space-4) var(--space-2);
    background: rgb(209, 212, 218); color: rgb(0, 0, 0);
    font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: .08em;
    border-top: 3px solid var(--page); border-bottom: none;
}

/* --- adding materials: four cells, each answering the next --- */

/* .stock-table keeps its cells on one line; a fabric name here is a sentence long. */
.adding-materials td { vertical-align: middle; padding: var(--space-3) var(--space-2); white-space: normal }
.adding-materials .material-cell { max-width: 460px }
.adding-materials .material-group { margin-bottom: var(--space-3); text-align: center }
.adding-materials .material-group b { display: block; margin-bottom: 4px; font-size: 13px }
/* One width for every group, or each dropdown sizes to its own longest fabric name. */
.adding-materials .material-group select { width: 100%; max-width: 440px }

/* Everything about one cloth in one column, read top to bottom: what it is, what is on
   the shelf, then the figures that change it. */
.adding-materials .meter-cell { text-align: center }
.adding-materials .meter-panel {
    display: inline-flex; flex-direction: column; align-items: stretch;
    gap: 6px; width: 260px; text-align: center;
}
/* Direct children only: "In stock:" and its figure stay on one line. */
.adding-materials .meter-panel > b,
.adding-materials .meter-panel > label { display: block }
.adding-materials .decimal-note { display: block; font-size: 12px; color: var(--quiet) }
.adding-materials .meter-panel label { font-size: 13px; margin-top: var(--space-2) }
.adding-materials .meter-panel .figure { width: 100%; text-align: center }
.adding-materials .meter-panel .btn { margin-top: var(--space-3) }

/* One cloth on a delivery: what was ordered on the left, what turned up on the right. */
.adding-materials .fabric-item {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    padding-bottom: var(--space-3); margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--line); text-align: left;
}
.adding-materials .fabric-item:last-of-type { border-bottom: none }
.adding-materials .fabric-item .production-name { margin-left: var(--space-2); font-weight: 600 }
.adding-materials .fabric-item .expected { font-size: 13px }
.adding-materials .fabric-item .figure { width: 120px; margin-top: 4px }

/* Four sizes side by side, each with its count and the boxes that change it. */
.adding-materials .piece-sizes-heading { margin-top: var(--space-3) }
.adding-materials .piece-sizes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) }
/* Four counts two abreast need more room than a single column of figures. */
.adding-materials .meter-panel:has(.piece-sizes) { width: 400px }
.adding-materials .piece-size { text-align: left }
/* One line: the count wrapping pushes that column's boxes below the other's. */
.adding-materials .piece-size label { font-size: 12px; line-height: 1.3; white-space: nowrap }
.adding-materials .piece-size .figure { width: 100%; margin-top: 4px }

/* Hidden fields only: they carry the choice the controls above write against. */
#receive-materials, #receive-delivery { display: none }

/* Missing foams is read in two halves: the made-up sets, then the rolls. */
#missing-foams tr.foam-kind td {
    padding: var(--space-4) var(--space-2);
    background: rgb(209, 212, 218); color: rgb(0, 0, 0);
    font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: .08em;
    text-align: center;
    border-top: 3px solid var(--page); border-bottom: none;
}

/* A band of page colour between one foam and the next, as the old screen separates
   them, so a long block cannot be read as running into the one below. */
#missing-foams tbody + tbody tr:first-child td { border-top: 8px solid var(--page) }

#missing-foams tr.foam-kind .muted {
    margin-top: 4px;
    font-weight: 400; font-size: 12px; text-transform: none; letter-spacing: 0;
}

/* --- materials ordered: the colour is the screen --- */

/* Each swatch and its words are one item, or the flex gap opens between them. */
.legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5); margin: 0 0 var(--space-4); font-size: 13px; color: var(--ink) }
.legend-item { display: inline-flex; align-items: center; gap: 8px }
.legend-key { width: 12px; height: 12px; border-radius: 50%; border: 1px solid rgba(0, 0, 0, .18); flex: none }

/* The old screen's own three, not paler versions of them. supplier-stock:672 */
.legend-key.is-overdue, #materials-ordered tr.is-overdue td { background: #FF8A65 }
.legend-key.is-coming, #materials-ordered tr.is-coming td { background: #FFFF8D }
.legend-key.is-arrived, #materials-ordered tr.is-arrived td { background: #81C784 }
#materials-ordered tr.is-no-date td { background: var(--card) }

/* The row is coloured, so its controls must sit on white to stay readable. */
#materials-ordered input[type=text] { background: #fff }

/* The code under the name, as the old screen prints it. */
.missing-materials .fabric-code { display: block; font-weight: 400; font-size: 11px; color: rgba(0, 0, 0, .55) }

/* One reference for every order of a fabric, set apart from the rows it covers. */
.missing-materials tr.all-orders-row td { background: #fbfcfd; border-bottom: 2px solid var(--faint) }
.missing-materials tr.all-orders-row .muted { display: block; margin-bottom: 4px; font-size: 12px; line-height: 1.4 }
.missing-materials tr.all-orders-row u { font-weight: 600 }

/* An order number is one token; wrapping splits "29810-P" across two lines. */
/* The number on one line, its date under it, as the old screen sets them. */
.missing-materials .order-id { white-space: nowrap; line-height: 1.4 }
.missing-materials .metres-cell { line-height: 1.4 }

/* An order's products are listed one under the other, ruled apart as the old screen rules them. */
.missing-materials .metres-cell .cut + .cut { margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--line) }

/* Long names wrap inside their own column instead of running into the next. */
.missing-materials .production-name { white-space: normal; overflow-wrap: anywhere; line-height: 1.4 }

/* The controls sit on one line and share the height of the button beside them. */
.inline-form { display: flex; align-items: center; justify-content: center; gap: var(--space-2) }
.missing-materials input[type=text],
.missing-materials input[type=date] {
    height: 34px; padding: 0 6px; border: 1px solid var(--line);
    border-radius: var(--radius); background: #fff; font: inherit; font-size: 12px; min-width: 0; flex: 1; width: 100%
}
.missing-materials .date-field { cursor: pointer; font-variant-numeric: tabular-nums; text-align: center }
.missing-materials .date-field::placeholder { color: var(--faint) }
.missing-materials input[type=text]:focus { outline: 2px solid var(--ink); outline-offset: -1px }

/* --- the delivery calendar --- */

/* One for the page, moved under the field that asked for it by missing-materials.js.
   Keep the .14s in step with the close in that file, or it vanishes instead of fading. */
.calendar {
    position: fixed; z-index: 50; width: 268px; padding: var(--space-3);
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 14px 32px rgba(17, 24, 28, .18);
    opacity: 0; transform: translateY(-6px) scale(.985);
    transition: opacity .14s ease, transform .14s ease;
}
.calendar.is-open { opacity: 1; transform: none }

.calendar-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2) }
.calendar-month { font-size: 13px; font-weight: 600 }
.calendar-step {
    width: 28px; height: 28px; padding: 0; font-size: 16px; line-height: 1; cursor: pointer;
    background: none; border: 1px solid transparent; border-radius: var(--radius); color: var(--quiet)
}
.calendar-step:hover { background: var(--header); color: var(--ink) }

.calendar-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px }
.calendar-weekday { padding: 4px 0; text-align: center; font-size: 11px; color: var(--faint) }

.calendar-day {
    height: 32px; padding: 0; cursor: pointer; font: inherit; font-size: 12px;
    font-variant-numeric: tabular-nums; background: none; border: 1px solid transparent;
    border-radius: var(--radius); color: var(--ink)
}
.calendar-day:hover { background: var(--header) }
/* Today is outlined, the chosen day is filled, so both can show at once. */
.calendar-day.is-today { border-color: var(--faint); font-weight: 600 }
.calendar-day.is-chosen { background: var(--ink); border-color: var(--ink); color: #fff }

.calendar-foot { display: flex; gap: var(--space-2); margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--line) }
.calendar-foot .btn { flex: 1; height: 30px; font-size: 12px; display: inline-flex; align-items: center; justify-content: center }

@media (prefers-reduced-motion: reduce) {
    .calendar { transition: none }
}
.missing-materials .inline-form .btn { height: 34px; padding: 0 var(--space-3); white-space: nowrap }

/* The note, the tick and the date share one cell, sized to hold them and no wider. */
.actions-cell { white-space: nowrap; text-align: center }
.actions-cell .btn { height: 34px; vertical-align: middle; padding: 0 var(--space-2); font-size: 12px }
.actions-cell .btn + .btn { margin-left: 4px }
.btn-note, .btn-save-info { min-width: 34px }
.btn-note.has-note { background: #e24f4f; border-color: #e24f4f; color: #fff }

.missing-materials tr.generate-order-row td { padding: var(--space-4) }
.btn-generate { letter-spacing: .04em }

/* --- home: one box per system --- */
.systems {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
    gap: var(--space-4);
}

.system {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: inherit;
    text-decoration: none;
    /* Colour and shadow only. Moving the box shifts the text under the pointer. */
    transition: border-color .14s, box-shadow .14s;
}

a.system:hover, a.system:focus-visible {
    border-color: var(--ink);
    box-shadow: 0 1px 3px rgb(20 22 26 / 12%);
}

.system-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em }

.system-logs { gap: var(--space-2) }
.system-logs-main { color: inherit; text-decoration: none }
.system-logs-main:hover,.system-logs-main:focus-visible { text-decoration: underline }
.system-logs-shortcuts { display: grid; margin-top: auto }
.system-logs-shortcuts a {
    display: block;
    padding: 2px 0;
    color: var(--quiet);
    font-size: 12px;
    line-height: 1.3;
    text-decoration: none;
}
.system-logs-shortcuts a:hover,.system-logs-shortcuts a:focus-visible {
    color: var(--ink);
    text-decoration: underline;
}

/* Pushed to the foot, so the figure sits on one line across boxes of unequal height. */
.system-figure { margin-top: auto; font-size: 13px; font-weight: 600 }

/* A system that cannot be opened here: dimmed, flat, and refusing the pointer, which is
   what every other disabled control on the screen does. */
.system-off {
    background: transparent;
    border-style: dashed;
    cursor: not-allowed;
    opacity: .55;
}

.system-off .system-figure { font-weight: 400; color: var(--quiet) }

/* The same price on a foam's other pieces: shown, not editable, because the figure it
   would edit is the one on the row above. */
.price-echo { color: var(--quiet) }

/* --- supplier system: the production queues --- */
/* The old screen's own values, from the style block in supplier-system.tpl and the
   .supplier-system rules in the theme's custom.css, including its two web fonts. Staff
   read this every day, so it is copied rather than restyled. */

@font-face {
    font-family: 'Quattrocento';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/quattrocento-v12-latin-ext_latin-700.woff2') format('woff2');
}

@font-face {
    font-family: 'Darker Grotesque';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/darker-grotesque-v2-latin-ext_latin-700.woff2') format('woff2');
}

/* The tab bar: one joined row of buttons, each taking an equal share, label over count.
   The old screen pulls the count up with a negative margin against its own line-height;
   that is a number tuned to a theme this application does not load, so the two lines are
   stacked here instead and the result is the same to look at. */
/* One line, as the old screen has it. The labels are already short enough for twelve
   tabs to fit; nowrap keeps them from stacking if a window is narrow, and the row scrolls
   sideways rather than wrapping into two. */
.section-buttons { display: flex; flex-wrap: nowrap; width: 100%; text-align: center; margin: 0 0 var(--space-4); overflow-x: auto }
.section-button {
    background-color: #dedede;
    padding: 6px 9px 7px;
    font-family: 'Darker Grotesque', sans-serif;
    font-size: 18px;
    line-height: 1.15;
    cursor: pointer;
    flex: 1 1 auto;
    white-space: nowrap;
    border: 1px solid #111;
    border-radius: 0;
    color: inherit;
    text-decoration: none;
}
.section-button:first-child { border-top-left-radius: 4px; border-bottom-left-radius: 4px }
.section-button:last-child { border-top-right-radius: 4px; border-bottom-right-radius: 4px }
.section-button:not(:last-child) { border-right: none }
.section-button.selected, .section-button:hover { background-color: #c8d1d2 }
.section-button .text1 { font-weight: 700 }
.section-button .text2 { font-size: 16px; font-weight: 500 }

/* The key. Four coloured circles, and what each means differs by screen. */
.colors_info { margin: 0 0 12px }
.colors_info .color_info_wrapper { display: inline-block }
.colors_info .green, .colors_info .yellow, .colors_info .red, .colors_info .gold,
.colors_info .text { display: inline-block; vertical-align: middle }
.colors_info .text { margin-left: 3px; margin-right: 15px; margin-top: -3px }
.colors_info .green, .colors_info .yellow, .colors_info .red, .colors_info .gold {
    width: 20px; height: 20px; border-radius: 50px; border: 1px solid #212121;
}
.colors_info .green { background-color: #81C784 }
.colors_info .yellow { background-color: #FFFF8D }
.colors_info .red { background-color: #FF8A65 }
.colors_info .gold { background: linear-gradient(145deg,#f9d77e 0%,#f6c54d 22%,#f9d77e 45%,#f6c54d 78%,#f9d77e 100%) }

h5 { font-family: 'Quattrocento', serif; font-size: 20px; font-weight: 700; margin: 0 0 8px }

/* Every cell is centred on the old screen, headers included. */
/* Collapsed, because a row spanning several lines only lines its borders up with its
   neighbours' when they share them. Separate borders left a 1px step wherever a cell
   spanned two products. */
.supplier-system { width: 100%; border-collapse: collapse; border: 1px solid #ddd }

/* --- supplier system: column widths --- */
/* Fixed, or each tab sizes its columns to its own rows and they stand somewhere else on
   every one: Number measured 92px on 11A and 315px on 11 - Balcony, Foam 103px and 514px.
   Product / Fabric takes whatever is left. The classes come from Screen::columnClasses()
   - keep the names. */
.supplier-system { table-layout: fixed; min-width: 1280px }
.supplier-system col.column-number { width: 160px }
.supplier-system col.column-order-date { width: 120px }
.supplier-system col.column-product-fabric { width: auto }
.supplier-system col.column-foam { width: 300px }
.supplier-system col.column-pcs { width: 60px }
.supplier-system col.column-shipment-date { width: 150px }
.supplier-system col.column-latest-shipping { width: 150px }
.supplier-system col.column-expected-materials-date { width: 170px }
.supplier-system col.column-customer { width: 240px }
.supplier-system col.column-samples { width: auto }
.supplier-system col.column-date-sent { width: 140px }
.supplier-system col.column-print { width: 200px }
.supplier-system col.column-unnamed { width: 130px }

/* 11.1 and 11.2 carry the whole ship form in these two columns - the foam chooser with its
   stock pieces and leftovers, and the two staff selects above the buttons. */
.supplier-system.on-inproduction, .supplier-system.on-toship { min-width: 1440px }
.supplier-system.on-inproduction col.column-foam,
.supplier-system.on-toship col.column-foam { width: 420px }
.supplier-system.on-inproduction col.column-print,
.supplier-system.on-toship col.column-print { width: 260px }

/* The two sample tabs. One row per order rather than per line, and the swatch list is
   the long column - the proportions are the old screen's: a narrow number, two middling
   columns of date and customer, the swatches taking what is left, and the buttons. */
.supplier-system.on-samples { min-width: 1100px }
.supplier-system.on-samples col.column-number { width: 130px }
.supplier-system.on-samples col.column-order-date { width: 220px }
.supplier-system.on-samples col.column-customer { width: 210px }
.supplier-system.on-samples col.column-samples { width: auto }
.supplier-system.on-samples col.column-date-sent { width: auto }
.supplier-system.on-samples col.column-unnamed { width: 190px }
.supplier-system th, .supplier-system td { text-align: center; vertical-align: middle }

/* The header follows the rows down. Collapsing drops the borders off a sticky cell, so it
   draws them as an inset shadow instead - the same trick the stock tables use. */
/* The section's own name stays with its columns: on the All tab there are nine tables one
   after another, and a row of headings with no status above it says nothing. */
.supplier-system-heading {
    position: sticky;
    top: 0;
    z-index: 3;
    background: #EEF0F2;

    /* 20px of Quattrocento plus this padding is the 46px the column headers sit below.
       Pulled out to the page's edges so the band is unbroken while it is pinned. */
    margin: 0 -16px;
    padding: 10px 16px 8px;
    line-height: 28px;
}

.supplier-system thead .history-title {
    position: sticky;
    top: 46px;
    z-index: 2;
    font-family: 'Quattrocento', serif;
    font-size: 16px;
    font-weight: 700;
    padding: 10px 5px;
    background: #ededeb;
    box-shadow: inset -1px 0 0 #ddd, inset 0 -1px 0 #ddd;
}
.supplier-system thead .history-title:last-child { box-shadow: inset 0 -1px 0 #ddd }
.supplier-system tbody tr { font-family: 'Darker Grotesque', sans-serif; font-weight: 700; font-size: 17px }
.supplier-system td { border: 1px solid #ddd; padding: 7px 5px }


.supplier-system .order_heading { font-weight: 900; font-size: 22px; line-height: 22px }
.supplier-system .order_confirmed_date { font-weight: 500; font-size: 15px; line-height: 1.2; margin-top: 6px }
.supplier-system .product_name_label { border-bottom: 1px solid #636363; padding-bottom: 10px; margin-bottom: 10px }
/* A line whose product is not set up: why its production name, cloth and metres are missing. */
.supplier-system .not_set_up_note { margin-bottom: 10px; color: #a12d2d; font-weight: bold }
.supplier-system .not_set_up_note a { color: inherit; text-decoration: underline }
.supplier-system .td_text { line-height: 1.4em }
.supplier-system .measured { font-size: 15px; font-weight: 500 }
.supplier-system .measured span { margin: 0 4px }

/* The metre workings, each in its own box, as the developer's view stacks them. The box
   is tinted a shade of whatever colour the row is - the old screen writes the three
   values inline against ship_color. */
.supplier-system .meters_required_wrapper {
    border: 1px solid #706e6e;
    border-radius: 3px;
    padding: 5px 8px;
    margin: 10px auto;
    max-width: 300px;
    font-weight: 500;
}
.supplier-system tr.ship-green .meters_required_wrapper { background-color: #9dd29f }
.supplier-system tr.ship-yellow .meters_required_wrapper { background-color: #f9f99f }
.supplier-system tr.ship-red .meters_required_wrapper { background-color: #f49172 }
.supplier-system tr.is-express .meters_required_wrapper {
    background: linear-gradient(145deg,#f9d77e 0%,#f6c54d 22%,#f9d77e 45%,#f6c54d 78%,#f9d77e 100%);
    color: #4a3c00;
}

/* The piece this line will be cut from, ruled off inside the In Stock bar it belongs to.
   supplier-system.tpl:4519. */
.supplier-system .fabric-piece-area { margin: 5px 8px 0 }
.supplier-system .fabric-piece-type,
.supplier-system .fabric-piece-type-ref {
    border-top: 1px solid rgba(255, 255, 255, .45);
    padding-top: 5px;
    font-size: 15px;
    line-height: 15px;
    cursor: default;
}

/* The row colour is the screen: how near an order is to its date, or gold for express. */
.supplier-system tr.ship-green > td { background-color: #81C784 }
.supplier-system tr.ship-yellow > td { background-color: #FFFF8D }
.supplier-system tr.ship-red > td { background-color: #FF8A65 }
.supplier-system tr.is-express > td {
    background: linear-gradient(145deg,#f9d77e 0%,#f6c54d 22%,#f9d77e 45%,#f6c54d 78%,#f9d77e 100%);
    color: #4a3c00;
}

/* The two stock badges, in the old screen's colours: supplier-system.tpl:4267 and :4311.
   They sit under the metres box, hence the negative top margin that pulls them onto it. */
.supplier-system .in_stock,
.supplier-system .out_of_stock { color: #fff; border: 1px solid #706e6e; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; padding: 4px 0; cursor: default; text-align: center;
    /* The same width as the box it hangs off, or it juts out past both its edges. The
       -16px meets that box's 15px bottom margin and its border, so the two touch. */
    max-width: 300px; margin: -16px auto 10px }
.supplier-system .in_stock { background-color: #3a8e4c }
.supplier-system .out_of_stock { background-color: #e53905 }
.supplier-system .in_stock .text,
.supplier-system .in_stock_express .text,
.supplier-system .out_of_stock .text { margin-left: 5px; font-weight: 600 }

/* Express wears gold everywhere else on the row, so the bar does too: tpl:4290. */
.supplier-system .in_stock_express {
    background: linear-gradient(145deg, #deba5b, #f6c54d 22%, #cda53a 45%, #f6c54d 74.37%, #d3a01a);
    color: #4a3c00;
    border: 1px solid #706e6e;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 3px;
    padding: 4px 0;
    cursor: default;
    text-align: center;
    max-width: 300px;
    margin: -16px auto 10px;
}
.supplier-system .in_stock_express .fabric-piece-type,
.supplier-system .in_stock_express .fabric-piece-type-ref { border-top-color: rgba(74, 60, 0, .35) }

/* The foam estimate box, as the old screen frames it: supplier-system.tpl:886. */
.supplier-system .foam_estimations { border: 1px solid #706e6e; border-radius: 3px; margin: 8px auto 0; max-width: 320px }
.supplier-system .foam_estimations .meters_required { padding: 4px 8px }
.supplier-system .foam_estimations .meters_required + .meters_required { border-top: 1px solid #706e6e }
.supplier-system .estimation_text_info_waste { color: #e53905; font-size: 13px }
.supplier-system .estimation_text_info { font-size: 13px; font-weight: 400 }
.supplier-system .foam_estimations.foam_estimations_out_stock { border-bottom-left-radius: 0; border-bottom-right-radius: 0; margin-bottom: 15px }

/* A made-up set, named in the Foam column in place of the cutting estimate. */
.supplier-system .foam_special { border: 1px solid #706e6e; border-radius: 3px; padding: 4px 8px; margin: 8px auto 0; max-width: 320px }
.supplier-system .foam_special + .out_of_stock_foam,
.supplier-system .foam_special + .in_stock_foam { border-top-left-radius: 0; border-top-right-radius: 0; margin-top: -1px }
.supplier-system .in_stock_foam { background-color: #3a8e4c; color: #fff; border: 1px solid #706e6e; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; padding: 4px 0; cursor: default; text-align: center; max-width: 320px; margin: 0 auto 10px }
.supplier-system .in_stock_foam .text { margin-left: 5px; font-weight: 600 }

/* The piece 11A prints under the metres box, joined to it. */
.supplier-system .fabric-piece-area-under { max-width: 300px; margin: -10px auto 10px; border: 1px solid #706e6e; border-top: none; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; padding: 4px 8px; font-size: 15px; line-height: 1.3 }
.supplier-system tr.ship-green .fabric-piece-area-under { background-color: #9dd29f }
.supplier-system tr.ship-yellow .fabric-piece-area-under { background-color: #f9f99f }
.supplier-system tr.ship-red .fabric-piece-area-under { background-color: #f49172 }
.supplier-system .fabric-piece-area-under > div { border: 0; padding: 0 }

/* The date the customer was given, under the one the system worked out. */
.supplier-system .original_added_date { margin-top: 8px; font-size: 14px; line-height: 1.2 }

/* The foam's own bar, the same shape as the cloth's but the width of the estimate box. */
.supplier-system .out_of_stock_foam { background-color: #e53905; color: #fff; border: 1px solid #706e6e; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; padding: 4px 0; cursor: default; text-align: center; max-width: 320px; margin: -16px auto 10px }
.supplier-system .out_of_stock_foam .text { margin-left: 5px; font-weight: 600 }

/* The two dark buttons are black on the old screen, not the theme's green. */

/* The box the badge hangs off: its bottom corners stay square so the badge's -16px pull
   meets a straight edge, as it does on the old screen. */
.supplier-system .meters_required_wrapper.holds-the-badge { border-bottom-left-radius: 0; border-bottom-right-radius: 0; margin-bottom: 15px }

/* The cloth code under the option name, which only the developer's view shows. */
.supplier-system .fabric_name_testing { font-size: 14px }
.supplier-system .fabric-piece-type { text-transform: uppercase }

/* The three buttons stacked in the Print column, full width as the old screen has them. */
/* Column widths in the old screen's proportions. Left to itself the Product and Foam
   columns take half the page each and the boxes inside them stretch with it. */
.supplier-system .col-number { width: 11% }
.supplier-system .col-product { width: 22% }
.supplier-system .col-foam { width: 24% }
.supplier-system .col-date { width: 12% }
.supplier-system .col-pcs { width: 4% }
.supplier-system .col-print { width: 16% }

.supplier-system .order-actions { vertical-align: middle; width: 225px }
.supplier-system .order-actions .btn {
    display: block;
    text-decoration: none;
    width: 100%;
    margin-bottom: 6px;
    padding: 8px 10px;
    font-family: 'Darker Grotesque', sans-serif;
    font-size: 16px;
    font-weight: 700;
    border: 1px solid #111;
    border-radius: 3px;
    cursor: pointer;
}
.supplier-system .order-actions .btn[disabled] { cursor: not-allowed }
.supplier-system .order-actions .btn-default { background: #ededed; color: #111 }
.supplier-system .order-actions .btn-dark { background: #111; color: #fff }
.supplier-system .order-actions .btn[disabled] { opacity: 1 }
/* --- test mode --- */
.test-mode-bar { background: #ffe155; border-bottom: 1px solid #706e6e; padding: 6px 16px; font-size: 14px; text-align: center }

/* --- the comment panel, copied from supplier-system.tpl:4543 --- */

/* Smaller and grey, not one of the full-width buttons beside it. */
.supplier-system .order-actions .btn.comment-btn { background: #dadada; color: #111; padding: 3px 20px; margin-bottom: 5px }
.supplier-system .order-actions .btn.comment-btn.has-comment { background: #e24f4f; color: #fff }

/* Slides down over the row itself: no panel, no border but the one underneath it. */
.supplier-system .comment-form { max-height: 0; overflow: hidden; opacity: 0; margin-top: 0; transition: all .3s ease-in-out }
.supplier-system .comment-form.show { max-height: 350px; opacity: 1; margin-bottom: 15px; border-bottom: 1px solid; padding-bottom: 15px; overflow-y: auto }

/* --- submit to ship, on 11.1 --- */
/* The boxes sit inside the Product and Foam cells, as the old screen has them, not in a
   panel of their own. */
/* The old screen's own sizes: width:90px on the metre boxes, width:60px on the offcuts,
   with the theme's input height under them. supplier-system.tpl:2147 and :2500. */
.supplier-system .ship-metres,
.supplier-system .ship-part-rolls input,
.supplier-system .ship-offcut input,
.supplier-system .ship-piece-quantity {
    height: 34px;
    padding: 0 8px;
    text-align: center;
    border: 1px solid #706e6e;
    border-radius: 3px;
    background: #fff;
    font-size: 16px;
}
.supplier-system .ship-metres { width: 90px; margin-top: 6px }
/* Label over box, two columns, as the old screen lays the four sizes out. tpl:2057. */
.supplier-system .ship-part-rolls { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px; margin-top: 5px }
.supplier-system .ship-part-rolls label { display: inline-block; margin: 0; font-weight: 400 }
.supplier-system .ship-part-rolls input { width: 90px }

/* A thick band under the last line of each order, so the eye can tell one order from
   the next in a table where an order can run to four rows. tpl:4224. */
.supplier-system tr.order_line > td,
/* The Number, date and button cells belong to the order's first row and span down to its
   last, so they need the band too or it stops halfway across. */
.supplier-system tbody td[rowspan] { border-bottom: 10px solid #dfdfdf }

/* An express order past its date, shouted at beside the date. tpl:2568. */
.supplier-system .missing_express { font-weight: bold }
.supplier-system .missing_express.is-red { color: red }
.supplier-system .missing_express.is-yellow { color: #f9f99f }

/* The four sizes listed under In Stock, inside the green bar. tpl:2006. */
.supplier-system .part-rolls-held { margin-top: 3px; font-size: 16px; line-height: 1.3 }
.supplier-system .ship-note { font-size: 14px; line-height: 18px; margin: 6px 0 3px }
.supplier-system .ship-foam { margin-top: 8px; text-align: left }
.supplier-system .ship-foam-heading { font-weight: 600; text-align: center; margin: 0 0 4px }

/* Ruled off above and below: the two lines across the Foam column. tpl:4390. */
.supplier-system .foams_checkboxes {
    border-top: 1px solid #706e6e;
    border-bottom: 1px solid #706e6e;
    padding: 5px 0;
    margin: 10px 0;
}

/* The grey note about a cushion longer than a sheet, with its own heading. tpl:4114. */
.supplier-system .pieces_needed_checkbox {
    font-size: 14px;
    font-weight: bold;
    margin-bottom: 8px;
    background-color: rgb(230, 230, 230);
    border-radius: 8px;
    padding: 0 10px 2px;
    text-align: center;
}
.supplier-system .pieces_needed_header { border-bottom: 1px solid rgb(77, 77, 77) }
.supplier-system .estimation_text_info { font-size: 13px; font-weight: 400; text-align: center }

.supplier-system .leftover_label { font-weight: 600; text-align: center; margin: 0 0 4px }
.supplier-system .piece-item { display: flex; align-items: center; gap: 8px }
.supplier-system .piece-item label { font-weight: 600; margin: 0 }
.supplier-system .ship-piece-quantity { width: 40px; margin-left: auto; padding: 0 0 0 4px }
.supplier-system .ship-offcut { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 10px }
.supplier-system .ship-offcut input { width: 60px }
.supplier-system .ship-offcut.is-hidden { display: none }

/* The black button that reveals the next offcut row: tpl:4249. */
.supplier-system .add_new_leftover {
    display: block;
    border: 1px solid #000;
    background-color: #000;
    color: #fff;
    border-radius: 3px;
    font-size: 17px;
    padding: 5px 8px;
    width: 136px;
    text-align: center;
    margin: 10px auto 0;
    cursor: pointer;
}

/* Full width, as the old screen sets them: tpl:4602. */
.supplier-system .ship-person { width: 100%; text-align-last: center; margin-bottom: 5px; height: 34px }
.supplier-system .ship-person.is-missing { border: 4px solid red; background-color: #ffebee }

/* How many parcels the carrier label is for, on 11.2: tpl:4089. */
.supplier-system .gls_label_text { display: inline-block; margin-right: 5px; font-size: 16px; font-weight: 800; vertical-align: middle; margin-bottom: 6px }
.supplier-system .gls_label_dropdown { min-width: 50px; display: inline-block; vertical-align: middle; margin-bottom: 5px; height: 34px }

/* FedEx's own colours, which the old screen sets inline on the label link. */
.supplier-system .btn-fedex { background-color: #4D148C; color: #FF6600; border-color: #4D148C }
.supplier-system .btn-fedex:hover { background-color: #3d1070; color: #FF6600 }
.supplier-system .order-actions .ship-person { width: 100%; margin-bottom: 5px }

/* The old theme uppercases every button, so its markup reads "Add Comment" and the
   screen reads ADD COMMENT. Ours has to do the same or the two do not match. */
.supplier-system .order-actions .btn,
.supplier-system .samples_buttons_area .btn { text-transform: uppercase }

/* --- the sample screens, 30 and 31 --- */
/* One row per order rather than per line, so no row spans and no colour key. */
.supplier-system .sample_line td { vertical-align: top; padding: 8px 10px }
.supplier-system .product_sample { max-width: 460px }
.supplier-system .sample-place { color: #555; font-size: 15px }
.supplier-system .sample-not-exist { color: red; font-size: 16px }
.supplier-system .sample-paid { font-size: 15px; font-weight: 600; color: #7a1f1f }
/* The old screen paints every sample row this pink, on both 30 and 31. */
.supplier-system .sample_line td { background: #e0b9ce }
.samples-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; margin-bottom: var(--space-4) }
.samples-heading .btn { flex: none }
.supplier-system .samples_buttons_area .btn,
.supplier-system .order-actions .btn[disabled] { width: 100%; margin-bottom: 5px }
.supplier-system .btn[disabled] { opacity: .55; cursor: not-allowed }

.supplier-system .current-comment { margin-bottom: 5px; width: 209px; font-style: italic; text-align: left; font-family: var(--font); font-size: 14px; font-weight: 400; overflow-wrap: anywhere }
.supplier-system .comment-text { width: 209px; font-size: 16px; resize: none; transition: all .3s ease-in-out; font-family: var(--font); padding: 4px; border: 1px solid #706e6e; border-radius: 3px }
.supplier-system .btn-send-comment { background: #111; color: #fff; padding: 3px 20px; margin-top: 5px }

/* 11.1 gives the column more room, so the box is wider there. */
.supplier-system.on-inproduction .current-comment,
.supplier-system.on-inproduction .comment-text { width: 291px }

.supplier-system .not-built { font-family: var(--font); font-weight: 400; font-size: 11px; color: #4a4a4a }

/* The Orders panel. Cloth arriving is the one row that adds rather than takes, and a
   reservation has not happened yet - the old panel greens the first and greys the
   second. */
.history-table tr.cloth-arriving > td { background: #f1fbf1 }
.history-table tr.cloth-arriving .log { color: #187628 }
.history-table tr.still-waiting .log { color: #7a7a7a; font-style: italic }

/* The filter on the left, the fabric centred, and a spacer of the same width on the
   right so the middle is centred on the panel rather than on what is left of it. */
.panel-head-orders { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px }
.panel-head-orders .panel-filter { width: 300px; flex: 0 0 300px }
.panel-head-orders .panel-filter input { width: 100% }
.panel-head-orders .panel-middle { flex: 1; text-align: center }
.panel-head-orders .panel-middle h2 { margin: 0 0 6px }
.panel-head-orders .panel-pieces { margin: 0 0 6px }
.panel-head-orders .panel-totals { display: inline-block; margin: 0; border: 1px solid #706e6e; border-radius: 3px; padding: 4px 12px }
.panel-pieces .piece-ref { color: #666 }

/* Every column centred, as the old panel has them: these are figures to compare down a
   column rather than prose. The log is the one thing that reads as a sentence. */
.fabric-orders th,
.fabric-orders td { text-align: center; vertical-align: middle }
.fabric-orders .log { text-align: center; line-height: 1.4 }

/* --- products --- */
/* A second action beside a main one. Sets every colour the global button rule sets. */
.button-quiet { padding: 6px 12px; font-size: 13px; background: var(--card); color: var(--ink); border: 1px solid var(--line); border-radius: 6px }
.button-quiet:hover { border-color: var(--faint); opacity: 1 }
/* Beside a main button in a page head, the same size as it. */
.page-head .button-quiet { padding: 9px 16px; font-size: 14px }

.products-set-up { max-width: none; margin-bottom: var(--space-5) }
.products-set-up-warning { border-color: #eccaca; background: #fffafa }
.products-set-up-warning h2 { color: #a12d2d }
.products-set-up h2 { margin-bottom: var(--space-2) }
.products-set-up-why { margin: 0 0 var(--space-4); max-width: 60rem; color: var(--quiet) }
.products-waiting { margin-bottom: var(--space-4) }
.products-waiting td { vertical-align: middle }
.products-waiting form { margin: 0 }
/* Status, Shopify id and what is missing under the name; a fabric warning under the fabric. */
.products-waiting-meta { display: block; margin-top: 2px; font-size: 12px }
/* The suggested product, what it gives, then Set up on its own line at the same width on every row. */
.products-waiting-suggested { display: block; font-size: 12.5px }
.products-waiting .products-waiting-set-up { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2) }
.products-waiting-set-up button { width: 7.5rem; justify-content: center }

/* The two choices side by side, the button on their baseline. */
.products-set-up-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto; gap: var(--space-4); align-items: end }
.products-set-up-form .field { margin: 0 }
.products-set-up-form .field select { width: 100% }
@media (max-width: 900px) {
    .products-set-up-form { grid-template-columns: minmax(0, 1fr) }
}

.products-table td { vertical-align: top }
.products-table td:nth-child(4) { max-width: 30rem }
/* Our old-shop id, and the Shopify one under it. */
.product-ids { white-space: nowrap; font-variant-numeric: tabular-nums }
.shopify-id { display: block; color: var(--faint); font-size: 11px }
.made-like { display: block; margin-top: 2px; color: var(--quiet); font-size: 12px }
.cloth-missing { color: var(--bad) }

/* The row a link from the Shopify admin opened. */
.products-table tr:target > td,
.products-waiting tr:target > td { background: #fff8d6 }

.products-not-made { margin-top: var(--space-5); color: var(--quiet) }
.products-not-made summary { cursor: pointer }
.products-not-made ul { margin: var(--space-3) 0 0; padding: 0; list-style: none }
.products-not-made li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); max-width: 40rem; padding: var(--space-2) 0; border-bottom: 1px solid var(--line) }
.products-not-made form { margin: 0 }

/* --- cronjobs --- */
.cronjobs td { vertical-align: top }
.cronjobs td:last-child { max-width: 40rem }
.cronjobs code { font-size: 12.5px; white-space: nowrap }
.cronjobs-elsewhere { margin-top: var(--space-6) }


/* Logs */
.logbook-muted { color:#5b6573; font-size:.9rem; }
.logbook-tabs { display:flex; gap:4px; overflow-x:auto; border-bottom:1px solid #cbd5e1; margin:0 0 20px; }
.logbook-tabs a { flex:none; padding:10px 20px; text-decoration:none; color:#334155; border-bottom:3px solid transparent; }
.logbook-tabs a[aria-current="page"] { border-color:#1d4ed8; color:#1d4ed8; font-weight:700; }
.logbook-filters { display:grid; grid-template-columns:minmax(260px,1fr) repeat(3,minmax(150px,180px)) minmax(180px,220px) max-content; gap:12px; padding:18px; background:#f1f5f9; border:1px solid #cbd5e1; border-radius:8px; align-items:end; }
.logbook-filters-statuses { grid-template-columns:minmax(260px,1fr) repeat(2,minmax(150px,180px)) minmax(180px,220px) max-content; }
.logbook-filters label { min-width:0; display:flex; flex-direction:column; gap:8px; font-weight:600; font-size:.9rem; line-height:1.25; white-space:nowrap; }
.logbook-filters input,.logbook-filters select { display:block; box-sizing:border-box; width:100%; height:44px; min-height:44px; margin:0; padding:0 12px; border:1px solid #94a3b8; border-radius:4px; background:white; color:#172033; font:inherit; }
.logbook-filters input[type="date"] { display:inline-flex; align-items:center; line-height:normal; }
.logbook-filter-actions { display:flex; align-items:center; height:44px; gap:12px; white-space:nowrap; }
.logbook-filter-actions button { display:inline-flex; align-items:center; justify-content:center; height:44px; min-width:92px; border:0; border-radius:4px; background:#1d4ed8; color:white; padding:0 16px; font:inherit; cursor:pointer; }
.logbook-filter-actions a { display:inline-flex; align-items:center; height:44px; }
.logbook-table-scroll { margin:18px 0; overflow-x:auto; border:1px solid #cbd5e1; border-radius:8px; background:#fff; }
.logbook-table { width:100%; min-width:760px; border-collapse:collapse; table-layout:fixed; }
.logbook-table th { padding:11px 14px; border-bottom:1px solid #cbd5e1; background:#f8fafc; color:#475569; font-size:.8rem; text-align:left; }
.logbook-table td { padding:11px 14px; border-bottom:1px solid #e2e8f0; vertical-align:top; line-height:1.35; }
.logbook-table tbody tr:last-child td { border-bottom:0; }
.logbook-table tbody tr:hover td { background:#f8fafc; }
.logbook-table th:first-child,.logbook-table td:first-child { width:175px; }
.logbook-table th:nth-child(3),.logbook-table td:nth-child(3) { width:140px; }
.logbook-table th:nth-child(4),.logbook-table td:nth-child(4) { width:180px; }
.logbook-table th:last-child,.logbook-table td:last-child { width:110px; }
.logbook-status-table { min-width:960px; }
.logbook-status-table th:nth-child(3),.logbook-status-table td:nth-child(3),
.logbook-status-table th:nth-child(4),.logbook-status-table td:nth-child(4) { width:230px; }
.logbook-status-table th:last-child,.logbook-status-table td:last-child { width:180px; }
.logbook-materials-table { min-width:1300px; }
.logbook-materials-table th:first-child,.logbook-materials-table td:first-child { width:165px; }
.logbook-materials-table th:nth-child(2),.logbook-materials-table td:nth-child(2) { width:190px; }
.logbook-materials-table th:nth-child(3),.logbook-materials-table td:nth-child(3) { width:275px; }
.logbook-materials-table th:nth-child(4),.logbook-materials-table td:nth-child(4) { width:135px; }
.logbook-materials-table th:nth-child(5),.logbook-materials-table td:nth-child(5) { width:270px; }
.logbook-materials-table th:nth-child(6),.logbook-materials-table td:nth-child(6) { width:155px; }
.logbook-materials-table th:last-child,.logbook-materials-table td:last-child { width:110px; }
.logbook-materials-table .logbook-table-summary { white-space:normal; overflow-wrap:anywhere; }
.logbook-material-foam,.logbook-material-figures span { display:block; margin-top:3px; }
.logbook-material-figures { color:#475569; font-size:.83rem; }
.logbook-table-event { color:#172033; font-weight:600; text-decoration:none; }
.logbook-table-event:hover { text-decoration:underline; }
.logbook-table-summary,.logbook-table-reference { display:block; overflow:hidden; max-width:100%; margin-top:3px; color:#526071; font-size:.83rem; white-space:nowrap; text-overflow:ellipsis; }
.logbook-table-person { display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.logbook-table-empty { padding:32px 16px !important; text-align:center; }
.logbook-table-empty strong,.logbook-table-empty span { display:block; }
.logbook-table-empty span { margin-top:5px; color:#526071; }
.logbook-entry { border:1px solid #cbd5e1; background:white; border-radius:7px; padding:16px 20px; min-width:0; }
.logbook-meta { display:flex; flex-wrap:wrap; gap:8px 18px; color:#526071; font-size:.85rem; margin:8px 0; overflow-wrap:anywhere; }
.logbook-description { margin:10px 0; overflow-wrap:anywhere; white-space:pre-wrap; }
.logbook-badge { font-size:.75rem; padding:3px 8px; border-radius:4px; color:#334155; background:#e2e8f0; white-space:nowrap; }
.logbook-badge-error { background:#fee2e2; color:#991b1b; }
.logbook-badge-test,.logbook-badge-blocked { background:#fef3c7; color:#854d0e; }
.logbook-details { display:grid; grid-template-columns:minmax(140px,200px) minmax(0,1fr); gap:10px 18px; padding-top:16px; border-top:1px solid #e2e8f0; }
.logbook-details dt { font-weight:600; color:#475569; }
.logbook-details dd { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; }
.logbook-technical { margin-top:20px; padding-top:16px; border-top:1px solid #cbd5e1; }
.logbook-technical summary { cursor:pointer; color:#334155; font-weight:600; }
.logbook-technical h3 { font-size:.9rem; }
.logbook-technical pre { background:#f1f5f9; padding:12px; white-space:pre-wrap; overflow-wrap:anywhere; font-size:.8rem; }
.logbook-pagination { display:flex; justify-content:space-between; margin:20px 0; }
.logbook-order-link { display:inline-block; font-size:12px; margin:4px 0; }
.logbook-validation { color:#991b1b; background:#fee2e2; padding:12px; margin-top:12px; }
@media (max-width:1450px) {
 .logbook-filters { grid-template-columns:repeat(4,minmax(0,1fr)); }
 .logbook-search,.logbook-person,.logbook-filter-actions { grid-column:span 2; }
}
@media (max-width:640px) {
 .logbook-filters { grid-template-columns:repeat(2,minmax(0,1fr)); }
 .logbook-search,.logbook-type,.logbook-person,.logbook-filter-actions { grid-column:1 / -1; }
 .logbook-entry { padding:14px; }
 .logbook-details { grid-template-columns:1fr; gap:4px; }
 .logbook-details dd { margin-bottom:12px; }
}
