﻿@layer reset, legacy, tokens, shell, components, pages, utilities;

/* One rule for every page: the text is the size we set, on every phone. Android
   Chrome "boosts" fonts on pages that do not say otherwise, on top of the
   system font scale, and the owner saw a form twice its size (2026-09-05:
   "اجعل قاعدة للصفحات كلها والقالب أن لا يكبّر الأندرويد الخط"). tokens.css is
   the first sheet on every screen, so this reaches them all. Unlayered on
   purpose: nothing may sit above it. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* BOOTSTRAP'S OWN VARIABLES, IN DARK MODE. Unlayered on purpose: Bootstrap
   declares these on an unlayered :root, and an unlayered declaration beats a
   layered one however specific — inside @layer tokens they never applied
   (measured 2026-09-07). Links with no colour of their own were #0d6efd on
   the dark surfaces (3.7:1) and .text-muted was rgba(33,37,41,.75) on near-
   black (1.3:1); these four pairs fix every such element at once. */
html[data-ds-mode="dark"] {
  --bs-link-color: #6ea8fe;
  --bs-link-color-rgb: 110, 168, 254;
  --bs-link-hover-color: #8bb9fe;
  --bs-link-hover-color-rgb: 139, 185, 254;
  --bs-body-color: #e8e8e8;
  --bs-body-color-rgb: 232, 232, 232;
  --bs-secondary-color: rgba(222, 226, 230, 0.78);
  --bs-secondary-color-rgb: 222, 226, 230;
  --bs-tertiary-color: rgba(222, 226, 230, 0.6);
  --bs-emphasis-color: #ffffff;
}

@layer tokens {
  :root {
    /* THE PROJECT'S TYPE, NAMED ONCE. Cairo covers Arabic and Latin, and
     * site.css self-hosts it. Nothing else may name a family: every stylesheet
     * says var(--font-ui) / var(--font-ar) / var(--font-mono), and
     * StylesheetFontsTests fails the build on a literal one.
     *
     * 2026-09-07, the owner: "رأيت في الشحنات يستخدم خطوط غير موجودة في
     * مشروعي". He was right — shipping asked for Tajawal and the mono stacks
     * asked for JetBrains Mono, and neither has an @font-face anywhere, so both
     * were phantom names that silently fell through to whatever the device had.
     * Only the families actually on disk may be named: Cairo, and Manrope on
     * the factory TV screen. */
    --font-ar: "Cairo", system-ui, sans-serif;
    --font-en: "Cairo", system-ui, sans-serif;
    --font-ui: var(--font-ar);
    --font-mono: ui-monospace, "Cascadia Mono", Consolas, monospace;

    --space-0: 0;
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;

    /* THE CONTROL SCALE, NAMED ONCE — the owner, 2026-09-07: "وحّد الأزرار
     * والحقول والفريمات ومسافة العرض للهواتف".
     *
     * A survey of the 59 stylesheets found control heights at 28, 30, 32, 34,
     * 36, 38, 40, 42, 44, 46, 48 and 52 pixels, so the same button was a
     * different size depending on which screen drew it. These four are the
     * whole vocabulary; a new rule picks one instead of inventing a number.
     *
     *   --control-sm   a chip, a tag, an inline icon button
     *   --control-md   the desktop default for a button or a field
     *   --control-lg   the PHONE floor: 44px is the smallest a thumb hits
     *                  reliably, and on iOS a field under 16px of text zooms
     *                  the page on focus
     *   --control-xl   a primary action standing alone at the foot of a screen
     *
     * --page-gutter is the space between the page and the edge of a phone. It
     * was 8, 10, 12 and 14px in different places, which is why frames looked
     * like they started at different margins on the same device. */
    /* THE TYPE LADDER. Eleven steps, and no size between them.
     *
     * The survey that prompted it (the owner, 2026-09-07): 2,497 font-size
     * declarations across ONE HUNDRED AND TWENTY-FOUR different sizes — .72rem
     * next to .73rem next to .74rem, which at a 16px root are a third of a
     * pixel apart. Nobody can see that difference; it is not design, it is
     * drift, and it is why two screens showing the same kind of row did not
     * look like the same program.
     *
     * The steps are round PIXELS at the 16px root, so the team can reason in
     * whole numbers, and they stay close together in the 10-16px band where an
     * ERP actually lives — a dense screen needs fine control there — then open
     * up for headings, where a small difference reads as a mistake.
     *
     *   2xs  10px  a count on a badge, a footnote in a table
     *   xs   11px  a field's caption, a chip, a tag
     *   sm   12px  a table cell, secondary text, meta
     *   base 13px  body text, an input's value, a button        <- the default
     *   md   14px  emphasised body, a card's title
     *   lg   16px  a section heading; also the phone's INPUT floor, because
     *              iOS zooms the page when a focused field is under 16px
     *   xl   18px  the page title
     *   2xl  20px  a screen headline
     *   3xl  24px  a KPI figure
     *   4xl  30px  a large KPI
     *   5xl  36px  the biggest number a workstation shows
     *
     * Above 36px is the factory TV and the station kiosks, where a figure is
     * read from across the room; those keep their own sizes on purpose. */
    --text-2xs: .625rem;
    --text-xs: .6875rem;
    --text-sm: .75rem;
    --text-base: .8125rem;
    --text-md: .875rem;
    --text-lg: 1rem;
    --text-xl: 1.125rem;
    --text-2xl: 1.25rem;
    --text-3xl: 1.5rem;
    --text-4xl: 1.875rem;
    --text-5xl: 2.25rem;

    --control-xs: 28px;
    --control-sm: 32px;
    --control-md: 40px;
    --control-lg: 44px;
    --control-xl: 52px;
    --control-2xl: 60px;
    --page-gutter: 8px;

    /* THE 4-PIXEL GRID. A survey of every box dimension between 24 and 72px
     * found 1,147 of them spread over THIRTY-FOUR different values — 34, 35,
     * 38, 39, 42, 43, 45, 46, 49, 50 and so on. Nobody chose that; it is what
     * happens when each screen picks a number by eye. Every height and width
     * from here on is a multiple of 4, which is why the tokens above are, and
     * a screen being unified moves its odd values to the nearest multiple —
     * never more than 2px, so nothing visibly jumps. */

    --radius-xs: 4px;
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-pill: 999px;

    --topbar-height: 54px;
    --topbar-total: 74px;
    --content-max: 1480px;

    /* THE accent. One colour for the whole project — the owner, 2026-08-22:
       "أريد أن تكون الشاشات بتصميم واحد ولون واحد وقالب واحد."

       There were three claiming the title: this file said indigo, erp-compact
       said purple (#875a7b), and what the project actually WEARS — the home
       grid, the top bar, the phone frame — is the orange below. Screens then
       overrode the purple inline, one inventing teal and another gold, which is
       how a project ends up with no colour at all.

       Everything else is an alias of this line. */
    --brand-accent: #f6ad3d;
    --brand-accent-ink: #1f2937;
    --brand-accent-soft: rgba(246, 173, 61, 0.14);

    --brand-primary: var(--brand-accent);
    --brand-success: #10b981;
    --brand-danger: #ef4444;
    --brand-warning: #f59e0b;
    --brand-info: #06b6d4;

    --success-soft: rgba(16, 185, 129, 0.12);
    --danger-soft:  rgba(239, 68, 68, 0.12);
    --warning-soft: rgba(245, 158, 11, 0.12);
    --info-soft:    rgba(6, 182, 212, 0.12);
    --primary-soft: rgba(99, 102, 241, 0.12);

    --z-base: 1;
    --z-sticky: 10;
    --z-dropdown: 1100;
    --z-modal: 1300;
    --z-popover: 1350;
    --z-toast: 1400;
    --z-overlay: 2000;
  }

  html[data-ds-mode="light"] {
    --bg-app: #f0f2f5;
    --bg-surface: #ffffff;
    --bg-elevated: #ffffff;
    --bg-hover: #f3f4f6;
    --bg-muted: #f9fafb;

    --text-primary: #1f2937;
    --text-strong: #111827;
    --text-muted: #55606e;
    --text-soft: #6b7688;
    --text-inverse: #ffffff;

    --border: #dbe3eb;
    --border-strong: #c8d4e0;
    --border-soft: #e5e7eb;

    --shadow-sm: 0 1px 2px rgba(0,0,0,.04);
    --shadow-md: 0 2px 6px rgba(0,0,0,.08);
    --shadow-lg: 0 8px 24px rgba(0,0,0,.10);

    --focus-ring: 0 0 0 3px rgba(99,102,241,.35);

    --erp-flat-page-bg: #f0f2f5;
    --erp-flat-surface-bg: #ffffff;
    --erp-flat-border: #dbe3eb;
    --erp-layer-page: #f0f2f5;
    --erp-layer-surface: #ffffff;
    --erp-layer-surface-soft: #f9fafb;
    --erp-layer-border: #dbe3eb;
    --erp-layer-border-strong: #c8d4e0;
    --erp-text-strong: #111827;
    --erp-text: #1f2937;
    --erp-text-muted: #55606e;
    --erp-text-soft: #6b7688;

    color-scheme: light;
  }

  html[data-ds-mode="dark"] {

    --bg-app: #000511;
    --bg-surface: transparent;
    --bg-elevated: transparent;
    --bg-hover: rgba(255,255,255,.06);
    --bg-muted: transparent;

    --text-primary: #e8e8e8;
    --text-strong: #ffffff;
    --text-muted: #b8b8b8;
    --text-soft: #9aa4b3;
    --text-inverse: #0b1020;

    --border: rgba(255,255,255,.08);
    --border-strong: rgba(255,255,255,.14);
    --border-soft: rgba(255,255,255,.05);

    --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
    --shadow-md: 0 4px 12px rgba(0,0,0,.45);
    --shadow-lg: 0 12px 30px rgba(0,0,0,.55);

    --focus-ring: 0 0 0 3px rgba(99,102,241,.40);

    --erp-flat-page-bg: #000511;
    --erp-flat-surface-bg: transparent;
    --erp-flat-border: rgba(255,255,255,.08);
    --erp-layer-page: #000511;
    --erp-layer-surface: transparent;
    --erp-layer-surface-soft: transparent;
    --erp-layer-border: rgba(255,255,255,.08);
    --erp-layer-border-strong: rgba(255,255,255,.14);
    --erp-text-strong: #ffffff;
    --erp-text: #e8e8e8;
    --erp-text-muted: #b8b8b8;
    --erp-text-soft: #9aa4b3;

    color-scheme: dark;
  }

  /* Responsive token scaling — phones, tablets, laptops, large TVs (45"+). */
  @media (max-width: 480px) {
    :root {
      --space-4: 12px;
      --space-5: 16px;
      --space-6: 20px;
      --space-8: 24px;
      --topbar-height: 52px;
      --topbar-total: 60px;
    }
  }

  @media (min-width: 1920px) {
    :root {
      --content-max: 1720px;
    }
  }

  /* THE NARROW PHONE, AND THE ONE WITH A LARGE DISPLAY SIZE.
     -------------------------------------------------------------------------
     Android's "Display size" setting makes every CSS pixel physically bigger,
     so a phone set to Large reports FEWER css pixels across — 360, sometimes
     340 — while an iPhone reports 390 or 430. The type ladder is anchored to
     the root font size, so on those devices the same words fill more of a
     narrower screen and everything reads oversized (the owner, 2026-09-08:
     "الكتابة كبيرة في اندرويد وفي الايفون جيدة").

     One rung down at 380px keeps the proportion the design was drawn at,
     without touching a single size in the ladder itself: every --text-* token
     follows the root, so the whole scale steps together and nothing drifts off
     the 4px control grid. It does NOT fight the reader's own accessibility
     choice — a person who has asked for larger text still gets it, one notch
     quieter than before. */
  @media (max-width: 380px) {
    html { font-size: 15px; }
  }

  @media (min-width: 2560px) {
    :root {
      --content-max: 2100px;
      --space-4: 20px;
      --space-5: 24px;
      --space-6: 28px;
      --space-8: 40px;
    }
    html { font-size: 17px; }
  }

  @media (min-width: 3200px) {
    :root {
      --content-max: 2600px;
    }
    html { font-size: 18px; }
  }
}

/* =============================================================================
 * أسماء المحطات — the station names for the general template's colours
 * =============================================================================
 * قالب المحطات (station-template.css) is retired, 2026-09-02. The owner: "اريد كل
 * المحطات تلبس القالب العام: الالوان والكروت والازرار، وتحذف اي طبقات قديمة
 * عليها." Its scale — the 56px button, the 1.1rem body — is gone with it; the
 * stations take the template's sizes like every other screen.
 *
 * What stays are the NAMES. Eleven hundred rules on the saw board and the
 * packing station say var(--st-surface), var(--st-accent), var(--st-ok); they
 * were always aliases of the template's own tokens and they remain exactly
 * that, so a rule written for a station and a rule written for HR resolve to
 * the same colour in both modes. Nothing here chooses a colour.
 * ========================================================================== */
@layer tokens {
  :root {
    --st-accent:        var(--brand-accent);
    --st-accent-ink:    var(--brand-accent-ink);
    --st-accent-soft:   var(--brand-accent-soft);
    --st-ok:            var(--brand-success);
    --st-stop:          var(--brand-danger);
    --st-warn:          var(--brand-warning);
    --st-info:          var(--brand-info);
    --st-surface:       var(--ec-surface);
    --st-surface-soft:  var(--ec-surface-soft);
    --st-line:          var(--ec-line);
    --st-text:          var(--ec-text);
    --st-muted:         var(--ec-muted);
  }
}

/* THE SAW BLADE. The owner, 2026-09-18: «الأيقونة يكون نصل المنشار وليس مقص».
   bootstrap-icons has no saw, so `bi-saw` is drawn here as a mask over
   currentColor — it inherits size and colour like any other bi-* icon, and
   works on the stations (which load only this sheet and the icon subset).
   The SVG is percent-encoded with single quotes: a double quote inside
   url("…") ends the string and the blade collapses into a square. */
.bi-saw::before {
  content: "";
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -.125em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M13.90 8.00 L15.22 9.61 L13.66 9.68 L13.11 10.95 L13.45 13.01 L12.06 12.28 L10.95 13.11 L10.21 15.06 L9.38 13.74 L8.00 13.90 L6.39 15.22 L6.32 13.66 L5.05 13.11 L2.99 13.45 L3.72 12.06 L2.89 10.95 L0.94 10.21 L2.26 9.38 L2.10 8.00 L0.78 6.39 L2.34 6.32 L2.89 5.05 L2.55 2.99 L3.94 3.72 L5.05 2.89 L5.79 0.94 L6.62 2.26 L8.00 2.10 L9.61 0.78 L9.68 2.34 L10.95 2.89 L13.01 2.55 L12.28 3.94 L13.11 5.05 L15.06 5.79 L13.74 6.62 Z M7.00 8 A 1.00 1.00 0 1 0 9.00 8 A 1.00 1.00 0 1 0 7.00 8 Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M13.90 8.00 L15.22 9.61 L13.66 9.68 L13.11 10.95 L13.45 13.01 L12.06 12.28 L10.95 13.11 L10.21 15.06 L9.38 13.74 L8.00 13.90 L6.39 15.22 L6.32 13.66 L5.05 13.11 L2.99 13.45 L3.72 12.06 L2.89 10.95 L0.94 10.21 L2.26 9.38 L2.10 8.00 L0.78 6.39 L2.34 6.32 L2.89 5.05 L2.55 2.99 L3.94 3.72 L5.05 2.89 L5.79 0.94 L6.62 2.26 L8.00 2.10 L9.61 0.78 L9.68 2.34 L10.95 2.89 L13.01 2.55 L12.28 3.94 L13.11 5.05 L15.06 5.79 L13.74 6.62 Z M7.00 8 A 1.00 1.00 0 1 0 9.00 8 A 1.00 1.00 0 1 0 7.00 8 Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
