/* Mini POS — the design tokens (P14, design v2).
 *
 * **This is the only file in the app that names a colour.** Every other sheet —
 * `styles.css` (the shell) and `pos.css` (the till) — writes `var(--…)` and
 * nothing else, so a shade is decided once and changes once. `tests/test_design_system.py`
 * enforces that rule mechanically: a literal `#rrggbb`, `rgb()` or `hsl()` anywhere
 * outside this file fails the suite. The two print sheets (`receipt.css`,
 * `zreport.css`) are deliberately *not* part of this: a thermal receipt is
 * monochrome and pinned byte for byte by its own tests, so it keeps its own ink.
 *
 * The scales are small on purpose — the ones the screens actually need, with the
 * existing names (`--bg`, `--surface`, `--accent`, `--radius`, `--shadow`, `--font`)
 * kept so nothing that already referred to a token had to change.
 *
 * --------------------------------------------------------------- design v2
 * The shop's identity is **green**: a dark green navigation column, a near-white
 * workspace, and one green for anything you press. The palette is the owner's
 * guide mapped onto the names that were already here, so not one template had to
 * learn a new word:
 *
 *   brand-900  #14532D  the column's base — a deep forest green, not a tint of one
 *   accent     #15803D  the shop's green: primary buttons, links, the mark
 *   strong     #16A34A  the interactive green: the active nav row, focus rings
 *   dark       #166534  hover / pressed of a filled primary
 *   soft       #F0FDF4  the quiet green behind a selected thing
 *
 * Green marks the **brand, the primary action and the active navigation item** —
 * never everything. The state colours keep their one meaning each: `--ok` money
 * in, `--warn` be careful, `--danger` money out / wrong, `--violet` goods spoken
 * for. A screen that painted a warning green would be lying about the one thing
 * the counter reads at a glance.
 *
 * ---------------------------------------------------------------- the font
 * **Inter**, self-hosted (`static/fonts/InterVariable.woff2`, SIL OFL 1.1 — the
 * licence travels with the file). Nothing comes from a third-party CDN: the shop
 * sells with the LAN cable out, and a page that waited on a font server would jump
 * from one typeface to another as the money was counted. `font-display: swap`
 * means the figure is readable in the fallback stack before Inter arrives — never
 * a blank line where a price should be. The fallback *is* the stack the app used
 * before design v2, so a browser that refuses the file changes nothing but the
 * letterforms.
 */
@font-face {
  font-family: "Inter";
  src: url("../fonts/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---------------------------------------------------------------- colour
   * One green identity on a warm near-white page: white surfaces, ink that is
   * near-black rather than blue-black, and three state colours that only ever
   * mean one thing each. */
  --brand-900: #14532d;
  --bg: #f8faf9;
  --surface: #ffffff;
  --surface-2: #f4f7f5;
  --surface-3: #e9efeb;
  --border: #e5e7eb;
  --text: #1f2937;
  --text-label: #374151;
  --muted: #64748b;
  --on-accent: #ffffff;
  --overlay: rgba(9, 30, 18, .5);

  --accent: #15803d;
  --accent-strong: #16a34a;
  --accent-dark: #166534;
  --accent-soft: #f0fdf4;

  --ok: #047857;
  --ok-soft: #d1fae5;

  --warn: #b45309;
  --warn-bg: #fef3c7;
  --warn-ink: #7c4a03;
  --warn-line: #fcd34d;
  --warn-fill: #fffbeb;

  --danger: #dc2626;
  --danger-soft: #fee2e2;
  /* The ink a *word* wears on the soft red ground (a rejected invoice, a form
     error, a void line). `--danger` itself is 3.95:1 there — under AA for text —
     so the pill's colour and the button's ground stay `--danger` while the sentence
     written on it is one shade deeper (5.30:1). Same meaning, readable at arm's
     length. */
  --danger-ink: #b91c1c;

  /* Held goods (apartado): the one thing on a screen that is neither stock on
     the shelf nor money taken — a violet that reads as "spoken for". */
  --violet: #6d28d9;
  --violet-soft: #e0e7ff;
  --violet-ink: #3730a3;

  /* --------------------------------------------------- the navigation column
   * The column is a surface of its own, so it carries its own shades: the base
   * (`--brand-900`), the near-white a label is written in, the softer green of a
   * heading, a hairline between sections, and the ink an active row wears on the
   * bright green.
   *
   * Measured, so nobody has to guess later (AA is 4.5:1 for text):
   *   --sidebar-text  #F0FDF4 on #14532D  8.70:1   labels, links, the account line
   *   --sidebar-muted #B9DCC5 on #14532D  6.12:1   group headings, secondary lines
   *   active ink      #052E16 on #16A34A  4.52:1   the row you are on
   * The bright green is 3.30:1 against white — a non-text ratio, which is exactly
   * why it is the **background** of the active row and the colour of the focus
   * ring, and never the colour of a word on a white page. */
  --sidebar-text: #f0fdf4;
  --sidebar-muted: #b9dcc5;
  --sidebar-hover: rgba(255, 255, 255, .09);
  --sidebar-line: rgba(255, 255, 255, .14);
  --sidebar-active-ink: #052e16;

  /* ----------------------------------------------------------------- type */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  --fs-2xs: 11px;
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-md: 14px;
  --fs-base: 15px;
  --fs-lg: 17px;
  --fs-xl: 21px;
  --fs-2xl: 24px;
  --fs-3xl: 32px;
  --lh-tight: 1.2;
  --lh-base: 1.5;
  --fw-regular: 400;
  --fw-medium: 550;
  --fw-semibold: 600;
  --fw-bold: 650;
  --fw-heavy: 700;

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

  /* --------------------------------------------------------------- radius
   * Two sizes and a pill: cards at 12 px, every control at 8 px. A dialog is the
   * same object as a card at one more depth, so it shares the card's radius
   * rather than announcing which one is on top. */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* ------------------------------------------------------------ elevation
   * One soft elevation for whatever sits on the page (a card, a sticky bar), one
   * for whatever floats over it (a dialog, a popover), and one for the toast —
   * which floats over a dialog. The shadows are cast in a green-black rather than
   * a blue one, so a shadow does not tint the green identity blue. */
  --shadow: 0 1px 2px rgba(9, 30, 18, .05), 0 8px 24px rgba(9, 30, 18, .06);
  --shadow-nav: 0 1px 3px rgba(9, 30, 18, .07);
  --shadow-lg: 0 2px 10px rgba(22, 163, 74, .16);
  --shadow-modal: 0 24px 60px rgba(9, 30, 18, .28);
  --shadow-toast: 0 12px 30px rgba(9, 30, 18, .3);
  /* The one focus ring, in two shapes: a ring that reads on a white surface (the
     surface's own white separates it from what is behind) and the same ring
     inverted for the dark column. Both are non-text 3:1 against their ground, so
     "where am I" is answerable on either. */
  --ring: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-strong);
  --ring-on-dark: 0 0 0 2px var(--brand-900), 0 0 0 4px var(--sidebar-text);

  /* ------------------------------------------------------- the shell (P14) */
  --shell-max: 1180px;
  /* The till is the one screen that may use a wide counter display. */
  --shell-max-wide: 1360px;
  --topbar-h: 60px;
  --z-nav: 30;
  --z-modal: 60;
  --z-toast: 80;
  /* The till's lock screen (P23) is above everything the shell draws — including
   * a toast and an open dialog — because it is not a thing on the page: it *is*
   * the page until somebody signs in again. */
  --z-lock: 90;

  /* The navigation column (P17)
   * `--sidebar-w` is the labelled column — the bilingual links the shop has
   * always carried, and the account — and `--rail-w` is the same navigation
   * collapsed to its icons. The rail is wider than one 44 px target on purpose:
   * the link's own padding sits *outside* the target, so a 48 px control lives in
   * a 56 px column. What the two widths must not become is equal: the whole point
   * of the button is that the page gets ~195 px back. The labelled width is
   * measured, not guessed — the longest label (`Movimientos · Movements`) in Inter
   * plus its icon, its gap and the list's own padding needs 250 — so that no link
   * wraps to a second line in the column the rail is compared against. */
  --rail-w: 56px;
  --sidebar-w: 252px;
  /* The drawer (P17) stacks above the page it slides over and below the dialogs
   * drawn on top of it: scrim, drawer, modal, toast — the shell's own order. */
  --z-scrim: 45;
  --z-drawer: 50;

  /* ------------------------------------------------------------- controls
   * The smallest thing a finger may have to hit. Phones and tablets join the
   * counter over the LAN (README, *Sharing it with other devices*), so every
   * control the shell and the till draw is at least this tall — and the browser
   * check for P14 measures it out of the live DOM rather than trusting this
   * comment. */
  --touch: 44px;

  /* ------------------------------------------------------- the record tables
   * `--table-row` is the one row height of the wide record tables (products,
   * movements, sales, facturas, compras): 40 px holds one line of text and one
   * 30 px control, which is what puts ~15 catalogue rows on a 1280×800 counter
   * screen (measured: 309 px rows before this rule, 40 px after). `--touch-sm`
   * is that control — a verb or a quantity stepper *inside a row*, and never
   * anything else: WCAG 2.2 AA asks 24 px of a target, a 44 px control cannot
   * live in a 40 px row, and every control a finger meets outside a table keeps
   * the shell's `--touch`. */
  --table-row: 40px;
  --touch-sm: 30px;
}
