/* Shared misc components: badges, alerts, dropdown-menu, pagination, tabs,
   empty-state, spinner, and spacing utilities. Aliases real class names
   already in use; extends table-system.css's .status-badge/.table-pagination
   rather than duplicating them. Additive only. */

/* ---- Global text-wrap safety net ----
   Loaded on every admin + SmmDadPrime + NebulaCircuit page (see header.twig /
   admin/views/layout.php), so this is the one place to fix "long text
   overflows its box" across pages instead of patching each template/page CSS
   individually. break-word (not anywhere) matches table-system.css's existing
   rule: anywhere also defeats flex/grid min-content sizing and wraps normal
   words one character per line in narrow columns. Scoped to text-bearing
   elements, not a universal *-selector, so it can't override intentional
   single-line truncation (.hideextra, .table-cell-truncate, .nowrap, etc.). */
h1, h2, h3, h4, h5, h6,
p, span, a, li, label, small, blockquote, figcaption,
.card-header, .card-body, .card-footer,
.component-card-header, .component-card-body, .component-card-footer,
.modal-title, .modal-body, .modal-footer,
.alert, .badge, .admin-badge,
.dropdown-menu, .dropdown-item, .admin-nav-dropdown-menu,
.nav-tabs, .admin-tabs,
.btn, .component-button, .app-button, .apx-btn, .admin-btn {
  overflow-wrap: break-word;
  word-break: normal;
}

/* Long unbroken tokens (URLs, hashes, slugs) have no natural break point for
   break-word to use, so links specifically get the more aggressive
   overflow-wrap: anywhere — same treatment already carved out for order
   links in table-system.css/theme.css, generalized to all links. */
a {
  overflow-wrap: anywhere;
}

/* Flex/grid rows pairing a text label with a fixed-size sibling (icon, close
   button, badge) need min-width:0 on the text side or the row refuses to
   shrink and pushes/clips instead of wrapping — the same gap
   .table-cell-media__content already closes for table cells. */
.modal-title,
.card-header > *:not(.card-actions):not(.component-card-actions),
.ui-card-header > *:first-child,
.dropdown-item,
.nav-tabs .nav-link,
.admin-tabs .admin-tab {
  min-width: 0;
}

/* Images/media never force horizontal overflow regardless of their
   intrinsic size. */
img, svg, video, iframe {
  max-width: 100%;
}

/* NebulaCircuit: Android install link is hidden except on Android UA
   (theme.js adds .is-android to <html>); moved out of a page-level <style>
   block in header.twig so it lives with the rest of the shared rules. */
html:not(.is-android) .android-install-link { display: none !important; }

/* api.twig: scrollable wrapper around sample-response <pre> blocks so long
   JSON doesn't overflow on mobile, plus a copy button reusing the existing
   .copy-inline-button JS handler. */
.api-code-block {
  position: relative;
  overflow-x: auto;
}
.api-code-block pre {
  margin: 0;
}
.api-code-block .api-code-copy {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
}

.badge,
.admin-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1.4;
  white-space: nowrap;
}

.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--ds-radius-sm);
  border: 1px solid transparent;
  font-size: var(--font-size-sm);
}

.alert-primary { background: color-mix(in srgb, var(--table-primary) 12%, transparent); border-color: color-mix(in srgb, var(--table-primary) 30%, transparent); color: var(--table-primary); }
.alert-success { background: color-mix(in srgb, var(--table-success) 12%, transparent); border-color: color-mix(in srgb, var(--table-success) 30%, transparent); color: var(--table-success); }
.alert-warning { background: color-mix(in srgb, var(--table-warning) 12%, transparent); border-color: color-mix(in srgb, var(--table-warning) 30%, transparent); color: var(--table-warning); }
.alert-danger { background: color-mix(in srgb, var(--table-danger) 12%, transparent); border-color: color-mix(in srgb, var(--table-danger) 30%, transparent); color: var(--table-danger); }
.alert-info { background: color-mix(in srgb, var(--table-info) 12%, transparent); border-color: color-mix(in srgb, var(--table-info) 30%, transparent); color: var(--table-info); }

.dropdown-menu,
.admin-nav-dropdown-menu {
  padding: var(--space-2);
  border-radius: var(--ds-radius-sm);
  border: 1px solid var(--table-border-color);
  box-shadow: var(--ds-shadow-md);
}

.nav-tabs,
.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  border-bottom: 1px solid var(--table-border-color);
}

.empty-state,
.table-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: clamp(1.5rem, 5vw, 2.5rem);
  color: var(--table-text-muted);
  text-align: center;
}

/* ---- Reusable CSS-only spinner ---- */
.spinner,
.loading-state::after {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid var(--table-border-color);
  border-top-color: var(--table-primary);
  border-radius: 50%;
  animation: ds-spin 0.6s linear infinite;
}

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

/* ---- Skeleton-loader placeholders (shimmer, theme-aware via table tokens) ---- */
.skeleton,
.skeleton-text,
.skeleton-card {
  display: block;
  background: linear-gradient(
    90deg,
    var(--table-border-color) 25%,
    var(--table-row-hover-bg) 37%,
    var(--table-border-color) 63%
  );
  background-size: 400% 100%;
  border-radius: var(--ds-radius-sm);
  animation: ds-skeleton-shimmer 1.4s ease infinite;
}

.skeleton-text {
  height: 0.85em;
  width: 100%;
  margin: 0.25em 0;
}

.skeleton-text + .skeleton-text {
  width: 80%;
}

.skeleton-card {
  width: 100%;
  height: 100px;
}

@keyframes ds-skeleton-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* ---- Spacing utilities: escape hatch only — prefer existing component
   classes/props; use these u-* helpers solely where no matching class
   already exists for the one-off spacing need. ---- */
.u-mt-1 { margin-top: var(--space-1); }
.u-mt-2 { margin-top: var(--space-2); }
.u-mt-3 { margin-top: var(--space-3); }
.u-mt-4 { margin-top: var(--space-4); }
.u-mt-5 { margin-top: var(--space-5); }
.u-mt-6 { margin-top: var(--space-6); }
.u-mt-7 { margin-top: var(--space-7); }
.u-mt-8 { margin-top: var(--space-8); }

.u-mb-1 { margin-bottom: var(--space-1); }
.u-mb-2 { margin-bottom: var(--space-2); }
.u-mb-3 { margin-bottom: var(--space-3); }
.u-mb-4 { margin-bottom: var(--space-4); }
.u-mb-5 { margin-bottom: var(--space-5); }
.u-mb-6 { margin-bottom: var(--space-6); }
.u-mb-7 { margin-bottom: var(--space-7); }
.u-mb-8 { margin-bottom: var(--space-8); }

.u-mt-16 { margin-top: var(--space-16); }
.u-mb-16 { margin-bottom: var(--space-16); }

.u-gap-1 { gap: var(--space-1); }
.u-gap-2 { gap: var(--space-2); }
.u-gap-3 { gap: var(--space-3); }
.u-gap-4 { gap: var(--space-4); }

/* ---- Grid column utilities (pairs with .admin-grid-2col) ---- */
.admin-grid-3col {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}

.admin-grid-4col {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}

/* ---- Inline flex row with gap (e.g. thumbnail + delete button) ---- */
.u-flex-align-gap {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---- Muted text modifiers ---- */
.admin-muted-sm { font-size: 12px; }
.admin-muted-normal { font-weight: 400; }

/* ---- Preview thumbnail sizing (settings logo/favicon previews) ---- */
.u-img-h-50 { max-height: 50px; border: 1px solid var(--admin-border); border-radius: 6px; }
.u-img-h-32 { max-height: 32px; border: 1px solid var(--admin-border); border-radius: 6px; }

.u-text-xs { font-size: 11px; }
.u-text-danger { color: var(--table-danger); }

/* ---- Display modifiers (pairs with .admin-nav-dropdown wrappers) ---- */
.is-hidden { display: none; }
.is-inline { display: inline-block; }
.u-w-auto { width: auto; }

/* ---- Dropdown item rendered as <a> instead of <button> ---- */
.admin-dropdown-item-link { text-decoration: none; }

/* ---- Category icon in services list header ---- */
.admin-cat-icon-img { width: 20px; height: 20px; vertical-align: middle; margin-right: 6px; }
.admin-cat-icon-glyph { margin-right: 6px; }

/* ---- SEO pages edit/list utility classes ---- */
.u-text-required { color: #dc2626; }
.u-hr-thin { border: 0; border-top: 1px solid rgba(127, 127, 127, .2); }
.u-mt-0 { margin-top: 0; }
.u-mt-sm { margin-top: .7rem; }
.u-checkbox-inline-label { display: flex; gap: .4rem; align-items: center; margin-top: .5rem; font-size: .85rem; }
.u-mb-1rem { margin-bottom: 1rem; }
.u-max-w-200 { max-width: 200px; }
.u-col-checkbox { width: 32px; }
.u-muted-fine { font-size: .78rem; }
.u-border-0 { border: 0; }

/* ---- Services import utility classes ---- */
.u-w-110 { width: 110px; }
.u-w-180-inline { width: 180px; display: inline-block; }
.u-checkbox-label-inline { margin: 0 8px; }
.u-table-scroll-520 { max-height: 520px; overflow-y: auto; }

/* ---- livechat.php layout helpers ---- */
.livechat-layout {
  grid-template-columns: 320px 1fr;
  gap: 16px;
}

.livechat-sessions-card {
  padding: 0;
  overflow: hidden;
}

.livechat-sessions-toolbar {
  padding: 12px;
  border-bottom: 1px solid var(--admin-border);
}

.livechat-sessions-list {
  max-height: 600px;
  overflow-y: auto;
}

.livechat-session-link {
  display: block;
  padding: 10px 12px;
  border-bottom: 1px solid var(--admin-border);
  text-decoration: none;
  color: inherit;
}

.livechat-session-link.is-selected {
  background: var(--admin-primary-soft);
}

.livechat-session-badge {
  float: right;
}

.livechat-transcript {
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  padding: 12px;
  margin: 12px 0;
}

.livechat-msg-right {
  text-align: right;
}

