/* ==========================================================================
   SZ365 tokens.css
   GENERATED FILE — do not hand-edit. Source of truth is tokens.json.
   Regenerate with build-tokens.js after changing tokens.json.
   ========================================================================== */

:root {
  /* Color ramps ------------------------------------------------------- */
  --color-neutral-0: #ffffff;
  --color-neutral-50: #f8fafb;
  --color-neutral-100: #eef2f4;
  --color-neutral-200: #dfe5e9;
  --color-neutral-300: #c3cdd4;
  --color-neutral-400: #99a7b1;
  --color-neutral-500: #71828c;
  --color-neutral-600: #566470;
  --color-neutral-700: #414d57;
  --color-neutral-800: #2b343c;
  --color-neutral-900: #1b2226;
  --color-neutral-950: #0f1416;
  --color-brand-50: #eaf7f5;
  --color-brand-100: #cdede7;
  --color-brand-200: #9edbd0;
  --color-brand-300: #69c2b4;
  --color-brand-400: #3ea495;
  --color-brand-500: #22897b;
  --color-brand-600: #187a6d;
  --color-brand-700: #146259;
  --color-brand-800: #124f49;
  --color-brand-900: #0f413c;
  --color-brand-950: #082825;
  --color-gold-50: #fdf7ec;
  --color-gold-100: #faeacb;
  --color-gold-200: #f3d28f;
  --color-gold-300: #e9b655;
  --color-gold-400: #dc9b2e;
  --color-gold-500: #c07f1b;
  --color-gold-600: #9c6416;
  --color-gold-700: #7a4e16;
  --color-gold-800: #633f18;
  --color-gold-900: #513516;
  --color-success-50: #ecfbf3;
  --color-success-100: #d2f5e1;
  --color-success-200: #a6e9c7;
  --color-success-300: #6fd5a8;
  --color-success-400: #3abd8a;
  --color-success-500: #17a171;
  --color-success-600: #0e8360;
  --color-success-700: #0c684e;
  --color-success-800: #0d5340;
  --color-success-900: #0b4335;
  --color-warning-50: #fff8eb;
  --color-warning-100: #feecc3;
  --color-warning-200: #fdd888;
  --color-warning-300: #fbbe4c;
  --color-warning-400: #f7a421;
  --color-warning-500: #e48a0e;
  --color-warning-600: #bd6b09;
  --color-warning-700: #964f0c;
  --color-warning-800: #7a400f;
  --color-warning-900: #66360f;
  --color-danger-50: #fef2f2;
  --color-danger-100: #fde1e1;
  --color-danger-200: #fbc5c5;
  --color-danger-300: #f79e9e;
  --color-danger-400: #ef6e6e;
  --color-danger-500: #e13f3f;
  --color-danger-600: #c42626;
  --color-danger-700: #9f1d1d;
  --color-danger-800: #831d1d;
  --color-danger-900: #6e1e1e;
  --color-info-50: #eff7ff;
  --color-info-100: #dbebff;
  --color-info-200: #badcff;
  --color-info-300: #8cc6ff;
  --color-info-400: #57a8ff;
  --color-info-500: #2e87f5;
  --color-info-600: #1b69d6;
  --color-info-700: #1955ad;
  --color-info-800: #1a478a;
  --color-info-900: #1b3e72;

  /* Semantic tokens (light theme — the only theme in this prototype) -- */
  --bg-canvas: #f8fafb;
  --bg-surface: #ffffff;
  --bg-surface-sunken: #eef2f4;
  --bg-surface-hover: #eef2f4;
  --bg-overlay-scrim: rgba(15, 20, 22, 0.6);
  --bg-brand-subtle: #eaf7f5;
  --bg-brand-subtle-hover: #cdede7;
  --bg-success-subtle: #ecfbf3;
  --bg-warning-subtle: #fff8eb;
  --bg-danger-subtle: #fef2f2;
  --bg-info-subtle: #eff7ff;
  --bg-gold-subtle: #fdf7ec;
  --border-default: #dfe5e9;
  --border-strong: #828f9b; /* 3.31:1 on surface — draws every input/checkbox/radio (was 1.61:1) */
  --border-brand: #69c2b4;
  --border-success: #6fd5a8;
  --border-warning: #fbbe4c;
  --border-danger: #f79e9e;
  --border-info: #8cc6ff;
  --text-primary: #1b2226;
  --text-secondary: #566470;
  --text-muted: #5e6b76; /* 5.47:1 on surface, 5.22 canvas, 4.85 sunken (was #99A7B1 = 2.47:1) */
  --text-disabled: #99a7b1; /* decorative / inactive only — exempt from 1.4.11 */
  --text-on-brand: #ffffff;
  --text-on-dark: #f8fafb;
  /* The muted rank ON a dark surface. Its absence is why the merchant sidebar's
     group titles reached for a raw ramp value (--color-neutral-500) and landed at
     4.05:1 on --color-neutral-900 — a real 1.4.3 failure on 40 screens. 5.16:1. */
  --text-muted-on-dark: #8494a0;
  --text-link: #146259;
  --text-brand: #146259;
  --text-success: #0c684e;
  --text-warning: #7a400f;
  --text-danger: #9f1d1d;
  --text-info: #1955ad;
  --text-gold: #7a4e16;
  --action-brand-default: #187a6d;
  --action-brand-hover: #146259;
  --action-brand-active: #124f49;
  --action-danger-default: #c42626;
  --action-danger-hover: #9f1d1d;
  --action-danger-active: #831d1d;
  /* Focus ring is brand-derived, not info-blue: on a teal product an info-blue ring reads as
     another product's colour (M42). Drawn with outline-offset so it sits on the BACKGROUND,
     which is what its contrast is measured against — 11.4:1 on surface. */
  --focus-ring: #0f413c;
  --focus-ring-inverse: #ffffff; /* for focus on a dark/accent-filled surface */

  /* Typography ---------------------------------------------------------- */
  /* 'IBM Plex Sans' is listed FIRST on purpose. Both faces are self-hosted in
     fonts/fonts.css and partitioned by unicode-range: the Arabic face covers the
     Arabic blocks only and stops short of U+0030-0039, so Western digits, SKUs,
     order ids and money amounts always resolve to the Latin face. That is what
     keeps the Western-digits rule true with no markup. Arabic letters are not in
     the Latin ranges, so Arabic still renders from Plex Arabic. */
  --font-sans:
    'IBM Plex Sans', 'IBM Plex Sans Arabic', -apple-system, 'Segoe UI', Tahoma, Arial, sans-serif;
  /* IBM Plex Mono is deliberately NOT shipped — it has no Arabic glyphs, which is
     the M7 defect. Column alignment is handled by tabular figures on the Latin
     face (see fonts/fonts.css); this stack is only for genuine code/ID display. */
  --font-mono: ui-monospace, 'SFMono-Regular', 'Roboto Mono', Menlo, Consolas, monospace;
  --font-size-micro: 0.75rem;
  --font-size-caption: 0.8125rem;
  --font-size-body-sm: 0.875rem;
  --font-size-body: 1rem;
  --font-size-body-lg: 1.125rem;
  --font-size-h4: 1.25rem;
  --font-size-h3: 1.5rem;
  --font-size-h2: 1.75rem;
  --font-size-h1: 2.25rem;
  --font-size-display: 3rem;
  --line-height-tight: 1.2;
  --line-height-snug: 1.35;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.65;
  --line-height-loose: 1.8;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* Spacing (4px grid) --------------------------------------------------- */
  --space-0: 0;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-32: 8rem;
  --space-px: 1px;
  --space-0-5: 0.125rem;

  /* Radius ---------------------------------------------------------------- */
  --radius-none: 0;
  --radius-xs: 0.25rem;
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-2xl: 1.5rem;
  --radius-full: 9999px;

  /* Elevation --------------------------------------------------------------- */
  --shadow-e0: none;
  --shadow-e1: 0 1px 2px rgba(15, 20, 22, 0.06), 0 1px 1px rgba(15, 20, 22, 0.04);
  --shadow-e2: 0 2px 6px rgba(15, 20, 22, 0.08), 0 1px 2px rgba(15, 20, 22, 0.05);
  --shadow-e3: 0 8px 24px rgba(15, 20, 22, 0.12), 0 2px 6px rgba(15, 20, 22, 0.06);
  --shadow-e4: 0 16px 48px rgba(15, 20, 22, 0.2), 0 4px 12px rgba(15, 20, 22, 0.08);

  /* Z-index scale ------------------------------------------------------------ */
  --z-base: 0;
  --z-sticky: 10;
  --z-dropdown: 20;
  --z-overlay: 30;
  --z-modal: 40;
  --z-toast: 50;
  --z-tooltip: 60;

  /* Breakpoints (reference only — media queries below hardcode these px values) */
  --breakpoint-sm: 480px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 1024px;
  --breakpoint-xl: 1280px;
  --breakpoint-xxl: 1536px;

  /* Motion -------------------------------------------------------------------- */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-decelerate: cubic-bezier(0, 0, 0, 1);
  --ease-accelerate: cubic-bezier(0.3, 0, 1, 1);

  /* Control sizing — default (overridden per [data-app] below) ---------------- */
  --control-height-sm: 2rem;
  --control-height-md: 2.5rem;
  --control-height-lg: 3rem;
  --control-radius: 0.5rem;
  --control-font-size: 1rem;
  --control-gap: 0.5rem;
  --container-max-width: 1180px;

  /* Touch targets (WCAG 2.5.8 floor is 24px; we hold 44px on touch surfaces) ---- */
  --tap-target-min: 2.75rem;

  /* Commerce surfaces (Phase 2) ------------------------------------------------ */
  --header-h: 3.5rem; /* one number the sticky rail, buy box and scroll-margin share */
  --sticky-cta-h: 4.5rem;
  --z-sticky-cta: 15; /* between --z-sticky (10) and --z-dropdown (20) */
  --bg-media: #eef2f4; /* letterbox field behind a non-1:1 product photo */
  --radius-media: 0.75rem;
  --grid-gap-card: var(--space-3); /* steps up at breakpoints in components.css */

  /* Sale badge — deliberately NOT --badge-danger. Red stays reserved for errors and
     destructive actions; sale gets its own solid treatment because the cream gold pill
     is illegible over arbitrary product photography (M41). */
  --badge-sale-bg: #c42626;
  --badge-sale-fg: #ffffff; /* 5.75:1 */

  /* Rating stars. The filled/unfilled distinction is FILL, not hue: unfilled stars are
     drawn as outlines, so the information survives greyscale and forced-colors. */
  --rating-star-on: #c07f1b; /* 3.34:1 on surface — non-text graphic */
  --rating-star-off: #7c8a95; /* 3.52:1 on surface — outline stroke */

  /* Per-shop accent, set from --shop-theme by the [data-shop-theme] block below. */
  --shop-accent: var(--action-brand-default);
  --shop-accent-hover: var(--action-brand-hover);
  --shop-accent-subtle: var(--bg-brand-subtle);
  --shop-on-accent: #ffffff;
}

/* ==========================================================================
   Arabic type step
   Arabic renders optically lighter and smaller than Latin at an identical token, so
   the PRIMARY locale was opening with the weaker headline. Arabic also needs more
   leading: ascending dots and diacritics clip at snug 1.35. Never letter-space and
   never uppercase Arabic — uppercase is a no-op and tracking breaks cursive joining.
   ========================================================================== */
:root:lang(ar),
[lang='ar'] {
  --font-size-micro: 0.8125rem;
  --font-size-caption: 0.875rem;
  --font-size-card-title: 0.9375rem;
  --line-height-snug: 1.5;
  --font-weight-card-title: 600;
}
:root:lang(en),
[lang='en'] {
  --font-size-card-title: 0.875rem;
  --font-weight-card-title: 500;
}

/* ==========================================================================
   Per-app temperament overrides
   Real screens: <html data-app="storefront|merchant|admin">.
   components.html only: a wrapping <div data-app="..."> per shell demo.
   ========================================================================== */

[data-app='storefront'] {
  --control-height-sm: 2.25rem;
  --control-height-md: 2.75rem;
  --control-height-lg: 3.25rem;
  --control-radius: 0.75rem;
  /* 1280, not 1180: a 5-up product grid at 1440 needs the extra room, and the facet-rail
     arithmetic (17rem rail + gap + grid) is computed against this number. */
  --container-max-width: 1280px;
  --bg-canvas: #f8fafb;
}
html[data-app='storefront'] {
  font-size: 16px;
}
@media (min-width: 1024px) {
  [data-app='storefront'] {
    --header-h: 4rem;
  }
}

[data-app='merchant'] {
  --control-height-sm: 2.25rem;
  --control-height-md: 2.75rem;
  --control-height-lg: 3.5rem;
  --control-radius: 0.5rem;
  --container-max-width: 1440px;
  --bg-canvas: #eef2f4;
}
html[data-app='merchant'] {
  font-size: 16px;
}

/* POS kiosk zone budget (components.css §21). Every one of these is a FIXED
   row/column in the till grid; the cart scroll region is the only flexible
   track, so nothing here may ever push the pay control off screen. */
[data-pos-kiosk] {
  --pos-bar-h: 3.5rem;
  --pos-entry-h: 3.75rem;
  --pos-status-h: 2.75rem;
  --pos-cart-head-h: 2rem;
  --pos-pay-h: 4rem;
  --pos-line-h: 3.75rem;
  /* The till column is capped as a FRACTION of the viewport as well as in rem.
     At 200% text zoom a bare 25rem becomes 800px of a 1024px till, leaving the
     catalogue 224px and every product tile cut in half. The vw term is inert at
     INERT at 100% text on every supported size and bite only when text grows.
     45vw was not: at the 800px narrow-landscape terminal it computed 360px
     against the 400px the rem asks for, shrinking the till column and clipping a
     struck list price. pos-sweep caught it. 50vw ties exactly at 800px and is
     slack at every size above it. */
  --pos-till-w: min(25rem, 50vw);
  --pos-tiles-h: 11rem;
}
@media (min-width: 64rem) {
  [data-pos-kiosk] {
    --pos-till-w: min(26rem, 50vw);
  }
}

[data-app='admin'] {
  --control-height-sm: 1.75rem;
  --control-height-md: 2.125rem;
  --control-height-lg: 2.5rem;
  --control-radius: 0.375rem;
  --container-max-width: 1360px;
  --bg-canvas: #f8fafb;
}
html[data-app='admin'] {
  font-size: 15px;
}

/* ==========================================================================
   Per-shop storefront theme (ShopThemeColor — 8 server-enforced values)

   VALUES ARE THE CONTRACT'S. These are SHOP_THEME_HEX from
   packages/contracts/src/storefront/index.ts, verbatim. The previous block
   hand-picked its own palette (SLATE #566470, TEAL #187A6D, INDIGO #4A5BB8…),
   which meant every themed screenshot reviewed in Phase 1 showed colours that
   could never render in production. Do not "improve" these — regenerate them
   from the contract.

   --shop-accent-hover  = accent darkened 12% toward black
   --shop-accent-subtle = accent at 8% over white
   --shop-on-accent     = #FFFFFF for all eight (each clears 4.5:1: SLATE 17.0,
                          EMERALD 5.48, TEAL 4.98, SKY 5.93, INDIGO 7.91,
                          VIOLET 7.10, ROSE 6.29, AMBER 5.02)

   Applied by putting data-shop-theme="<ENUM>" on the SHOP CONTENT region — never
   on :root, which repainted platform chrome. The allow-list of what the accent may
   paint is enforced in components.css.
   ========================================================================== */
[data-shop-theme] {
  --shop-accent: var(--action-brand-default);
  --shop-accent-hover: var(--action-brand-hover);
  --shop-accent-subtle: var(--bg-brand-subtle);
  --shop-on-accent: #ffffff;
  /* legacy alias — existing markup still references --shop-theme */
  --shop-theme: var(--shop-accent);
  --shop-theme-subtle: var(--shop-accent-subtle);
}
[data-shop-theme='SLATE'] {
  --shop-accent: #0f172a;
  --shop-accent-hover: #0d1425;
  --shop-accent-subtle: #ecedee;
}
[data-shop-theme='EMERALD'] {
  --shop-accent: #047857;
  --shop-accent-hover: #046a4d;
  --shop-accent-subtle: #ebf4f2;
}
[data-shop-theme='TEAL'] {
  --shop-accent: #0f766e;
  --shop-accent-hover: #0d6861;
  --shop-accent-subtle: #ecf4f3;
}
[data-shop-theme='SKY'] {
  --shop-accent: #0369a1;
  --shop-accent-hover: #035c8e;
  --shop-accent-subtle: #ebf3f8;
}
[data-shop-theme='INDIGO'] {
  --shop-accent: #4338ca;
  --shop-accent-hover: #3b31b2;
  --shop-accent-subtle: #f0effb;
}
[data-shop-theme='VIOLET'] {
  --shop-accent: #6d28d9;
  --shop-accent-hover: #6023bf;
  --shop-accent-subtle: #f3eefc;
}
[data-shop-theme='ROSE'] {
  --shop-accent: #be123c;
  --shop-accent-hover: #a71035;
  --shop-accent-subtle: #faecef;
}
[data-shop-theme='AMBER'] {
  --shop-accent: #b45309;
  --shop-accent-hover: #9e4908;
  --shop-accent-subtle: #f9f1eb;
}

/* Belt-and-braces: platform chrome and the checkout path reset the accent to the
   platform brand, so even a mis-scoped data-shop-theme cannot repaint them again.
   The checkout CTA stays platform-teal inside a themed shop on purpose — the customer
   is transacting against the platform's ZATCA/invoice rails, and a shop-coloured "ادفع"
   on a page that produces a platform-numbered tax invoice is a trust regression. */
.sf-header,
.sf-footer,
.sticky-cta,
.buy-box__checkout,
.cart-summary__cta {
  --shop-accent: var(--action-brand-default);
  --shop-accent-hover: var(--action-brand-hover);
  --shop-accent-subtle: var(--bg-brand-subtle);
  --shop-theme: var(--action-brand-default);
  --shop-theme-subtle: var(--bg-brand-subtle);
}
