/* Applewood Portal — Applewood Fresh branding (applewoodfresh.com).
   Palette lifted from their logo SVG: script-red #da1f26, leaf-green
   #46a929. White chrome to match their site; the deep green is our own
   darkening of the leaf green so white button text keeps AA contrast.

   ── The standard, in one place (Crew 2026-09-17) ──────────────────────
   Everything below is built from the tokens in :root. Adding a page means
   composing the existing pieces; if a new colour, size or spacing is
   needed, it becomes a token here first so the next page inherits it.

   * Shell     one width (--shell) shared by the header and the page, so
               brand, nav and content sit on the same left edge at every
               window size. Gutters and section spacing scale with the
               viewport; TYPE barely does, because data has to stay
               legible rather than dramatic.
   * Surfaces  --paper is the ground, --card is anything raised. One
               hairline (--border). No shadows anywhere except the one
               menu that floats (the user dropdown).
   * Colour    red is identity and selection; green is commit ("Add",
               "Send order"). Status tints are their own quiet family.
               Nothing is coloured for decoration.
   * Tables    .tbl for data. Add .tbl-cards and a data-label on each cell
               and the rows become readable cards on a narrow window
               instead of scrolling sideways.
   * Pills     one base (.pill) with variants: .st status, .chip filter,
               .test-chip / .freq-chip markers. Same height and radius, so
               they read as one vocabulary.
   * Motion    only the freshness pulse, because how current the stock is
               IS the product. Nothing else moves on its own.
   ---------------------------------------------------------------------- */
:root {
    /* Brand */
    --brand-red: #da1f26; --brand-red-dark: #b0161c; --brand-red-soft: #FBEAEA;
    --green: #46a929; --green-deep: #2f7318; --green-darker: #25610f;
    --green-soft: #E7F5EC;
    --amber: #D97706;

    /* Surfaces — warm near-whites, lightest to deepest */
    --paper: #FBFAF7;      /* page ground */
    --card: #FFFFFF;       /* raised surface */
    --paper-2: #FBF9F4;    /* row hover */
    --sand-1: #F4EFE5;     /* table head, quiet fills */
    --sand-2: #EDE7DA;     /* pressed / secondary fill */
    --border: #E7E2D8;
    --border-strong: #CFC7B5;

    /* Ink */
    --ink: #2A2A26; --ink-2: #504B44; --muted: #7A756C;
    --error: #B4232A; --ok: #1E7A4C;

    /* Layout — one shell for the header and the page. Data pages want the
       room; forms cap themselves with --shell-narrow. */
    --shell: 1440px;
    --shell-narrow: 760px;
    --gutter: clamp(14px, 2.6vw, 32px);
    /* Side rails (order summary, request form) grow with the window but
       never crowd the table beside them. */
    --rail: clamp(290px, 24vw, 370px);

    /* Space scale */
    --s1: 4px; --s2: 8px; --s3: 12px;
    --s4: clamp(16px, 1.6vw, 22px);
    --s5: clamp(22px, 2.4vw, 32px);
    --s6: clamp(34px, 4vw, 56px);

    /* Type — a narrow fluid range: headings flex, data holds still */
    --t-micro: 11px; --t-small: 12.5px; --t-body: 14.5px; --t-lead: 16px;
    --t-h3: clamp(15px, 0.85rem + 0.2vw, 16.5px);
    --t-h2: clamp(17.5px, 1rem + 0.5vw, 21px);
    --t-h1: clamp(22px, 1.25rem + 0.9vw, 29px);

    --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-pill: 999px;
    --shadow-menu: 0 6px 18px rgba(42, 42, 38, .09);
}
* { box-sizing: border-box; }
body { margin: 0; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
       background: var(--paper); color: var(--ink); font-size: var(--t-body);
       line-height: 1.5; -webkit-text-size-adjust: 100%; }
a { color: var(--brand-red); }

/* One visible focus ring for every interactive thing, brand-coloured. */
:focus-visible { outline: 2px solid var(--brand-red-dark); outline-offset: 2px;
                 border-radius: var(--r-sm); }

/* Display face for titles only — the data stays in the fast system sans. */
h1, h2, h3, .card h3 {
    font-family: 'Bricolage Grotesque', 'Segoe UI', system-ui, sans-serif;
    letter-spacing: -.01em;
    text-wrap: balance;
}

/* Compact single-row header: Applewood brand, then channel columns (each
   heading directly above its pages), user chip on the right. No co-brand
   logo — it never sat right (Crew 2026-08-25).

   The bar spans the window; its CONTENTS sit in the same --shell as the
   page, so the logo, the nav and the first table column share one left
   edge at every width. It sticks, because the catalog is long and the nav
   is how you leave it. */
.topbar { background: var(--card); color: var(--ink);
          border-bottom: 1px solid var(--border);
          position: sticky; top: 0; z-index: 30; }
.topbar-inner { display: flex; align-items: center; flex-wrap: wrap;
                gap: clamp(14px, 2.2vw, 30px);
                width: 100%; max-width: var(--shell); margin-inline: auto;
                padding: var(--s2) var(--gutter); }
.brand { display: flex; align-items: center; }
.brand-logo { display: block; height: 42px; width: auto; }
.topbar nav a { color: var(--ink); text-decoration: none; padding: 4px 12px;
                border-radius: 6px; font-size: 13.5px; opacity: .8; }
.topbar nav a:hover { background: var(--brand-red-soft); opacity: 1; }
.topbar nav a.active { background: var(--brand-red-soft); color: var(--brand-red-dark);
                       opacity: 1; font-weight: 600; }

.topbar nav a:focus-visible { background: var(--brand-red-soft); opacity: 1; }

.nav-groups { display: flex; align-items: stretch; gap: 0; flex-wrap: wrap; }
.nav-group { display: flex; flex-direction: column; align-items: center;
             justify-content: center; gap: 2px; }
.nav-group + .nav-group { border-left: 1.5px solid var(--border-strong);
                          margin-left: clamp(12px, 1.6vw, 22px);
                          padding-left: clamp(12px, 1.6vw, 22px); }
.nav-group-label { font-size: 9.5px; text-transform: uppercase;
                   letter-spacing: .11em; font-weight: 700; color: var(--muted);
                   white-space: nowrap; text-align: center; }
.nav-group-links { display: flex; gap: 2px; justify-content: center; }

.top-right { margin-left: auto; display: flex; align-items: center; }

/* User menu — a promoted, always-outlined chip opening a small dropdown. */
.user-menu { position: relative; }
.user-menu summary { list-style: none; display: flex; align-items: center; gap: 9px;
                     cursor: pointer; padding: 5px 12px 5px 6px; border-radius: 999px;
                     border: 1px solid var(--border); background: var(--paper); }
.user-menu summary::-webkit-details-marker { display: none; }
.user-menu summary:hover, .user-menu[open] summary {
    background: var(--brand-red-soft); border-color: var(--brand-red-dark); }
.avatar { display: flex; align-items: center; justify-content: center;
          width: 30px; height: 30px; border-radius: 50%;
          background: var(--brand-red-soft); color: var(--brand-red-dark);
          font-size: 13.5px; font-weight: 700; }
.user-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.caret { font-size: 9px; color: var(--muted); }
.user-dropdown { position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
                 min-width: 200px; background: var(--card);
                 border: 1px solid var(--border); border-radius: var(--r-lg);
                 box-shadow: var(--shadow-menu); overflow: hidden; }
.user-dropdown-head { padding: 11px 14px; font-size: 12.5px; color: var(--muted);
                      border-bottom: 1px solid var(--border); }
.user-dropdown-head b { color: var(--ink); }
.user-email { display: block; margin-top: 2px; font-size: 11.5px; }
.user-dropdown form { margin: 0; }
.user-dropdown-item { display: block; width: 100%; text-align: left; background: none;
                      border: 0; padding: 10px 14px; font-size: 13.5px; cursor: pointer;
                      color: var(--brand-red); font-family: inherit; }
.user-dropdown-item:hover { background: var(--brand-red-soft); }
a.user-dropdown-item { text-decoration: none; box-sizing: border-box; }
.linklike { background: none; border: 0; color: var(--brand-red); text-decoration: underline;
            cursor: pointer; font-size: 13px; margin-left: 8px; }

/* The page shares the header's shell and grows with the window: a catalog
   with room to breathe beats a 1,180px column with empty space beside it. */
.page { width: 100%; max-width: var(--shell); margin-inline: auto;
        padding: var(--s4) var(--gutter) var(--s6); }
/* Forms and prose cap themselves — a 1,400px-wide text field helps nobody. */
.page--narrow { max-width: var(--shell-narrow); }

.page-head { display: flex; align-items: center; gap: var(--s3) var(--s4);
             flex-wrap: wrap; margin-bottom: var(--s4); }
.page-head h1 { margin: 0; font-size: var(--t-h1); font-weight: 700; }
.asof { margin-left: auto; font-size: var(--t-small); color: var(--muted);
        display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; }
.sub-head { font-size: var(--t-h2); margin: 0 0 var(--s3); }
.sub-head + * { margin-top: 0; }
/* A second section under a table needs air above it; this replaced an
   inline style on the Users page. */
.section-gap { margin-top: var(--s5); }

/* The freshness pulse — inventory is produce; how current the numbers are
   IS the product. One quiet animated element, everywhere data is shown. */
.fresh { display: inline-flex; align-items: center; gap: 7px; }
.fresh-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green);
             box-shadow: 0 0 0 0 rgba(70, 169, 41, .45);
             animation: fresh-pulse 3s ease-out infinite; }
@keyframes fresh-pulse {
    0% { box-shadow: 0 0 0 0 rgba(70, 169, 41, .45); }
    70% { box-shadow: 0 0 0 7px rgba(70, 169, 41, 0); }
    100% { box-shadow: 0 0 0 0 rgba(70, 169, 41, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .fresh-dot { animation: none; }
}

/* Keyboard users land here first; invisible until focused. */
.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { left: var(--gutter); top: 6px; z-index: 50; background: var(--card);
                   border: 1px solid var(--brand-red-dark); border-radius: var(--r-sm);
                   padding: 8px 14px; font-size: var(--t-small); }

/* Green is commit — "Add", "Send order". Everything else is a plain button. */
.btn { display: inline-block; padding: 8px 16px; border-radius: var(--r-md);
       font-size: var(--t-body); line-height: 1.25;
       border: 1px solid var(--border); background: var(--card); color: var(--ink);
       cursor: pointer; text-decoration: none; white-space: nowrap;
       transition: border-color .12s ease, background-color .12s ease; }
.btn:hover { border-color: var(--green-deep); }
.btn-primary { background: var(--green-deep); border-color: var(--green-deep); color: #fff; }
.btn-primary:hover { background: var(--green-darker); border-color: var(--green-darker); }
.btn-ghost { background: transparent; }
.btn-sm { padding: 5px 11px; font-size: var(--t-small); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* A search box wider than the longest thing you'd type in it just looks
   unfinished, so it stops growing well before the page does. */
.filters { display: flex; gap: var(--s2); margin-bottom: var(--s4); flex-wrap: wrap; }
.filters input[type=text], .filters input[type=search] {
    flex: 1 1 240px; min-width: 0; max-width: 420px; }
input, select, textarea { padding: 8px 10px; border: 1px solid var(--border);
    border-radius: var(--r-md); font-size: var(--t-body); font-family: inherit;
    background: var(--card); color: var(--ink); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--green-deep); outline-offset: 0; border-color: var(--green-deep); }

/* ── Data tables ──────────────────────────────────────────────────────────
   .tbl is the look. Wrap it in .tbl-wrap so a table that really is too wide
   scrolls inside its own box instead of widening the page. Add .tbl-cards
   and a data-label on every cell and the rows turn into readable cards on a
   narrow window — which beats sideways scrolling on a laptop or a phone. */
.tbl-wrap { width: 100%; overflow-x: auto; border-radius: var(--r-lg); }
/* A table given more room than its content needs does not divide the extra
   evenly — the one column without a fixed width swallows all of it, and the
   name ends up half a screen from its own category. Sizing the WRAPPER to
   max-content stops that at the source: the table is exactly as wide as its
   widest row, and the space left over becomes a gutter between panes rather
   than a void inside a row. Only above the card breakpoint, where there is
   still a table to size. */
@media (min-width: 901px) {
    .tbl-wrap--fit { width: max-content; max-width: 100%; }
}
.tbl { width: 100%; border-collapse: collapse; background: var(--card);
       border: 1px solid var(--border); border-radius: var(--r-lg);
       overflow: hidden; font-size: var(--t-body); }
.tbl th { text-align: left; padding: 9px 12px; background: var(--sand-1);
          font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .06em;
          font-weight: 600; color: var(--muted); white-space: nowrap;
          border-bottom: 1px solid var(--border); }
.tbl td { padding: 10px 12px; border-bottom: 1px solid var(--border);
          vertical-align: middle; }
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tbody tr:hover td { background: var(--paper-2); }
/* Column widths: the name column absorbs what slack there is, every other
   column takes only what it needs and sits next to its neighbour. */
/* Enough that a name column never collapses to one word per line, small
   enough that a column of short references isn't padded out with air. */
.tbl .col-grow { width: auto; min-width: 150px; }
/* width:1px + nowrap is the shrink-to-content idiom. NOT width:1% — a
   percentage column asks the table to be wide enough for its content to BE
   one percent, which inflates the table's intrinsic width and hands the
   slack straight back to the name column. */
.tbl .col-action { width: 1px; white-space: nowrap; text-align: right; }
.tbl .col-tight { width: 1px; white-space: nowrap; }
/* A table of five or six columns caps its measure and sits left. Stretched
   across a 1,900px monitor, one row's values end up a screen apart and you
   lose the row on the way across — so the table stops growing at a width
   where the eye can still travel along a row, and the space that frees up
   goes to something worth reading (see .work-split).
   width:auto so the columns take what they need and no more — a stretched
   table pads its own cells with air. */
.tbl--measured { width: auto; max-width: 1040px; }
/* .tbl th (0,1,1) out-specifies a bare .num (0,1,0), so the header of a
   numeric column needs naming explicitly or it left-aligns over its own
   right-aligned figures. */
.num, .tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.qty-input { width: 84px; text-align: right; padding: 5px 8px; }
/* nowrap: the quantity and its button belong on one line — wrapped, they
   read as two separate controls and double the row height. */
.addform { display: flex; gap: var(--s2); justify-content: flex-end;
           align-items: center; flex-wrap: nowrap; }
.agecell .age { display: inline-block; background: var(--sand-2); border-radius: var(--r-sm);
                padding: 1px 7px; font-size: var(--t-micro); margin: 1px 3px 1px 0; }

/* On-hand is a cap, not a statistic: BelleHarvest rejects a line that asks
   for more than this. It is the number the row is about, so it is the one
   thing set larger than its neighbours. */
.stock { font-size: var(--t-lead); font-variant-numeric: tabular-nums;
         white-space: nowrap; }
.stock-unit { font-size: var(--t-small); color: var(--muted); margin-left: 2px; }
.stock-none { color: var(--muted); }
/* Shown by the quantity input's own script when the ask exceeds the cap. */
.over-limit { color: var(--error); font-size: var(--t-small); display: block;
              margin-top: 3px; max-width: 160px; }
.qty-input.is-over { border-color: var(--error); outline-color: var(--error); }

@media (max-width: 900px) {
    .tbl-cards { border: 0; background: none; }
    .tbl-cards thead { display: none; }
    .tbl-cards, .tbl-cards tbody, .tbl-cards tr, .tbl-cards td { display: block; }
    .tbl-cards tr { background: var(--card); border: 1px solid var(--border);
                    border-radius: var(--r-lg); padding: var(--s3) var(--s4);
                    margin-bottom: var(--s3); }
    .tbl-cards tbody tr:hover td { background: none; }
    /* A label pinned left with its value pinned right leaves a void between
       two things that belong together — the further apart, the harder to
       read across. They sit side by side instead, on a label column sized
       to the longest label, so every value in the card lines up. */
    .tbl-cards td { border: 0; padding: 3px 0; display: grid;
                    grid-template-columns: minmax(84px, max-content) 1fr;
                    gap: 0 var(--s3); align-items: baseline; text-align: left; }
    /* The header text travels with the cell, so a card still says what each
       value is without a header row. */
    .tbl-cards td[data-label]::before { content: attr(data-label);
                    color: var(--muted); font-size: var(--t-small);
                    text-transform: uppercase; letter-spacing: .05em; }
    /* A cell with no label is the row's own identity or its action: one
       full-width column, no label gutter. */
    .tbl-cards td:not([data-label]) { grid-template-columns: 1fr; }
    /* The name and its item code stack, so the code reads as a subtitle
       here exactly as it does in the table. */
    .tbl-cards td.col-grow { padding-bottom: var(--s2); }
    .tbl-cards td.col-grow .item-code { display: block; }
    .tbl-cards td.col-action { padding-top: var(--s3); justify-items: start; }
    .tbl-cards td.thumbcell { padding-bottom: var(--s2); }
    .tbl-cards .addform { justify-content: flex-start; width: 100%; }
    .tbl-cards .qty-input { width: 96px; }
    .tbl-cards .num, .tbl-cards td.num { text-align: left; }
}

/* ── One pill vocabulary ──────────────────────────────────────────────────
   Four things are pill-shaped and they used to disagree on height, radius
   and weight: order status (.st), a filter (.chip), the channel marker
   (.type-chip) and the TEST marker (.test-chip). They share these metrics
   now, so a row of them lines up and reads as one family.

   Status tints are their own quiet scale — amber waiting, blue in hand,
   green done, grey closed, red failed. An unknown status from Belle still
   renders legibly on the .st base. */
.st, .type-chip, .test-chip, .chip {
    display: inline-block; border-radius: var(--r-pill); line-height: 1.5;
    white-space: nowrap; vertical-align: middle;
}
.st { padding: 2px 10px; font-size: 11.5px; font-weight: 600;
      background: var(--sand-2); color: var(--ink-2); }
.st-submitted, .st-needs_review, .st-pending { background: #FEF3C7; color: #92400E; }
.st-approved, .st-queued { background: #DBEAFE; color: #1E40AF; }
.st-pushed, .st-received { background: #D1FAE5; color: #065F46; }
.st-rejected, .st-cancelled { background: #F3F4F6; color: #4B5563; }
.st-push_failed, .st-denied { background: #FEE2E2; color: #991B1B; }

/* Users page (read-only directory + request-new-user) */
.users-grid { display: grid; grid-template-columns: minmax(0, 1fr) var(--rail);
              gap: var(--s5); align-items: start; }
.request-card { background: var(--card); border: 1px solid var(--border);
                border-radius: var(--r-lg); padding: var(--s4) var(--s4); }
.request-card form { display: flex; flex-direction: column; gap: var(--s3);
                     margin-top: var(--s3); }
/* The fieldset only exists so the whole form can be disabled at once; it
   carries the form's own stacking so it adds no box of its own. */
.request-fields { display: flex; flex-direction: column; gap: var(--s3);
                  border: 0; padding: 0; margin: 0; min-width: 0; }
.request-fields:disabled { opacity: .55; }
/* A select is intrinsically as wide as its longest option ("Applewood
   Orchards (Deerfield) — Deerfield, MI"), which would set the card's — and
   on a phone the whole page's — minimum width. A percentage width makes it
   take the card's width instead of dictating it. */
.request-card select { width: 100%; }
.users-grid > * { min-width: 0; }
.request-card label { display: flex; flex-direction: column; gap: var(--s1);
                      font-size: var(--t-small); color: var(--muted); }
.handoff { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.handoff-dismiss { display: inline; margin-left: auto; }
.temp-code { font-size: 14.5px; background: #fff; border: 1px solid var(--border);
             border-radius: 6px; padding: 3px 9px; user-select: all; }
.review-note { display: block; margin-top: 2px; font-size: 12px; }
@media (max-width: 900px) { .users-grid { grid-template-columns: 1fr; } }
.notedot { cursor: help; margin-left: 4px; }
.test-chip { padding: 1px 7px; border-radius: var(--r-sm); font-size: 10px;
             font-weight: 700; background: #FEF3C7; color: #92400E; letter-spacing: .04em; }

/* Marks items ordered before. The catalog already arrives most-ordered
   first, so this just explains why those rows are at the top. */
.freq-chip { color: #C58A16; font-size: 12px; margin-left: 3px; cursor: help; }

/* Order-channel chip in My Orders — both channels share one list, so the
   chip only appears when the merged list is on screen. */
.type-chip { padding: 1px 8px; font-size: 10.5px; font-weight: 700; letter-spacing: .03em; }
.type-finished_goods { background: var(--brand-red-soft); color: var(--brand-red-dark); }
.type-materials { background: var(--green-soft); color: #1F6B42; }

/* Materials category filter chips. The vocabulary comes from BelleHarvest,
   so this styles whatever labels arrive rather than a fixed set. */
/* Labelled filter rows: channel, item-group categories, name-matched types.
   The label column is fixed so several rows stack into a readable grid. */
.chip-row { display: flex; align-items: flex-start; gap: var(--s3);
            margin-bottom: var(--s3); }
.chip-label { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .05em;
              color: var(--muted); font-weight: 600; width: 62px; flex: 0 0 auto;
              padding-top: 7px; }
.chip-row .chips { margin-bottom: 0; }
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0 0 var(--s3); }
.chip { padding: 4px 12px; font-size: var(--t-small);
        border: 1px solid var(--border); color: var(--muted); text-decoration: none;
        background: var(--card);
        transition: border-color .12s ease, color .12s ease; }
.chip:hover { border-color: var(--brand-red); color: var(--brand-red-dark); }
/* Red is selection. It is the only place the brand colour fills a shape. */
.chip.on { background: var(--brand-red); border-color: var(--brand-red);
           color: #fff; font-weight: 600; }

@media (max-width: 620px) {
    /* Stack the label above its chips rather than squeezing both. */
    .chip-row { flex-direction: column; gap: var(--s1); }
    .chip-label { width: auto; padding-top: 0; }
}

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
        font-size: 12px; color: var(--muted); }

/* Packaging photos. Items with no picture in NetSuite show the Applewood
   logo, washed out so it reads as a placeholder, not a product photo. */
.thumbcell { width: 52px; }
.thumb { display: block; width: 44px; height: 44px; border-radius: var(--r-sm);
         object-fit: contain; background: var(--card); border: 1px solid var(--border); }
.thumb-none { padding: 7px; box-sizing: border-box; opacity: 0.35;
              filter: grayscale(35%); }
/* The product name is what you scan for, so it carries the row, with the
   item code as a quiet second line rather than a column of its own — one
   fewer column means the ones that remain stay next to each other instead
   of drifting apart on a wide screen. */
.item-name { font-weight: 600; display: block; }
.item-code { font-size: var(--t-small); margin-top: 1px; }
@media (max-width: 900px) {
    /* In card mode the photo and the name sit together at the top. */
    .tbl-cards .thumb { width: 54px; height: 54px; }
}

.messages { margin-bottom: var(--s3); }

/* Raw Availability — per-variety supply cards with pure-CSS bar charts. */
.ra-intro { margin: 0 0 16px; }
.ra-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px;
           padding: 20px 22px; margin-bottom: 18px; }
.ra-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.ra-head h2 { margin: 0; font-size: 20px; }
.ra-kpis { display: flex; gap: 14px; margin-left: auto; }
.ra-kpi { font-size: 13px; color: var(--muted); }
.ra-kpi b { font-size: 16px; color: inherit; }
.ra-statuses { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 14px; }
.ra-body { display: grid; grid-template-columns: minmax(230px, 1fr) 2fr; gap: 26px; }
.ra-body--single { grid-template-columns: 1fr; }
.ra-body--single .ra-bars { max-width: 560px; }
.ra-col h3 { margin: 0 0 10px; font-size: 14px; }
.ra-bars { display: flex; flex-direction: column; gap: 5px; }
.ra-bar-row { display: flex; align-items: center; gap: 8px; }
.ra-bar-label { width: 44px; text-align: right; font-size: 12px; color: var(--muted);
                font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ra-bar-track { flex: 1; height: 14px; background: #F3F4F6; border-radius: 4px; overflow: hidden; }
.ra-bar-fill { display: block; height: 100%; background: var(--green-deep, #2F6B4F);
               border-radius: 4px; }
.ra-fit-fill { background: var(--brand-red, #B33A3A); opacity: 0.75; }
.ra-bar-val { width: 46px; font-size: 12px; color: var(--muted);
              font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ra-band { white-space: nowrap; font-variant-numeric: tabular-nums; }
.ra-fit { min-width: 160px; }
.ra-fit .ra-bar-track { display: inline-block; width: 90px; vertical-align: middle; }
.ra-fit .ra-bar-val { display: inline-block; margin-left: 6px; }
.ra-note { font-size: 12px; margin-top: 8px; }
@media (max-width: 860px) { .ra-body { grid-template-columns: 1fr; } }
.msg { padding: 10px 14px; border-radius: var(--r-md); font-size: var(--t-body);
       margin-bottom: var(--s2); }
.msg-success { background: #D1FAE5; color: #065F46; }
.msg-error { background: #FEE2E2; color: #991B1B; }
.msg-info { background: #E0EAFF; color: #273E8A; }

/* An empty screen is an invitation, so it holds the next action rather than
   just reporting the absence. Capped and centred: a one-line message stretched
   across a wide monitor reads as a mistake. */
.empty { padding: var(--s6) var(--s4); text-align: center; color: var(--ink-2);
         background: var(--card); border: 1px dashed var(--border);
         border-radius: var(--r-lg); max-width: 720px; margin-inline: auto; }
.empty p { margin: 0 0 var(--s3); }
.empty p:last-child { margin-bottom: 0; }
.empty .muted { display: block; max-width: 46ch; margin-inline: auto; }
.muted { color: var(--muted); font-size: var(--t-small); }
/* Secondary line under an order number: the partner's own reference. */
.subref { color: var(--muted); font-size: 12px; font-weight: 400; }
.hint { color: var(--muted); font-size: 12px; font-weight: 400; }

/* Order review: lines on the left, a checkout rail on the right. The rail
   holds everything needed to finish — totals, details, the submit — so the
   eye never has to hunt below a table for loose fields. */
/* ── Two-pane work layout ─────────────────────────────────────────────────
   Browse on the left, the order you are building on the right. This is what
   a wide window buys: a second thing worth reading, rather than the same row
   stretched until its own values are a screen apart. Below 1150px there is
   no room for both, so the rail goes and the "Review order" button in the
   page head carries the job. */
/* The two panes sit next to each other, not at opposite edges of the window
   — the point is to keep what you are reading together. Leftover width
   trails to the right rather than opening a canyon down the middle. */
.work-split { display: grid;
              grid-template-columns: minmax(0, max-content) var(--rail);
              gap: var(--s5); align-items: start; justify-content: start; }
.cart-rail { position: sticky; top: calc(var(--s4) + 52px); }
.cart-rail h3 { display: flex; justify-content: space-between; align-items: baseline;
                gap: var(--s3); }
.cart-rail .cart-count { font-family: var(--font-sans); font-size: var(--t-small);
                         font-weight: 400; color: var(--muted); }
.cart-lines { display: flex; flex-direction: column; gap: var(--s2);
              margin: 0 0 var(--s3); max-height: 46vh; overflow-y: auto; }
.cart-line { display: grid; grid-template-columns: 1fr auto; gap: 0 var(--s3);
             align-items: baseline; font-size: var(--t-small); }
.cart-line b { font-variant-numeric: tabular-nums; font-size: var(--t-body); }
.cart-line .cart-line-code { grid-column: 1; font-size: var(--t-micro); }
.cart-rail .btn-primary { width: 100%; text-align: center; }
.cart-empty { font-size: var(--t-small); color: var(--muted); margin: 0; }
@media (max-width: 1150px) {
    .work-split { grid-template-columns: 1fr; }
    .cart-rail { display: none; }
}

.order-grid { display: grid;
              grid-template-columns: minmax(0, max-content) var(--rail);
              gap: var(--s4); align-items: start; justify-content: start; }
/* The rail follows you down a long order: totals and Send are always to hand.
   Offset by the sticky header so it never hides under it. */
.order-rail { position: sticky; top: calc(var(--s5) + 44px);
              display: flex; flex-direction: column; gap: 0; }
.rail-totals { display: flex; flex-direction: column; gap: var(--s2);
               margin-bottom: var(--s4); padding-bottom: var(--s3);
               border-bottom: 1px solid var(--border); }
.rail-row { display: flex; justify-content: space-between; gap: var(--s3);
            font-size: var(--t-body); color: var(--muted); }
.rail-row b { color: var(--ink); font-variant-numeric: tabular-nums; }
.rail-row.rail-em { font-size: var(--t-lead); }
.rail-row.rail-em b { font-size: 19px; }
.order-rail label { display: flex; flex-direction: column; gap: var(--s1);
                    font-size: var(--t-small); color: var(--muted);
                    margin-bottom: var(--s3); }
.order-rail textarea { resize: vertical; }
.order-rail .btn-primary { width: 100%; padding: 11px 16px; font-size: 15px;
                           margin-top: 4px; }
.rail-back { display: block; text-align: center; margin-top: 10px; font-size: 13px;
             color: var(--muted); }
.remove-x { background: none; border: 0; color: var(--muted); font-size: 15px;
            cursor: pointer; padding: 4px 8px; border-radius: var(--r-sm);
            line-height: 1; font-family: inherit; }
.remove-x:hover { color: var(--brand-red); background: var(--brand-red-soft); }
/* A bare ✕ is a small target on a touch screen, so in card mode it says
   what it does. The label is CSS-only: the markup stays one button. */
@media (max-width: 900px) {
    .remove-x { border: 1px solid var(--border); padding: 6px 12px; font-size: var(--t-small); }
    .remove-x::after { content: ' Remove'; }
}

@media (max-width: 900px) {
    .order-grid { grid-template-columns: 1fr; }
    .order-rail { position: static; }
}

/* Both cards size to what they hold. A card stretched to the window while
   its table sits at 360px is mostly empty box, and the reader has to work
   out that the emptiness means nothing. */
.detail-grid { display: grid;
               grid-template-columns: var(--rail) minmax(0, max-content);
               gap: var(--s4); align-items: start; justify-content: start; }
.detail-grid .card { min-width: 0; }
.card { background: var(--card); border: 1px solid var(--border);
        border-radius: var(--r-lg); padding: var(--s4); }
.card h3 { margin: 0 0 var(--s3); font-size: var(--t-h3); }
/* A card holding a table gets no double border or double padding. */
.card > .tbl, .card > .tbl-wrap > .tbl { border: 0; border-radius: 0; }
.card > .tbl th { background: none; border-bottom: 1px solid var(--ink-2); }
.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s1) var(--s3);
      margin: 0; font-size: var(--t-body); }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }

.login-card { max-width: 390px; margin: clamp(24px, 8vh, 90px) auto; background: var(--card);
              border: 1px solid var(--border); border-radius: var(--r-lg);
              padding: var(--s5) var(--s5); text-align: center; }
.login-logo { display: block; width: 190px; margin: 4px auto 10px; }
.login-card form { text-align: left; }
.login-partner { display: flex; align-items: center; justify-content: center; gap: 9px;
                 margin-top: 22px; font-size: 11px; color: var(--muted);
                 text-transform: uppercase; letter-spacing: .05em; }
.login-partner img { height: 24px; width: auto; }
.login-card form { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.login-card label { display: flex; flex-direction: column; gap: 5px; font-size: 13px;
                    color: var(--muted); }

/* Page padding and the header gap now come from --gutter, so this block only
   holds what genuinely changes shape on a small screen. Tables are handled by
   .tbl-wrap (scrolls in its own box) and .tbl-cards (becomes cards) above. */
@media (max-width: 900px) {
    .detail-grid { grid-template-columns: 1fr; }
    .brand-logo { height: 36px; }
    .nav-groups { row-gap: var(--s2); }
    .nav-group + .nav-group { border-left: 0; margin-left: var(--s3); padding-left: 0; }
}
@media (max-width: 620px) {
    .user-name { display: none; }         /* chip collapses to the avatar */
    .topbar { position: static; }         /* a wrapped nav would eat the screen */
    .page-head h1 { width: 100%; }
    .asof { margin-left: 0; }
    /* Brand and account sit on the first line, the nav wraps below them —
       rather than the account chip stranded on a line of its own. */
    .topbar-inner { row-gap: var(--s2); }
    .brand { order: 1; }
    .top-right { order: 2; }
    .nav-groups { order: 3; width: 100%; }
    .nav-group:first-child { padding-left: 0; }
}

/* Raw availability: selectable size rows + per-size est. cases */
.ra-bar-row--pick { cursor: pointer; }
.ra-bar-row--pick:hover .ra-bar-label { color: var(--ink); }
.ra-size-pick { accent-color: var(--green-deep, #2f6b3a); margin: 0; flex: 0 0 auto; }
.ra-bar-cases { width: 92px; text-align: right; font-size: 12px; color: var(--ink);
    font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ra-select-note { margin-top: 10px; padding: 8px 12px; border-radius: 8px;
    background: var(--card, #fff); border: 1px solid var(--green-deep, #2f6b3a);
    font-size: 13px; }
.ra-select-note b { font-variant-numeric: tabular-nums; }

/* A filter chip that would leave the list empty: visible so the vocabulary
   stays stable, but inert. */
.chip-dead { opacity: .38; cursor: not-allowed; pointer-events: none; }
