/**
 * ALNADL design tokens. `15 §2`, and the owner's approval of `W0-GATE-006`.
 *
 * WHAT THIS FILE BECAME, AND WHY
 * ------------------------------
 * It used to be sixteen colour values, six spaces, three radii and four motion
 * durations under names this project invented: `--color-ink`, `--space-md`,
 * `--motion-fast`. The approved token file — `architecture/W0-v1.2/
 * design-system/tokens.css`, immutable and hash-verified — is a complete
 * system under different names, and the product implemented neither it nor its
 * identity: no brand colour at all, no type scale, no easing curves, no focus
 * ring, no elevation, no density modes, no white-label layer, no ops dark mode.
 *
 * `15 §1` is explicit about which half of that was open:
 *
 *   "What is NOT provisional and does not change if the palette or the faces
 *    change: the token architecture, the semantic and status layer, the
 *    contrast rules, the component inventory and its state matrix, the icon
 *    system, the motion and alert safety bounds, the bilingual and RTL rules,
 *    and the accessibility contract."
 *
 * So the architecture was never a proposal — it was decided in W0 and simply
 * not built. The PALETTE and the TYPEFACES were the proposal.
 *
 * THE BRAND COLOUR IS NO LONGER A PROPOSAL
 * -----------------------------------------
 * `W0-GATE-006` approved deep petrol `#106D7B` and brass `#9C7222` in the
 * absence of any corporate identity document — they were this project's own
 * proposal, approved as the product's palette, never derived from a brand the
 * owner holds. The corporate identity file has since been supplied, and it
 * settles the question it was never asked before: the النادل / ALNADEL mark is
 * drawn in ONE ink, and the artwork's own declared device-RGB value is
 * `#723D90`. That is read out of the vector, not sampled off a screenshot —
 * `docs/BRAND_SOURCE_AUDIT.md` records where every value here comes from and,
 * just as importantly, what the file does NOT document.
 *
 * So `--c-brand-*` is now the corporate purple and `--c-n-*` sits on the file's
 * own grey `#606060` instead of a petrol tint. Both ramps are DERIVED, not
 * drawn by eye: each step keeps the exact mix ratio the approved ramp used at
 * that step, so the steps, their spacing and every contrast relationship the
 * architecture depends on are the approved ones with a different ink in them.
 * The audit calls that what it is — a UI adaptation. The file documents a
 * logo, not a digital palette, and this comment does not pretend otherwise.
 *
 * `--c-accent-*` stays brass, and stays a PRODUCT colour with no claim on the
 * corporate identity: the brand file contains no second ink to derive one from,
 * and removing the slot would take a component state with it.
 *
 * Everything else from here to the compatibility layer is the approved file,
 * VERBATIM. Nothing is re-authored, re-tuned or re-named — that would be the
 * invented design language the owner forbade, and it would put this file back
 * on the path that produced the divergence it is correcting.
 *
 * The owner's constraints on top, which the file already encodes and which the
 * screens must honour:
 *   * semantic states keep their semantic colours — `success`, `warning` and
 *     `error` are never restyled in petrol or brass;
 *   * the accent is used sparingly and is never a surface wash;
 *   * not every card and button is the primary colour;
 *   * surfaces, borders, text and actions keep a visible hierarchy.
 */

:root {
  /* ---------------------------------------------------------------- palette
     Neutrals sit on the brand file's own grey, `#606060` — the third of the
     three inks the artwork is drawn in, and a true neutral, so they read as
     grey beside the purple rather than as a second hue competing with it. */
  --c-n-000: #FFFFFF;
  --c-n-025: #F8F8F8;
  --c-n-050: #EFEFEF;
  --c-n-100: #E2E2E2;
  --c-n-200: #CCCCCC;
  --c-n-300: #B0B0B0;
  --c-n-400: #8D8D8D;
  --c-n-500: #606060;
  --c-n-600: #4D4D4D;
  --c-n-700: #3A3A3A;
  --c-n-800: #262626;
  --c-n-900: #171717;
  --c-n-950: #0D0D0D;

  /* Brand — the النادل purple. `500` is the corporate ink itself, exactly as
     the brand artwork declares it; the rest are that colour mixed toward white
     or black at the approved ramp's own ratios. 7.54:1 on white, so the
     primary action and a link built on `600` (10.31:1) clear AA without the
     contrast layer being re-tuned. */
  --c-brand-050: #F1EBF4;
  --c-brand-100: #DFD3E6;
  --c-brand-200: #C4AED0;
  --c-brand-300: #A584B8;
  --c-brand-400: #895DA2;
  --c-brand-500: #723D90;   /* primary — the corporate ink */
  --c-brand-600: #572F6E;
  --c-brand-700: #422353;
  --c-brand-800: #30193C;
  --c-brand-900: #201128;

  /* Accent — brass. Hospitality warmth, used sparingly: never for status.
     A PRODUCT colour, not a corporate one: the brand file contains no second
     ink. See `docs/BRAND_SOURCE_AUDIT.md`. */
  --c-accent-050: #FBF2E0;
  --c-accent-100: #F4E1B9;
  --c-accent-200: #E8C888;
  --c-accent-300: #D8AB57;
  --c-accent-400: #C08F33;
  --c-accent-500: #9C7222;
  --c-accent-600: #7C5A19;

  /* Semantic — reserved. These never appear as decoration. */
  --c-success-050: #E4F3EB;
  --c-success-500: #1B7A4B;
  --c-success-700: #115634;
  --c-warning-050: #FBEEDF;
  --c-warning-500: #A96410;
  --c-warning-700: #7C4809;
  --c-danger-050:  #FBE9E7;
  --c-danger-500:  #C0342B;
  --c-danger-700:  #8E241D;
  --c-critical-600:#8E1D16;  /* KDS board alert accent only */
  --c-info-050:    #E7F0FA;
  --c-info-500:    #2A6BB0;
  --c-info-700:    #1D4C7E;

  /* ------------------------------------------------------- semantic surface */
  --s-page:            var(--c-n-025);
  --s-surface:         var(--c-n-000);
  --s-surface-sunken:  var(--c-n-050);
  --s-surface-inverse: var(--c-n-900);
  --s-border:          var(--c-n-200);
  --s-border-strong:   var(--c-n-300);
  --s-text:            var(--c-n-900);
  --s-text-secondary:  var(--c-n-600);
  --s-text-muted:      var(--c-n-500);
  --s-text-inverse:    var(--c-n-000);
  --s-text-link:       var(--c-brand-600);

  --s-primary:         var(--c-brand-500);
  --s-primary-hover:   var(--c-brand-600);
  --s-primary-active:  var(--c-brand-700);
  --s-primary-subtle:  var(--c-brand-050);
  --s-on-primary:      var(--c-n-000);

  --s-focus-ring:      var(--c-brand-400);
  --s-focus-ring-offset: var(--c-n-000);

  /* ------------------------------------------- canonical operational status
     Used identically on venue map, KDS, runner queue, lists and dashboards.
     Colour NEVER travels alone: each status also has an icon and a label.
     (MAP-003, SLA-001, UX-004) */
  --st-available-fg:   var(--c-n-700);   --st-available-bg:  var(--c-n-050);
  --st-occupied-fg:    var(--c-brand-700); --st-occupied-bg: var(--c-brand-050);
  --st-placed-fg:      var(--c-info-700);  --st-placed-bg:   var(--c-info-050);
  --st-preparing-fg:   var(--c-warning-700); --st-preparing-bg: var(--c-warning-050);
  --st-ready-fg:       var(--c-success-700); --st-ready-bg:  var(--c-success-050);
  --st-delivering-fg:  var(--c-accent-600); --st-delivering-bg: var(--c-accent-050);
  --st-completed-fg:   var(--c-n-600);   --st-completed-bg:  var(--c-n-050);
  --st-cancelled-fg:   var(--c-n-500);   --st-cancelled-bg:  var(--c-n-100);
  --st-failed-fg:      var(--c-danger-700); --st-failed-bg:  var(--c-danger-050);
  --st-disabled-fg:    var(--c-n-500);   --st-disabled-bg:   var(--c-n-100);
  --st-unknown-fg:     var(--c-n-600);   --st-unknown-bg:    var(--c-n-050);

  /* SLA bands (SLA-001) */
  --sla-ok:       var(--c-success-500);
  --sla-approach: var(--c-warning-500);
  --sla-breach:   var(--c-danger-500);

  /* GPS freshness (EXT-005) */
  --gps-live:      var(--c-success-500);
  --gps-stale:     var(--c-warning-500);
  --gps-nosignal:  var(--c-n-400);

  /* ------------------------------------------------------------- typography
     Readex Pro  — display. Designed for Arabic and Latin together, tall
                   x-height, low contrast; reads at a glance on a wall screen.
     IBM Plex Sans Arabic — UI and body. One family across both scripts, so
                   AR and EN line boxes match without a fallback seam.
     IBM Plex Mono — tabular figures only: money, IDs, timers, ledgers. */
  --font-display: "Readex Pro", "IBM Plex Sans Arabic", system-ui, sans-serif;
  --font-body:    "IBM Plex Sans Arabic", "IBM Plex Sans", system-ui, sans-serif;
  /* FINAL VISUAL ACCEPTANCE CORRECTION — the figure face had no Arabic digits.
   *
   * `15 §1` reserves this face for "figures that need to align in a column",
   * and `formatNumber` renders every figure in the Arabic locale as
   * ARABIC-INDIC digits (U+0660-0669) — `DSG-00` requires it. The only
   * `IBM Plex Mono` @font-face declared in `fonts.css` carries the LATIN
   * `unicode-range`, so those digits fell straight past it to the generic
   * `monospace` and were drawn by whatever the operating system happened to
   * have. Measured in the product: the advance width of U+0660 in this stack
   * was 18.06px — the `.notdef` box — against 8px for the real glyph. The
   * headline figure of every console tile was a black square in Arabic.
   *
   * `IBM Plex Sans Arabic` is already a declared design-system face and its
   * arabic `unicode-range` (U+0600-06FF) covers the digits. Latin figures
   * still take IBM Plex Mono, which is unchanged; Arabic-Indic figures now
   * take a face this product ships rather than one it hopes for. Column
   * alignment is unaffected: every figure rule already sets
   * `font-variant-numeric: tabular-nums`, which Plex Sans Arabic supports. */
  --font-mono:    "IBM Plex Mono", "IBM Plex Sans Arabic", ui-monospace, monospace;

  --fs-caption:  0.75rem;   /* 12 */
  --fs-small:    0.8125rem; /* 13 */
  --fs-body-sm:  0.875rem;  /* 14 */
  --fs-body:     1rem;      /* 16 — base, never smaller for guest body copy */
  --fs-body-lg:  1.125rem;  /* 18 */
  --fs-h5:       1.25rem;   /* 20 */
  --fs-h4:       1.5rem;    /* 24 */
  --fs-h3:       1.875rem;  /* 30 */
  --fs-h2:       2.375rem;  /* 38 */
  --fs-h1:       3rem;      /* 48 */

  --lh-tight:  1.2;
  --lh-snug:   1.35;
  --lh-normal: 1.55;   /* Arabic needs more leading than Latin: this is the AR default */
  --lh-loose:  1.75;

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semibold:600;
  --fw-bold:    700;

  --ls-tight: -0.01em;   /* display sizes, Latin only; AR never gets negative tracking */
  --ls-normal: 0;
  --ls-caps:  0.04em;

  /* ------------------------------------------------------------------ space
     4px micro grid, 8px base grid. */
  --sp-0:  0;
  --sp-1:  0.125rem; /* 2  micro */
  --sp-2:  0.25rem;  /* 4  micro */
  --sp-3:  0.5rem;   /* 8  base */
  --sp-4:  0.75rem;  /* 12 */
  --sp-5:  1rem;     /* 16 */
  --sp-6:  1.25rem;  /* 20 */
  --sp-7:  1.5rem;   /* 24 */
  --sp-8:  2rem;     /* 32 */
  --sp-9:  2.5rem;   /* 40 */
  --sp-10: 3rem;     /* 48 */
  --sp-11: 4rem;     /* 64 */
  --sp-12: 5rem;     /* 80 */

  /* ----------------------------------------------------------------- radius */
  --r-none: 0;
  --r-sm:   4px;
  --r-md:   8px;
  --r-lg:   12px;
  --r-xl:   16px;
  --r-pill: 999px;

  /* -------------------------------------------------------------- elevation
     Exactly three levels plus flat. More than three and the hierarchy stops
     meaning anything. (DSG-00) */
  --e-0: none;
  --e-1: 0 1px 2px rgba(10,18,20,.06), 0 1px 3px rgba(10,18,20,.08);
  --e-2: 0 2px 6px rgba(10,18,20,.07), 0 6px 16px rgba(10,18,20,.09);
  --e-3: 0 8px 24px rgba(10,18,20,.10), 0 16px 48px rgba(10,18,20,.12);

  /* ----------------------------------------------------------------- motion */
  --d-instant: 80ms;
  --d-micro:   120ms;   /* hover, focus, toggle */
  --d-standard:200ms;   /* panel, drawer, tab */
  --d-large:   320ms;   /* route transition, sheet */
  --ease-standard: cubic-bezier(.2,0,0,1);
  --ease-enter:    cubic-bezier(0,0,0,1);
  --ease-exit:     cubic-bezier(.3,0,1,1);

  /* Alert pulse — 1200ms cycle ≈ 0.83 Hz, far below the 3 Hz photosensitivity
     threshold. Opacity and border only: never a full-screen luminance flash.
     (KDS-002, UX-005) */
  --alert-pulse-duration: 1200ms;
  --alert-pulse-min-opacity: 0.55;
  --alert-pulse-max-opacity: 1;

  /* ------------------------------------------------------------------- misc */
  --icon-size-sm: 16px;
  --icon-size-md: 20px;
  --icon-size-lg: 24px;
  --icon-size-xl: 32px;
  --icon-stroke: 1.75;
  --touch-min: 44px;          /* console/guest minimum hit target */
  --touch-min-ops: 56px;      /* KDS and runner: gloved hands, arm's length */
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;
  --z-base: 0; --z-sticky: 100; --z-drawer: 200; --z-modal: 300;
  --z-toast: 400; --z-alert: 500;
}

/* ------------------------------------------------------------- density modes
   One component set, three densities. Set on a container, not per component. */
[data-density="comfortable"] { --row-h: 48px; --control-h: 40px; --pad-x: var(--sp-5); }
[data-density="compact"]     { --row-h: 36px; --control-h: 32px; --pad-x: var(--sp-4); }
[data-density="operational"] {
  --row-h: 64px; --control-h: 56px; --pad-x: var(--sp-6);
  --fs-body: 1.125rem; --fs-body-sm: 1rem;   /* readable across a kitchen */
}

/* -------------------------------------------------------------- white label
   Partner branding overrides ONLY this layer, and only within the partner's
   own scope. Semantic and status tokens are platform-owned and cannot be
   overridden — a partner cannot make "failed" look like "ready".
   (WLB-001..WLB-005, DEC-006) */
[data-tenant-theme] {
  --s-primary:        var(--tenant-primary, var(--c-brand-500));
  --s-on-primary:     var(--tenant-on-primary, var(--c-n-000));
  --font-display:     var(--tenant-font-display, "Readex Pro", sans-serif);
  --r-md:             var(--tenant-radius, 8px);

  /* THE OTHER THREE STEPS ARE DERIVED, NOT ASKED FOR.
     `FINAL-PRODUCT-WHITE-LABEL-STOPS-AT-THE-SCAN-01`.

     `--s-primary-hover` used to read `var(--tenant-primary-hover, …)` and
     `--s-primary-active` and `--s-primary-subtle` were not in this layer at
     all — so a partner-branded surface drew their brand colour on the button
     and ALNADL's ramp on its hover, its pressed state and every tinted panel
     beside it. `15 §2.2` gives a partner ONE primary because that is what a
     brand has; asking a hotel for four is asking them to do a design system's
     job, and taking only one and inventing the rest from our own ramp is how
     our lilac ends up next to their crimson on the same control.

     Derived from `--s-primary` rather than from `--tenant-primary`, so the
     relationship holds whichever colour is in force and there is no second
     code path for the default. */
  --s-primary-hover:  color-mix(in srgb, var(--s-primary) 88%, #000);
  --s-primary-active: color-mix(in srgb, var(--s-primary) 76%, #000);
  --s-primary-subtle: color-mix(in srgb, var(--s-primary) 10%, #fff);
}

/* ------------------------------------------------------------------- RTL/LTR
   Direction is handled by logical properties throughout. Physical left/right
   is banned by lint except for the allow-list in the design-system package.
   Arabic gets slightly looser leading and no negative tracking. */
[dir="rtl"] { --lh-normal: 1.65; --ls-tight: 0; }
[dir="rtl"] [data-mirror="true"] { transform: scaleX(-1); }

/* ------------------------------------------------------------ reduced motion
   The alert's operational signal survives; only the movement is removed.
   (UX-005, KDS-002, NFR-008) */
@media (prefers-reduced-motion: reduce) {
  :root {
    --d-instant: 0ms; --d-micro: 0ms; --d-standard: 0ms; --d-large: 0ms;
    --alert-pulse-duration: 0ms;
    --alert-pulse-min-opacity: 1;
  }
  *, *::before, *::after { animation-duration: .01ms !important;
                           transition-duration: .01ms !important; }
}

/* --------------------------------------------------------- forced high contrast */
@media (prefers-contrast: more) {
  :root { --s-border: var(--c-n-400); --s-text-secondary: var(--c-n-700); }
}

/* ---------------------------------------------------------------- dark mode
   Ops surfaces only (kitchen lighting). Console and guest are light-first.
   Status foreground/background pairs are re-derived, never merely inverted. */
[data-theme="ops-dark"] {
  --s-page: var(--c-n-950);
  --s-surface: var(--c-n-900);
  --s-surface-sunken: var(--c-n-950);
  --s-border: var(--c-n-700);
  --s-text: var(--c-n-050);
  --s-text-secondary: var(--c-n-300);
  --s-text-muted: var(--c-n-400);
  --st-ready-fg: #6FD9A2;  --st-ready-bg: #0E2E20;
  --st-preparing-fg: #F0BE72; --st-preparing-bg: #33240C;
  --st-failed-fg: #F2938B; --st-failed-bg: #3A1512;
  --sla-ok: #6FD9A2; --sla-approach: #F0BE72; --sla-breach: #F2938B;
}


/* ======================================================================== */
/*  COMPATIBILITY LAYER                                                     */
/*                                                                          */
/*  The names this project's own stylesheets already use, mapped onto the    */
/*  approved layer above. It exists so adopting the approved architecture is  */
/*  one reviewable change rather than a rewrite of every stylesheet in the    */
/*  same commit, and so the meaning of each old name is stated once, here,    */
/*  where a reader can check it.                                             */
/*                                                                          */
/*  Each mapping is a judgement and is written down as one:                  */
/*    --color-ok maps to `success-700`, not `success-500`, because every use  */
/*    in this product is TEXT on a light tint and 700 is the ink of that      */
/*    pair; --color-critical keeps `critical-600`, which the archive reserves */
/*    for the KDS board accent and which is the only place the product uses   */
/*    it; --space-xl maps to `sp-7` (24px) and not `sp-8`, preserving the     */
/*    value the existing layouts were built against rather than silently      */
/*    reflowing every screen while changing the palette.                     */
/*                                                                          */
/*  New work uses the approved names. This layer shrinks as screens migrate. */
/* ======================================================================== */
:root {
  --color-surface:          var(--s-surface);
  --color-surface-raised:   var(--s-surface-sunken);
  --color-ink:              var(--s-text);
  --color-ink-muted:        var(--s-text-muted);
  --color-border:           var(--s-border);
  --color-alert:            var(--c-danger-500);
  --color-alert-surface:    var(--c-danger-050);
  --color-ok:               var(--c-success-700);
  --color-ok-surface:       var(--c-success-050);
  --color-warning:          var(--c-warning-700);
  --color-warning-surface:  var(--c-warning-050);
  --color-critical:         var(--c-critical-600);
  --color-critical-surface: var(--c-danger-050);

  --space-xs: var(--sp-2);  --space-sm: var(--sp-3);  --space-md: var(--sp-4);
  --space-lg: var(--sp-5);  --space-xl: var(--sp-7);  --space-xxl: var(--sp-8);

  --radius-sm: var(--r-sm); --radius-md: var(--r-md); --radius-lg: var(--r-lg);

  --motion-fast: var(--d-micro);   --motion-base: var(--d-standard);
  --motion-slow: var(--d-large);   --motion-deliberate: 480ms;

  /* `15 §4.2` requires the pulse to be a unit-tested property of the token
     rather than a CSS value somebody can tune. Both names now resolve to the
     same approved source, so the test and the archive cannot disagree. */
  --alert-pulse-cycle:        var(--alert-pulse-duration);
  --alert-pulse-opacity-from: var(--alert-pulse-min-opacity);
  --alert-pulse-opacity-to:   var(--alert-pulse-max-opacity);

  /* `15 §5` states TWO minimums and the difference is deliberate: 44px for
     console and guest, 56px for ops because the hands are gloved and the
     board is read at arm's length.

     CORRECTION 7. This alias resolved to the OPS value for all three
     surfaces, so `forms.css` — which is imported by all three — gave every
     input, select and textarea in the console and the guest app a 56px
     minimum height. That is not `15 §5`; it is one surface's number applied
     to the other two, and it made every console form taller than the design
     it was measured against.

     The floor is now the general minimum, and the OPS value arrives the way
     `15 §5` says density arrives — from the density CONTAINER, "set on a
     container, not per component". `apps/ops` declares
     `data-density="operational"`, so its controls are 56px and nothing else
     changed. */
  --touch-target: var(--touch-min);
}

[data-density="operational"] { --touch-target: var(--touch-min-ops); }

/* `12 §4.1`: opacity and border, never a full-screen luminance flash. */
@keyframes alnadl-alert-pulse {
  from { opacity: var(--alert-pulse-opacity-from); }
  to   { opacity: var(--alert-pulse-opacity-to); }
}

/*
 * `KDS-002`, `UX-005`: two classes, two different facts.
 *
 *   --alerting  the SIGNAL. Always present while the board is alerting, and
 *               already a static high-contrast treatment on its own.
 *   --pulsing   the MOTION. Added on top, and withheld under reduced motion.
 *
 * "The operational signal survives; the motion does not" is only true if the
 * two are separable — one class doing both would mean a reduced-motion user
 * either kept the animation or lost the alert.
 */
.alnadl-alert--alerting {
  position: relative;
  border-inline-start: var(--space-xs) solid var(--color-alert);
  outline: 3px solid var(--color-alert);
  outline-offset: -3px;
  opacity: 1;
}

/*
 * The pulse animates an ACCENT LAYER, never the element's own opacity.
 *
 * Found by axe-core against the real rendered board: animating the header's
 * opacity to 0.55 drags its TEXT down with it, and `color-contrast` fails for
 * part of every cycle — a WCAG 2.2 AA violation `11 §8` does not allow, on the
 * one element a cook has to read fastest. `12 §4.1` asks for "an opacity and
 * border animation, not a full-screen luminance flash", and an inset accent is
 * exactly that: the border breathes, the words do not move.
 */
.alnadl-alert--pulsing::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 var(--space-xs) var(--color-alert);
  animation: alnadl-alert-pulse var(--alert-pulse-cycle) ease-in-out infinite alternate;
}

/*
 * Belt and braces. The controller already withholds `--pulsing` under reduced
 * motion, and this makes the stylesheet safe on its own for any future client
 * that applies the class without asking the controller.
 */
@media (prefers-reduced-motion: reduce) {
  .alnadl-alert--pulsing::after { animation: none; opacity: 1; }
}

/* `15 §6.2`: logical properties only. A physical margin fails lint. */
.alnadl-stack > * + * { margin-block-start: var(--space-md); }
.alnadl-row { display: flex; gap: var(--space-md); align-items: center; }
