:root {
  --navy: #1a2456;
  --navy-dark: #12173b;
  --blue: #2f5bea;
  --blue-light: #eef2ff;
  --purple: #6a4cf0;
  --purple2: #4b2fc9;
  --green: #16a35a;
  --green-light: #e7f8ef;
  --orange: #f5921b;
  --orange-light: #fef2e2;
  --red: #e6455d;
  --red-light: #fdecef;
  --pink: #ec4899;
  --teal: #0d9488;
  --teal-light: #e3f6f4;
  --gray-50: #f6f7fb;
  --gray-100: #eef0f6;
  --gray-500: #7a80a0;
  --gray-700: #454a63;
  --border: #e6e8f0;
  --radius: 14px;
}

* { box-sizing: border-box; }

body {
  background: var(--gray-50);
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  color: #232741;
}

a { text-decoration: none; }

/* ---------- Layout shell ---------- */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 258px;
  flex-shrink: 0;
  background: #fff;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; bottom: 0; left: 0;
  overflow-y: auto;
  z-index: 1030;
  transition: transform .2s ease;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 20px 16px;
  border-bottom: 1px solid var(--border);
}

.brand-logo-img { width: 100%; max-width: 190px; height: auto; display: block; }

.sidebar-nav { padding: 14px 12px; flex: 1; }
.sidebar-nav .nav-link {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-radius: 10px;
  color: var(--gray-700); font-size: .89rem; font-weight: 500;
  margin-bottom: 2px;
}
.sidebar-nav .nav-link i { font-size: 1.05rem; width: 20px; text-align: center; color: var(--gray-500); }
.sidebar-nav .nav-link:hover { background: var(--gray-100); color: var(--navy); }
.sidebar-nav .nav-link.active { background: var(--blue); color: #fff; box-shadow: 0 4px 10px rgba(47,91,234,.25); }
.sidebar-nav .nav-link.active i { color: #fff; }
.sidebar-nav .nav-link .badge { margin-left: auto; }
.sidebar-nav .nav-section-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--gray-500); padding: 14px 14px 6px;
}

/* min-width: 0 overrides the flex-item default (min-width: auto), which otherwise
   refuses to shrink below the width of its widest descendant (e.g. a wide genealogy
   tree) and stretches the whole page instead of letting that descendant's own
   `overflow: auto` contain it. */
.main-col { flex: 1; min-width: 0; margin-left: 258px; display: flex; flex-direction: column; min-height: 100vh; transition: margin-left .2s ease; }

.topbar {
  background: #fff; border-bottom: 1px solid var(--border);
  padding: 14px 26px; display: flex; align-items: center; justify-content: space-between;
  position: sticky; top: 0; z-index: 1020; min-width: 0;
}
.topbar .page-title { font-weight: 700; font-size: 1.15rem; color: var(--navy); margin: 0; }
.topbar .breadcrumb-mini { font-size: .8rem; color: var(--gray-500); margin: 0; }
.topbar-actions { display: flex; align-items: center; gap: 14px; }
.icon-btn {
  width: 40px; height: 40px; border-radius: 50%; background: var(--gray-100);
  display: flex; align-items: center; justify-content: center; color: var(--gray-700);
  position: relative; border: none;
}
.icon-btn .badge-dot {
  position: absolute; top: -2px; right: -2px; background: var(--red); color: #fff;
  font-size: .62rem; min-width: 17px; height: 17px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; border: 2px solid #fff;
}
.user-chip { display: flex; align-items: center; gap: 10px; padding-left: 12px; border-left: 1px solid var(--border); }
.user-chip img, .user-chip .avatar-fallback {
  width: 38px; height: 38px; border-radius: 50%; object-fit: cover; background: var(--blue-light); color: var(--blue);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: .85rem;
}
.user-chip .user-name { font-size: .85rem; font-weight: 600; color: var(--navy); }
.user-chip .user-meta { font-size: .72rem; color: var(--gray-500); }

.content-area { padding: 24px 26px 60px; flex: 1; min-width: 0; }

/* ---------- Cards ---------- */
.stat-card {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 20px; display: flex; align-items: center; gap: 14px; height: 100%; min-width: 0;
}
.stat-card > div:last-child { min-width: 0; }
.stat-card .stat-label, .stat-card .stat-value { overflow-wrap: break-word; }
.stat-card .stat-icon {
  width: 46px; height: 46px; border-radius: 12px; display: flex; align-items: center;
  justify-content: center; font-size: 1.2rem; flex-shrink: 0;
}
.stat-card .stat-label { font-size: .78rem; color: var(--gray-500); margin-bottom: 2px; }
.stat-card .stat-value { font-size: 1.35rem; font-weight: 700; color: var(--navy); }
.stat-card .stat-trend { font-size: .72rem; margin-top: 2px; }
.stat-card .stat-trend.up { color: var(--green); }
.stat-card .stat-trend.down { color: var(--red); }

.bg-soft-blue { background: var(--blue-light); color: var(--blue); }
.bg-soft-green { background: var(--green-light); color: var(--green); }
.bg-soft-orange { background: var(--orange-light); color: var(--orange); }
.bg-soft-red { background: var(--red-light); color: var(--red); }
.bg-soft-purple { background: #f1edfe; color: var(--purple); }
.bg-soft-teal { background: var(--teal-light); color: var(--teal); }

.panel {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 20px 22px; height: 100%;
}
/* Opt-out for a standalone panel that isn't sitting next to row siblings it needs to
   match the height of — .panel's own height:100% otherwise stretches it to fill
   whatever height its container happens to have (e.g. the page's remaining viewport
   height), leaving a large empty gap below short content. */
.panel-auto-height { height: auto; }
.panel-title { font-weight: 700; font-size: 1rem; color: var(--navy); margin-bottom: 2px; }

.gradient-panel {
  border-radius: var(--radius); padding: 20px 22px; color: #fff;
  background: linear-gradient(135deg, var(--purple2), var(--blue));
}
.gradient-panel .panel-title { color: #fff; }

.badge-status { font-size: .72rem; font-weight: 600; padding: .32em .7em; border-radius: 20px; }
.badge-active { background: var(--green-light); color: var(--green); }
.badge-inactive { background: var(--gray-100); color: var(--gray-500); }
.badge-vacant { background: var(--orange-light); color: var(--orange); }
.badge-pending { background: var(--orange-light); color: var(--orange); }
.badge-approved { background: var(--green-light); color: var(--green); }
.badge-rejected { background: var(--red-light); color: var(--red); }

.btn-primary { background: var(--blue); border-color: var(--blue); }
.btn-primary:hover { background: #2448c4; border-color: #2448c4; }
.btn-soft-purple { background: #f1edfe; color: var(--purple2); border: none; }
.btn-soft-green { background: var(--green-light); color: var(--green); border: none; }
.btn-soft-orange { background: var(--orange-light); color: var(--orange); border: none; }
.btn-soft-pink { background: #fdeaf3; color: var(--pink); border: none; }
.btn-soft-blue { background: var(--blue-light); color: var(--blue); border: none; }

.table-clean thead th { border-top: none; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--gray-500); font-weight: 600; }
.table-clean td, .table-clean th { vertical-align: middle; padding: .85rem .75rem; }

/* ---------- Genealogy tree ---------- */
.tree-toolbar { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 20px; margin-bottom: 18px; }

.filter-label { display: block; font-weight: 700; color: var(--navy); font-size: .84rem; margin-bottom: 8px; }

/* Fixed widths moved here from inline styles specifically so a mobile media query can
   override them without needing !important (inline styles beat any stylesheet rule
   regardless of specificity, so they couldn't be responsive as inline attributes). */
.tree-filter-viewby select { width: 170px; }
.tree-filter-legview select { width: 140px; }
.tree-filter-search .search-input-wrap, .tree-filter-search input { width: 230px; }

.search-input-wrap { position: relative; }
.search-input-wrap input { padding-right: 34px; }
.search-input-wrap .bi-search {
  position: absolute; top: 50%; right: 12px; transform: translateY(-50%);
  color: var(--gray-500); font-size: .85rem; pointer-events: none;
}

.level-btn-group { display: flex; gap: 6px; }
.level-btn {
  min-width: 38px; height: 31px; padding: 0 10px; border-radius: 8px; border: 1px solid var(--border);
  background: #fff; color: var(--gray-700); font-size: .84rem; font-weight: 600;
  display: flex; align-items: center; justify-content: center; text-decoration: none;
}
.level-btn:hover { border-color: var(--blue); color: var(--blue); }
.level-btn.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.level-btn.disabled { pointer-events: none; opacity: .5; }
.tree-wrap {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 30px 16px; overflow: auto; position: relative;
}
.tree-wrap:fullscreen { padding-top: 70px; background: #fff; }
/* Left-aligned rather than centered, so the tree cluster sits clear of the
   right-pinned info panel / zoom controls instead of drifting under them.
   Scaled via the `zoom` CSS property (set in JS) rather than `transform: scale`,
   since `zoom` actually resizes the layout box instead of just repainting it. */
.tree-zoom-layer { display: inline-flex; justify-content: flex-start; min-width: 100%; }
.tree { display: inline-flex; flex-direction: column; align-items: center; min-width: 100%; }

/* Placement-mode toggle used in the page header */
.mode-toggle { display: inline-flex; gap: 6px; }
.mode-toggle button {
  border: none; background: var(--gray-100); font-size: .78rem; font-weight: 600; color: var(--gray-500);
  padding: 6px 16px; border-radius: 8px;
}
.mode-toggle button.active { background: var(--blue); color: #fff; }

/* Member-info grid, pinned top-right — the tree itself is left-aligned (see .tree-zoom-layer)
   so the two no longer compete for the same space. right offset clears the ~88px-wide
   zoom/pan control boxes pinned at right:14px, plus a 16px gap. */
.tree-info-float {
  position: absolute; top: 26px; right: 120px; z-index: 5; font-size: .78rem;
}
.tree-info-float .info-grid { display: grid; grid-template-columns: auto auto auto auto; column-gap: 16px; row-gap: 7px; }
.tree-info-float .info-label { color: var(--gray-500); white-space: nowrap; }
.tree-info-float .info-value { font-weight: 600; color: var(--navy); white-space: nowrap; }

/* Floating pan/zoom controls, pinned to the top-right of the tree canvas */
.tree-float-controls { position: absolute; top: 26px; right: 14px; z-index: 5; display: flex; flex-direction: row; align-items: center; gap: 8px; }
.tree-float-controls .ctrl-box {
  background: #fff; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 4px 12px rgba(20,25,60,.08);
  padding: 4px; display: grid;
}
.tree-float-controls .ctrl-box.pan { grid-template-columns: repeat(3, 26px); grid-template-rows: repeat(2, 26px); }
.tree-float-controls .ctrl-box.zoom { grid-template-columns: repeat(3, 30px); grid-auto-rows: 30px; gap: 2px; }
.tree-float-controls button {
  border: none; background: transparent; color: var(--gray-700); border-radius: 6px;
  display: flex; align-items: center; justify-content: center; font-size: .85rem;
}
.tree-float-controls button:hover { background: var(--gray-100); color: var(--blue); }

/* ---------- Genealogy tree — mobile ---------- */
@media (max-width: 767px) {
  /* Each filter's width was tuned for a single wide desktop row — once flex-wrap
     stacks them onto their own lines below this width, let each one fill that line
     instead of staying a narrow fixed-width box floating on the left. */
  .tree-filter-col { width: 100%; }
  .tree-filter-viewby select,
  .tree-filter-legview select,
  .tree-filter-search .search-input-wrap,
  .tree-filter-search input {
    width: 100%;
  }
  .tree-toolbar { gap: 14px; padding: 14px 16px; }
  .tree-filter-actions { width: 100%; margin-left: 0 !important; }
  .tree-filter-actions .btn { flex: 1; }

  /* The pan/zoom controls were pinned top-right assuming plenty of spare width
     beside the tree canvas — on a narrow screen they'd sit on top of the tree
     itself instead, so they drop into normal flow above the canvas and center
     themselves, same idea as the toolbar filters above. */
  .tree-float-controls { position: static; justify-content: center; margin: 0 0 14px; }
  .tree-wrap { padding: 16px 10px; }
}

.node-card.is-vacant { cursor: pointer; }
.node-card.is-vacant:hover { box-shadow: 0 0 0 3px var(--orange-light); }
.node-card.is-highlighted { outline: 2px solid var(--blue); outline-offset: 1px; }

.node-card.js-expand-node { cursor: pointer; }
.node-card.js-expand-node:hover { box-shadow: 0 0 0 3px var(--blue-light); }
.node-expand-hint {
  margin-top: 6px; font-size: .64rem; font-weight: 600; color: var(--blue);
  display: flex; align-items: center; justify-content: center; gap: 3px;
}
.node-card.is-loading .node-expand-hint { opacity: .5; }
.node-card.is-loading .node-expand-hint i { animation: node-expand-spin .8s linear infinite; }
@keyframes node-expand-spin { to { transform: rotate(360deg); } }

.tree ul { display: flex; padding-top: 26px; position: relative; margin: 0; }
.tree li { display: flex; flex-direction: column; align-items: center; list-style: none; position: relative; padding: 0 8px; }

/* Sibling connector line, split across each li's left half (::before) and right
   half (::after). Both halves sit at the SAME top offset and height so they join
   into one continuous horizontal bar — that consistency is what previously broke
   (::before was shifted 26px above ::after, producing a "staircase" instead of a
   straight line). top: -26px is essential: the li's own top edge is where its
   CARD starts (li has no padding-top), so `top: 0` draws the connector 26px
   *inside* the card instead of in the actual 26px gap the parent `ul`'s
   padding-top reserves above it — confirmed by measuring the rendered pixels,
   where the "connector" and the card were starting at the exact same y. -26px
   moves it up into that real gap, matching `.tree ul ul::before` below (the
   parent-to-row stub), which was already using -26px correctly. The vertical
   drop into each card's own center comes from ::after's left border (its left
   edge sits exactly at the li's 50% midpoint); the last child has no ::after to
   provide that, so it gets an equivalent right border on ::before instead
   (whose right edge is also at the midpoint). */
.tree li::before, .tree li::after {
  content: ''; position: absolute; top: -26px; height: 26px; border-top: 2px solid #5b6180;
}
.tree li::before { right: 50%; width: 50%; }
.tree li::after { left: 50%; width: 50%; border-left: 2px solid #5b6180; }

.tree li:first-child::before { border-top: none; }
.tree li:last-child::after { border-top: none; border-left: none; }
.tree li:last-child::before { border-right: 2px solid #5b6180; }

/* Soften the joint where each outer branch's vertical stub meets its horizontal
   run, instead of a sharp 90° corner. */
.tree li:first-child::after { border-radius: 6px 0 0 0; }
.tree li:last-child::before { border-radius: 0 6px 0 0; }

/* Every 3-leg group has exactly one middle child, sitting at (almost) the same
   x-position as the group's overall center — which is exactly where the
   parent-to-row stub (.tree ul ul::before below) already draws its own vertical
   line. Drawing the middle child's own center-drop on top of that (independently
   computed, so it lands a pixel or two off) produced a doubled/fuzzy line. The
   shared stub already covers it, so suppress the middle child's redundant one. */
.tree li:nth-child(2)::after { border-left: none; }

.tree li:only-child::before, .tree li:only-child::after { display: none; }
.tree li:only-child { padding-top: 0; }
.tree > li { padding-top: 0; }

/* Vertical stub from a parent card down into its children's shared horizontal bar.
   Positioned relative to the child <ul> itself, whose own top edge sits right at
   the parent card's bottom (it's the very next thing in the parent li's flow) —
   so top: 0 (not -26px, which measurement showed was 26px too high, sitting
   inside the parent card instead of the gap below it) lets this span exactly the
   26px gap created by the ul's own padding-top, down to where the child row begins. */
.tree ul ul::before { content: ''; position: absolute; top: 0; left: 50%; border-left: 2px solid #5b6180; height: 26px; }

.node-card {
  width: 148px; max-width: 100%; background: #fff; border: 1px solid #8890b3; border-radius: 12px;
  padding: 10px 10px 12px; text-align: center; box-shadow: 0 2px 6px rgba(20,25,60,.04);
}
/* Status-tinted card background — a colored fill (not just the small status badge) makes
   active/inactive/root read at a glance across a wide tree. .is-root is declared after
   .is-active/.is-inactive so the root's blue always wins over the green an active root
   would otherwise also match (a member is nearly always both root AND active). */
.node-card.is-active { background: var(--green-light); border-color: var(--green); }
.node-card.is-inactive { background: var(--gray-100); border-color: var(--gray-500); }
.node-card.is-root { background: var(--blue-light); border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-light); }
.node-card .node-avatar {
  width: 46px; height: 46px; border-radius: 50%; margin: 0 auto 6px; background: var(--blue-light);
  color: var(--blue); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.15rem;
  overflow: hidden; flex-shrink: 0;
}
.node-card .node-avatar img { width: 100%; height: 100%; object-fit: cover; }
.node-card.is-active .node-avatar { background: #fff; color: var(--green); border: 2px solid var(--green); }
.node-card.is-inactive .node-avatar { background: #fff; color: var(--gray-500); border: 2px solid var(--gray-500); }
.node-card.is-root .node-avatar { background: #fff; color: var(--blue); border: 2px solid var(--blue); }
.node-you-tag { color: var(--gray-500); font-weight: 500; }
.node-card.is-vacant { border-style: dashed; background: var(--orange-light); }
.node-card.is-vacant .node-avatar { background: #fff; color: var(--orange); border: 2px dashed var(--orange); }
.node-card .node-name { font-size: .78rem; font-weight: 700; color: var(--navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.node-card .node-id { font-size: .68rem; color: var(--gray-500); }
/* The card itself is now tinted the same light color as .badge-active/.badge-inactive
   (see .is-active/.is-inactive above), so without this the status pill would nearly
   blend into its own card background. A white pill keeps it legible on any tint. */
.node-card .badge-status { background: #fff; }
.leg-tag {
  font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #fff;
  padding: .18em .55em; border-radius: 6px; margin-bottom: 6px; display: inline-block;
}
.leg-tag.leg-1 { background: var(--green); }
.leg-tag.leg-2 { background: var(--blue); }
.leg-tag.leg-3 { background: var(--orange); }

.legend-strip { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; padding: 14px 20px; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); font-size: .82rem; color: var(--gray-700); }
.legend-strip .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; margin-right: 6px; }

@media (max-width: 991px) {
  .sidebar { transform: translateX(-100%); }
  .sidebar.show { transform: translateX(0); }
  .main-col { margin-left: 0; }
}

@media (max-width: 575px) {
  .topbar { padding: 12px 14px; }
  .topbar-actions { gap: 8px; }
  .icon-btn { width: 34px; height: 34px; }
}

/* Desktop sidebar collapse — reclaims the 258px for page content (e.g. the
   genealogy tree canvas). Toggled independently of the mobile overlay above. */
@media (min-width: 992px) {
  body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
  body.sidebar-collapsed .main-col { margin-left: 0; }
}
.sidebar-collapse-toggle {
  width: 36px; height: 36px; border-radius: 8px; border: 1px solid var(--border);
  background: #fff; color: var(--gray-700); display: flex; align-items: center; justify-content: center;
}
.sidebar-collapse-toggle:hover { background: var(--gray-100); color: var(--blue); }

/* ---------- Social-proof activity toast ("New member joined — 5 mins ago") ---------- */
.activity-toast {
  position: fixed; left: 22px; bottom: 22px; z-index: 1600;
  width: 320px; max-width: calc(100vw - 44px);
  background: #fff; border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 12px 32px rgba(20,25,60,.16);
  padding: 14px 16px; display: flex; align-items: flex-start; gap: 12px;
  opacity: 0; transform: translateY(16px) scale(.97);
  transition: opacity .35s ease, transform .35s ease;
  pointer-events: none;
}
.activity-toast.is-visible { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.activity-toast .toast-icon {
  width: 42px; height: 42px; border-radius: 50%; flex-shrink: 0;
  background: var(--green-light); color: var(--green); font-size: 1.2rem;
  display: flex; align-items: center; justify-content: center;
}
.activity-toast .toast-body { flex: 1; min-width: 0; }
.activity-toast .toast-title { font-size: .84rem; font-weight: 700; color: var(--navy); margin-bottom: 2px; }
.activity-toast .toast-name { color: var(--green); }
.activity-toast .toast-meta { font-size: .74rem; color: var(--gray-500); }
.activity-toast .toast-close {
  border: none; background: transparent; color: var(--gray-500); font-size: .95rem;
  line-height: 1; padding: 2px; flex-shrink: 0;
}
.activity-toast .toast-close:hover { color: var(--gray-700); }
.activity-toast .toast-progress {
  position: absolute; left: 14px; right: 14px; bottom: 8px; height: 2px;
  background: var(--gray-100); border-radius: 2px; overflow: hidden;
}
.activity-toast .toast-progress-bar { height: 100%; background: var(--green); width: 100%; transform-origin: left; }
.activity-toast.is-visible .toast-progress-bar { animation: activity-toast-progress 8s linear forwards; }
@keyframes activity-toast-progress { from { transform: scaleX(1); } to { transform: scaleX(0); } }

@media (max-width: 575px) {
  .activity-toast { left: 12px; bottom: 12px; width: calc(100vw - 24px); }
}

/* ---------- Dashboard advertisement slider ---------- */
.ad-slide { display: flex; min-height: 150px; }
.ad-slide-image {
  width: 260px; flex-shrink: 0; background-size: cover; background-position: center;
  background-color: var(--blue-light);
}
.ad-slide-image-fallback { display: flex; align-items: center; justify-content: center; color: var(--blue); font-size: 2.4rem; }
.ad-slide-body { flex: 1; min-width: 0; padding: 22px 26px; display: flex; flex-direction: column; justify-content: center; }
.ad-slide-title { font-weight: 700; font-size: 1.1rem; color: var(--navy); margin-bottom: 6px; }
.ad-slide-content { font-size: .88rem; color: var(--gray-700); line-height: 1.5; }
.ad-slide-link { font-size: .82rem; font-weight: 600; color: var(--blue); margin-top: 10px; display: inline-flex; align-items: center; gap: 4px; }

.ad-slider .carousel-control-prev, .ad-slider .carousel-control-next { width: 42px; opacity: 0; transition: opacity .15s ease; }
.ad-slider:hover .carousel-control-prev, .ad-slider:hover .carousel-control-next { opacity: 1; }
.ad-slider .carousel-control-prev-icon, .ad-slider .carousel-control-next-icon {
  width: 30px; height: 30px; background-color: rgba(20,25,60,.35); border-radius: 50%; background-size: 60%;
}
.ad-slider-indicators { position: absolute; bottom: 10px; margin: 0; }
.ad-slider-indicators button {
  width: 7px; height: 7px; border-radius: 50%; background: rgba(20,25,60,.25); border: none; opacity: 1;
}
.ad-slider-indicators button.active { background: var(--blue); width: 18px; border-radius: 4px; }

/* Compact variant: used when the slider sits in the dashboard column (replacing
   Income Overview). Styled as a member-spotlight / testimonial card — a circular
   profile photo, name, and description — rather than a rectangular banner, since
   the actual ad content is a member's photo + name + description. */
.ad-slider-compact .ad-slide {
  flex-direction: column; align-items: center; text-align: center; min-height: 0;
  padding: 26px 24px 22px; justify-content: center; height: 100%;
}
.ad-slider-compact .ad-slide-image {
  width: 84px; height: 84px; flex: none; border-radius: 50%;
  border: 3px solid var(--blue-light); box-shadow: 0 2px 8px rgba(20,25,60,.08);
}
.ad-slider-compact .ad-slide-image-fallback { font-size: 1.8rem; }
.ad-slider-compact .ad-slide-body { padding: 14px 4px 0; align-items: center; }
.ad-slider-compact .ad-slide-title { font-size: 1rem; }
.ad-slider-compact .ad-slide-content {
  font-size: .84rem; -webkit-line-clamp: 3; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.ad-slider-compact .ad-slide-link { justify-content: center; }

@media (max-width: 575px) {
  .ad-slide { flex-direction: column; }
  .ad-slide-image { width: 100%; height: 140px; }
  .ad-slide-body { padding: 16px 18px; }
}

/* ---------- Auth pages: split-screen layout (branding left, form right) ---------- */
.auth-body { margin: 0; min-height: 100vh; }
.auth-split { display: flex; min-height: 100vh; }

.auth-side {
  flex: 0 0 44%; max-width: 560px; position: relative; overflow: hidden;
  background: linear-gradient(150deg, var(--purple2) 0%, var(--blue) 65%, #2447c9 100%);
  display: flex; align-items: center;
}
.auth-side::before, .auth-side::after {
  content: ''; position: absolute; border-radius: 50%; background: rgba(255,255,255,.06);
}
.auth-side::before { width: 420px; height: 420px; top: -140px; right: -160px; }
.auth-side::after { width: 300px; height: 300px; bottom: -120px; left: -100px; background: rgba(255,255,255,.05); }

.auth-side-inner { position: relative; z-index: 1; padding: 56px 52px; color: #fff; width: 100%; }

.auth-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 44px; }
/* The logo is a solid blue wordmark, same family as this panel's own blue/purple
   gradient — a translucent backdrop isn't enough contrast (blue-on-blue washes out),
   so this needs a solid, opaque light card behind it instead. */
.auth-brand-on-dark { background: #fff; border-radius: 12px; padding: 14px 18px; display: inline-flex; box-shadow: 0 4px 14px rgba(0,0,0,.12); }

.auth-side-title { font-size: 1.85rem; font-weight: 800; line-height: 1.28; margin-bottom: 16px; }
.auth-side-lead { font-size: .95rem; color: rgba(255,255,255,.78); max-width: 400px; margin-bottom: 32px; }

.auth-feature-list { list-style: none; padding: 0; margin: 0 0 40px; display: flex; flex-direction: column; gap: 14px; }
.auth-feature-list li { display: flex; align-items: flex-start; gap: 12px; font-size: .86rem; color: rgba(255,255,255,.92); }
.auth-feature-list li i { flex-shrink: 0; margin-top: 2px; font-size: 1rem; color: #fff; background: rgba(255,255,255,.16); width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; }

.auth-side-matrix { display: flex; flex-direction: column; align-items: center; gap: 16px; opacity: .9; }
.matrix-node {
  width: 42px; height: 42px; border-radius: 50%; background: rgba(255,255,255,.14);
  border: 1.5px solid rgba(255,255,255,.4); display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 1rem;
}
.matrix-node.matrix-root { background: #fff; color: var(--purple2); border-color: #fff; }
.auth-side-matrix .matrix-row { display: flex; gap: 34px; }

.auth-form-side { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 24px; overflow-y: auto; min-height: 100vh; }
.auth-form-wrap { width: 100%; max-width: 420px; }
.auth-brand-mobile { margin-bottom: 28px; }

@media (max-width: 991px) {
  .auth-side { display: none; }
  .auth-form-side { padding: 32px 20px; }
}

/* ---------- Registration wizard ---------- */
.reg-steps { display: flex; align-items: center; gap: 8px; }
.reg-step { display: flex; align-items: center; gap: 8px; font-size: .8rem; font-weight: 600; color: var(--gray-500); }
.reg-step:not(:last-child)::after { content: ''; width: 24px; height: 2px; background: var(--border); margin-left: 8px; }
.reg-step-dot {
  width: 26px; height: 26px; border-radius: 50%; background: var(--gray-100); color: var(--gray-500);
  display: flex; align-items: center; justify-content: center; font-size: .78rem; flex-shrink: 0;
}
.reg-step.active { color: var(--navy); }
.reg-step.active .reg-step-dot { background: var(--blue); color: #fff; }
.reg-step.done .reg-step-dot { background: var(--green); color: #fff; }

.doc-upload {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 4px; border: 1.5px dashed var(--border); border-radius: 12px;
  padding: 18px 10px; cursor: pointer; background: var(--gray-50); min-height: 118px; overflow: hidden;
}
.doc-upload:hover { border-color: var(--blue); background: var(--blue-light); }
.doc-upload-input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.doc-upload-preview { position: absolute; inset: 0; background-size: cover; background-position: center; opacity: 0; transition: opacity .15s ease; }
.doc-upload.has-file .doc-upload-preview { opacity: 1; }
.doc-upload.has-file .doc-upload-body { position: relative; z-index: 1; background: rgba(255,255,255,.88); border-radius: 8px; padding: 6px 10px; }
.doc-upload-body { display: flex; flex-direction: column; align-items: center; gap: 4px; pointer-events: none; }
.doc-upload-body i { font-size: 1.4rem; color: var(--blue); }
.doc-upload-label { font-size: .78rem; font-weight: 600; color: var(--navy); }
.doc-upload.has-file .doc-upload-label { color: var(--green); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
.doc-upload-hint { font-size: .68rem; color: var(--gray-500); }

.reg-qr-img { width: 220px; height: 220px; border: 1px solid var(--border); border-radius: 12px; padding: 10px; background: #fff; }

.reg-pending-icon {
  width: 64px; height: 64px; border-radius: 50%; background: var(--blue-light); color: var(--blue);
  display: flex; align-items: center; justify-content: center; font-size: 1.8rem; margin: 0 auto 18px;
}

/* ---------- Registration success celebration ---------- */
.confetti-layer { position: fixed; inset: 0; pointer-events: none; z-index: 2000; overflow: hidden; }
.confetti-piece {
  position: absolute; top: -12px; width: 9px; height: 14px; opacity: .9;
  border-radius: 2px; animation: confetti-fall linear forwards;
}
@keyframes confetti-fall {
  0%   { transform: translate(0, 0) rotate(var(--rot)); opacity: 1; }
  100% { transform: translate(var(--drift), 105vh) rotate(calc(var(--rot) + 540deg)); opacity: 0; }
}

.reg-success-icon-wrap { position: relative; width: 84px; height: 84px; margin: 0 auto 18px; }
.reg-success-icon {
  position: relative; z-index: 1; width: 84px; height: 84px; border-radius: 50%;
  background: var(--green-light); color: var(--green); display: flex; align-items: center;
  justify-content: center; font-size: 2.4rem; animation: reg-success-pop .5s cubic-bezier(.34,1.56,.64,1);
}
.reg-success-ring {
  position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--green);
  opacity: 0; animation: reg-success-ring 1.6s ease-out infinite;
}
.reg-success-ring-2 { animation-delay: .5s; }
@keyframes reg-success-pop {
  0%   { transform: scale(0); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes reg-success-ring {
  0%   { transform: scale(.8); opacity: .6; }
  100% { transform: scale(1.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .reg-success-icon, .reg-success-ring { animation: none; }
}
