/* Iron+Steel Inventory — light UI.
   Structure: fixed sidebar, quiet paper content area, soft pill tags, one ink
   primary action. Type is deliberately large: this gets read at a work table,
   not leaned into. */
:root {
  /* paper and ink */
  --bg: #FAFAF9;
  --panel: #FFFFFF;
  --panel-2: #F4F4F2;
  --line: #E3E3DF;
  --line-soft: #EEEEEA;
  --fg: #16181A;
  --fg-2: #585E64;
  --fg-3: #8A9097;

  /* one accent for focus and links; the primary action is ink, like the mark */
  --accent: #4F46E5;
  --accent-soft: #EFEDFD;

  --green: #1B7F3B;  --green-bg: #E7F6EA;
  --blue:  #1A56C4;  --blue-bg:  #E8F0FE;
  --violet:#5B3FD6;  --violet-bg:#EFEAFE;
  --amber: #8A5D00;  --amber-bg: #FDF1DA;
  --red:   #C0332F;  --red-bg:   #FDEAEA;

  --body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --r1: 8px; --r2: 10px; --r3: 14px;
  --shadow-1: 0 1px 2px rgba(16,18,20,0.05);
  --shadow-2: 0 2px 6px rgba(16,18,20,0.06), 0 1px 2px rgba(16,18,20,0.04);
  --shadow-3: 0 24px 60px rgba(16,18,20,0.18), 0 2px 8px rgba(16,18,20,0.08);

  /* Motion. The built-in CSS easings are too weak to read as intentional. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --fast: 120ms;   /* hover, colour, things seen dozens of times a day */
  --enter: 200ms;  /* occasional surfaces appearing */
  --exit: 130ms;   /* leaving is always quicker than arriving */
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); font: 13px/1.5 var(--body); -webkit-font-smoothing: antialiased; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 { font-family: var(--body); font-weight: 700; letter-spacing: -0.022em; margin: 0 0 10px; }
h1 { font-size: 20px; line-height: 26px; }
h2 { font-size: 16px; line-height: 22px; }
h3 { font-size: 12px; line-height: 20px; }
.muted { color: var(--fg-2); }
.mono { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--fg-2); white-space: nowrap; }
.eyebrow { font: 600 12px/16px var(--body); letter-spacing: 0.07em; text-transform: uppercase; color: var(--fg-3); }

/* ---------------------------------------------------------------- shell */
.shell { display: grid; grid-template-columns: 268px minmax(0, 1fr); min-height: 100vh; }
.side { position: sticky; top: 0; align-self: start; height: 100vh; overflow: auto; background: var(--panel); border-right: 1px solid var(--line); padding: 22px 14px 16px; display: flex; flex-direction: column; gap: 2px; }

.brand { display: block; text-decoration: none; padding: 0 8px 22px; }
.wordmark { display: block; width: 150px; height: auto; }
.brand-sub { display: block; margin-top: 7px; font-size: 12px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }

nav { display: flex; flex-direction: column; gap: 2px; }
nav a { display: flex; align-items: center; gap: 11px; padding: 10px 11px; border-radius: var(--r2); color: var(--fg-2); font-size: 13px; font-weight: 500; text-decoration: none;
  transition: background var(--fast) ease, color var(--fast) ease; }
nav a svg { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; color: var(--fg-3); transition: color var(--fast) ease; }
nav a.active { background: var(--panel-2); color: var(--fg); font-weight: 600; }
nav a.active svg { color: var(--fg); }
@media (hover: hover) and (pointer: fine) {
  nav a:hover { background: var(--panel-2); color: var(--fg); }
  nav a:hover svg { color: var(--fg-2); }
}
nav a:focus-visible, .brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.side-label { margin: 22px 11px 7px; font: 600 13px/16px var(--body); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }

/* Inside the Shopify admin the navigation lives in the admin's own sidebar, so
   ours is dropped and the content gets the full width. s-app-nav is an App
   Bridge element: it renders nothing here, but without this it would fall back
   to showing its link text as plain inline content. */
s-app-nav { display: none; }
body.embedded .side { display: none; }
body.embedded .shell { grid-template-columns: minmax(0, 1fr); }

/* The mode badge used to sit in the sidebar foot. It is the one thing that must
   never be missed, so with the sidebar gone it gets its own bar instead. */
/* A request in flight. The bar sits at the very top of the content, travels
   left to right, and is the only thing on screen that moves, so a press that is
   waiting on the network never looks like a press that did nothing. It is
   painted only while body.busy is set, which the request counter controls. */
.loadbar { position: sticky; top: 0; z-index: 30; height: 3px; overflow: hidden; background: none; }
.loadbar::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 40%;
  background: linear-gradient(90deg, transparent, var(--fg), transparent);
  transform: translateX(-100%); opacity: 0;
  transition: opacity var(--fast) ease;
}
body.busy .loadbar::after { opacity: 1; animation: loadbar 1.1s var(--ease-in-out) infinite; }
@keyframes loadbar { from { transform: translateX(-100%); } to { transform: translateX(350%); } }
body.busy { cursor: progress; }
/* Buttons keep their hover affordance but should not invite a second press. */
body.busy button, body.busy .btn { pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  body.busy .loadbar::after { animation: none; transform: none; width: 100%; opacity: 0.5; }
}

.topbar { display: flex; justify-content: flex-end; padding: 18px 34px 0; }
.topbar .mode { width: auto; }

/* Mode is the one thing on screen that must never be misread. */
.mode { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 11px; border-radius: var(--r2); border: 1px solid var(--line); background: var(--panel-2); font-size: 13px; font-weight: 600; color: var(--fg-2); cursor: pointer;
  transition: background var(--fast) ease, border-color var(--fast) ease, color var(--fast) ease; }
.mode::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: currentColor; flex: none; }
.mode.live { background: var(--green-bg); border-color: #CBE7D3; color: var(--green); }
.mode.shadow { background: var(--amber-bg); border-color: #F0E0BC; color: var(--amber); }
.mode.killed { background: var(--red-bg); border-color: #F5CFCE; color: var(--red); }
@media (hover: hover) and (pointer: fine) { .mode:hover { border-color: var(--fg-3); } }

/* A sortable heading is a link, but it should still read as a table heading:
   same weight and colour, with the arrow carrying the state. */
th.sortable { padding: 0; }
th.sortable a { display: block; padding: 9px 12px; text-decoration: none; color: inherit; white-space: nowrap;
  transition: background var(--fast) ease, color var(--fast) ease; }
th.sortable.num a { text-align: right; }
th.sorted a { color: var(--fg); }
@media (hover: hover) and (pointer: fine) { th.sortable a:hover { background: var(--line-soft); color: var(--fg); } }
th.sortable a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.content { min-width: 0; }
main { padding: 22px 34px 72px; max-width: 1560px; }
body.embedded main { max-width: none; }

/* ------------------------------------------------------------- primitives */
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.between { justify-content: space-between; }
.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.card { background: var(--panel); padding: 20px; border: 1px solid var(--line); border-radius: var(--r3); box-shadow: var(--shadow-1); transition: border-color var(--fast) ease, box-shadow var(--fast) ease; }
.card h3 { margin-bottom: 10px; }
.stat { font-size: 24px; line-height: 1.1; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; margin: 6px 0 2px; }
.stat.warn { color: var(--amber); }
.stat.bad { color: var(--red); }
.rule { height: 3px; width: 32px; background: var(--fg); border-radius: 2px; margin: 10px 0 20px; }

/* ----------------------------------------------------------------- tables */
table { width: 100%; border-collapse: separate; border-spacing: 0; margin: 12px 0 22px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r3); box-shadow: var(--shadow-1); }
th { text-align: left; font: 600 12px/16px var(--body); letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-3); padding: 9px 12px; background: var(--panel-2); position: sticky; top: 0; z-index: 2; white-space: nowrap; }
th:first-child { border-top-left-radius: var(--r3); }
th:last-child { border-top-right-radius: var(--r3); }
td { text-align: left; padding: 6px 12px; border-top: 1px solid var(--line-soft); vertical-align: middle; font-size: 13px; }

/* ---- scanning a long list ------------------------------------------------
   A list of 500 materials is read by sweeping down one column, so a row has
   to be one line tall and only the thing being looked for may carry colour.
   Names do not wear link blue or an underline until pointed at; everything
   that is context rather than answer is set in the muted grey. */
td.name { max-width: 0; width: 99%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
td.name a { text-decoration: none; font-weight: 500; }
@media (hover: hover) and (pointer: fine) { td.name a:hover { text-decoration: underline; } }
td.name .sub { margin-left: 9px; font-size: 12px; color: var(--fg-3); }
td.quiet { color: var(--fg-2); }
td.num.quiet { color: var(--fg-2); }
td.stock { font-weight: 600; color: var(--fg); }

/* Out and low are the row, not a badge on the row. On the reorder page every
   line is low already, so .flat keeps the number's colour and drops the tint. */
tr.low > td { background: var(--amber-bg); }
tr.out > td { background: var(--red-bg); }
tr.low > td.stock { color: var(--amber); }
tr.out > td.stock { color: var(--red); }
tr.flat > td { background: none; }

/* Row actions are for the row you are on, not for all five hundred at once.
   They also set the row's height even while hidden, so they are sized to sit
   inside the line rather than stretch it. */
/* The row actions are lifted out of the layout entirely. Left in flow they
   reserved close to 200px on every row for buttons that are invisible until
   the pointer is on that row, and that width came straight out of the name,
   which is the column actually being read. The cell now measures nothing and
   the buttons float over the right edge only while the row is hovered. */
td.actions { padding: 0; width: 1%; position: relative; }
.acts { position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  display: flex; gap: 8px; white-space: nowrap; padding-left: 14px;
  /* No backdrop and no hit area while the buttons are hidden: the span sits
     over the last two columns, so a background here would paint the row's tint
     across Cost and Used by on every tinted row, and a live pointer area would
     swallow clicks meant for the cells underneath. */
  background: none; pointer-events: none; }
/* Only once the buttons are actually showing does the backdrop come with them,
   inheriting the row's own colour so they never sit on a white patch. */
tr:hover > td.actions .acts { background: inherit; pointer-events: auto; }
/* Fade the buttons, not the cell: opacity on the cell would take its tint with
   it and leave a white notch at the end of every coloured row. */
td.actions button { padding: 2px 9px; font-size: 12px; line-height: 18px; box-shadow: none;
  opacity: 0; transition: opacity var(--fast) ease; }
tr:hover > td.actions button, td.actions button:focus-visible { opacity: 1; }
@media (hover: none) { td.actions button { opacity: 1; } }

/* Numbers and short labels take only what they need; the name takes the rest. */
td.quiet, td.num, th.num, th.sortable:not(:first-child) { width: 1%; white-space: nowrap; }
/* The action column holds the row's buttons; they belong side by side, and the
   column should take whatever width that needs rather than stacking them. */
td:last-child, th:last-child { white-space: nowrap; width: 1%; }
td:last-child button + button { margin-left: 8px; }
/* Tables nested in a dashboard card are a summary, not the record. They lose
   the frame and tighten up so a name like "Tee / Adult / Black / L" stays on
   one line in a 340px column. */
.card table { border: none; box-shadow: none; margin: 4px 0 0; background: transparent; }
.card th { background: transparent; padding: 8px 6px; }
.card td { padding: 10px 6px; font-size: 13px; }
.card td:first-child { padding-left: 0; }
.card td:last-child, .card th:last-child { padding-right: 0; }
.card tbody tr:first-child td { border-top: none; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.num { font-size: 13px; }
tbody td { transition: background var(--fast) ease; }
@media (hover: hover) and (pointer: fine) { tbody tr:hover td { background: #FBFBF9; } }

.tag { display: inline-flex; align-items: center; border-radius: 999px; padding: 2px 9px; font: 500 12px/18px var(--body); background: var(--panel-2); color: var(--fg-2); margin-right: 5px; white-space: nowrap; }
.tag.ok { background: var(--green-bg); color: var(--green); }
.tag.warn { background: var(--amber-bg); color: var(--amber); }
.tag.bad { background: var(--red-bg); color: var(--red); }
.tag.print { background: var(--violet-bg); color: var(--violet); }
.tag.blank { background: var(--blue-bg); color: var(--blue); }

/* ---------------------------------------------------------------- controls */
/* .btn is worn by links as well as buttons. A button centres its own label; an
   anchor does not, so anything given a fixed height needs to say so itself. */
button, .btn { display: inline-flex; align-items: center; justify-content: center; text-align: center; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); color: var(--fg); padding: 7px 14px; font: 500 13px/20px var(--body); cursor: pointer; border-radius: var(--r2); box-shadow: var(--shadow-1);
  transition: background var(--fast) ease, border-color var(--fast) ease, color var(--fast) ease, box-shadow var(--fast) ease, transform var(--fast) var(--ease-out); }
button.primary { background: var(--fg); border-color: var(--fg); color: #fff; font-weight: 600; }
button.ghost { background: transparent; box-shadow: none; color: var(--fg-2); }
button.danger { background: var(--red-bg); border-color: #F2C8C7; color: var(--red); }
button.small { padding: 4px 10px; font-size: 13px; border-radius: var(--r1); }
@media (hover: hover) and (pointer: fine) {
  button:hover:not(:disabled), .btn:hover { border-color: var(--fg-3); box-shadow: var(--shadow-2); }
  button.primary:hover:not(:disabled) { background: #2C3033; border-color: #2C3033; }
  button.ghost:hover:not(:disabled) { background: var(--panel-2); color: var(--fg); }
  button.danger:hover:not(:disabled) { background: #FBDEDD; border-color: #E9B4B2; }
}
/* A button must feel the press. 60ms so it lands before the finger lifts. */
button:active:not(:disabled), .btn:active { transform: scale(0.97); box-shadow: none; transition-duration: 60ms; }
button:focus-visible, .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button:disabled { opacity: 0.45; cursor: default; box-shadow: none; }

input, select, textarea { background: var(--panel); border: 1px solid var(--line); padding: 7px 11px; min-height: 34px; border-radius: var(--r2); font-size: 13px; width: 100%;
  transition: border-color var(--fast) ease, box-shadow var(--fast) ease; }
/* A native select renders at its own height with its own arrow, so it never
   lined up with the text fields beside it. Same box, one drawn chevron. */
select { appearance: none; -webkit-appearance: none; padding-right: 38px; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23585E64' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 16px 16px; }
select::-ms-expand { display: none; }
/* Number spinners take space and invite mis-clicks on a count field. */
input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="checkbox"], .picker-input { width: auto; }
.picker-input { width: 100%; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input.short { width: 100px; min-width: 100px; text-align: right; font-variant-numeric: tabular-nums; }
input.mid { width: 200px; min-width: 160px; }
label.field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--fg-2); }
label.field > span { font-weight: 600; color: var(--fg); }
label.field > span.hint { font-weight: 400; font-size: 12px; color: var(--fg-2); }
.form { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); margin: 14px 0; }
/* Everything on a filter row is one control height, sitting on one baseline,
   whether it is an input, a select, a checkbox or a button. */
.toolbar { display: flex; gap: 10px; align-items: end; flex-wrap: wrap; margin: 14px 0 18px; }
.toolbar input, .toolbar select, .toolbar button, .toolbar .btn, .toolbar .picker-input { min-height: 34px; height: 34px; }
.toolbar button, .toolbar .btn { padding: 0 14px; font-size: 13px; border-radius: var(--r2); }
.toolbar label.field > span { min-height: 21px; }
.toolbar label.row { display: flex; align-items: center; gap: 9px; height: 34px; font-size: 13px; white-space: nowrap; cursor: pointer; }
.toolbar label.row input[type="checkbox"] { height: 19px; }
.reason { color: var(--amber); font-size: 13px; }
.note { color: var(--fg-2); font-size: 13px; }
.empty { padding: 44px; text-align: center; color: var(--fg-2); font-size: 13px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r3); }

/* ------------------------------------------------------------ transitions */
/* Toast. Enters and leaves through the bottom edge, the direction it lives in,
   so its arrival and dismissal read as the same gesture. The -50% is the
   centring offset and has to survive every keyframe of the animation. */
.toast { position: fixed; bottom: 26px; left: 50%; background: var(--fg); color: #fff; padding: 13px 20px; border-radius: var(--r2); font-size: 13px; font-weight: 500; z-index: 20; max-width: 90vw; box-shadow: var(--shadow-3);
  transform: translate(-50%, 12px); opacity: 0;
  transition: transform var(--exit) var(--ease-out), opacity var(--exit) var(--ease-out); }
.toast.in { transform: translate(-50%, 0); opacity: 1; transition-duration: var(--enter); }
.toast.err { background: #A32A26; }

/* Modal. A modal owns the screen, so it scales from its own centre rather than
   from a trigger. Never from scale(0): nothing in the real world appears from nothing. */
.modal { position: fixed; inset: 0; background: rgba(22,24,26,0.32); backdrop-filter: blur(2px); display: flex; align-items: flex-start; justify-content: center; padding: 56px 16px; overflow: auto; z-index: 10;
  opacity: 0; transition: opacity var(--exit) var(--ease-out); }
.modal.in { opacity: 1; transition-duration: var(--enter); }
.modal-card { background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: 28px; width: min(900px, 100%); box-shadow: var(--shadow-3);
  transform-origin: center; transform: scale(0.97) translateY(-6px);
  transition: transform var(--exit) var(--ease-out); }
.modal.in .modal-card { transform: scale(1) translateY(0); transition-duration: var(--enter); }
/* The rule draws itself once the card has landed. Rare enough to earn it. */
.modal .rule { width: 0; transition: width var(--enter) var(--ease-out) 80ms; }
.modal.in .rule { width: 32px; }

.bar { height: 7px; background: var(--panel-2); border-radius: 999px; position: relative; margin-top: 6px; overflow: hidden; }
.bar > i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 999px; background: var(--fg-3); transition: width var(--enter) var(--ease-in-out), background var(--fast) ease; }
.bar > i.warn { background: #D9A22B; }
.bar > i.bad { background: #D9534F; }

/* A summary card is a list of things, not a spreadsheet. Two columns at most:
   what it is on the left, the one number that matters on the right. Anything
   else belongs on a second, quieter line. */
.list { list-style: none; margin: 12px 0 0; padding: 0; }
.list li { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line-soft); }
.list li:first-child { border-top: none; padding-top: 4px; }
.list li:last-child { padding-bottom: 2px; }
.li-main { min-width: 0; }
.li-main a, .li-main strong { font-size: 13px; font-weight: 600; line-height: 22px; }
.li-meta { display: block; margin-top: 3px; font-size: 12px; line-height: 19px; color: var(--fg-2); }
.li-side { flex: none; display: flex; align-items: center; gap: 8px; padding-top: 1px; font-variant-numeric: tabular-nums; }
.li-count { font-size: 13px; color: var(--fg-2); white-space: nowrap; }
.delta { font-size: 13px; font-weight: 600; }
.shift { font-size: 13px; font-weight: 600; white-space: nowrap; }
.shift i { font-style: normal; color: var(--fg-3); margin: 0 2px; }
.delta.up { color: var(--green); }
.delta.down { color: var(--red); }
/* A row whose right-hand side is a set of choices rather than one value. */
.list li.stack { flex-direction: column; align-items: stretch; gap: 10px; }
/* Separate the decision from the choices it applies to. */
/* A long log reads better as columns than as one tall ribbon. Rows stay whole:
   CSS columns would split one across a break. */
.list.cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); column-gap: 28px; max-height: 520px; overflow-y: auto; }
.list.cols li { border-top: 1px solid var(--line-soft); }
.list.cols li:first-child { padding-top: 12px; }
.list + .row { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.big { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }

/* Checkboxes carry decisions here, so they get a real hit area and their label
   sits close enough to read as one control. */
.checks { display: flex; flex-direction: column; gap: 2px; }
.check { display: flex; align-items: center; gap: 10px; padding: 7px 9px; margin: 0 -9px; border-radius: var(--r1); font-size: 13px; cursor: pointer;
  transition: background var(--fast) ease; }
.check span { line-height: 22px; }
@media (hover: hover) and (pointer: fine) { .check:hover { background: var(--panel-2); } }
input[type="checkbox"] { width: 19px; height: 19px; min-height: 0; padding: 0; margin: 0; flex: none; accent-color: var(--fg); cursor: pointer; }
input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; box-shadow: none; }

/* The setup table: the print name is the field being edited, so it gets the
   room, and the "for" column stays on one line instead of stacking. */
#prints { table-layout: fixed; }
#prints th:nth-child(1) { width: 19%; }
#prints th:nth-child(2) { width: 32%; }
#prints th:nth-child(3) { width: 19%; }
#prints th:nth-child(4) { width: 10%; }
#prints th:nth-child(5) { width: 10%; }
#prints th:nth-child(6) { width: 10%; text-align: center; }
#prints td:first-child .note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#prints td, #prints th { padding-left: 10px; padding-right: 10px; }
#prints td:last-child, #prints th:last-child { width: 10%; text-align: center; white-space: normal; }
#prints td.mid-center { text-align: center; vertical-align: middle; }
#prints input, #prints .picker, #prints .picker-input { width: 100%; min-width: 0; }
#prints .short { width: 100%; min-width: 0; }

/* Searchable picker. A text box that filters a list, standing in for a select
   that would otherwise carry 500 options and size itself to the longest one. */
.picker { position: relative; min-width: 240px; }
.picker-input { width: 100%; }
.picker-list { position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 6px); margin: 0; padding: 6px; list-style: none;
  max-height: 290px; overflow-y: auto; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r2); box-shadow: var(--shadow-3); }
.picker-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 9px 11px; border-radius: var(--r1); cursor: pointer; font-size: 13px; }
.picker-list li em { font-style: normal; font-size: 12px; color: var(--fg-3); white-space: nowrap; }
.picker-list li.on { background: var(--panel-2); }
.picker-list li.picker-none { color: var(--fg-3); cursor: default; }
/* Creating a new vendor is a real option, so it looks like one. */
.picker-list li.picker-new { font-weight: 600; }
.picker-list li.picker-new + li { border-top: 1px solid var(--line-soft); margin-top: 4px; padding-top: 11px; }
/* Selects elsewhere must never out-grow the dialog that holds them. */
select { max-width: 100%; }

details summary { cursor: pointer; color: var(--fg-2); transition: color var(--fast) ease; }
@media (hover: hover) and (pointer: fine) { details summary:hover { color: var(--fg); } }
.recipe { padding: 0; margin: 0; }
.recipe li { list-style: none; padding: 3px 0; }

/* Dashboard cards land in sequence. Decorative only: nothing waits on it, and
   the whole run is over in under 400ms so the page never feels withheld. */
@media (prefers-reduced-motion: no-preference) {
  .grid.stagger > * { opacity: 0; transform: translateY(6px); animation: rise var(--enter) var(--ease-out) forwards; }
  .grid.stagger > :nth-child(1) { animation-delay: 0ms; }
  .grid.stagger > :nth-child(2) { animation-delay: 40ms; }
  .grid.stagger > :nth-child(3) { animation-delay: 80ms; }
  .grid.stagger > :nth-child(4) { animation-delay: 120ms; }
  .grid.stagger > :nth-child(5) { animation-delay: 160ms; }
  .grid.stagger > :nth-child(n+6) { animation-delay: 200ms; }
}
@keyframes rise { to { opacity: 1; transform: translateY(0); } }

@media (max-width: 960px) {
  .shell { grid-template-columns: 1fr; }
  .side { position: static; height: auto; flex-direction: row; align-items: center; gap: 10px; overflow-x: auto; border-right: none; border-bottom: 1px solid var(--line); padding: 12px 16px; }
  .brand { padding: 0 12px 0 0; flex: none; }
  .wordmark { width: 108px; }
  .brand-sub { display: none; }
  nav { flex-direction: row; flex: none; }
  nav a { white-space: nowrap; }
  .side-label { display: none; }
  .side-foot { margin-top: 0; padding-top: 0; margin-left: auto; flex: none; }
  .mode { width: auto; }
  main { padding: 22px 16px 56px; }
  th { position: static; }
}

/* Respect the system setting: keep the state changes, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important; animation-delay: 0ms !important;
    transition-duration: 1ms !important; transition-delay: 0ms !important;
  }
  .grid.stagger > * { opacity: 1; transform: none; }
}
[hidden] { display: none !important; }
