/*
 * Nexus dashboard tokens — MemberPress ReadyLaunch layer.
 * Source of truth: docs/design-system/tokens.json (Figma UI v3).
 * Names mirror docs/design-system/preview/ds.css so both layers stay in sync.
 * Dashboard-only additions are prefixed --nx-*.
 */
:root {
  /* Brand palette */
  --navy: #0c1232;
  --footer-navy: #002854;
  --plum: #350044;
  --purple: #9552da;
  --light-purple: #b86beb;
  --purple-glow: #c77dff;
  --royal: #2b5ef0;
  --cyan: #5bcbff;
  --cyan-print: #35ddf0;
  --white: #ffffff;
  --surface: #f7f8fb;
  --muted: #bbc1c8;
  --ink: #373c57;
  --chip: #f4e5ff;
  --deep: #020132;

  /*
   * Status (dashboard extension of the Figma palette — 05-forms / 07-components).
   * Solid = stroke, icon, helper text. Soft = notice fill. Never fill an input.
   */
  --ok: #1e9e6a;
  --ok-soft: #e6f6ef;
  --error: #d8365d;
  --error-soft: #fcebef;
  --warn: #c88a12;
  --warn-soft: #fff5df;
  --info: #2b5ef0;
  --info-soft: #eaf0fe;

  /* Spacing scale — the only vertical/horizontal steps inside RL screens */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 40px;
  --sp-8: 48px;
  --nx-stack: var(--sp-5);

  /* Focus rings (inputs, checks, icon buttons) */
  --ring: 0 0 0 3px rgba(43, 94, 240, 0.16);
  --ring-error: 0 0 0 3px rgba(216, 54, 93, 0.16);
  --stroke-soft: rgba(12, 18, 50, 0.08);
  --stroke-row: rgba(12, 18, 50, 0.06);

  /* Gradients */
  --cta: linear-gradient(135deg, #9552da 0%, #2b5ef0 62%, #5bcbff 100%);
  --cta-active: linear-gradient(135deg, #5bcbff 0%, #2b5ef0 38%, #9552da 100%);
  --membership-dark: linear-gradient(180deg, #350044 0%, #0c1232 100%);
  --icon-ring: linear-gradient(135deg, #35ddf0 0%, #b86beb 31.3%, #2b5ef0 67.8%, #5bcbff 100%);

  /* Radii */
  --r-check: 4px;
  --r-md: 8px;
  --r-row: 16px;
  --r-card: 24px;
  --r-modal: 32px;
  --r-icon: 100px;
  --r-pill: 999px;

  /* Shadows */
  --shadow-header: 0 8px 16px rgba(12, 18, 50, 0.08);
  --shadow-btn: 0 6px 8px rgba(12, 18, 50, 0.2);
  --shadow-header-cta: 0 0 4px #2b5ef0, 0 0 16px #2b5ef0;
  --shadow-card: 0 12px 24px rgba(12, 18, 50, 0.12);
  --shadow-showcase: 0 18px 48px rgba(12, 18, 50, 0.14);
  --shadow-gate: 0 34px 100px rgba(12, 18, 50, 0.24);
  --shadow-icon: 0 0 240px rgba(149, 82, 218, 0.3);
  --shadow-soft: 0 1px 2px rgba(16, 24, 40, 0.1), 0 1px 3px rgba(16, 24, 40, 0.06);

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-fast: 160ms;
  --dur-med: 280ms;
  --dur-sheet: 360ms;
  --dur-slow: 480ms;
  --nx-sbw: 0px;

  /* Opacity */
  --op-disabled: 0.36;
  --op-nav-inactive: 0.6;
  --op-locked-cta: 0.3;

  /* Type */
  --font: Montserrat, Inter, "Segoe UI", Arial, sans-serif;
  --fs-h1: 48px; --lh-h1: 56px;
  --fs-h2: 32px; --lh-h2: 44px;
  --fs-h3: 21px; --lh-h3: 32px;
  --fs-body-big: 18px; --lh-body-big: 28px;
  --fs-body: 16px; --lh-body: 24px;
  --fs-small: 14px; --lh-small: 20px;
  --fs-upper: 12px; --lh-upper: 18px;

  /* Layout */
  --content: 1216px;
  --gutter: 112px;
  --nx-gutter: 40px;
  --nx-header-h: 80px;
  --nx-sidebar-w: 264px;
  --nx-bottom-nav-h: 60px;
  --nx-panel-pad: 32px;
  --nx-focus: 2px solid var(--royal);

  /*
   * Account stacking (low → high). Dashboard-only — not a Figma color token.
   *  local     decorative rings / in-component chrome
   *  subnav    sticky section pills
   *  savebar   sticky “Save changes” — above fields, below open menus
   *  nav       header + mobile tab bar
   *  nav-float profile menu / mobile sheet
   *  dropdown  Select2 + row-action menus on the page
   *  modal     Mepr billing / icon picker (covers chrome)
   *  modal-pop Select2 opened from inside a modal
   */
  --nx-z-local: 1;
  --nx-z-local-ui: 2;
  --nx-z-subnav: 40;
  --nx-z-savebar: 60;
  --nx-z-nav: 200;
  --nx-z-nav-backdrop: 210;
  --nx-z-nav-float: 220;
  --nx-z-dropdown: 300;
  --nx-z-modal: 400;
  --nx-z-modal-pop: 420;
}

@media (max-width: 1279px) {
  :root {
    --nx-gutter: 24px;
    --nx-sidebar-w: 232px;
    --nx-panel-pad: 24px;
  }
}

@media (max-width: 839px) {
  :root {
    --nx-gutter: 15px;
    --nx-header-h: 64px;
    --nx-panel-pad: 20px;
    --nx-stack: var(--sp-4);
    --fs-h1: 32px; --lh-h1: 40px;
    --fs-h2: 26px; --lh-h2: 32px;
    --fs-h3: 18px; --lh-h3: 28px;
    --fs-body-big: 16px; --lh-body-big: 24px;
    --fs-body: 15px; --lh-body: 22px;
    --fs-small: 13px; --lh-small: 18px;
    --fs-upper: 10px; --lh-upper: 16px;
  }
}

/* Avatar primitive — the PHP helper prints img.nx-avatar; crop lives here. */
img.nx-avatar {
  display: block;
  object-fit: cover;
  object-position: center;
  border-radius: 50%;
}
img.nx-avatar--photo {
  object-position: center 20%;
}

/* Utilities shared by every mp-nexus-* sheet */
.nx-gradient-text {
  background: var(--cta);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.nx-upper {
  font-size: var(--fs-upper);
  line-height: var(--lh-upper);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/*
 * Stack — vertical rhythm between sibling blocks. A block never carries its own
 * outer margin; the parent stack does. Notices, helpers and AJAX-inserted rows
 * therefore always sit at a known distance from neighbours.
 */
.nx-stack > * + * {
  margin-top: var(--nx-stack);
}
.nx-stack--tight > * + * {
  margin-top: var(--sp-3);
}

/* Spinner primitive — buttons, save bar, checkout submit */
@keyframes nx-spin {
  to { transform: rotate(360deg); }
}

/* Overlay motion — every sheet / modal / menu uses one of these */
@keyframes nx-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes nx-pop-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
@keyframes nx-sheet-in {
  from { transform: translateY(100%); }
  to { transform: none; }
}
@keyframes nx-menu-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

/*
 * Scroll lock while an overlay is open (sheet, modal, Select2 sheet).
 * JS sets html.nx-lock and --nx-sbw (scrollbar width) so desktop layout
 * does not jump when the page scrollbar disappears.
 */
html.nx-lock,
html.nx-lock body {
  overflow: hidden !important;
  overflow-x: hidden !important;
  overscroll-behavior: none;
}
html.nx-lock body {
  padding-right: var(--nx-sbw);
  max-width: 100%;
}
/* Scrollbar compensation is desktop-only. On a phone there is no classic
   scrollbar — extra padding-right shifts the header and opens a 15px
   horizontal gutter (the “header з’їхав” bug). */
@media (min-width: 840px) {
  html.nx-lock body .site-header {
    padding-right: calc(var(--nx-gutter) + var(--nx-sbw));
  }
}
@media (max-width: 839px) {
  html.nx-lock body {
    padding-right: 0;
  }
}
.nx-spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: nx-spin 0.7s linear infinite;
  vertical-align: middle;
}

.nx-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0ms;
    --dur-med: 0ms;
    --dur-sheet: 0ms;
    --dur-slow: 0ms;
  }
}
