/* Coneso CF — component primitives.
 * Phase A.2 deliverable. Built on the tokens defined in _tokens.css.
 *
 * Components are namespaced `c-*` so they never collide with Bootstrap's
 * `.btn`, `.card`, `.badge` (those continue to work in legacy markup).
 * Migration order: introduce `c-*` on new screens; leave Bootstrap
 * classes alone in pages that haven't been retemplated yet.
 *
 * Every value below should resolve to a `var(--…)`. If you need a literal,
 * promote it to a token in _tokens.css first.
 */

/* ============================================================
 * .c-card — surface block with subtle border + shadow
 * ============================================================ */
.c-card {
  background-color: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  color: var(--text-primary);
}
.c-card--raised {
  box-shadow: var(--shadow-md);
}
.c-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  margin-bottom: var(--space-3);
  color: var(--text-primary);
}
.c-card__body {
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--text-secondary);
}

/* ============================================================
 * .c-btn — themed button with variants
 * ============================================================ */
.c-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease,
              border-color 120ms ease, box-shadow 120ms ease;
  user-select: none;
  white-space: nowrap;
}
.c-btn:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}
.c-btn:disabled,
.c-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.c-btn--primary {
  background-color: var(--brand-primary-600);
  color: var(--text-inverse);
  border-color: var(--brand-primary-600);
}
.c-btn--primary:hover:not(:disabled) {
  background-color: var(--brand-primary-700);
  border-color: var(--brand-primary-700);
}

.c-btn--secondary {
  background-color: var(--bg-surface);
  color: var(--text-primary);
  border-color: var(--border-default);
}
.c-btn--secondary:hover:not(:disabled) {
  background-color: var(--bg-base);
  border-color: var(--border-strong);
}

.c-btn--danger {
  background-color: var(--color-danger);
  color: var(--text-inverse);
  border-color: var(--color-danger);
}
.c-btn--danger:hover:not(:disabled) {
  filter: brightness(0.92);
}

.c-btn--ghost {
  background-color: transparent;
  color: var(--text-link);
  border-color: transparent;
}
.c-btn--ghost:hover:not(:disabled) {
  background-color: var(--brand-primary-50);
  color: var(--text-link-hover);
}

.c-btn--sm {
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
}
.c-btn--lg {
  padding: var(--space-3) var(--space-5);
  font-size: var(--fs-md);
}
.c-btn--block {
  display: flex;
  width: 100%;
}

/* ============================================================
 * .c-input — text inputs / selects / textareas
 * ============================================================ */
.c-input {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background-color: var(--bg-surface);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.c-input:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px var(--brand-primary-100);
}
.c-input:disabled {
  background-color: var(--bg-base);
  cursor: not-allowed;
  color: var(--text-muted);
}
.c-input--invalid {
  border-color: var(--color-danger);
}
.c-input--invalid:focus {
  box-shadow: 0 0 0 3px var(--color-danger-bg);
}
.c-input__label {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
}
.c-input__hint {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.c-input__hint--error {
  color: var(--color-danger);
}

/* ============================================================
 * .c-badge — short status label (cart status, payment, HAL tracking)
 * ============================================================ */
.c-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background-color: var(--bg-base);
  color: var(--text-secondary);
}
.c-badge--success { background-color: var(--color-success-bg); color: var(--color-success); }
.c-badge--warning { background-color: var(--color-warning-bg); color: var(--color-warning); }
.c-badge--danger  { background-color: var(--color-danger-bg);  color: var(--color-danger); }
.c-badge--info    { background-color: var(--color-info-bg);    color: var(--color-info); }
.c-badge--brand   { background-color: var(--brand-primary-100); color: var(--brand-primary-700); }

/* ============================================================
 * .c-pill — like badge but rounded, used for filters / tags
 * ============================================================ */
.c-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
  background-color: var(--bg-base);
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
}
.c-pill--active {
  background-color: var(--brand-primary-600);
  color: var(--text-inverse);
  border-color: var(--brand-primary-600);
}
.c-pill--clickable {
  cursor: pointer;
  transition: background-color 120ms ease;
}
.c-pill--clickable:hover {
  background-color: var(--brand-primary-50);
  color: var(--brand-primary-700);
}

/* ============================================================
 * .c-table — data table primitive (DataTables-friendly)
 * ============================================================ */
.c-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background-color: var(--bg-surface);
  color: var(--text-primary);
  font-size: var(--fs-sm);
}
.c-table thead th {
  background-color: var(--bg-base);
  color: var(--text-secondary);
  font-weight: var(--fw-semibold);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-default);
  white-space: nowrap;
}
.c-table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: middle;
}
.c-table tbody tr:hover {
  background-color: var(--bg-base);
}
.c-table--compact thead th,
.c-table--compact tbody td {
  padding: var(--space-2) var(--space-3);
}

/* ============================================================
 * .c-empty-state — used when a list / table has zero rows
 * ============================================================ */
.c-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-7) var(--space-5);
  background-color: var(--bg-surface);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
}
.c-empty-state__icon {
  font-size: var(--fs-3xl);
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}
.c-empty-state__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  margin-bottom: var(--space-2);
}
.c-empty-state__body {
  font-size: var(--fs-base);
  color: var(--text-muted);
  max-width: 480px;
  margin-bottom: var(--space-4);
  line-height: var(--lh-normal);
}

/* ============================================================
 * .c-skeleton — loading placeholder (replaces blocking spinners)
 * ============================================================ */
@keyframes c-skeleton-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.c-skeleton {
  display: block;
  position: relative;
  background-color: var(--bg-base);
  background-image: linear-gradient(
    90deg,
    var(--bg-base) 0%,
    var(--border-subtle) 50%,
    var(--bg-base) 100%
  );
  background-size: 800px 100%;
  animation: c-skeleton-shimmer 1.4s linear infinite;
  border-radius: var(--radius-sm);
  height: 1em;
  width: 100%;
}
.c-skeleton--circle {
  border-radius: 50%;
  width: var(--space-7);
  height: var(--space-7);
}
.c-skeleton--row {
  height: var(--space-5);
  margin-bottom: var(--space-2);
}

/* Reduced-motion friendly: don't hammer users with animation. */
@media (prefers-reduced-motion: reduce) {
  .c-skeleton {
    animation: none;
  }
}

/* ============================================================
 * .c-loading — wrapper for skeleton placeholders (E.3).
 * `loading.skeleton(...)` mounts these. The shimmer is on the inner
 * .c-skeleton blocks; the wrapper just provides spacing + a faux
 * table grid via CSS so we don't have to author <table> markup at
 * runtime.
 * ============================================================ */
.c-loading {
  display: block;
  padding: var(--space-3) 0;
}
.c-loading > .c-skeleton + .c-skeleton {
  margin-top: var(--space-2);
}
.c-loading--table {
  background-color: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.c-loading__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px dashed var(--border-subtle);
}
.c-loading__row:last-child { border-bottom: 0; }
.c-loading__row--head .c-skeleton {
  height: var(--space-3);
  background-image: linear-gradient(
    90deg,
    var(--border-subtle) 0%,
    var(--border-default) 50%,
    var(--border-subtle) 100%
  );
}
.c-loading--card {
  background-color: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

/* ============================================================
 * .cf-themeswitch — dark-mode toggle (E.6).
 * Lives next to the language switcher in _navbar_user / _navbar_admin.
 * Uses tokens so the dark mode palette flips it automatically.
 * ============================================================ */
.cf-themeswitch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  color: var(--text-secondary);
  font: inherit;
  cursor: pointer;
  line-height: 1;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cf-themeswitch:hover,
.cf-themeswitch:focus-visible {
  background-color: var(--bg-base);
  color: var(--text-primary);
  border-color: var(--border-default);
  outline: none;
}
.cf-themeswitch__icon {
  font-size: var(--fs-base);
  line-height: 1;
}
.cf-themeswitch__icon--sun { display: inline; }
.cf-themeswitch__icon--moon { display: none; }
[data-theme="dark"] .cf-themeswitch__icon--sun { display: none; }
[data-theme="dark"] .cf-themeswitch__icon--moon { display: inline; }
.cf-themeswitch__label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}

/* Navbar context override.
 *
 * The shop-owner / admin navbar (.cf-mainnav) has a hard-coded dark
 * background (`background-color: #333`) inherited from the legacy
 * /static/assets/css/styles.css `ul {}` rule, regardless of theme. The
 * default cf-themeswitch palette uses theme tokens (`--text-secondary`,
 * `--border-subtle`) which only have enough contrast against the
 * matching theme surface — on a fixed-dark navbar in *light* mode the
 * button text becomes #334155 on #333 (invisible), and in *dark* mode
 * the border drops to #1f2a40 (also invisible). Lock to white-ish
 * tokens whenever the switch is rendered inside the navbar so it stays
 * legible in both themes. Same idea as the .customerorder-brandstrip
 * override in customerorder.css. */
.cf-mainnav .cf-themeswitch {
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.35);
}
.cf-mainnav .cf-themeswitch:hover,
.cf-mainnav .cf-themeswitch:focus-visible {
  background-color: rgba(255, 255, 255, 0.12);
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.6);
}
[data-theme="dark"] .cf-mainnav .cf-themeswitch {
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.35);
}
[data-theme="dark"] .cf-mainnav .cf-themeswitch:hover,
[data-theme="dark"] .cf-mainnav .cf-themeswitch:focus-visible {
  background-color: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.6);
}

/* ============================================================
 * .c-toast — themed toast notifications (B.1).
 * Replaces x-notify's per-call inline `font:` overrides; the toast
 * wrapper in `static/js/core/notify.js` constructs nodes with these
 * classes. Stacks bottom-right; auto-dismiss; reduced-motion friendly.
 * ============================================================ */
.c-toast-stack {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: min(420px, calc(100vw - 2 * var(--space-5)));
  pointer-events: none;
}
.c-toast-stack--top-right { top: var(--space-5); bottom: auto; }
.c-toast-stack--top-center {
  top: var(--space-5);
  bottom: auto;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
}

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

.c-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background-color: var(--bg-surface);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  border-left: 4px solid var(--text-muted);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-family: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  animation: c-toast-in 180ms ease-out;
}
.c-toast--leaving {
  animation: c-toast-out 160ms ease-in forwards;
}
.c-toast__icon {
  flex: 0 0 auto;
  font-size: var(--fs-lg);
  line-height: 1;
  margin-top: 2px;
  color: var(--text-muted);
}
.c-toast__body {
  flex: 1 1 auto;
  min-width: 0;
}
.c-toast__title {
  font-weight: var(--fw-semibold);
  margin-bottom: 2px;
  color: var(--text-primary);
}
.c-toast__desc {
  color: var(--text-secondary);
  word-wrap: break-word;
}
.c-toast__close {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: var(--fs-base);
  line-height: 1;
  cursor: pointer;
  padding: 2px var(--space-1);
  border-radius: var(--radius-sm);
}
.c-toast__close:hover { color: var(--text-primary); background-color: var(--bg-base); }
.c-toast__close:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 1px;
}

.c-toast--success { border-left-color: var(--color-success); }
.c-toast--success .c-toast__icon { color: var(--color-success); }

.c-toast--error,
.c-toast--danger { border-left-color: var(--color-danger); }
.c-toast--error .c-toast__icon,
.c-toast--danger .c-toast__icon { color: var(--color-danger); }

.c-toast--warning { border-left-color: var(--color-warning); }
.c-toast--warning .c-toast__icon { color: var(--color-warning); }

.c-toast--info { border-left-color: var(--color-info); }
.c-toast--info .c-toast__icon { color: var(--color-info); }

.c-toast--loading .c-toast__icon {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid var(--border-default);
  border-top-color: var(--brand-primary-600);
  border-radius: 50%;
  animation: c-toast-spin 800ms linear infinite;
}
@keyframes c-toast-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .c-toast,
  .c-toast--leaving { animation: none; }
  .c-toast--loading .c-toast__icon { animation: none; }
}

/* SweetAlert2 brand override (B.2). The wrapper picks up tokens so the
 * confirm dialog matches the rest of the design. */
.swal2-popup.c-swal {
  font-family: inherit;
  border-radius: var(--radius-lg);
  background-color: var(--bg-surface);
  color: var(--text-primary);
}
.swal2-popup.c-swal .swal2-title {
  font-family: var(--font-display);
  color: var(--text-primary);
}
.swal2-popup.c-swal .swal2-html-container { color: var(--text-secondary); }
.swal2-popup.c-swal .swal2-actions { gap: var(--space-2); }
.swal2-popup.c-swal .c-swal__confirm,
.swal2-popup.c-swal .c-swal__cancel {
  border-radius: var(--radius-md);
  font-weight: var(--fw-medium);
  padding: var(--space-2) var(--space-4);
  border: 1px solid transparent;
  box-shadow: none;
}
.swal2-popup.c-swal .c-swal__confirm {
  background-color: var(--brand-primary-600);
  color: var(--text-inverse);
}
.swal2-popup.c-swal .c-swal__confirm--danger {
  background-color: var(--color-danger);
}
.swal2-popup.c-swal .c-swal__cancel {
  background-color: var(--bg-surface);
  color: var(--text-primary);
  border-color: var(--border-default);
}

/* ============================================================
 * PR-C — language-aware title fonts.
 *
 * `.c-card__title` and `.c-empty-state__title` set `font-family: var(--font-display)`
 * (Inter), which lacks Lao/Thai glyphs. On Lao/Thai pages those titles fall
 * back to system fonts and render as tofu boxes (visible on filemanagement,
 * usermanagement, productmanagement, ordermanagement bilingual headers).
 * Scope the language fonts onto these titles via `:lang()` and `.lao-font`
 * (body class) so only non-English pages get the override and the existing
 * English login pages keep Inter.
 * ============================================================ */
.lao-font .c-card__title,
:lang(lo) .c-card__title,
.lao-font .c-empty-state__title,
:lang(lo) .c-empty-state__title,
.lao-font .swal2-popup.c-swal .swal2-title,
:lang(lo) .swal2-popup.c-swal .swal2-title {
  font-family: var(--font-lao);
}
:lang(th) .c-card__title,
:lang(th) .c-empty-state__title,
:lang(th) .swal2-popup.c-swal .swal2-title {
  font-family: var(--font-thai);
}

/* ============================================================
 * PR-H — A11y utilities.
 *
 * `.sr-only`           — visually hidden but still announced by screen
 *                        readers. Use it to attach a `<label>` to an
 *                        unlabeled input, or to provide an accessible
 *                        name to an icon-only button without changing
 *                        the visual chrome:
 *                          <button class="c-btn c-btn--ghost" aria-label="Delete">
 *                            <i class="fa fa-trash" aria-hidden="true"></i>
 *                          </button>
 *                        or
 *                          <button class="c-btn c-btn--ghost">
 *                            <i class="fa fa-trash" aria-hidden="true"></i>
 *                            <span class="sr-only">Delete</span>
 *                          </button>
 *
 * `.sr-only-focusable` — same as `.sr-only` until focused (skip-to-content
 *                        links).
 *
 * The focus-ring styles already live in _brand.css (`:focus-visible`); this
 * file just provides the screen-reader-only helpers since no equivalent
 * exists in Bootstrap 4 by default with these names.
 * ============================================================ */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Decorative-icon hint: any FontAwesome icon inside a button/link that
 * already has an aria-label can be marked aria-hidden in templates. As a
 * safety net for legacy templates, fa icons that sit alone inside a focusable
 * element are treated as decoration. (Doesn't change announce behavior — it
 * just stops the icon's font-glyph from being read as text on some screen
 * readers when the element has accessible text.) */
.c-btn > i.fa,
.c-btn > i.fas,
.c-btn > i.far,
button > i.fa,
button > i.fas,
button > i.far,
a > i.fa,
a > i.fas,
a > i.far {
  pointer-events: none;
}
