/* =============================================================================
   design-language-primitives.css — the components mandated by the ONE design
   language (`docs/ui-proposals-2026-07-28/_design-language.html`, "ערכת השפה v1",
   2026-08-01) that did not yet exist anywhere in the live shared kit.
   =============================================================================

   OWNER: Module 1.5 — Shared Components. Authored by WAVE1_LANE_A (2026-08-06),
   but it is NOT lane A's file; it is the shell kit's, and it is recorded with
   the shell's own assets.

   WHY THIS FILE EXISTS
   --------------------
   The design language declares components every one of the 53 screens must use
   ("מה שלא כאן — לא קיים"). Several of them — most importantly the `.purpose`
   strip, which §1·א calls compulsory on every screen — had no live
   implementation at all. Their natural home is `shared/css/components.css`,
   which is on the freeze list (26 hosts, spanning all five build lanes). A lane
   run may not edit that file: an error in a stylesheet every host loads breaks
   all 23 shell-adopting screens at once, which is precisely what one bare
   `nav{}` rule did to the shell and it cost three runs to find.

   So the primitives live here instead, in a file that is NEW and therefore
   uncontended, and each host opts in with a single <link> line — the same shape
   as the shell's own three include lines, which caused no collision across 23
   hosts.

   THIS FILE IS ON THE FREEZE LIST (BUILD MAP §D3.5)
   -------------------------------------------------
   Created once, then off-limits. Later lanes LINK it; they do not edit it. If a
   lane genuinely needs a primitive added, that is a cross-lane change and it
   goes back to the Architect — otherwise the contention simply moves one file to
   the right, which is the whole thing the freeze list exists to prevent.

   IT IS DELIBERATELY COMPLETE, NOT LANE-A-SHAPED
   ----------------------------------------------
   Everything the language mandates and the kit lacked is here, including
   primitives none of lane A's six screens consume (the loading, save-failure and
   confirm-gate families are for lanes B and E). That is intentional per the
   authoring condition: lane B must be able to LINK this file, not extend it.

   WHAT IS **NOT** HERE, AND WHY — all of these already exist live, so
   redefining them would be a Rule 21 duplicate:
     · `.pill` base + `.pill-success` (green) + `.pill-muted` (gray)
                                            -> shared/css/components.css (frozen)
     · `.empty-state` / `-icon` / `-title`  -> shared/css/components.css (frozen)
     · `.page-header`                       -> shared/css/layout.css      (frozen)
     · modal chrome for the PIN + confirm gates
                                            -> shared/css/modal.css       (frozen)
       (only the error/lock/recipient/amount LINES below were missing. The PIN
        contract itself is behaviour in shared/js/pin-modal.js and is not
        touched here — Iron Rule 8.)
     · the top ERP bar / sidebar / rail     -> the shell (run 0), frozen
     · §2 dictionary  -> terminology, carries no CSS
     · §3 bdi / logical-property rules -> authoring rules for screen code, not
       components. The one exception is `.money`, which is a real component
       because tabular numerals must be identical in every column.

   HOUSE RULES FOR EDITING (if the freeze is ever lifted)
     · NO bare element selectors, ever. Every rule below starts with a class.
       This is asserted mechanically — see tools/design-language-primitives-assert.mjs.
     · Logical properties only (§3): inline-start/inline-end, never left/right.
     · Values come from var(--token); a literal needs a comment saying why.
   ============================================================================= */

:root {
  /* §1·ב mandates a sixth severity, purple, for system-only statuses ("תיקון
     חוזר"). variables.css is frozen and carries no purple pair, so the two
     values live here — the only literals in this file. They belong in
     variables.css beside the other severities once that file can be edited. */
  --color-special-light: #ede9fe;
  --color-special-dark:  #5b21b6;
}

/* =============================================================================
   §1·א — the "מה עושים במסך הזה" strip.  COMPULSORY ON EVERY SCREEN.
   Always directly under the screen title, always info-blue. One per screen;
   there is no second explanatory banner and no hero.
   Markup (both forms render):
     <div class="purpose"><span class="purpose-ic">🎯</span><div>…</div></div>
     <div class="purpose">💡 <b>מה עושים במסך הזה?</b> …</div>
   ============================================================================= */
.purpose {
  display: flex;
  gap: var(--space-sm, 8px);
  align-items: flex-start;
  background: var(--color-info-light);
  color: var(--color-info-dark);
  border-inline-start: 3px solid var(--color-info);
  border-radius: var(--radius-md, 8px);
  padding: 10px var(--space-md, 12px);
  margin-block: var(--space-sm, 8px) var(--space-md, 12px);
  font-size: var(--font-size-sm, 0.85rem);
  line-height: 1.6;
}
.purpose-ic { flex: 0 0 auto; font-size: var(--font-size-md, 0.92rem); line-height: 1.5; }

/* =============================================================================
   §1·ח + §1·ב — status pills. Colour = SEVERITY, never identity.
   Green (`.pill-success`) and gray (`.pill-muted`) already exist in
   components.css; these are the four the scale was missing, plus the שלב 2 tag.
   ============================================================================= */
.pill-info    { background: var(--color-info-light);    color: var(--color-info-dark); }
.pill-warn    { background: var(--color-warning-light); color: var(--color-warning-dark); }
.pill-danger  { background: var(--color-error-light);   color: var(--color-error-dark); }
.pill-special { background: var(--color-special-light); color: var(--color-special-dark); }

/* §1·ח — marks an element that needs data or logic which does not exist yet.
   Tagged = documented for separate approval; untagged = due for immediate build. */
.pill-phase2 {
  background: var(--color-special-light);
  color: var(--color-special-dark);
  border: 1px dashed currentColor;
}

/* =============================================================================
   §1·ג — one tooltip (term explanation) and one callout (action guidance).
   There is no third reading component. Warnings/errors use §1·ז only.
   Markup: עוצמה<span class="tip" tabindex="0">?<span class="tip-tx">…</span></span>
   Opens ABOVE, 230px, and works on keyboard focus as well as hover.
   ============================================================================= */
.tip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 15px;
  block-size: 15px;
  margin-inline-start: 4px;
  border-radius: var(--radius-full, 9999px);
  background: var(--color-gray-300);
  color: var(--color-gray-700);
  font-size: var(--font-size-xs);
  font-weight: 700;
  cursor: help;
  vertical-align: middle;
}
.tip-tx {
  position: absolute;
  inset-block-end: calc(100% + 6px);
  inset-inline-start: 50%;
  transform: translateX(50%);
  inline-size: 230px;
  padding: var(--space-sm, 8px) 10px;
  border-radius: var(--radius-md, 8px);
  background: var(--color-gray-800);
  color: var(--white);
  font-size: var(--font-size-xs, 0.75rem);
  font-weight: 400;
  line-height: 1.55;
  text-align: start;
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s ease;
  z-index: 60;
}
.tip:hover .tip-tx,
.tip:focus .tip-tx,
.tip:focus-within .tip-tx { opacity: 1; visibility: visible; }

/* Teaching aid only — never a warning, never an error. */
.callout {
  background: var(--color-warning-light);
  color: var(--color-warning-dark);
  border-inline-start: 3px solid var(--color-warning);
  border-radius: var(--radius-md, 8px);
  padding: 10px var(--space-md, 12px);
  font-size: var(--font-size-sm, 0.85rem);
  line-height: 1.6;
}

/* =============================================================================
   §1·ז — loading · error · save failure. Every screen draws a loading state;
   an error always says what happened + what was NOT lost + what to do now.
   ============================================================================= */
.load-caption {
  display: flex;
  align-items: center;
  gap: var(--space-sm, 8px);
  color: var(--color-gray-500);
  font-size: var(--font-size-sm, 0.85rem);
  padding: var(--space-md, 12px);
}
.load-spinner {
  inline-size: 14px;
  block-size: 14px;
  border: 2px solid var(--color-gray-300);
  border-block-start-color: var(--primary);
  border-radius: var(--radius-full, 9999px);
  animation: dlp-spin .7s linear infinite;
}
@keyframes dlp-spin { to { transform: rotate(360deg); } }

/* Skeletons for lists/tables. `.msg-skeleton` in communications.css is the
   messaging bubble variant and is deliberately left alone. */
.skeleton-row { display: flex; flex-direction: column; gap: var(--space-sm, 8px); padding: var(--space-md, 12px); }
.skeleton-bar {
  block-size: 11px;
  border-radius: var(--radius-sm, 6px);
  background: linear-gradient(90deg,
    var(--color-gray-100) 25%,
    var(--color-gray-200) 37%,
    var(--color-gray-100) 63%);
  background-size: 400% 100%;
  animation: dlp-shimmer 1.3s ease infinite;
}
@keyframes dlp-shimmer { from { background-position: 100% 50%; } to { background-position: 0 50%; } }

/* F-7 (M2_LOGIN_ENABLEMENT_PREREQS, 2026-08-12) — the banner must obey `hidden`.
   `display: flex` below is an AUTHOR rule; the UA's `[hidden] { display: none }`
   is a USER-AGENT rule, and author beats user-agent regardless of specificity.
   So `<div class="save-failure" hidden>` rendered VISIBLE on a clean page load,
   before any save, and `clearSettingsDirty()`'s `f.hidden = true` on a successful
   save had no effect either — staff read "השמירה לא הצליחה" after a save that
   worked, and saved again. Two live consumers: settings.html:227 and
   employee-wizard.js:65. This one line repairs both. */
.save-failure[hidden] { display: none; }

.save-failure {
  display: flex;
  gap: var(--space-sm, 8px);
  align-items: flex-start;
  background: var(--color-error-light);
  color: var(--color-error-dark);
  border-inline-start: 3px solid var(--color-error);
  border-radius: var(--radius-md, 8px);
  padding: 10px var(--space-md, 12px);
  font-size: var(--font-size-sm, 0.85rem);
  line-height: 1.6;
}

/* =============================================================================
   §1·ה + §1·ו — the lines the PIN modal and the two confirm gates need.
   The modal shell itself is modal.css; the PIN contract is pin-modal.js.
   ============================================================================= */
.field-error { border-color: var(--color-error) !important; background: var(--color-error-light); }
.error-line  { color: var(--color-error-dark); font-size: var(--font-size-sm, 0.85rem); margin-block-start: var(--space-xs, 4px); }
.lock-line   { color: var(--color-warning-dark); background: var(--color-warning-light);
               border-radius: var(--radius-sm, 6px); padding: var(--space-sm, 8px) 10px;
               font-size: var(--font-size-xs, 0.75rem); line-height: 1.55; margin-block-start: var(--space-sm, 8px); }

/* §1·ו — send gate: who this is about to reach, before it reaches them. */
.confirm-recipient {
  background: var(--color-info-light);
  color: var(--color-info-dark);
  border-radius: var(--radius-md, 8px);
  padding: 10px var(--space-md, 12px);
  font-size: var(--font-size-sm, 0.85rem);
  line-height: 1.6;
}
/* §1·ו — payment gate: the "after this payment, X remains" row is compulsory. */
.confirm-amount-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md, 12px);
  padding: var(--space-sm, 8px) 0;
  border-block-start: 1px solid var(--color-gray-200);
  font-size: var(--font-size-sm, 0.85rem);
  color: var(--color-gray-700);
}

/* =============================================================================
   §3 — money and signed numerals. A component, not just a rule: columns must
   align digit-for-digit, and in an optical prescription "2.25-" instead of
   "-2.25" is a clinical error rather than a cosmetic one. Pair with <bdi>.
   ============================================================================= */
.money { font-variant-numeric: tabular-nums; unicode-bidi: isolate; white-space: nowrap; }
