/* Shared alignment system: used by admin panel, SmmDadPrime and NebulaCircuit.
   Extends css/shared/design-tokens.css (spacing/typography scale) and
   css/shared/table-system.css (mobile-card layout). Additive only — aliases
   existing selectors where an equivalent utility already exists instead of
   duplicating rules. */

:root {
  --control-height-sm: 36px;
  --control-height-md: 44px;
  --control-height-lg: 52px;

  --content-max-width: 1440px;
  --label-column-width: 140px;

  /* Alias to the existing --space-* scale (design-tokens.css) rather than
     introducing a parallel scale; fallbacks keep this file safe to load
     standalone if design-tokens.css hasn't loaded yet. */
  --align-gap-xs: var(--space-1, 4px);
  --align-gap-sm: var(--space-2, 8px);
  --align-gap-md: var(--space-3, 12px);
  --align-gap-lg: var(--space-4, 16px);
  --align-gap-xl: var(--space-6, 24px);
}

/* ---- Layout primitives ---- */
.ui-row {
  display: flex;
  align-items: center;
  gap: var(--align-gap-md);
}

.ui-stack {
  display: flex;
  flex-direction: column;
  gap: var(--align-gap-sm);
}

.ui-inline {
  display: inline-flex;
  align-items: center;
  gap: var(--align-gap-sm);
}

.ui-center {
  justify-content: center;
  align-items: center;
}

.ui-between {
  justify-content: space-between;
  align-items: center;
}

.ui-start {
  justify-content: flex-start;
}

.ui-end {
  justify-content: flex-end;
}

/* .ui-actions: same job as table-system.css's .table-actions, aliased
   together instead of duplicated. */
.ui-actions,
.table-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--align-gap-sm);
}

.ui-label-value {
  display: grid;
  grid-template-columns: var(--label-column-width) minmax(0, 1fr);
  align-items: start;
  gap: var(--align-gap-sm) var(--align-gap-md);
}

.ui-media {
  display: flex;
  align-items: flex-start;
  gap: var(--align-gap-sm);
}

/* .ui-toolbar: same job as table-system.css's .table-toolbar, aliased
   together and extended with justify-content/wrap per the spec here. */
.ui-toolbar,
.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--align-gap-md);
}

.ui-toolbar__group {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--align-gap-sm);
}

.ui-form-row {
  display: grid;
  grid-template-columns: minmax(120px, 180px) minmax(0, 1fr);
  align-items: start;
  gap: var(--align-gap-md) var(--align-gap-lg);
}

@media (max-width: 767.98px) {
  .ui-form-row {
    grid-template-columns: 1fr;
  }
}

.ui-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--align-gap-md);
}

.ui-card-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--align-gap-sm);
}

.icon-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  line-height: 1;
}

/* ---- Table cell media pattern: icon/image + text, no manual offsets ---- */
.table-cell-media {
  display: flex;
  align-items: flex-start;
  gap: var(--align-gap-sm);
}

.table-cell-media__icon,
.table-cell-media__image {
  flex: 0 0 auto;
}

.table-cell-media__content {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---- Text wrap modifiers ---- */
.ui-text-wrap {
  min-width: 0;
  white-space: normal;
  word-break: normal;
  overflow-wrap: break-word;
}

.ui-text-nowrap {
  white-space: nowrap;
  word-break: normal;
  overflow-wrap: normal;
}

/* ---- Actions-column alignment ----
   .ui-actions/.table-actions (above) are display:flex with no
   justify-content set, so a plain `class="table-actions"` trailing-column
   cell (NebulaCircuit orders.twig/subscriptions.twig) still left-aligns its
   buttons — pairing it with Bootstrap's `.text-end`/`.justify-content-end`
   has no effect on a flex container's children, and NebulaCircuit doesn't
   even load Bootstrap. This is the theme-independent equivalent, so every
   actions column can align the same way regardless of which theme loads
   Bootstrap. */
.ui-justify-end {
  justify-content: flex-end;
}

.header-control {
  min-height: var(--control-height-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--align-gap-sm);
}

/* ---- Primary nav sidebar link row: icon / label / trailing content ---- */
.sidebar-link {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--align-gap-md);
}

.sidebar-link__label {
  min-width: 0;
  white-space: normal;
  overflow-wrap: break-word;
}

/* ---- Header notification badge offset ----
   theme.css's base `.private-notification-count` rule (desktop header)
   positions the badge with negative margins (margin-left: -8px;
   margin-top: -18px), while the mobile/#block_118 variant of the same
   class already uses position:absolute with a -6px/-6px offset. This
   overrides the desktop rule to use the same absolute-offset pattern
   (parent `.private-notification-link` already has position:relative),
   consolidating both notification badges onto one offset approach
   instead of a margin hack. Loads after theme.css so this equal-
   specificity single-class override wins by source order. */
.private-notification-count {
  position: absolute;
  top: -6px;
  right: -6px;
  margin: 0;
}

/* ---- Section spacer: replaces repeated <br><br> tags used to push a
   footer down (found in NebulaCircuit refill.twig / refund.twig). ---- */
.ui-section-spacer {
  display: block;
  margin-top: calc(var(--align-gap-xl) * 4);
  height: 0;
}

/* ---- Inline checkbox/radio + label text: used across admin views
   (.admin-field-inline had no rule anywhere, .u-checkbox-label-inline only
   had margin) so the 20x20 checkbox and its text sat on the default inline
   baseline instead of centered. */
.admin-field-inline,
.u-checkbox-label-inline {
  display: inline-flex;
  align-items: center;
  gap: var(--align-gap-sm);
}

/* ---- Page-head with a breadcrumb: saas-refresh.css makes .admin-page-head
   a flex row (title-block + trailing action button, e.g. appearance_blog.php's
   "Create Blog" pattern). Detail pages instead put <nav class="admin-breadcrumb">,
   <h1> and <p class="admin-muted"> as three separate direct children (e.g.
   orders_detail.php, services_import.php, clients_details.php) — the flex row
   spread them out horizontally with justify-content:space-between instead of
   stacking, so the breadcrumb and heading visually overlapped. Scoped to only
   pages with a breadcrumb so the title+button row layout is untouched. */
.admin-page-head:has(.admin-breadcrumb) {
  flex-direction: column;
  align-items: flex-start;
}

/* ---- scroll-margin-top for elements several views reveal via
   element.scrollIntoView({behavior:"smooth"}) (appearance-integrations.js,
   payments-bank.js, tickets.js, services.js) — .admin-navbar is
   position:sticky, and with no scroll-margin-top the scrolled-to element's
   top edge lands flush under it, so the sticky bar covers the first ~70px
   of the revealed card/form. #reply-edit-card and #bank-account-form are
   the two scrollIntoView targets that aren't .admin-card elements. */
.admin-card,
#reply-edit-card,
#bank-account-form {
  scroll-margin-top: 90px;
}

/* ---- .admin-btn--info-icon: saas-refresh.css's minified .admin-btn rule
   (border-radius: 10px) has equal specificity to app.css's
   .admin-btn--info-icon (border-radius: 50%) and loads after it, so it was
   silently winning and flattening this round "i" info button into a
   rounded square. Restore the circle here where it actually takes effect. */
.admin-btn--info-icon {
  border-radius: 50%;
  font-weight: 800;
}

/* ---- .admin-stat-value--sm: same cascade-order bug — saas-refresh.css's
   .admin-stat-value{font-size:27px} loads after app.css's
   .admin-stat-value--sm{font-size:16px} with equal specificity, so the
   "small" stat variant (client profile "Last login", order detail
   timestamps) was silently rendering at full size instead. */
.admin-stat-value--sm {
  font-size: 16px;
}

/* ---- Navbar brand logo removed by request. saas-refresh.css draws it as
   a ::before pseudo-element (gradient square + sparkle glyph) on
   .admin-brand — display:none removes the box, content:none removes the
   glyph so it leaves no residual inline gap. */
.admin-brand::before {
  display: none;
  content: none;
}
