/* ============================================================
   DropshipSA v2 — Base components (P0.2)
   Source of truth: design.md section 7 (component library).

   Rules for this file:
     - Consume tokens only. No raw hex, no raw spacing values.
       All colors/sizes come from design-system.css (#2).
     - RTL + LTR from one sheet: use CSS logical properties
       (padding-inline, margin-inline, inset-inline, border-inline).
       Never left/right physical props for flow-relative layout.
     - Every interactive component has hover, focus-visible,
       active and disabled states, and a visible focus ring
       (--focus-ring, 3px) per design.md 7 + 14.
     - Motion uses the --dur / --ease tokens so the reduced-motion
       guard in design-system.css can damp it.
     - Presentation only. No page is changed by loading this file.

   Load AFTER design-system.css. Requires those tokens.

   Order:
     1. Buttons (7.1)
     2. Inputs & forms (7.2)
     2b. Bootstrap switch bridge (issue 434)
     3. Cards (7.3)
     4. Status chips (7.6)
     5. Inline alerts + toast (7.7)
     6. Modal + backdrop (7.8)
   ============================================================ */

/* ------------------------------------------------------------
   1. Buttons — design.md 7.1
   Variants: primary, secondary, ghost, danger, link.
   Sizes: sm (32) / md (40, default) / lg (48).
   No uppercase, no letter-spacing (Arabic).
   ------------------------------------------------------------ */
.btn {
  /* base: size md */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  block-size: 40px;
  padding-inline: var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  text-transform: none;    /* no uppercase — Arabic */
  letter-spacing: normal;  /* no tracking — Arabic */
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.btn:disabled,
.btn[disabled],
.btn.is-disabled {
  opacity: 0.55;
  cursor: not-allowed;
  box-shadow: none;
}

/* Sizes */
.btn-sm {
  block-size: 32px;
  padding-inline: var(--sp-3);
  font-size: var(--fs-small);
}
.btn-lg {
  block-size: 48px;
  padding-inline: var(--sp-6);
  font-size: var(--fs-body-lg);
}

/* Full-width on mobile for primary actions (7.1) */
.btn-block {
  display: flex;
  inline-size: 100%;
}

/* Primary — accent fill */
.btn-primary {
  background-color: var(--accent);
  border-color: var(--accent);
  color: var(--n-0);
}
.btn-primary:hover {
  background-color: var(--accent-hover);
  border-color: var(--accent-hover);
}
.btn-primary:active {
  background-color: var(--accent-hover);
}

/* Secondary — surface + border */
.btn-secondary {
  background-color: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-secondary:hover {
  background-color: var(--surface-2);
  border-color: var(--border-strong);
}
.btn-secondary:active {
  background-color: var(--surface-2);
}

/* Ghost — text only */
.btn-ghost {
  background-color: transparent;
  border-color: transparent;
  color: var(--text);
}
.btn-ghost:hover {
  background-color: var(--surface-2);
}
.btn-ghost:active {
  background-color: var(--surface-2);
}

/* Danger / destructive */
.btn-danger {
  background-color: var(--danger);
  border-color: var(--danger);
  color: var(--n-0);
}
.btn-danger:hover {
  background-color: var(--danger);
  filter: brightness(0.92);
}
.btn-danger:active {
  filter: brightness(0.86);
}

/* Link — looks like text, acts like a button */
.btn-link {
  block-size: auto;
  padding-inline: 0;
  background-color: transparent;
  border-color: transparent;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.btn-link:hover {
  color: var(--accent-hover);
}

/* Loading — spinner + disabled + preserve width (7.1) */
.btn.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-loading::after {
  content: "";
  position: absolute;
  inline-size: 1em;
  block-size: 1em;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--r-pill);
  color: var(--n-0);
  animation: ds-spin var(--dur-slow) linear infinite;
}
.btn-secondary.is-loading::after,
.btn-ghost.is-loading::after,
.btn-link.is-loading::after {
  color: var(--text);
}

@keyframes ds-spin {
  to { transform: rotate(360deg); }
}

/* ------------------------------------------------------------
   2. Inputs & forms — design.md 7.2
   Label above field. Helper text below. Inline validation.
   40px height, --r-md, 1px border, focus = accent border + ring.
   ------------------------------------------------------------ */

/* Field wrapper: label above, control, then help/error below */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.field-label {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--text);
}
.field-help {
  font-size: var(--fs-small);
  color: var(--text-muted);
}
.field-error {
  font-size: var(--fs-small);
  color: var(--danger);
}

/* Shared control look for text inputs, select and textarea */
.input,
.select,
.textarea {
  display: block;
  inline-size: 100%;
  min-block-size: 40px;
  padding-block: var(--sp-2);
  padding-inline: var(--sp-3);
  background-color: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  transition: border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--text-subtle);
}

.input:hover,
.select:hover,
.textarea:hover {
  border-color: var(--border-strong);
}

.input:focus,
.input:focus-visible,
.select:focus,
.select:focus-visible,
.textarea:focus,
.textarea:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.input:disabled,
.input[disabled],
.select:disabled,
.select[disabled],
.textarea:disabled,
.textarea[disabled] {
  background-color: var(--surface-2);
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.7;
}

/* Error state on a control (pair with .field-error text) */
.input.is-error,
.select.is-error,
.textarea.is-error {
  border-color: var(--danger);
}
.input.is-error:focus,
.select.is-error:focus,
.textarea.is-error:focus {
  box-shadow: 0 0 0 3px var(--danger-bg);
}

.textarea {
  min-block-size: 96px;
  resize: vertical;
}

/* Dropdowns — never cut off the option text (issue 314).
   Keep the browser's own caret: it is drawn on the trailing edge in RTL and
   LTR automatically. Reserve room for it with a logical padding so it never
   sits on top of a long Arabic label. Height grows with the text instead of
   being pinned, and the control shrinks to its cell instead of overflowing.
   The selector list covers every select class used in the app, so all panels
   (merchant, store settings, admin, wizard) are fixed at once. */
.select,
.panel-main select,
select.form-control,
select.ss-input,
select.od-input,
select.input-modern {
  appearance: auto;
  min-inline-size: 0;
  max-inline-size: 100%;
  block-size: auto;
  min-block-size: var(--sp-8);
  padding-inline-end: var(--sp-8);
}

/* Typed text must read as real, editable text — not a faded placeholder
   (issue 602). Bootstrap `.form-control` ships its own medium-grey text color.
   On the cream panel that grey looks almost the same as the placeholder, so a
   value the user typed looked like a hint. Force every panel text input to the
   dark --text token, and keep the placeholder on the lighter --text-subtle
   token so the hint and the value stay clearly different. This covers
   `.form-control` (used on almost every panel input) plus the store settings,
   order detail and modern input classes, so the fix reaches all pages at once,
   not just the variant name field. */
.form-control,
.ss-input,
.od-input,
.input-modern,
.panel-main input,
.panel-main textarea {
  color: var(--text);
}
.form-control::placeholder,
.ss-input::placeholder,
.od-input::placeholder,
.input-modern::placeholder,
.panel-main input::placeholder,
.panel-main textarea::placeholder {
  color: var(--text-subtle);
}

/* Read-only inputs that hold a code, a key or a link the user copies
   (issue 1469 — the referral link; the number carries no hash here because this
   file may hold no raw hex colour, and a bare 1469 reads as one).
   These were painted with an inline near-white background. An inline style
   beats every stylesheet rule, `!important` included, so the dark theme could
   not repaint it: the merchant's own referral link came out grey on near-white
   and could not be read at all. Both colours are design tokens now, so the
   light and the dark theme each paint it from their own palette. */
.input-readonly-code {
  background-color: var(--surface-2);
  color: var(--text);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 13px;
}

/* Custom dropdown menus — long labels wrap instead of being clipped. */
.dropdown-menu {
  max-inline-size: min(92vw, 28rem);
}
.dropdown-item {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Checkbox + radio — square vs pill, same box model */
.checkbox,
.radio {
  appearance: none;
  inline-size: 18px;
  block-size: 18px;
  margin: 0;
  background-color: var(--surface);
  border: 1px solid var(--border-strong);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.checkbox { border-radius: var(--r-sm); }
.radio { border-radius: var(--r-pill); }

.checkbox:checked,
.radio:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}
.checkbox:focus-visible,
.radio:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.checkbox:disabled,
.radio:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Toggle — accessible switch built on a checkbox.

   ON vs OFF is carried by TWO cues, never colour alone (issue 434):
     - colour: accent fill when ON, muted track when OFF
     - non-colour cue: a check glyph in the knob when ON, a cross when OFF.
   The knob travels with inset-inline-start, so it moves toward the start
   of the line in RTL as well as LTR. */
.toggle {
  appearance: none;
  position: relative;
  inline-size: 44px;
  block-size: 24px;
  margin: 0;
  background-color: var(--border-strong);
  border: 1px solid var(--n-400);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.toggle::after {
  content: "\2715";
  position: absolute;
  inset-block-start: 1px;
  inset-inline-start: 1px;
  inline-size: 20px;
  block-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-subtle);
  background-color: var(--n-0);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-sm);
  transition: inset-inline-start var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.toggle:hover {
  border-color: var(--text-subtle);
}
.toggle:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}
.toggle:checked::after {
  content: "\2713";
  color: var(--accent);
  inset-inline-start: 21px;
}
.toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.toggle:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ------------------------------------------------------------
   2b. Bootstrap switch bridge — issue 434

   Most of the app draws its on/off switches with the Bootstrap
   `custom-switch` markup:

       <div class="custom-control custom-switch">
         <input type="checkbox" class="custom-control-input" id="x">
         <label class="custom-control-label" for="x">Label</label>
       </div>

   The vendor look makes ON and OFF nearly the same pale grey, so people
   could not tell which way a switch was set. We restyle it here, once,
   so every page using that markup (admin settings, plans, stores,
   campaigns, notifications, product views) improves together.

   Presentation only. The real checkbox is still `.custom-control-input`,
   so click, keyboard, form value and ARIA state are unchanged.

   Loaded after the Bootstrap sheet in wrapper.php. The `.custom-control`
   prefix keeps our specificity above the vendor rules in both the LTR
   and the RTL Bootstrap builds.
   ------------------------------------------------------------ */

.custom-control.custom-switch {
  position: relative;
  display: block;
  min-block-size: 26px;
  padding-left: 0;
  padding-right: 0;
  padding-inline-start: 54px;
  padding-inline-end: 0;
}

.custom-control.custom-switch .custom-control-label {
  position: relative;
  margin-block-end: 0;
  min-block-size: 26px;
  padding-block-start: 2px;
  cursor: pointer;
  vertical-align: top;
}

/* Track */
.custom-control.custom-switch .custom-control-label::before {
  content: "";
  position: absolute;
  display: block;
  inset-block-start: 0;
  left: auto;
  right: auto;
  inset-inline-start: -54px;
  inline-size: 44px;
  block-size: 24px;
  background-color: var(--border-strong);
  border: 1px solid var(--n-400);
  border-radius: var(--r-pill);
  box-shadow: none;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

/* Knob — carries the non-colour cue: cross when OFF, check when ON */
.custom-control.custom-switch .custom-control-label::after {
  content: "\2715";
  position: absolute;
  inset-block-start: 1px;
  left: auto;
  right: auto;
  inset-inline-start: -53px;
  inline-size: 20px;
  block-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-subtle);
  background: var(--n-0);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-sm);
  transform: none;
  transition: inset-inline-start var(--dur) var(--ease),
              color var(--dur) var(--ease);
}

/* Hover — the track edge firms up so the control reads as clickable */
.custom-control.custom-switch:hover .custom-control-label::before {
  border-color: var(--text-subtle);
}

/* ON */
.custom-control.custom-switch .custom-control-input:checked ~ .custom-control-label::before {
  background-color: var(--accent);
  border-color: var(--accent);
}
.custom-control.custom-switch .custom-control-input:checked ~ .custom-control-label::after {
  content: "\2713";
  color: var(--accent);
  background: var(--n-0);
  transform: none;
  inset-inline-start: -31px;
}

/* Focus — visible ring for keyboard users, on the track */
.custom-control.custom-switch .custom-control-input:focus ~ .custom-control-label::before,
.custom-control.custom-switch .custom-control-input:focus-visible ~ .custom-control-label::before {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Disabled */
.custom-control.custom-switch .custom-control-input:disabled ~ .custom-control-label {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Mobile — a thumb needs a bigger target than a mouse pointer */
@media (pointer: coarse) {
  .custom-control.custom-switch {
    min-block-size: 32px;
    padding-inline-start: 62px;
  }
  .custom-control.custom-switch .custom-control-label {
    min-block-size: 32px;
    padding-block-start: 5px;
  }
  .custom-control.custom-switch .custom-control-label::before {
    inset-inline-start: -62px;
    inline-size: 52px;
    block-size: 30px;
  }
  .custom-control.custom-switch .custom-control-label::after {
    inset-inline-start: -61px;
    inline-size: 26px;
    block-size: 26px;
    font-size: 13px;
  }
  .custom-control.custom-switch .custom-control-input:checked ~ .custom-control-label::after {
    inset-inline-start: -37px;
  }
}

/* Reduced motion — hold the knob still, keep the colour and glyph cues */
@media (prefers-reduced-motion: reduce) {
  .toggle,
  .toggle::after,
  .custom-control.custom-switch .custom-control-label::before,
  .custom-control.custom-switch .custom-control-label::after {
    transition: none;
  }
}

/* ------------------------------------------------------------
   3. Cards & surfaces — design.md 7.3
   Surface, border, --r-lg, --shadow-sm, padding --sp-6.
   Hover lift only when the whole card is a link.
   ------------------------------------------------------------ */
.card {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-6);
}
.card-link {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.card-link:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
  transform: translateY(-2px);
}
.card-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* ------------------------------------------------------------
   4. Status chips & badges — design.md 7.6
   Pill radius, tinted bg + colored text, optional dot.
   State reads from shape + color, not color alone (a11y): the
   leading dot gives a non-color cue.
   ------------------------------------------------------------ */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding-block: var(--sp-1);
  padding-inline: var(--sp-3);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}
/* Non-color cue: a small dot before the label */
.chip::before {
  content: "";
  inline-size: 6px;
  block-size: 6px;
  border-radius: var(--r-pill);
  background-color: currentColor;
  flex: none;
}

/* Success family — paid, delivered, live */
.chip-paid,
.chip-delivered,
.chip-live {
  background-color: var(--success-bg);
  color: var(--success);
}
/* Warning family — pending, setup */
.chip-pending,
.chip-setup {
  background-color: var(--warning-bg);
  color: var(--warning);
}
/* Info family — processing, shipped */
.chip-processing,
.chip-shipped {
  background-color: var(--info-bg);
  color: var(--info);
}
/* Danger family — cancelled, failed */
.chip-cancelled,
.chip-failed {
  background-color: var(--danger-bg);
  color: var(--danger);
}

/* ------------------------------------------------------------
   5. Feedback — inline alerts + toast — design.md 7.7
   Inline alerts: form-level messages, localized.
   Toast: top-center, auto-dismiss, RTL-aware.
   ------------------------------------------------------------ */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding-block: var(--sp-3);
  padding-inline: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
/* Colored leading edge — logical so it flips in RTL */
.alert {
  border-inline-start: 3px solid var(--border-strong);
}
.alert-success {
  background-color: var(--success-bg);
  border-inline-start-color: var(--success);
  color: var(--success);
}
.alert-warning {
  background-color: var(--warning-bg);
  border-inline-start-color: var(--warning);
  color: var(--warning);
}
.alert-danger {
  background-color: var(--danger-bg);
  border-inline-start-color: var(--danger);
  color: var(--danger);
}
.alert-info {
  background-color: var(--info-bg);
  border-inline-start-color: var(--info);
  color: var(--info);
}

/* Toast container — top-center, above everything */
.toast-region {
  position: fixed;
  inset-block-start: var(--sp-4);
  inset-inline: 0;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding-inline: var(--sp-4);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  max-inline-size: 420px;
  padding-block: var(--sp-3);
  padding-inline: var(--sp-4);
  background-color: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-body);
  pointer-events: auto;
  animation: ds-toast-in var(--dur) var(--ease);
}
.toast-success { border-inline-start: 3px solid var(--success); }
.toast-danger  { border-inline-start: 3px solid var(--danger); }

@keyframes ds-toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ------------------------------------------------------------
   6. Modal + backdrop — design.md 7.8
   Center modal for focused tasks. Bottom sheet on mobile.
   Trap focus, Esc to close, backdrop click to dismiss (in JS).

   Every rule here is scoped to `.modal-backdrop > .modal` on purpose.
   Bootstrap uses the same class names but a different structure:
     - design system: .modal-backdrop > .modal          (the card)
     - bootstrap:     .modal > .modal-dialog > .modal-content
   Bootstrap never puts a `.modal` inside a `.modal-backdrop`, so this scope
   keeps the two apart. A bare `.modal` rule here would take `position: fixed`
   away from every Bootstrap popup in the merchant panel and make it render at
   the bottom of the page. Do not unscope these rules.
   ------------------------------------------------------------ */
/* Only OUR backdrop — the one that wraps a design system `.modal` card.
   Bootstrap's backdrop is an empty div, so it keeps its own styles. */
.modal-backdrop:has(> .modal) {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  /* Scrim from a token, not a raw color */
  background-color: color-mix(in srgb, var(--n-900) 55%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
}
.modal-backdrop > .modal {
  position: relative;
  z-index: var(--z-modal);
  inline-size: 100%;
  max-inline-size: 520px;
  max-block-size: calc(100vh - var(--sp-16));
  overflow-y: auto;
  background-color: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-6);
  animation: ds-modal-in var(--dur) var(--ease);
}
.modal-backdrop > .modal:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring), var(--shadow-lg);
}
.modal-backdrop > .modal .modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-block-end: var(--sp-4);
  font-size: var(--fs-h3);
  font-weight: var(--fw-h3);
}
.modal-backdrop > .modal .modal-body { font-size: var(--fs-body); line-height: var(--lh-body); }
.modal-backdrop > .modal .modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-block-start: var(--sp-6);
}

@keyframes ds-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Bottom sheet on mobile (7.8) — thumb-friendly */
@media (max-width: 576px) {
  .modal-backdrop:has(> .modal) { align-items: flex-end; padding: 0; }
  .modal-backdrop > .modal {
    max-inline-size: 100%;
    border-start-start-radius: var(--r-xl);
    border-start-end-radius: var(--r-xl);
    border-end-start-radius: 0;
    border-end-end-radius: 0;
  }
}
