/* ═══════════════════════════════════════════════════════════════════
   static/css/nxg-ui.css — NXG Collective motion + responsive layer

   Loaded on every page by base.html and allauth/layouts/base.html.
   Plain CSS on purpose: nothing here depends on a Tailwind rebuild.

   Rules of the road
   * Motion is progressive enhancement. Anything that starts hidden only
     does so under html.nxg-motion, which JS sets — and a failsafe in
     <head> removes it again if nxg-ui.js never arrives. Content can
     never get stuck invisible.
   * Everything respects prefers-reduced-motion (bottom of this file).
   * Only transform/opacity/scale/translate are animated (GPU-friendly).

   Hooks (add to markup):
     data-reveal[="up|fade|scale|left|right"]  reveal on scroll
     data-reveal-delay="120"                    extra delay (ms)
     data-reveal-stagger                        reveal children one by one
     data-count-up="1234"                       count from 0 to the value
     data-count-up-scope                        count every plain number inside
     data-spotlight                             pointer-following glow
     .nxg-lift                                  hover lift for cards
     data-busy-on-submit (on <form>)            spinner + no double submit
     data-scroll-x-guard (wrapper)              make a row swipeable on mobile
     data-mobile-link-guard (wrapper)           never lose links on mobile
     data-avatar-zoom="Name" (wrapper)          tap the photo inside to enlarge
═══════════════════════════════════════════════════════════════════ */

:root {
  --nxg-blue: #0079C2;
  --nxg-violet: #6C47FF;
  --nxg-cyan: #00B5B0;
  --nxg-navy-900: #0D1B2A;
  --nxg-navy-850: #112236;
  --nxg-navy-750: #1B2B40;
  --nxg-muted: #8A9BB3;
  --nxg-ease-out: cubic-bezier(.22, 1, .36, 1);     /* easeOutQuint */
  --nxg-ease-spring: cubic-bezier(.34, 1.56, .64, 1);
}

/* ── Page-to-page crossfade (Chrome/Edge 126+, Safari 18.2+) ───────── */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-old(root) { animation: nxg-vt-out .18s ease both; }
::view-transition-new(root) { animation: nxg-vt-in .26s var(--nxg-ease-out) both; }
@keyframes nxg-vt-out { to { opacity: 0; } }
@keyframes nxg-vt-in { from { opacity: 0; transform: translateY(6px); } }

/* ── Responsive safety net ─────────────────────────────────────────── */
body { overflow-wrap: break-word; }
.prose pre, pre { max-width: 100%; overflow-x: auto; }
.prose table { display: block; max-width: 100%; overflow-x: auto; }
.prose img { height: auto; }

/* Horizontal rows that should swipe instead of overflow the page */
.nxg-scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.nxg-scroll-x::-webkit-scrollbar { display: none; }

/* A wrapper around ANY tab strip / chip row. Makes the inner row stay on
   one line and swipe on small screens, with soft fading edges that show
   there is more to scroll. Works without knowing the inner markup. */
[data-scroll-x-guard] {
  position: relative;
  max-width: 100%;
}
[data-scroll-x-guard] > .nxg-sxg-track {
  position: relative;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
}
[data-scroll-x-guard] > .nxg-sxg-track::-webkit-scrollbar { display: none; }
/* .nxg-sxg-row is the strip's own row of tabs, found by nxg-ui.js */
[data-scroll-x-guard] .nxg-sxg-row {
  flex-wrap: nowrap !important;
  width: max-content !important;
  min-width: 100%;
  max-width: none !important;
  overflow: visible !important;
}
[data-scroll-x-guard] .nxg-sxg-row > * {
  flex-shrink: 0 !important;
  white-space: nowrap;
}
[data-scroll-x-guard]::before,
[data-scroll-x-guard]::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 28px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .2s ease;
  z-index: 2;
}
[data-scroll-x-guard]::before { left: 0; background: linear-gradient(90deg, var(--nxg-fade-bg, var(--nxg-navy-900)), transparent); }
[data-scroll-x-guard]::after { right: 0; background: linear-gradient(270deg, var(--nxg-fade-bg, var(--nxg-navy-900)), transparent); }
[data-scroll-x-guard].has-left::before { opacity: 1; }
[data-scroll-x-guard].has-right::after { opacity: 1; }

/* Profile hero / header cards on phones: rows of links and buttons wrap
   instead of being pushed off-screen, and long URLs break. */
@media (max-width: 639.98px) {
  [data-mobile-link-guard] a { overflow-wrap: anywhere; }
  [data-mobile-link-guard] .justify-between:not(.flex-col) { flex-wrap: wrap; row-gap: .75rem; }
  [data-mobile-link-guard] :is(div, nav, ul, p):has(> :is(a, button, form) + :is(a, button, form)) {
    flex-wrap: wrap;
    row-gap: .5rem;
  }
  [data-mobile-link-guard] :is(a, button) { max-width: 100%; }
  [data-mobile-link-guard] .nxg-guard-shown { display: flex !important; flex-wrap: wrap; gap: .5rem; }
}

/* ── Scroll reveal ─────────────────────────────────────────────────── */
html.nxg-motion [data-reveal]:not(.is-revealed),
html.nxg-motion [data-reveal-stagger] > :not(.is-revealed) {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}
html.nxg-motion [data-reveal="fade"]:not(.is-revealed) { transform: none; }
html.nxg-motion [data-reveal="scale"]:not(.is-revealed) { transform: scale(.96); }
html.nxg-motion [data-reveal="left"]:not(.is-revealed) { transform: translate3d(-22px, 0, 0); }
html.nxg-motion [data-reveal="right"]:not(.is-revealed) { transform: translate3d(22px, 0, 0); }
/* Only while entering; once settled, the element's own transitions
   (hover colours, lifts) are back in charge. */
html.nxg-motion [data-reveal]:not(.is-settled),
html.nxg-motion [data-reveal-stagger] > :not(.is-settled) {
  transition:
    opacity .6s var(--nxg-ease-out),
    transform .7s var(--nxg-ease-out);
  transition-delay: var(--nxg-delay, 0ms);
}

/* ── Count-up numbers ──────────────────────────────────────────────── */
[data-count-up], .nxg-counting { font-variant-numeric: tabular-nums; overflow-wrap: normal; white-space: nowrap; }
html.nxg-motion:not(.nxg-ready) [data-count-up] { visibility: hidden; }
.nxg-count-done { animation: nxg-count-pop .45s var(--nxg-ease-spring); }
@keyframes nxg-count-pop { 40% { transform: scale(1.08); } }

/* ── Cards ─────────────────────────────────────────────────────────── */
.nxg-lift {
  transition:
    translate .25s var(--nxg-ease-out),
    box-shadow .25s ease,
    border-color .2s ease,
    background-color .2s ease,
    color .2s ease;
}
@media (hover: hover) {
  .nxg-lift:hover {
    translate: 0 -3px;
    box-shadow: 0 16px 36px -18px rgba(0, 0, 0, .75), 0 0 0 1px rgba(0, 121, 194, .22);
  }
  .nxg-lift-children > * { transition: translate .25s var(--nxg-ease-out), box-shadow .25s ease, border-color .2s ease, background-color .2s ease, color .2s ease; }
  .nxg-lift-children > *:hover {
    translate: 0 -3px;
    box-shadow: 0 16px 36px -18px rgba(0, 0, 0, .75);
  }
}

/* Pointer-following glow */
[data-spotlight] { position: relative; isolation: isolate; }
[data-spotlight]::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: -1;
  opacity: 0;
  transition: opacity .3s ease;
  background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%), rgba(0, 121, 194, .14), transparent 60%);
}
@media (hover: hover) { [data-spotlight]:hover::before { opacity: 1; } }

/* ── Buttons: tactile press ────────────────────────────────────────── */
/* Uses the individual `scale` property so it never fights an element's
   own transform (e.g. -translate-y-1/2 on icon buttons). */
/* Elements that already animate their colours also ease the press. */
button[class*="transition-colors"],
a[class*="transition-colors"] {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, box-shadow, scale;
}
button[class*="bg-"]:not(:disabled):active,
button[class*="border"]:not(:disabled):active,
a[class*="bg-brand"]:active,
a[class*="rounded-lg"][class*="border"]:active,
[data-press]:active {
  scale: .97;
}

/* Busy state for submit buttons (data-busy-on-submit forms) */
.nxg-busy { cursor: progress !important; opacity: .85; }
.nxg-spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-right: .5em;
  vertical-align: -.15em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 9999px;
  animation: nxg-spin .7s linear infinite;
}
@keyframes nxg-spin { to { transform: rotate(360deg); } }

/* ── HTMX: new content eases in; requests show progress ────────────── */
.nxg-swap-in { animation: nxg-swap-in .32s var(--nxg-ease-out) both; }
@keyframes nxg-swap-in { from { opacity: 0; transform: translateY(6px); } }
.htmx-request.htmx-indicator, .htmx-request .htmx-indicator { opacity: 1; }

/* Thin brand progress bar at the very top (HTMX + page navigation) */
#nxg-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 200;
  pointer-events: none;
  transform-origin: 0 50%;
  transform: scaleX(0);
  opacity: 0;
  background: linear-gradient(90deg, var(--nxg-blue), var(--nxg-violet), var(--nxg-cyan));
  box-shadow: 0 0 12px rgba(0, 121, 194, .6);
}
#nxg-progress.is-running { opacity: 1; transition: transform 8s cubic-bezier(.1, .7, .1, 1); transform: scaleX(.85); }
#nxg-progress.is-done { opacity: 0; transform: scaleX(1); transition: transform .2s ease, opacity .35s ease .15s; }

/* ── Signature bits for the home page / hero areas ─────────────────── */
.nxg-gradient-text {
  background-size: 200% auto;
  animation: nxg-shimmer 6s ease-in-out infinite alternate;
}
@keyframes nxg-shimmer { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }

.nxg-orb-a { animation: nxg-float-a 18s ease-in-out infinite alternate; }
.nxg-orb-b { animation: nxg-float-b 22s ease-in-out infinite alternate; }
@keyframes nxg-float-a { to { translate: 60px 40px; scale: 1.08; } }
@keyframes nxg-float-b { to { translate: -70px 30px; scale: .92; } }

.nxg-dot-grid {
  background-image: radial-gradient(rgba(138, 155, 179, .16) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 30%, transparent 75%);
}

/* Decorative background layers fade out at their edges (no hard seams) */
.nxg-soft-edges {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 78%, transparent);
}

.nxg-live-dot { position: relative; display: inline-flex; width: 8px; height: 8px; }
.nxg-live-dot::before,
.nxg-live-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background: currentColor;
}
.nxg-live-dot::before { animation: nxg-ping 1.8s cubic-bezier(0, 0, .2, 1) infinite; }
@keyframes nxg-ping { 75%, 100% { transform: scale(2.4); opacity: 0; } }

/* Reaction "pop" + floating emoji */
.nxg-pop { animation: nxg-pop .45s var(--nxg-ease-spring); }
@keyframes nxg-pop { 30% { scale: 1.18; } 60% { scale: .96; } }
.nxg-float-emoji {
  position: fixed;
  z-index: 150;
  pointer-events: none;
  font-size: 1.25rem;
  animation: nxg-float-up .9s var(--nxg-ease-out) forwards;
}
@keyframes nxg-float-up {
  from { opacity: 1; transform: translate(-50%, 0) scale(.8); }
  to { opacity: 0; transform: translate(-50%, -54px) scale(1.35); }
}

/* Newly arrived feed items glow once */
.nxg-new-glow { animation: nxg-new-glow 2.4s ease-out 1; }
@keyframes nxg-new-glow {
  0%, 30% { box-shadow: 0 0 0 1px rgba(0, 181, 176, .55), 0 0 24px -6px rgba(0, 181, 176, .45); }
  100% { box-shadow: 0 0 0 1px rgba(0, 181, 176, 0), 0 0 0 0 rgba(0, 181, 176, 0); }
}

/* Generic entrance for dropdowns/popovers */
.nxg-pop-in { animation: nxg-pop-in .18s var(--nxg-ease-out) both; transform-origin: top right; }
.nxg-pop-out { animation: nxg-pop-out .12s ease-in both; transform-origin: top right; }
@keyframes nxg-pop-in { from { opacity: 0; transform: translateY(-6px) scale(.96); } }
@keyframes nxg-pop-out { to { opacity: 0; transform: translateY(-4px) scale(.97); } }

/* Skeleton shimmer for loading placeholders */
.nxg-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--nxg-navy-750);
  border-radius: .5rem;
}
.nxg-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .06), transparent);
  animation: nxg-skeleton 1.4s ease-in-out infinite;
}
@keyframes nxg-skeleton { to { transform: translateX(100%); } }

/* Avatar that failed to load (e.g. file lost on an old deploy) */
img.nxg-img-missing { visibility: hidden; }

/* ── Profile photo zoom (data-avatar-zoom) ─────────────────────────── */
.nxg-zoomable { cursor: zoom-in; transition: filter .2s ease, box-shadow .2s ease; }
@media (hover: hover) { .nxg-zoomable:hover { filter: brightness(1.08); } }
.nxg-zoomable:focus-visible { outline: 2px solid var(--nxg-blue); outline-offset: 3px; }

.nxg-zoom {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.5rem;
  cursor: zoom-out;
  background: rgba(5, 12, 22, 0);
  -webkit-backdrop-filter: blur(0);
  backdrop-filter: blur(0);
  transition: background-color .3s ease, backdrop-filter .3s ease, -webkit-backdrop-filter .3s ease;
}
.nxg-zoom.is-open {
  background: rgba(5, 12, 22, .82);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.nxg-zoom-figure {
  margin: 0;
  overflow: hidden;
  background: var(--nxg-navy-750);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .85), 0 0 0 1px rgba(255, 255, 255, .08);
  border-radius: 1.5rem;
  transform-origin: center;
}
.nxg-zoom-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  -webkit-user-drag: none;
  user-select: none;
}
.nxg-zoom-caption,
.nxg-zoom-close {
  opacity: 0;
  transition: opacity .25s ease .12s;
}
.nxg-zoom.is-open .nxg-zoom-caption,
.nxg-zoom.is-open .nxg-zoom-close { opacity: 1; }
.nxg-zoom.is-closing .nxg-zoom-caption,
.nxg-zoom.is-closing .nxg-zoom-close { opacity: 0; transition-delay: 0s; }
.nxg-zoom-caption {
  margin: 0;
  color: #fff;
  font-weight: 600;
  font-size: .95rem;
  text-align: center;
}
.nxg-zoom-close {
  position: absolute;
  top: max(1rem, env(safe-area-inset-top));
  right: 1rem;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  color: #fff;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .16);
  cursor: pointer;
}
.nxg-zoom-close:hover { background: rgba(255, 255, 255, .18); }
.nxg-zoom-close:focus-visible { outline: 2px solid var(--nxg-blue); outline-offset: 2px; }

/* ── Links that look like links (feeds, previews) ────────────────── */
/* At rest: a light tint of the hover blue, so it reads as clickable.
   Hover/focus: the full brand blue plus an underline that draws in. */
.nxg-link {
  color: #8FCDF3;
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  transition: color .15s ease, text-decoration-color .2s ease;
}
.nxg-link:hover,
.nxg-link:focus-visible {
  color: #33AEF0;
  text-decoration-color: currentColor;
}
.nxg-link-name { font-weight: 600; }

/* ── Footer ────────────────────────────────────────────────────────── */
.nxg-footer { overflow: hidden; background: linear-gradient(180deg, rgba(13, 27, 42, 0), rgba(8, 18, 30, .9)); }
.nxg-footer-glow {
  position: absolute; left: 50%; top: -1px; width: min(720px, 90%); height: 1px; transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(0, 121, 194, .7), rgba(108, 71, 255, .7), transparent);
  box-shadow: 0 0 24px 2px rgba(0, 121, 194, .35);
}
.nxg-footer-heading { margin-bottom: .9rem; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .72rem;
                      letter-spacing: .08em; text-transform: uppercase; color: #5B6E8C; }
.nxg-footer-link { font-size: .875rem; color: #8A9BB3; transition: color .15s ease; }
.nxg-footer-link:hover, .nxg-footer-link:focus-visible { color: #fff; }
@media (max-width: 767.98px) { body:has(.nxg-tabbar) .nxg-footer { padding-bottom: 4.5rem; } }

/* Social icon buttons */
.nxg-social {
  display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 12px;
  color: #B4C0D2; background: #13233A; border: 1px solid #243650;
  transition: color .2s ease, border-color .2s ease, background-color .2s ease, translate .25s var(--nxg-ease-out), box-shadow .25s ease;
}
.nxg-social.is-sm { width: 36px; height: 36px; border-radius: 10px; }
.nxg-social:hover, .nxg-social:focus-visible { color: #fff; translate: 0 -2px; border-color: rgba(0, 121, 194, .6);
  box-shadow: 0 10px 24px -12px rgba(0, 121, 194, .7); }
.nxg-social-instagram:hover { border-color: rgba(225, 48, 108, .6); box-shadow: 0 10px 24px -12px rgba(225, 48, 108, .6); }

/* WhatsApp community CTA */
.nxg-community-btn {
  display: inline-flex; align-items: center; gap: .55rem; padding: .7rem 1.1rem; border-radius: .75rem;
  font-weight: 600; font-size: .875rem; color: #DCFCE7; background: rgba(37, 211, 102, .12); border: 1px solid rgba(37, 211, 102, .35);
  transition: background-color .2s ease, border-color .2s ease, translate .25s var(--nxg-ease-out), box-shadow .25s ease;
}
.nxg-community-btn:hover, .nxg-community-btn:focus-visible { background: rgba(37, 211, 102, .2); border-color: rgba(37, 211, 102, .6);
  translate: 0 -2px; box-shadow: 0 12px 28px -14px rgba(37, 211, 102, .6); }
.nxg-community-btn svg { color: #25D366; }

/* Share bar */
.nxg-share-btn {
  display: inline-flex; align-items: center; gap: .45rem; height: 36px; padding: 0 .8rem; border-radius: .6rem;
  font-size: .8rem; font-weight: 600; color: #B4C0D2; background: #13233A; border: 1px solid #243650; cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease, scale .12s ease;
}
.nxg-share-btn[hidden] { display: none; }
.nxg-share-btn:hover, .nxg-share-btn:focus-visible { color: #fff; border-color: #34496A; }
.nxg-share-btn:active { scale: .96; }
.nxg-share-btn.is-primary { color: #fff; background: #0079C2; border-color: #0079C2; }
.nxg-share-btn.is-primary:hover { background: #1A94DD; }
.nxg-share-btn.is-done { color: #22C55E; border-color: rgba(34, 197, 94, .45); }
@media (max-width: 639.98px) {
  .nxg-share-heading { display: none; }
  .nxg-share-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* Big hero headings shrink to fit phones instead of breaking words */
@media (max-width: 639.98px) {
  .nxg-hero-title { font-size: clamp(1.85rem, 8.6vw, 2.6rem) !important; line-height: 1.12 !important; letter-spacing: -.01em; }
}

/* ── Profile completeness ring ─────────────────────────────────────── */
.nxg-ring { --pct: 0; width: 64px; height: 64px; flex-shrink: 0; }
.nxg-ring circle { fill: none; stroke-width: 6; }
.nxg-ring .nxg-ring-track { stroke: #1B2B40; }
.nxg-ring .nxg-ring-value { stroke: url(#nxg-ring-grad); stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%;
  stroke-dasharray: 163.36; stroke-dashoffset: 163.36; transition: stroke-dashoffset 1.4s var(--nxg-ease-out) .2s; }
.nxg-ring.is-in .nxg-ring-value { stroke-dashoffset: calc(163.36 - 163.36 * var(--pct) / 100); }
.nxg-checklist-chip { display: inline-flex; align-items: center; gap: .35rem; padding: .3rem .65rem; border-radius: 9999px;
  font-size: .75rem; font-weight: 600; color: #B4C0D2; background: #13233A; border: 1px dashed #34496A;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease; }
.nxg-checklist-chip:hover { color: #fff; border-color: #0079C2; border-style: solid; background: rgba(0, 121, 194, .12); }

/* ── How it works (home) ───────────────────────────────────────────── */
.nxg-steps { position: relative; counter-reset: step; }
.nxg-steps::before { content: ""; position: absolute; left: 21px; top: 22px; bottom: 22px; width: 2px; background: #1B2B40; }
.nxg-steps-fill { position: absolute; left: 21px; top: 22px; width: 2px; height: calc(100% - 44px); transform-origin: top; transform: scaleY(var(--fill, 0));
  background: linear-gradient(180deg, #0079C2, #6C47FF, #00B5B0); box-shadow: 0 0 12px rgba(0, 121, 194, .6);
  transition: transform 1.6s var(--nxg-ease-out) .25s; }
@media (min-width: 1024px) {
  .nxg-steps::before { left: 22px; right: 22px; top: 21px; bottom: auto; width: auto; height: 2px; }
  .nxg-steps-fill { left: 22px; top: 21px; width: calc(100% - 44px); height: 2px; transform-origin: left; transform: scaleX(var(--fill, 0)); }
}
.nxg-step-dot { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 9999px; color: #8FCDF3; background: #0D1B2A; border: 2px solid #243650; transition: border-color .4s ease, box-shadow .4s ease, color .4s ease; }
.is-revealed .nxg-step-dot { border-color: #0079C2; color: #fff; box-shadow: 0 0 0 6px rgba(0, 121, 194, .12); }

/* ── Blog: reading progress + code copy ────────────────────────────── */
.nxg-read-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 60; transform-origin: 0 50%;
  transform: scaleX(var(--read, 0)); background: linear-gradient(90deg, #0079C2, #6C47FF); pointer-events: none; }
.nxg-code-wrap { position: relative; }
.nxg-code-copy { position: absolute; top: .5rem; right: .5rem; padding: .25rem .6rem; border-radius: .45rem; font-size: .72rem; font-weight: 600;
  color: #B4C0D2; background: rgba(13, 27, 42, .85); border: 1px solid #243650; opacity: 0; transition: opacity .15s ease, color .15s ease; cursor: pointer; }
.nxg-code-wrap:hover .nxg-code-copy, .nxg-code-copy:focus-visible { opacity: 1; }
.nxg-code-copy.is-done { color: #22C55E; opacity: 1; }
@media (hover: none) { .nxg-code-copy { opacity: 1; } }

/* ── Command palette (Ctrl/Cmd + K) ────────────────────────────────── */
.nxg-cmdk { position: fixed; inset: 0; z-index: 250; display: flex; align-items: flex-start; justify-content: center; padding: 12vh 1rem 1rem;
  background: rgba(5, 12, 22, .6); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: nxg-fade-in .15s ease; }
.nxg-cmdk-box { width: 100%; max-width: 560px; overflow: hidden; border-radius: 1rem; background: #112236; border: 1px solid #243650;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .9); animation: nxg-pop-in .2s var(--nxg-ease-out) both; transform-origin: top center; }
.nxg-cmdk-input { width: 100%; padding: 1rem 1.1rem; background: transparent; border: 0; border-bottom: 1px solid #243650; color: #fff; font-size: 1rem; outline: none; }
.nxg-cmdk-input::placeholder { color: #5B6E8C; }
.nxg-cmdk-list { max-height: min(52vh, 420px); overflow-y: auto; padding: .4rem; margin: 0; list-style: none; }
.nxg-cmdk-item { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .65rem .8rem; border-radius: .6rem;
  color: #B4C0D2; font-size: .9rem; cursor: pointer; }
.nxg-cmdk-item[aria-selected="true"] { color: #fff; background: rgba(0, 121, 194, .16); }
.nxg-cmdk-item small { color: #5B6E8C; font-size: .72rem; }
.nxg-cmdk-empty { padding: 1.2rem; color: #5B6E8C; font-size: .875rem; text-align: center; }
.nxg-cmdk-foot { display: flex; gap: 1rem; padding: .55rem .9rem; border-top: 1px solid #243650; color: #5B6E8C; font-size: .72rem; }
.nxg-kbd { display: inline-flex; align-items: center; padding: 0 .35rem; min-width: 1.3rem; height: 1.3rem; border-radius: .3rem;
  border: 1px solid #34496A; color: #8A9BB3; font-size: .7rem; font-family: "JetBrains Mono", ui-monospace, monospace; }
@keyframes nxg-fade-in { from { opacity: 0; } }

/* Keyboard hints only make sense with a keyboard */
.nxg-desktop-only { display: none; }
@media (min-width: 1024px) and (hover: hover) { .nxg-desktop-only { display: inline; } .nxg-mobile-only { display: none; } }

/* Confetti canvas (approval moment) */
.nxg-confetti { position: fixed; inset: 0; z-index: 260; pointer-events: none; }

@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* Sample (seeded demo) profiles: understated, always present */
.nxg-sample-tag { display: inline-flex; align-items: center; flex-shrink: 0; height: 1.15rem; padding: 0 .4rem; border-radius: 9999px;
  font-size: .6rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; line-height: 1; cursor: help;
  color: #8A9BB3; border: 1px solid #34496A; background: rgba(138, 155, 179, .06); vertical-align: middle; }

/* ── Meet the Collective cards (home) ──────────────────────────────── */
.nxg-ccard { transition: translate .25s var(--nxg-ease-out), box-shadow .25s ease, border-color .2s ease; }
@media (hover: hover) {
  .nxg-ccard:hover { translate: 0 -4px; border-color: #34496A; box-shadow: 0 18px 40px -20px rgba(0, 0, 0, .8), 0 0 0 1px rgba(0, 121, 194, .18); }
}
.nxg-ccard-name { font-family: "Space Grotesk", ui-sans-serif, system-ui, sans-serif; font-size: 1rem; font-weight: 700; color: #fff; }
a.nxg-ccard-name::after { content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 1; }
a.nxg-ccard-name:focus-visible { outline: none; }
.nxg-ccard:has(a.nxg-ccard-name:focus-visible) { outline: 2px solid #0079C2; outline-offset: 3px; }
.nxg-ccard:hover a.nxg-ccard-name { color: #8FCDF3; }
.nxg-ccard-avatar { position: relative; flex-shrink: 0; width: 52px; height: 52px; border-radius: 9999px; padding: 2px;
  background: #243650; }
.nxg-ccard-avatar > img, .nxg-ccard-initials { border-radius: 9999px; }
.nxg-ccard-avatar.is-open { background: conic-gradient(from 180deg, #22C55E, #00B5B0, #0079C2, #22C55E); }
.nxg-ccard-avatar.is-open::after { content: ""; position: absolute; inset: -3px; border-radius: 9999px; border: 2px solid rgba(34, 197, 94, .35);
  animation: nxg-open-pulse 2.4s ease-out infinite; }
@keyframes nxg-open-pulse { 0% { opacity: .9; transform: scale(.96); } 100% { opacity: 0; transform: scale(1.18); } }
.nxg-ccard-initials { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, #0079C2, #6C47FF); }
.nxg-ccard-new { position: absolute; left: 50%; bottom: -7px; z-index: 1; transform: translateX(-50%); padding: 0 .4rem; border-radius: 9999px;
  font-size: .6rem; font-weight: 800; line-height: 1.35rem; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
  color: #1A1206; background: #FBBF24; box-shadow: 0 0 0 2px #13233A; }
.nxg-ccard-tag { padding: .15rem .5rem; border-radius: .4rem; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .7rem;
  color: #B4C0D2; background: #1B2B40; border: 1px solid #243650; }
.nxg-ccard-tag.is-more { color: #5B6E8C; }
.nxg-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.nxg-ccard-view { color: #8FCDF3; transition: color .15s ease; }
.nxg-ccard:hover .nxg-ccard-view { color: #33AEF0; }

.nxg-follow-btn { min-width: 92px; height: 34px; padding: 0 .9rem; border-radius: .6rem; font-size: .8rem; font-weight: 700; cursor: pointer;
  color: #fff; background: #0079C2; border: 1px solid #0079C2; transition: background-color .15s ease, border-color .15s ease, color .15s ease, scale .12s ease; }
.nxg-follow-btn:hover { background: #1A94DD; }
.nxg-follow-btn:active { scale: .95; }
.nxg-follow-btn .nxg-follow-on, .nxg-follow-btn .nxg-follow-hover { display: none; }
.nxg-follow-btn[aria-pressed="true"] { color: #B4C0D2; background: transparent; border-color: #34496A; }
.nxg-follow-btn[aria-pressed="true"] .nxg-follow-off { display: none; }
.nxg-follow-btn[aria-pressed="true"] .nxg-follow-on { display: inline; }
@media (hover: hover) {
  .nxg-follow-btn[aria-pressed="true"]:hover { color: #FCA5A5; border-color: rgba(239, 68, 68, .5); background: rgba(239, 68, 68, .08); }
  .nxg-follow-btn[aria-pressed="true"]:hover .nxg-follow-on { display: none; }
  .nxg-follow-btn[aria-pressed="true"]:hover .nxg-follow-hover { display: inline; }
}
.nxg-follow-btn.htmx-request { opacity: .7; cursor: progress; }
.nxg-bump { animation: nxg-pop .45s var(--nxg-ease-spring); display: inline-block; }

.nxg-sort-chip { flex-shrink: 0; white-space: nowrap; padding: .4rem .85rem; border-radius: 9999px; font-size: .78rem; font-weight: 600;
  color: #B4C0D2; background: #13233A; border: 1px solid #243650; cursor: pointer; transition: color .15s ease, background-color .15s ease, border-color .15s ease; }
.nxg-sort-chip:hover { color: #fff; border-color: #34496A; }
.nxg-sort-chip.is-active { color: #fff; background: #0079C2; border-color: #0079C2; }

.nxg-ccard-join { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .35rem; min-height: 220px; padding: 1.5rem;
  text-align: center; border-radius: 1rem; border: 1.5px dashed #34496A; background: rgba(0, 121, 194, .04);
  transition: border-color .2s ease, background-color .2s ease, translate .25s var(--nxg-ease-out); }
.nxg-ccard-join:hover { border-color: #0079C2; background: rgba(0, 121, 194, .09); translate: 0 -4px; }
.nxg-ccard-join-plus { display: flex; align-items: center; justify-content: center; width: 52px; height: 52px; margin-bottom: .35rem; border-radius: 9999px;
  font-size: 1.6rem; font-weight: 300; color: #8FCDF3; border: 1.5px dashed #34496A; transition: transform .35s var(--nxg-ease-spring), border-color .2s ease; }
.nxg-ccard-join:hover .nxg-ccard-join-plus { transform: rotate(90deg); border-color: #0079C2; }
[data-collective-item].is-filtered-out { display: none; }

/* Printing / "save as PDF" always shows everything */
@media print {
  html.nxg-motion [data-reveal], html.nxg-motion [data-reveal-stagger] > * { opacity: 1 !important; transform: none !important; }
  #nxg-progress, .nxg-float-emoji, .nxg-zoom, .nxg-read-progress, .nxg-cmdk, .nxg-confetti, .nxg-code-copy { display: none !important; }
}

/* ── Reduced motion: keep every state change, drop the movement ────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html.nxg-motion [data-reveal]:not(.is-revealed),
  html.nxg-motion [data-reveal-stagger] > :not(.is-revealed) { opacity: 1; transform: none; }
  html.nxg-motion:not(.nxg-ready) [data-count-up] { visibility: visible; }
  .nxg-lift:hover, .nxg-lift-children > *:hover { translate: none; }
}

/* ── Dialogs (followers / following) ──────────────────────────────── */
.nxg-dialog-in { animation: nxg-dialog-in .28s var(--nxg-ease-out) both; }
[data-nxg-dialog] [data-dialog-backdrop] { animation: nxg-fade-in .2s ease-out both; }
@keyframes nxg-dialog-in { from { opacity: 0; transform: translateY(24px); } }
@keyframes nxg-fade-in { from { opacity: 0; } }
@media (min-width: 640px) {
  @keyframes nxg-dialog-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
}

/* ── Rendered Markdown (.prose) ────────────────────────────────────
   Blog posts, project case studies, bounty briefs, bios and comments
   are rendered Markdown inside .prose — but the Tailwind typography
   plugin was never installed, so .prose did nothing: headings, lists,
   quotes and spacing all collapsed into plain lines. These rules give
   that HTML the platform's type scale. Body colour comes from the
   wrapper's own text-* class. */
.prose { line-height: 1.75; overflow-wrap: anywhere; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose p, .prose ul, .prose ol, .prose blockquote, .prose table, .prose figure { margin: 0 0 1.1em; }
.prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
  font-family: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  color: #F9FAFB; font-weight: 700; line-height: 1.3; letter-spacing: -0.01em;
  margin: 1.8em 0 0.6em; scroll-margin-top: 5rem;
}
.prose h1 { font-size: 1.75em; }
.prose h2 { font-size: 1.45em; }
.prose h3 { font-size: 1.2em; }
.prose h4, .prose h5, .prose h6 { font-size: 1.05em; }
.prose a { color: #0EA5E9; text-decoration: underline; text-decoration-color: rgba(14, 165, 233, .4); text-underline-offset: 3px; transition: text-decoration-color .15s; }
.prose a:hover { text-decoration-color: currentColor; }
.prose strong { color: #F9FAFB; font-weight: 600; }
.prose ul { list-style: disc; padding-left: 1.4em; }
.prose ol { list-style: decimal; padding-left: 1.5em; }
.prose li { margin: 0.35em 0; padding-left: 0.2em; }
.prose li::marker { color: #8A94A6; }
.prose li > ul, .prose li > ol { margin: 0.35em 0; }
.prose blockquote { border-left: 3px solid #0079C2; padding: 0.2em 0 0.2em 1em; color: #D1D5DB; font-style: italic; }
.prose hr { border: 0; border-top: 1px solid #243B5C; margin: 2em 0; }
.prose :not(pre) > code {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; font-size: 0.875em;
  background: #1E3A5F; color: #E5E7EB; padding: 0.15em 0.4em; border-radius: 0.35rem;
}
.prose pre code { background: none; padding: 0; font-size: inherit; color: inherit; }
.prose img { border-radius: 0.75rem; margin: 1.5em 0; }
.prose th, .prose td { border: 1px solid #243B5C; padding: 0.45em 0.75em; text-align: left; }
.prose th { background: #1E3A5F; color: #F9FAFB; font-weight: 600; }
.prose-sm { font-size: 0.875rem; line-height: 1.65; }
.prose-sm p, .prose-sm ul, .prose-sm ol, .prose-sm blockquote { margin-bottom: 0.8em; }
/* Comments are short: tighter rhythm, no oversized headings. */
.nxg-comment-body.prose p, .nxg-comment-body.prose ul, .nxg-comment-body.prose ol { margin-bottom: 0.5em; }
.nxg-comment-body.prose h1, .nxg-comment-body.prose h2, .nxg-comment-body.prose h3 { font-size: 1em; margin: 0.8em 0 0.3em; }

/* ── Snippet code window (line numbers) ─────────────────────────── */
.nxg-snippet-code .highlight { margin: 0; border: 0; border-radius: 0; background: transparent; padding: 0; }
.nxg-snippet-code .highlighttable { border-collapse: collapse; width: 100%; }
.nxg-snippet-code .highlighttable td { padding: 0; vertical-align: top; }
.nxg-snippet-code td.linenos { width: 1%; user-select: none; -webkit-user-select: none; border-right: 1px solid #1E3A5F; }
.nxg-snippet-code td.linenos pre { margin: 0; padding: 1rem 0.75rem 1rem 1rem; text-align: right; color: #5B6B82; background: transparent; border: 0; border-radius: 0; }
.nxg-snippet-code td.linenos .normal { color: #5B6B82; background: transparent; padding: 0; }
.nxg-snippet-code td.code pre { margin: 0; padding: 1rem 1.25rem; background: transparent; border: 0; border-radius: 0; }
.nxg-snippet-code pre { line-height: 1.65; font-size: 0.8125rem; }
@media (min-width: 640px) { .nxg-snippet-code pre { font-size: 0.875rem; } }

/* ── Project card placeholder (no thumbnail) ────────────────────── */
.nxg-project-placeholder {
  background:
    radial-gradient(120% 90% at 0% 0%, rgba(0, 121, 194, .45), transparent 60%),
    radial-gradient(120% 90% at 100% 100%, rgba(108, 71, 255, .40), transparent 60%),
    #1E3A5F;
}

/* ── Busy label swap (e.g. GitHub "Verify") ────────────────────────
   Only one label occupies space at a time; htmx adds .htmx-request to
   the element making the request. */
.nxg-busy-swap .nxg-when-busy { display: none; }
.nxg-busy-swap.htmx-request .nxg-when-busy { display: inline-flex; }
.nxg-busy-swap.htmx-request .nxg-when-idle { display: none; }

/* ── Phones: form rows never push past the screen ──────────────────
   A text input that is a flex item keeps a built-in minimum width
   (about 20 characters), so "input + button" rows overflowed narrow
   screens. Let such inputs shrink; buttons beside them keep their size. */
.flex > input:not([type="checkbox"]):not([type="radio"]),
.flex > select,
.flex > textarea { min-width: 0; }

/* ── Chat (Messages) ────────────────────────────────────────────── */
.nxg-chat-btn-primary,
.nxg-chat-btn-ghost {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.55rem 1rem; border-radius: 0.75rem;
  font-size: 0.875rem; font-weight: 600; line-height: 1.25rem;
  transition: background-color .15s, border-color .15s, color .15s;
}
.nxg-chat-btn-primary { background: #0079C2; color: #fff; box-shadow: 0 8px 20px -10px rgba(0, 121, 194, .7); }
.nxg-chat-btn-primary:hover:not(:disabled) { background: #0EA5E9; }
.nxg-chat-btn-ghost { background: #1A2E44; color: #E5E7EB; border: 1px solid #243B5C; }
.nxg-chat-btn-ghost:hover { background: #1E3A5F; color: #fff; }

/* Pop-over menus built on <details> (chat ⋮, message actions). */
.nxg-menu {
  position: absolute; z-index: 40; padding: 0.375rem 0;
  background: #1A2E44; border: 1px solid #243B5C; border-radius: 0.875rem;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .65);
}
.nxg-menu.nxg-menu-up { top: auto !important; bottom: 100%; margin-top: 0; margin-bottom: 0.25rem; }
.nxg-menu-item {
  display: block; width: 100%; text-align: left; padding: 0.5rem 0.875rem;
  font-size: 0.875rem; color: #E5E7EB; transition: background-color .12s, color .12s;
}
.nxg-menu-item:hover, .nxg-menu-item:focus-visible { background: #1E3A5F; color: #fff; outline: none; }
.nxg-menu-danger { color: #F87171; }
.nxg-menu-danger:hover, .nxg-menu-danger:focus-visible { background: rgba(220, 38, 38, .12); color: #FCA5A5; }
details[data-chat-menu] > summary::-webkit-details-marker { display: none; }
details > summary.list-none::-webkit-details-marker { display: none; }

/* Message actions: shown on hover / focus; always there on touch screens. */
.nxg-msg-actions { opacity: 0; transition: opacity .12s; }
.nxg-msg:hover .nxg-msg-actions, .nxg-msg-actions:focus-within, .nxg-msg-actions[open] { opacity: 1; }
@media (hover: none) { .nxg-msg-actions { opacity: .75; } }
.nxg-msg-flash .nxg-bubble { animation: nxg-msg-flash 1.2s ease-out; }
@keyframes nxg-msg-flash { 0%, 30% { box-shadow: 0 0 0 3px rgba(14, 165, 233, .7); } 100% { box-shadow: 0 0 0 0 rgba(14, 165, 233, 0); } }

/* Formatting inside messages (apps/messaging/templatetags/chat.py). */
.nxg-chat-text { white-space: normal; overflow-wrap: anywhere; }
.nxg-chat-link { text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(255, 255, 255, .45); }
.nxg-chat-link:hover { text-decoration-color: currentColor; }
.nxg-bubble:not(.nxg-bubble-mine) .nxg-chat-link { color: #38BDF8; text-decoration-color: rgba(56, 189, 248, .4); }
.nxg-chat-code {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; font-size: 0.82em;
  background: rgba(3, 11, 20, .45); padding: 0.1em 0.38em; border-radius: 0.35rem;
}
.nxg-chat-pre { position: relative; margin: 0.35rem 0; border-radius: 0.6rem; background: #030B14; border: 1px solid rgba(255, 255, 255, .08); }
.nxg-chat-pre pre {
  margin: 0; padding: 0.65rem 0.75rem; overflow-x: auto; max-height: 22rem;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; font-size: 0.78rem; line-height: 1.55;
  color: #E5E7EB; white-space: pre;
}
.nxg-chat-pre-lang {
  display: block; padding: 0.3rem 0.75rem 0; font-size: 0.65rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: #8A94A6;
}
.nxg-composer-error {
  margin-bottom: 0.5rem; padding: 0.45rem 0.75rem; border-radius: 0.6rem;
  background: rgba(220, 38, 38, .12); border: 1px solid rgba(220, 38, 38, .35);
  color: #FCA5A5; font-size: 0.8125rem;
}
.nxg-composer-drop { outline: 2px dashed #0EA5E9; outline-offset: -6px; background: rgba(0, 121, 194, .06); }

/* ── Confirm dialog (nxg-ui.js section 23) ──────────────────────── */
.nxg-confirm-card { animation: nxg-confirm-in .16s ease-out; }
@keyframes nxg-confirm-in { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .nxg-confirm-card, .nxg-msg-flash .nxg-bubble { animation: none; } }
/* The hidden attribute must win over display utilities (e.g. inline-flex). */
[data-chat-jump][hidden], [data-composer-context][hidden] { display: none !important; }
