/*
 * Design system.
 *
 * The rule that drives everything here: a border is a last resort. Sections are
 * separated by background, spacing, typography and hairlines — not by putting
 * each one inside a rounded rectangle. A panel (white surface + border) is
 * reserved for genuinely independent things: a metric, a warning, an action.
 *
 * Type scale is fixed and small:
 *   page title 30 / section 19 / body 15 / meta 13
 * Nothing below 12px. Secondary text is grey-600, not grey-400 — this is read
 * at arm's length in a room with a coffee grinder running.
 *
 * Colour is semantic only:
 *   red = out of stock / overdue / critical      amber = low / attention
 *   green = healthy / done                        blue = waiting on someone else
 *   grey = draft / inactive
 * No colour is used decoratively anywhere.
 */

:root {
    /* Ink — a green-tinted neutral ramp, not pure grey. --ink-4 is the lightest
       text allowed anywhere and sits at 4.5:1 on white; every step above it is
       darker. Nothing in this product is decorative enough to justify pale. */
    --ink:        #151918;  /* headings, primary numbers */
    --ink-2:      #39433f;  /* body */
    --ink-3:      #626c68;  /* secondary text                       5.4:1 */
    --ink-4:      #6e7975;  /* metadata, the lightest allowed       4.5:1 */

    --surface:    #ffffff;
    --canvas:     #f3f5f3;  /* workspace behind the white surfaces */
    --raised:     #f7f9f8;  /* table head, inset rows */

    --line:       #e3e8e5;  /* subtle separator */
    --line-2:     #eef1ef;  /* hairline between rows */
    --line-3:     #d7deda;  /* stronger control border */

    /* Brand. Deep green is the identity layer (headers, brand regions);
       accent is the action colour. They are deliberately different values so a
       branded surface never reads as a giant button. */
    --brand:      #075e52;
    --brand-2:    #0b6858;
    --accent:     #0b7a5c;
    --accent-ink: #075e52;  /* brand text on mint */
    --accent-bg:  #e5f6ec;  /* active navigation mint */
    --brand-soft: #eef8f3;  /* soft brand surface */

    /* Semantic. Distinct from the brand teal so "healthy" never reads as
       "branded", and calm enough to sit next to money without shouting. */
    --red:        #dc2626;  --red-ink:   #b3261e;  --red-bg:   #fef3f2;
    --amber:      #d97706;  --amber-ink: #a25c07;  --amber-bg: #fdf6e9;
    --green:      #16a34a;  --green-ink: #15803d;  --green-bg: #ecfdf3;
    --blue:       #2563eb;  --blue-ink:  #1d4ed8;  --blue-bg:  #eef4ff;
    --grey:       #6e7975;  --grey-ink:  #626c68;  --grey-bg:  #eef1ef;

    /* Radius climbs with the importance of the surface: controls stay crisp,
       modules get shape. Nothing gets a capsule unless it is truly a chip. */
    --r-sm: 8px;    /* chips, badges, small controls */
    --r:    10px;   /* inputs, buttons */
    --r-lg: 14px;   /* standard cards, tables, drawers */
    --r-xl: 16px;   /* major dashboard modules, brand regions */

    /* Depth: offset plus soft blur, kept close to the threshold of visible.
       A white surface on this canvas is already separated; the shadow only
       stops it from floating. */
    --shadow-sm: 0 1px 2px rgba(21,25,24,.05);
    --shadow:    0 1px 2px rgba(21,25,24,.04), 0 12px 24px -14px rgba(21,25,24,.16);

    --content:      1120px;  /* dense operational pages */
    --content-form: 780px;   /* forms and settings — a reading width */
    --page-pad:     28px;    /* gutter; full-bleed elements negate exactly this */

    /* One interior gutter for every white module: panel padding, card header,
       list row, empty state, and the first and last cell of a table all start
       on this edge. Before this was a token the same column of content began at
       14px in a table, 16px in a row and 20px in a panel header, and a card
       whose body was a table had its title 2px off its own first column. */
    --pad: 20px;
}

/* ------------------------------------------------------------------ base -- */

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

body {
    background: var(--canvas);
    color: var(--ink-2);
    /* Manrope: geometric enough to feel designed, with complete Romanian and
       Cyrillic coverage. The stack falls back to the platform sans if the face
       has not loaded, so text never waits on the network. */
    font-family: 'Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI',
                 Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    font-weight: 450;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Three weights carry the whole interface: 450 body, 600 labels and controls,
   700 headings and numbers. A fourth would be decoration. */

/* Quantities and money must line up when the eye scans a column. */
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }

/* Motion is short, eased and opt-out. Nothing here bounces or pulses. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important; animation-iteration-count: 1 !important;
        transition-duration: .01ms !important; scroll-behavior: auto !important;
    }
}

/* ------------------------------------------------------------ typography -- */

.page-title {
    font-size: 32px;
    line-height: 1.15;
    font-weight: 700;
    letter-spacing: -0.022em;
    color: var(--ink);
}

/* The dashboard's operational question — the one place a larger statement is
   the point of the screen rather than decoration. */
.page-question {
    font-size: 36px;
    line-height: 1.12;
    font-weight: 700;
    letter-spacing: -0.026em;
}

.page-lede { margin-top: 7px; font-size: 15px; color: var(--ink-3); }

.section-title {
    font-size: 21px;
    line-height: 1.3;
    font-weight: 700;
    letter-spacing: -0.017em;
    color: var(--ink);
}

.eyebrow {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ink-3);
}

.meta { font-size: 13px; color: var(--ink-4); }
.meta-strong { font-size: 13px; color: var(--ink-3); font-weight: 600; }

@media (max-width: 640px) {
    .page-title { font-size: 27px; letter-spacing: -0.02em; }
    .page-question { font-size: 28px; }
    .section-title { font-size: 19px; }
}

/* --------------------------------------------------------------- layout -- */

.page { width: 100%; max-width: var(--content); margin-inline: auto; padding-inline: var(--page-pad); }

/*
 * Forms and settings read at a narrower measure than an operational table.
 * A settings field stretched to 1120px is a worse control, not a bigger one.
 *
 * The measure is left-aligned, never centred. Thirteen screens used to centre
 * the form inside the full-width column while the page title and the tab row
 * above it stayed at the left edge, so the heading and the first field it
 * belonged to started 150px apart and the page read as two documents.
 */
.page-narrow, .form-measure { max-width: var(--content-form); }
/* A form of six short fields — a write-off, an onboarding step — is narrower
   still; the fields are the measure, not the container. */
.form-measure-sm { max-width: 620px; }

@media (min-width: 1600px) { :root { --page-pad: 40px; } }
@media (max-width: 1024px) { :root { --page-pad: 24px; } }
@media (max-width: 640px)  { :root { --page-pad: 18px; --pad: 16px; } }

/* A section is spacing plus an optional hairline. Not a box.
   More room above a heading than below it, so a heading belongs to what
   follows it rather than floating between two blocks. */
.section { padding-block: 32px 28px; }
.section:first-child { padding-top: 0; }
.section + .section { border-top: 1px solid var(--line); }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 16px; }

@media (max-width: 640px) {
    .section { padding-block: 26px 24px; }
}

/*
 * The dashboard's lower half. One column below 1280 in the order the markup
 * declares; above it the working queue takes the wide side and the glance-at
 * summaries stack beside it, so a wide screen stops being a very long column
 * of full-width strips with a page fold between each of them.
 */
.dash-grid { display: grid; gap: 0; }
.dash-side { min-width: 0; }

/* Each column opens on the same hairline the stacked sections already use, so
   the separator rhythm survives the split — and in two columns the two rules
   start at the same y and read as one line across the page. */
.dash-grid > .section:first-child,
.dash-side > .section:first-child { border-top: 1px solid var(--line); }

@media (min-width: 1280px) {
    .dash-grid {
        grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
        gap: 0 32px;
        align-items: start;
    }
}

/* A panel is a real module: an independent summary, metric or action. Depth
   comes from a barely-visible shadow rather than a grey outline, so a row of
   them reads as objects on a workspace instead of boxes drawn on paper. */
.panel {
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
}
.panel-pad { padding: var(--pad); }

/* Major dashboard modules get the larger shape and the fuller shadow. */
.panel-lg { border-radius: var(--r-xl); box-shadow: var(--shadow); }

/* A plain white surface — for tables and lists sitting on the canvas. */
.surface {
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
}

/* The module gutter, for markup that has to set it directly — a dashboard
   panel header sitting above a list that is padded by its own component. */
.pad-x { padding-inline: var(--pad); }

/*
 * A KPI row of four identical white boxes states four numbers and no priority.
 * One tile per row may take the soft brand surface to mark the metric the
 * screen is actually about; the rest stay white. The tint is the same mint the
 * active navigation uses, so it reads as "this one" and not as a new colour.
 */
.panel-feature {
    background: var(--brand-soft);
    box-shadow: inset 0 0 0 1px rgba(7,94,82,.09);
}
.panel-feature .stat-label { color: var(--accent-ink); }

/* -------------------------------------------------------------- buttons -- */

/* 40px on desktop, 48px for a mobile primary. Height is set by padding rather
   than a fixed value so a wrapped Romanian label grows the button instead of
   spilling out of it. */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    border: 1px solid transparent; border-radius: var(--r);
    padding: 9px 16px;
    font-size: 14px; font-weight: 600; line-height: 20px;
    white-space: nowrap; cursor: pointer;
    transition: background-color .14s ease, border-color .14s ease,
                color .14s ease, box-shadow .14s ease;
}
.btn:disabled { opacity: .45; cursor: not-allowed; }
/* A pressed button should register on a touch screen, where there is no hover
   to confirm the tap landed. */
.btn:active:not(:disabled) { transform: translateY(0.5px); }

.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--accent-ink); }

.btn-secondary { background: var(--surface); color: var(--ink-2); border-color: var(--line-3); }
.btn-secondary:hover:not(:disabled) { background: var(--raised); border-color: #c6cfca; }

.btn-ghost { background: transparent; color: var(--ink-3); }
.btn-ghost:hover:not(:disabled) { background: var(--brand-soft); color: var(--accent-ink); }

/* Destructive stays quiet until it is hovered. A red-filled button sitting
   permanently next to Send is a dare, not a control. */
.btn-danger { background: var(--surface); color: var(--red-ink); border-color: #f2c9c6; }
.btn-danger:hover:not(:disabled) { background: var(--red-bg); border-color: #e5a9a4; }

.btn-sm { padding: 6px 11px; font-size: 13px; line-height: 18px; border-radius: var(--r-sm); }
/* 44px: the singular primary action reads as the largest control on the page
   without becoming a mobile-sized slab on a desktop. */
.btn-lg { padding: 11px 22px; font-size: 15px; line-height: 20px; }
.btn-icon { padding: 8px; }
.btn-sm.btn-icon { padding: 6px; }

/* Phone sizing for controls lives in one block at the end of this file, after
   every base rule it has to override. */

/* ---------------------------------------------------------------- forms -- */

.label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; }
.hint  { margin-top: 5px; font-size: 13px; line-height: 1.45; color: var(--ink-4); }
.error-text { margin-top: 4px; font-size: 13px; color: var(--red-ink); }

/* 44px on desktop, 48px on a phone. The focus ring is a shadow, never a border
   width change, so focusing a field cannot nudge the row it sits in. */
.input, .select, .textarea {
    display: block; width: 100%;
    border: 1px solid var(--line-3); border-radius: var(--r);
    background: var(--surface);
    padding: 10px 12px;
    font-size: 15px; line-height: 22px; color: var(--ink);
    transition: border-color .14s ease, box-shadow .14s ease;
}
/* Readable, and clearly not a value. */
.input::placeholder, .textarea::placeholder { color: var(--ink-4); opacity: 1; }
.input:hover:not(:focus):not(:disabled),
.select:hover:not(:focus):not(:disabled) { border-color: #c6cfca; }
.input:focus, .select:focus, .textarea:focus {
    outline: none; border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(11,122,92,.14);
}

/* A native select next to a styled input is the single loudest "this is a form,
   not a product" signal on the page: different height, different radius, a
   platform arrow in a platform grey. It gets the same box as .input and the
   same chevron the location switcher already uses. */
.select {
    appearance: none; -webkit-appearance: none;
    padding-right: 36px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23626c68' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 16px 16px;
    cursor: pointer;
}
/* Firefox draws its own inner focus outline on a select. */
.select:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--ink); }

.input-error { border-color: var(--red); }
.input-error:focus { box-shadow: 0 0 0 3px rgba(220,38,38,.14); }

.input:disabled, .select:disabled, .textarea:disabled,
.input[readonly], .textarea[readonly] {
    background: var(--raised); color: var(--ink-4); cursor: not-allowed;
}

.input-qty { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.input-sm  { padding: 6px 10px; font-size: 14px; }

/* "Pick a value, then apply it" is one action, so it gets one control: the
   select and its button share an edge instead of standing as two equal buttons
   in a row of other equal buttons. */
.input-group { display: inline-flex; min-width: 0; }
.input-group > .select { width: auto; max-width: 12rem; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.input-group > .btn { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
.input-group > .select:focus { position: relative; z-index: 1; }

/* Checkboxes and radios take the brand from the token. Markup was carrying two
   different hard-coded greens across twenty call sites. */
input[type=checkbox], input[type=radio] { accent-color: var(--accent); }

/* Logo / image drop area — replaces the raw file input. Sized to the control,
   not to the form: stretched to a 780px measure it read as a drop target for
   the whole page rather than as one field among the others. */
.upload {
    display: flex; align-items: center; gap: 14px;
    max-width: 26rem;
    border: 1px dashed var(--line-3); border-radius: var(--r-lg);
    padding: 12px 14px; background: var(--raised);
    cursor: pointer;
}
.upload:hover { border-color: var(--accent); background: var(--accent-bg); }
.upload input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; }

/* --------------------------------------------------------------- status -- */

/* A dot is enough most of the time. */
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 999px; flex: none; }
.dot-red { background: var(--red); } .dot-amber { background: var(--amber); }
.dot-green { background: var(--green); } .dot-blue { background: var(--blue); }
.dot-grey { background: var(--grey); }

/* Badges are compact and only used where a label carries real information. */
.badge {
    display: inline-flex; align-items: center; gap: 5px;
    border-radius: var(--r-sm); padding: 1px 7px;
    font-size: 12.5px; font-weight: 600; line-height: 18px; white-space: nowrap;
}
.badge-red   { background: var(--red-bg);   color: var(--red-ink); }
.badge-amber { background: var(--amber-bg); color: var(--amber-ink); }
.badge-green { background: var(--green-bg); color: var(--green-ink); }
.badge-blue  { background: var(--blue-bg);  color: var(--blue-ink); }
.badge-grey  { background: var(--grey-bg);  color: var(--grey-ink); }

/* Status shown as plain coloured text, when a badge would be noise.
   The colours themselves live in the utility layer at the end of this file. */
.status-text { font-size: 13px; font-weight: 500; }

/* ---------------------------------------------------------------- table -- */

.table { width: 100%; border-collapse: collapse; }

.table thead th {
    padding: 11px 14px;
    text-align: left;
    font-size: 13px; font-weight: 600;
    color: var(--ink-3);
    background: var(--raised);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.table thead th:first-child { border-top-left-radius: var(--r-lg); }
.table thead th:last-child  { border-top-right-radius: var(--r-lg); }

/* ~60px rows: dense enough to compare, tall enough to read a name over a line
   of metadata. No vertical rules — the columns are held by alignment. */
.table tbody td {
    padding: 13px 14px;
    font-size: 14.5px;
    border-bottom: 1px solid var(--line-2);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr[data-href], .table tbody tr.is-clickable { cursor: pointer; }
.table tbody tr[data-href]:hover, .table tbody tr.is-clickable:hover { background: var(--brand-soft); }
.table tbody tr:focus-within { background: var(--brand-soft); }

/* The outer cells align to the module gutter, so a card's title sits directly
   above its own first column. Interior cells stay at 14px — a dense table does
   not want the panel gutter between every pair of columns. */
.table thead th:first-child, .table tbody td:first-child { padding-left: var(--pad); }
.table thead th:last-child,  .table tbody td:last-child  { padding-right: var(--pad); }

.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .shrink { width: 1%; white-space: nowrap; }

/*
 * Row height, where the width can pay for it.
 *
 * "ajunge ~3 zile" breaking across two lines gave every row a different height
 * and turned a scannable column into a paragraph. Holding measured values and
 * the product name on one line fixes that — but it costs about 130px, and a
 * nine-column stock table on a 1280px laptop does not have 130px to give. Below
 * 1400 the table goes back to filling the width and wrapping, which is worse
 * than uniform rows and much better than scrolling a table sideways to reach
 * the price column.
 */
@media (min-width: 1400px) {
    .table .num, .table .num * { white-space: nowrap; }
    .table .num .block, .table .num .meta { white-space: normal; }
}
/* The column carrying the record's name. Auto table layout hands the widest
   share to whatever refuses to wrap, which after the numeric columns stopped
   wrapping meant the product name got what was left — two lines of name over
   two lines of metadata, and a different row height for every row.

   A floor, not a share: a percentage width makes this column claim space the
   row actions then have to give up, and the edit control at the end of the row
   gets clipped by the surface.

   The floor is modest by default and generous only where the width pays for
   it: asking for the generous one at 1280 pushed the price and the row actions
   past the edge of a surface that clips, losing them outright, while asking
   for nothing at all let a product name collapse to four stacked words. */
.table .col-main { min-width: 9.5rem; }

@media (min-width: 1280px) { .table .col-main { min-width: 11rem; } }
@media (min-width: 1400px) { .table .col-main { min-width: 14rem; } }

/* The trailing actions cell is sized by icons, which auto layout is happy to
   squeeze — and the surface clips, so a squeeze of four pixels takes the edge
   off the edit control rather than wrapping it. It asks for what it needs. */
.table th:last-child.shrink, .table td:last-child.shrink { min-width: 6rem; }
/* A verdict column. "Întârzieri frecvente" broke over two lines and made every
   third row 24px taller than its neighbours; the long "no completed orders yet"
   fallback still wraps, which is correct — it is a sentence, not a verdict. */
.table .col-status { min-width: 10.5rem; }

/* A report table is a comparison grid: splitting it into stacked rows on a
   phone destroys the comparison. So the narrow-screen treatment tightens the
   grid until it fits instead — which works because these tables are a label
   plus two or three numbers. Lists of records get the .rows treatment
   instead; this is only for the report screens. */
@media (max-width: 640px) {
    /* 12px, not 11.5 — the floor at the top of this file is a rule, and the
       narrow-screen header was quietly under it. The width this costs is paid
       for by .hide-sm dropping the context columns. */
    .table thead th { padding: 8px 7px; font-size: 12px; }
    .table tbody td { padding: 10px 7px; font-size: 13.5px; }
    .table thead th:first-child, .table tbody td:first-child { padding-left: var(--pad); }
    .table thead th:last-child,  .table tbody td:last-child  { padding-right: var(--pad); }
    .table .badge { padding: 0 5px; font-size: 12px; }
    /* A column that carries context rather than the answer, dropped when
       the screen cannot hold every column. */
    .hide-sm { display: none !important; }
}

/*
 * The same idea one size up. A nine-column stock table has about 970px to
 * spend on a 1280px laptop, and the only ways to fit nine columns into it are
 * to wrap the product name over three lines, to scroll sideways, or to drop
 * the least decision-relevant column. The design brief ranks the columns —
 * name, stock, days remaining, status, supplier, last price — and seven-day
 * consumption is not among them; it is background for the coverage figure
 * sitting next to it, and it is still on the product page and in the phone
 * row's detail. So it goes, and the six that answer the question stay on one
 * line each.
 */
@media (max-width: 1399px) {
    .hide-md { display: none !important; }
}

/* The urgency bar that used to sit in the first cell is gone. Every row that
   carried one already stated its status as a badge or coloured status text in
   its own column, so the bar repeated the answer in a second visual language —
   and a column of red ticks reads as alarm regardless of how many rows are
   actually urgent. Status now has exactly one home per row. */

/* --------------------------------------------------- mobile: rows, not scroll */

/* Tables collapse into stacked rows with an expandable detail area rather than
   scrolling sideways. A phone is not a narrow desktop. */
.rows { background: var(--surface); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
.row {
    display: flex; align-items: center; gap: 12px;
    padding: 13px var(--pad);
    min-height: 62px;
    border-bottom: 1px solid var(--line-2);
    transition: background-color .14s ease;
}
.row:last-child { border-bottom: 0; }

/* A row that can be opened reacts like one, wherever it appears. This used to
   be a hover utility written per screen, so some clickable rows responded and
   others did not. */
a.row:hover, .row[data-href]:hover, .row.is-clickable:hover { background: var(--brand-soft); }
a.row, .row[data-href], .row.is-clickable { cursor: pointer; }

.row-main { min-width: 0; flex: 1; }
.row-title { font-size: 15px; font-weight: 500; line-height: 1.35; color: var(--ink); }
.row-meta { margin-top: 2px; font-size: 13px; line-height: 1.4; color: var(--ink-4); }
.row-side { text-align: right; flex: none; }

.row-detail {
    display: none;
    padding: 2px var(--pad) 14px;
    border-bottom: 1px solid var(--line-2);
    background: var(--raised);
}
.row-detail.is-open { display: block; }
.row-detail dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; font-size: 14px; }
.row-detail dt { color: var(--ink-4); }
.row-detail dd { color: var(--ink-2); text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- drawer -- */

/* Viewing and editing happens beside the list, so the user keeps their place. */
.drawer-backdrop {
    position: fixed; inset: 0; z-index: 60;
    background: rgba(24,24,27,.35);
    opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.drawer-backdrop.is-open { opacity: 1; pointer-events: auto; }

.drawer {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 70;
    width: min(560px, 100%);
    background: var(--surface);
    border-left: 1px solid var(--line);
    display: flex; flex-direction: column;
    transform: translateX(100%);
    transition: transform .2s cubic-bezier(.32,.72,0,1);
}
.drawer.is-open { transform: none; }

/* Head and foot are fixed; only the body scrolls. */
.drawer-head {
    display: flex; align-items: flex-start; gap: 12px; flex: none;
    padding: 18px 22px; border-bottom: 1px solid var(--line);
}
.drawer-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 22px; }
.drawer-foot {
    display: flex; gap: 8px; align-items: center; flex: none;
    padding: 14px 22px; border-top: 1px solid var(--line);
    background: var(--raised);
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
}

@media (max-width: 640px) {
    .drawer {
        top: auto; height: 92vh; width: 100%; border-left: 0;
        border-top-left-radius: var(--r-xl); border-top-right-radius: var(--r-xl);
        transform: translateY(100%);
    }
    .drawer.is-open { transform: none; }
    .drawer-head, .drawer-body, .drawer-foot { padding-inline: 18px; }
}

/* ----------------------------------------------------------- explanation -- */

/* Every forecast in the product can explain itself. Recommendations that
   cannot be interrogated do not get trusted, and untrusted numbers get ignored. */
.why { position: relative; display: inline-flex; }
.why-btn {
    display: inline-grid; place-items: center;
    width: 17px; height: 17px; border-radius: 999px;
    border: 1px solid #d4d4d8; background: var(--surface);
    font-size: 11px; font-weight: 700; color: var(--ink-4); cursor: pointer;
}
.why-btn:hover { border-color: var(--accent); color: var(--accent); }
.why-pop {
    position: absolute; z-index: 50; top: calc(100% + 6px); right: 0;
    width: 268px; padding: 12px 14px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
    box-shadow: 0 10px 30px -8px rgba(24,24,27,.22);
    text-align: left;
}
.why-pop dl { display: grid; grid-template-columns: 1fr auto; gap: 5px 12px; font-size: 13px; }
.why-pop dt { color: var(--ink-4); }
.why-pop dd { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.why-pop .why-result { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-2); }

/* ------------------------------------------------------------ nav / tabs -- */

/* 42px rows, mint when active, 10px radius — a marker, not a capsule. */
.nav-link {
    display: flex; align-items: center; gap: 11px;
    border-radius: var(--r); padding: 10px 11px;
    font-size: 14.5px; font-weight: 600; color: var(--ink-2);
    transition: background-color .14s ease, color .14s ease;
}
.nav-link:hover { background: var(--brand-soft); color: var(--accent-ink); }
.nav-link:hover svg { color: var(--accent); }
.nav-link-active, .nav-link-active:hover { background: var(--accent-bg); color: var(--accent-ink); }
.nav-link-active svg { color: var(--accent); }

/* Tabs: a small fixed set that always fits. Anything more granular belongs in
   a filter dropdown, not in a strip that scrolls sideways. */
/* Tabs wrap onto a second line rather than pushing the page sideways.
   A phone-width strip of five tabs does not fit, and a sideways-scrolling
   strip hides exactly the statuses that need attention. */
.tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--line); }
.tab {
    position: relative; display: inline-flex; align-items: center; gap: 7px;
    padding: 10px 14px; margin-bottom: -1px;
    font-size: 14.5px; font-weight: 600; color: var(--ink-3);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    transition: color .14s ease, border-color .14s ease;
}
@media (max-width: 480px) { .tab { padding: 10px 11px; font-size: 14px; } }
.tab:hover { color: var(--ink); border-bottom-color: var(--line-3); }
.tab-active, .tab-active:hover { color: var(--accent-ink); border-bottom-color: var(--accent); }
.tab-count {
    font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
    background: var(--grey-bg); color: var(--ink-3);
    border-radius: 999px; padding: 0 7px; min-width: 20px; text-align: center;
}
.tab-active .tab-count { background: var(--accent-bg); color: var(--accent-ink); }
.tab-count-alert { background: var(--red-bg); color: var(--red-ink); }

/* ------------------------------------------------- four control families -- */

/*
 * Tabs, filters, chips and badges are not interchangeable, and styling them
 * alike is what makes an interface read as generated. Each one gets its own
 * shape so its job is legible before the label is read:
 *
 *   .tab       navigation between views      underline, no container
 *   .chip      a filter over a list          bordered control, mint when on
 *   .segmented a choice within one view      white thumb on a grey track
 *   .badge     a status, not a control       tinted, no border, not clickable
 *
 * Notably none of them is a black pill. A black active state belongs to no
 * family here and reads as a system control the product does not have.
 */

/* A filter modifies a list, so it looks like a control: real border, square-ish
   corners, and a mint fill when it is on. Not a capsule, not a badge. */
.chip {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid var(--line-3); border-radius: var(--r-sm);
    background: var(--surface); padding: 6px 12px;
    font-size: 13.5px; font-weight: 600; color: var(--ink-2);
    transition: background-color .14s ease, border-color .14s ease, color .14s ease;
}
.chip:hover { background: var(--raised); border-color: #c6cfca; }
.chip-active {
    background: var(--accent-bg);
    border-color: #b7ddc8;
    color: var(--accent-ink);
}
.chip-count { font-size: 12px; font-weight: 600; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.chip-active .chip-count { color: var(--accent-ink); }

/*
 * The filter toolbar.
 *
 * Search and the dropdowns are one control group, so they share one row, one
 * height and one radius. Before this they were a 44px field beside a 32px
 * button beside a native select, and on a phone the search box collapsed to the
 * width of its own icon while a category dropdown took a full line: the field a
 * person actually types in was the smallest thing in the group.
 */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.toolbar .input, .toolbar .select { height: 40px; padding-block: 0; }
.toolbar .btn { min-height: 40px; }
.toolbar .btn-sm { padding-block: 0; font-size: 14px; }

.toolbar-search { position: relative; flex: 1 1 230px; min-width: 0; max-width: 320px; }
/* Sized by its own label, but never past a third of the row — a supplier list
   with one long name used to push search off the toolbar entirely. */
.toolbar-select { flex: 0 1 auto; width: auto; max-width: 15rem; }
.toolbar-end { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

@media (max-width: 640px) {
    .toolbar .input, .toolbar .select { height: 46px; }
    .toolbar .btn { min-height: 46px; }
    /* Search gets its own line at full width; the dropdowns pair up under it. */
    .toolbar-search { flex: 1 0 100%; max-width: none; }
    .toolbar-select { flex: 1 1 calc(50% - 4px); max-width: none; min-width: 0; }
    /* Its own line, but the buttons keep their own width — a ghost Reset
       stretched to half the row is a large area with no edge, which reads as a
       rendering fault rather than as a quiet action. */
    .toolbar-end { margin-left: 0; flex: 1 0 100%; }
}

/* A segmented control picks one view of the same data — period, scope, mode.
   The moving part is a white thumb, which reads as a switch rather than as a
   row of separate buttons. */
.segmented {
    display: inline-flex; gap: 2px; padding: 3px;
    background: var(--grey-bg); border-radius: var(--r);
}
.segmented-item {
    padding: 6px 14px; border-radius: 8px;
    font-size: 13.5px; font-weight: 600; color: var(--ink-3);
    transition: background-color .14s ease, color .14s ease;
}
.segmented-item:hover { color: var(--ink); }
.segmented-item-active {
    background: var(--surface); color: var(--accent-ink);
    box-shadow: var(--shadow-sm);
}

/* The top bar's rhythm is tighter than a page's: a two-letter language toggle
   at the full control height would be the tallest thing up there. */
.segmented-xs { padding: 2px; }
.segmented-xs .segmented-item { padding: 4px 8px; font-size: 12.5px; letter-spacing: .01em; }

/* Comfortable to tap. */

/* The sidebar is a white plane held against the workspace by one hairline,
   not a bordered box. */
.sidebar {
    background: var(--surface);
    border-right: 1px solid var(--line);
}

/* The top bar carries context and account controls. It stays quiet: one
   hairline, no shadow until the page scrolls under it. */
.topbar {
    background: rgba(255,255,255,.92);
    backdrop-filter: saturate(180%) blur(10px);
    border-bottom: 1px solid var(--line);
}

/* The location switcher is a context control, not a browser select: it reads
   as a labelled place, and only shows its edges when you go to change it. */
.context-select {
    appearance: none; -webkit-appearance: none;
    background: var(--brand-soft);
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    padding: 7px 30px 7px 11px;
    font-size: 13.5px; font-weight: 600; color: var(--accent-ink);
    /* width, not just max-width: a select sizes itself to its longest option,
       so on a 360px phone "Centru — str. Ștefan cel Mare 42" pushed the language
       toggle and the sign-out button off the top bar. It fills what the row can
       spare and truncates. */
    width: 100%; max-width: 15rem; text-overflow: ellipsis;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23075e52' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-size: 15px 15px;
    cursor: pointer;
    transition: background-color .14s ease, border-color .14s ease;
}
.context-select:hover { background-color: var(--accent-bg); }
.context-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(11,122,92,.14); }

/* Bottom tab bar — primary navigation on a phone, where the thumb is. */
.tabbar {
    position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    background: rgba(255,255,255,.97); backdrop-filter: saturate(180%) blur(10px);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
}
/* 56px tall before the safe area — comfortably past the 44px target — and a
   12px label, because the floor applies here too. Tracking is tightened rather
   than the size dropped, so "Настройки" still fits a 360px fifth. */
.tabbar a {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-height: 56px; padding: 8px 3px 7px;
    font-size: 12px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink-4);
    transition: color .14s ease;
}
.tabbar a[aria-current="page"] { color: var(--accent-ink); }
.tabbar a[aria-current="page"] svg { color: var(--accent); }

/* On a 360px phone each of the five tabs gets 72px. Romanian "Inventariere"
   needs 69px of that at the default tracking and was losing its tail to an
   ellipsis. Reclaim the gutters and tighten tracking rather than drop below
   the 12px floor — the label is the only thing distinguishing two tabs whose
   icons both read as "a list". */
@media (max-width: 400px) {
    .tabbar a { padding-inline: 2px; letter-spacing: -0.03em; }
}

/* --------------------------------------------------------------- stats -- */

.stat-value { font-size: 26px; font-weight: 600; letter-spacing: -0.025em; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.stat-label { font-size: 13px; font-weight: 500; color: var(--ink-3); }

/* Period-over-period delta shown next to a metric. */
.delta { display: inline-flex; align-items: center; gap: 3px; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.delta-up   { color: var(--red-ink); }
.delta-down { color: var(--green-ink); }
.delta-flat { color: var(--ink-4); }
/* Spend going up is bad, stock cover going up is good — callers pick the class. */

.bar { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.bar > span { display: block; height: 100%; border-radius: 999px; background: var(--accent); }

/* -------------------------------------------------------------- utility -- */

/*
 * A dense table inside a clipping surface. The surface rounds its corners with
 * overflow:hidden, which means anything wider than it is not scrolled to — it
 * is silently gone. This wrapper makes the overflow reachable, and because the
 * columns are sized to fit the common desktop widths it stays inert almost
 * everywhere; it exists so that a long Romanian supplier name on a 1280px
 * laptop costs a scrollbar rather than the price column.
 */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.divide-line > * + * { border-top: 1px solid var(--line-2); }
/* A single hairline, for separating an action row from the facts above it.
   Markup was reaching for border-t plus an arbitrary colour to get this. */
.rule-t { border-top: 1px solid var(--line-2); }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Action bar pinned to the bottom of the viewport. It bleeds to the page
   edge on a phone, but the bleed is derived from the gutter rather than
   hand-matched with a negative margin — a 20px negative margin inside a
   16px gutter pushed the whole document sideways. */
/*
 * A task bar, not a floating card. It used to become a bordered, shadowed,
 * rounded white box on desktop, which read as a panel that had come loose from
 * the page — and on a form whose measure is narrower than the page, a box that
 * bled past the last field it belonged to. Now it is a band: solid background,
 * one hairline on top, aligned to whatever column contains it.
 */
.sticky-actions {
    position: sticky; bottom: 0; z-index: 30;
    margin-inline: calc(-1 * var(--page-pad));
    background: rgba(255,255,255,.97); backdrop-filter: saturate(180%) blur(10px);
    border-top: 1px solid var(--line);
    padding: 12px var(--page-pad) calc(12px + env(safe-area-inset-bottom));
}
/* On a phone the bottom tab bar owns the very bottom edge, so the task bar
   sits directly above it instead of underneath it. */
@media (max-width: 1023px) {
    .sticky-actions { bottom: calc(56px + env(safe-area-inset-bottom)); }
}
@media (min-width: 641px) {
    .sticky-actions {
        margin-inline: 0;
        padding: 14px 0;
        background: var(--canvas);
        backdrop-filter: none;
    }
}
/* Where the bar carries a single primary action on a phone, that action is the
   thing a thumb is reaching for: it takes the full width. */
@media (max-width: 640px) {
    .sticky-actions .btn-lg { flex: 1 1 100%; }
}

/* ------------------------------------------------- branded page header ---- */

/*
 * The deep-green contextual region at the top of the dashboard. It exists so
 * the product has an identity layer and so the workspace stops being one
 * uninterrupted pale canvas with white rectangles dropped on it.
 *
 * It bleeds to the content gutter and sits flush under the top bar, then over-
 * pads its lower edge and pulls the next block up into it, so the first module
 * overlaps the green rather than starting a new unrelated band. Nothing here is
 * positioned: a later block in normal flow paints over an earlier one, so the
 * overlap needs no z-index and cannot trap clicks.
 */
.brandhead {
    margin-inline: calc(-1 * var(--page-pad));
    margin-top: -24px;
    margin-bottom: -36px;
    padding: 30px var(--page-pad) 62px;
    background: var(--brand);
    color: #fff;
    border-bottom-left-radius: var(--r-xl);
    border-bottom-right-radius: var(--r-xl);
}
.brandhead .page-title, .brandhead .page-question { color: #fff; }

/* Secondary text on green is tinted from the green, never grey. 4.6:1. */
.brandhead-meta { font-size: 13.5px; font-weight: 600; color: #a8cfc5; }

/* The location, stated as context rather than offered as a control — the
   switcher itself stays in the top bar where it has always been. */
.brandhead-context {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 12px 6px 10px;
    border-radius: 999px;
    background: rgba(255,255,255,.12);
    font-size: 13px; font-weight: 600; color: #eaf5f1;
}

@media (max-width: 640px) {
    .brandhead { padding: 24px var(--page-pad) 52px; margin-bottom: -30px; }
}

/* Inline alert — a line of text with a tint, not a large bordered banner. */
.notice {
    display: flex; align-items: flex-start; gap: 9px;
    border-radius: var(--r); padding: 9px 12px;
    font-size: 14px; line-height: 1.45;
}
.notice-red   { background: var(--red-bg);   color: var(--red-ink); }
.notice-amber { background: var(--amber-bg); color: var(--amber-ink); }
.notice-green { background: var(--green-bg); color: var(--green-ink); }
.notice-blue  { background: var(--blue-bg);  color: var(--blue-ink); }
/* Completes the set. The dashboard builds `notice-{tone}` from a variable, and
   every other family (dot, badge, status) answers all five tones. */
.notice-grey  { background: var(--grey-bg);  color: var(--grey-ink); }

/* Empty state: says what is missing and what to do, never just "no data".
   Reports stacks eight of these on one screen, so the block stays compact —
   an empty result should not occupy more room than a full one. */
.empty { padding: 26px var(--pad); text-align: center; }
.empty-title { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.empty-body { margin: 4px auto 0; max-width: 44ch; font-size: 14px; line-height: 1.5; color: var(--ink-4); }
.empty-action { margin-top: 14px; }

[hidden], .js-hidden { display: none !important; }

/* ------------------------------------------------------ compat aliases ---- */

/*
 * .card / .card-header / .card-title predate .surface / .section-head /
 * .section-title and are still the wrapper on the detail, report and form
 * screens. They are now aliases of the current primitives rather than a
 * heavier parallel treatment:
 *
 *   .card        = .surface       — white, no border, radius
 *   .card-header = .section-head  — hairline under a real heading
 *   .card-title  = .section-title — 19px, not 13px
 *
 * That removes the border from every screen still on the old names, and ends
 * the split where the same heading was 19px on one screen and 13px on the
 * next. New markup should use the current names; these stay so the change is
 * a restyle and not a rewrite.
 */

/* Elevation was the one thing this alias did not inherit, so a report page put
   shadowed .panel metrics directly above unshadowed .card panels and the second
   row read as a different, flatter kind of object. */
.card { background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }

/* Fixed height, not content height. Two cards side by side in the same grid row
   had their first data row on different baselines purely because one of them
   carried an Export link and the other did not. */
.card-header {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    min-height: 54px;
    padding: 10px var(--pad); border-bottom: 1px solid var(--line-2);
}

.card-title {
    font-size: 18px; line-height: 1.35; font-weight: 700;
    letter-spacing: -0.014em; color: var(--ink);
}
@media (max-width: 640px) { .card-title { font-size: 17px; } }

/* ------------------------------------------------------- utility layer ---- */

/*
 * Colour utilities, deliberately last.
 *
 * These set colour and nothing else, so an element can keep its own type scale
 * — a table cell, a .row-title, a .stat-value — and still carry a semantic or
 * grey tint. Because a component like .stat-value also declares a colour and
 * both are single-class selectors, the one written later wins. Putting the
 * utilities at the end is what makes `class="stat-value status-green"` render
 * green instead of silently falling back to ink.
 *
 * There are four greys and four semantic colours. Markup that reaches past
 * these for a raw text-zinc-400 or text-amber-900 is drifting: zinc-400 is
 * below the legibility floor set at the top of this file, and a ninth shade of
 * amber is a colour nobody chose.
 */

.ink   { color: var(--ink); }
.ink-2 { color: var(--ink-2); }
.ink-3 { color: var(--ink-3); }
.ink-4 { color: var(--ink-4); }

.status-red   { color: var(--red-ink); }
.status-amber { color: var(--amber-ink); }
.status-green { color: var(--green-ink); }
.status-blue  { color: var(--blue-ink); }
.status-grey  { color: var(--ink-4); }

/* ---------------------------------------------- controls on a phone ------- */

/*
 * Touch sizing, deliberately last.
 *
 * A media query adds no specificity, so these have to be declared after every
 * base rule they override — otherwise `.btn` beats `.btn-lg` and the desktop
 * `.input-sm` beats its own phone size, which is exactly what happened when
 * they lived next to their components. Everything a thumb hits clears 44px.
 */
@media (max-width: 640px) {
    .btn            { padding: 11px 16px; }
    .btn-lg         { padding: 14px 22px; font-size: 15px; }
    .btn-sm         { padding: 8px 12px; }
    .btn-icon       { padding: 11px; }
    /* An icon-only control has no label to widen it, so it needs the padding. */
    .btn-sm.btn-icon { padding: 13px; }

    /*
     * 16px is not a taste decision. Safari on iOS zooms the viewport when a
     * focused field's text is smaller than that, and it does not zoom back out
     * — so tapping the inline quantity on the dashboard shifted the whole page
     * sideways and left it there. Every field a thumb can reach is 16px.
     */
    .input, .select, .textarea { padding: 12px 13px; font-size: 16px; }
    .input-sm       { padding: 10px 11px; font-size: 16px; }
    .select         { padding-right: 38px; }

    .chip           { padding: 9px 13px; }
    .segmented-item { padding: 12px 15px; }
    .segmented-xs .segmented-item { padding: 10px 11px; }
}

@media print {
    .no-print { display: none !important; }
    body { background: #fff; }
    .panel, .surface { border-color: #ddd; box-shadow: none; }
}
