/* ============================================================================
   NEXORA DESIGN SYSTEM — v1 (V2026.153)
   ============================================================================
   A real three-layer token architecture built ON TOP of the KYMA skin.
   Nothing here invents a new identity: the canvas is still cream #f5f4e7,
   the ink is still #050505, the accent is still electric-lime #c6ff34 with
   violet #7e3bed as the secondary. What this layer adds is the *system* —
   harmonised scales, elevation, focus, motion and component states that were
   previously ad-hoc or missing.

   LOAD ORDER (must be 4th, last):
     style.css → style-extra.css → kyma.css → nx-system.css

   Because kyma.css leans heavily on !important, overrides here use the same
   weapon ONLY where kyma already did. Everything else is plain specificity,
   so this file stays easy to reason about and easy to remove.

   LAYERS
     1 · PRIMITIVES  raw, un-opinionated scales (never used directly in markup)
     2 · SEMANTIC    meaning-bearing aliases (surface, text, accent, border)
     3 · COMPONENT   per-component tokens + the refinements that use them
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1 · PRIMITIVES
   Raw values. Referenced only by layer 2. Renaming a brand colour is a
   one-line change here instead of a find-replace across 8,000 lines.
   --------------------------------------------------------------------------- */
:root{
  /* Brand ramps ---------------------------------------------------------- */
  --nxp-lime-100:#f2ffd6;
  --nxp-lime-200:#e3ff9e;
  --nxp-lime-300:#d4ff66;
  --nxp-lime-400:#c6ff34;   /* ← the brand lime */
  --nxp-lime-500:#aee518;
  --nxp-lime-600:#8fbf12;

  --nxp-violet-100:#f0e9ff;
  --nxp-violet-200:#d9c6ff;
  --nxp-violet-300:#b493ff;
  --nxp-violet-400:#9d6bff;
  --nxp-violet-500:#7e3bed;  /* ← the brand violet */
  --nxp-violet-600:#5b21b6;

  /* Neutral ramp (cream → ink) ------------------------------------------- */
  --nxp-cream-50:#fbfaf3;
  --nxp-cream-100:#f5f4e7;   /* ← the canvas */
  --nxp-cream-200:#eceadb;
  --nxp-cream-300:#e0ddcb;
  --nxp-cream-400:#c9c6b4;
  --nxp-ink-300:#8a8a80;
  --nxp-ink-400:#6b6b62;
  --nxp-ink-500:#4a4a44;
  --nxp-ink-700:#1a1a19;
  --nxp-ink-800:#0f0f11;
  --nxp-ink-900:#050505;     /* ← the ink */

  /* Status ---------------------------------------------------------------- */
  --nxp-success:#2ea043;
  --nxp-warning:#d98a00;
  --nxp-danger:#d3252b;
  --nxp-info:#7e3bed;

  /* Spacing — 4px base, geometric after 8 ---------------------------------- */
  --nxp-space-1:4px;   --nxp-space-2:8px;   --nxp-space-3:12px;
  --nxp-space-4:16px;  --nxp-space-5:24px;  --nxp-space-6:32px;
  --nxp-space-7:48px;  --nxp-space-8:64px;  --nxp-space-9:96px;
  --nxp-space-10:128px;

  /* Duration + easing ------------------------------------------------------ */
  --nxp-dur-instant:90ms;
  --nxp-dur-fast:160ms;
  --nxp-dur-base:240ms;
  --nxp-dur-slow:420ms;
  --nxp-dur-slower:680ms;
  /* Expressive standard easing — fast out, settled in. Matches the site's
     existing cubic-bezier(.16,1,.3,1) feel but named and reused. */
  --nxp-ease-out:cubic-bezier(.16,1,.3,1);
  --nxp-ease-in-out:cubic-bezier(.65,0,.35,1);
  --nxp-ease-spring:cubic-bezier(.34,1.56,.64,1);

  /* Z-index scale — stops the "z-index: 99999" arms race ------------------- */
  --nxp-z-base:1;    --nxp-z-sticky:100;  --nxp-z-header:400;
  --nxp-z-drop:500;  --nxp-z-overlay:800; --nxp-z-modal:900; --nxp-z-toast:1000;
}

/* ---------------------------------------------------------------------------
   2 · SEMANTIC
   What a thing MEANS, not what colour it is. Components reference these.
   --------------------------------------------------------------------------- */
:root{
  /* Surfaces */
  --nx-surface:var(--nxp-cream-100);
  --nx-surface-sunken:var(--nxp-cream-200);
  --nx-surface-raised:var(--nxp-cream-50);
  --nx-surface-inverse:var(--nxp-ink-800);
  --nx-surface-inverse-deep:var(--nxp-ink-900);

  /* Text */
  --nx-text:var(--nxp-ink-900);
  --nx-text-secondary:var(--nxp-ink-500);
  --nx-text-muted:var(--nxp-ink-300);
  --nx-text-on-inverse:#f4f4e8;
  --nx-text-on-inverse-muted:rgba(244,244,232,.66);
  --nx-text-on-accent:var(--nxp-ink-900);

  /* Accent */
  --nx-accent:var(--nxp-lime-400);
  --nx-accent-hover:var(--nxp-lime-500);
  --nx-accent-secondary:var(--nxp-violet-500);
  --nx-accent-secondary-hover:var(--nxp-violet-600);

  /* Borders — hairlines are core to the KYMA look */
  --nx-border:rgba(5,5,5,.16);
  --nx-border-soft:rgba(5,5,5,.08);
  --nx-border-strong:rgba(5,5,5,.38);
  --nx-border-inverse:rgba(244,244,232,.18);

  /* Elevation — KYMA is a flat, hairline language, so elevation is used
     sparingly and stays tight/low-spread rather than soft and diffuse. */
  --nx-elev-0:none;
  --nx-elev-1:0 1px 2px rgba(5,5,5,.06), 0 0 0 1px rgba(5,5,5,.05);
  --nx-elev-2:0 4px 14px rgba(5,5,5,.08), 0 0 0 1px rgba(5,5,5,.06);
  --nx-elev-3:0 12px 34px rgba(5,5,5,.12), 0 0 0 1px rgba(5,5,5,.07);
  --nx-elev-4:0 26px 70px rgba(5,5,5,.20), 0 0 0 1px rgba(5,5,5,.08);
  --nx-elev-accent:0 8px 28px rgba(198,255,52,.34);
  --nx-elev-violet:0 8px 28px rgba(126,59,237,.30);

  /* Focus — the single most important a11y token. Lime on a 2px offset so it
     reads on both the cream canvas and the dark bands. */
  --nx-focus-ring:0 0 0 2px var(--nxp-ink-900), 0 0 0 5px var(--nxp-lime-400);
  --nx-focus-ring-inverse:0 0 0 2px var(--nxp-ink-900), 0 0 0 5px var(--nxp-lime-400);

  /* Geometry — KYMA is deliberately sharp. 2px, not 12px. */
  --nx-r-sharp:0px;
  --nx-r-xs:2px;
  --nx-r-sm:4px;
  --nx-r-md:8px;
  --nx-r-pill:999px;
}

/* ---------------------------------------------------------------------------
   3 · TYPE SYSTEM
   A fluid modular scale. Every step clamps between a phone and a desktop size
   so headings stop being either tiny on mobile or absurd on 27" monitors.
   Optical tracking tightens as size grows — the mark of typography that was
   set rather than defaulted.
   --------------------------------------------------------------------------- */
:root{
  --nx-fs-display:clamp(44px, 7.2vw, 104px);
  --nx-fs-h1:clamp(34px, 5vw, 68px);
  --nx-fs-h2:clamp(27px, 3.4vw, 46px);
  --nx-fs-h3:clamp(21px, 2.1vw, 30px);
  --nx-fs-h4:clamp(18px, 1.5vw, 22px);
  --nx-fs-body-lg:clamp(16px, 1.15vw, 18.5px);
  --nx-fs-body:15.5px;
  --nx-fs-sm:13.5px;
  --nx-fs-xs:12px;
  --nx-fs-label:11px;

  --nx-lh-tight:1.02;
  --nx-lh-snug:1.14;
  --nx-lh-normal:1.5;
  --nx-lh-relaxed:1.65;

  --nx-track-display:-.045em;
  --nx-track-heading:-.032em;
  --nx-track-body:-.008em;
  --nx-track-label:.14em;
}

/* Apply the scale to the existing heading elements. These are plain-specificity
   rules, so any page-level rule still wins — nothing is hijacked. */
h1{font-size:var(--nx-fs-h1);line-height:var(--nx-lh-tight);letter-spacing:var(--nx-track-heading)}
h2{font-size:var(--nx-fs-h2);line-height:var(--nx-lh-snug);letter-spacing:var(--nx-track-heading)}
h3{font-size:var(--nx-fs-h3);line-height:var(--nx-lh-snug);letter-spacing:-.024em}
h4{font-size:var(--nx-fs-h4);line-height:var(--nx-lh-snug);letter-spacing:-.018em}

/* Optical refinements that lift the whole page without moving anything. */
html{
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
  scroll-padding-top:96px;          /* anchors clear the sticky header */
}
body{
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  font-variant-numeric:tabular-nums; /* prices/stats stop jittering */
  letter-spacing:var(--nx-track-body);
}
/* Headings should NOT inherit tabular figures — it looks mechanical in display
   type. Reset them to proportional. */
h1,h2,h3,h4,h5{font-variant-numeric:normal}

/* The mono eyebrow is a signature of this brand — make it consistent. */
.nx-eyebrow{
  font-family:var(--font-mono);
  font-size:var(--nx-fs-label);
  font-weight:700;
  letter-spacing:var(--nx-track-label);
  text-transform:uppercase;
  line-height:1;
}

/* Long-form readability: cap measure so paragraphs never run 140 characters. */
.nx-prose p,.nx-doc-body p,.nx-post p{max-width:68ch;line-height:var(--nx-lh-relaxed)}

/* ---------------------------------------------------------------------------
   4 · FOCUS & ACCESSIBILITY
   The site previously had NO keyboard focus indicator outside form inputs —
   keyboard and screen-reader users had no idea where they were. This is the
   single highest-impact fix in this file.
   --------------------------------------------------------------------------- */
:where(a,button,[role="button"],[tabindex],summary,input,select,textarea):focus-visible{
  outline:none;
  box-shadow:var(--nx-focus-ring);
  border-radius:var(--nx-r-xs);
  position:relative;
  z-index:var(--nxp-z-sticky);
}
/* Mouse users keep a clean UI — no ring on plain :focus. */
:where(a,button,[role="button"]):focus:not(:focus-visible){outline:none}

/* Skip-to-content link, injected by shell.js. Visible only on keyboard focus. */
.nx-skip-link{
  position:absolute;left:-9999px;top:0;z-index:var(--nxp-z-toast);
  background:var(--nxp-ink-900);color:var(--nx-accent);
  padding:14px 22px;font:800 12px/1 var(--font-mono);
  letter-spacing:var(--nx-track-label);text-transform:uppercase;text-decoration:none;
}
.nx-skip-link:focus{left:12px;top:12px;box-shadow:var(--nx-focus-ring)}

/* Respect the OS "reduce motion" setting across every animation on the site. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* Selection + caret carry the brand. */
::selection{background:var(--nx-accent);color:var(--nxp-ink-900)}
::-moz-selection{background:var(--nx-accent);color:var(--nxp-ink-900)}
:root{accent-color:var(--nxp-violet-500);caret-color:var(--nxp-ink-900)}

/* Scrollbar — thin, inky, brand-consistent (Firefox + WebKit). */
html{scrollbar-color:var(--nxp-ink-400) transparent;scrollbar-width:thin}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--nxp-cream-400);
  border:3px solid transparent;
  background-clip:content-box;
  border-radius:var(--nx-r-pill);
}
::-webkit-scrollbar-thumb:hover{background:var(--nxp-ink-400);background-clip:content-box}

/* ---------------------------------------------------------------------------
   5 · BUTTON SYSTEM
   kyma.css sets colour with !important, so colour overrides here match that.
   Everything else (geometry, motion, states) is plain specificity.
   The refinement: a real pressed state, a real disabled state, a light sheen
   sweep on hover, and consistent optical height.
   --------------------------------------------------------------------------- */
/* NOTE ON THE CASCADE
   style.css:236 already defines the diagonal sheen (`.nx-cta::after`) and
   `.nx-cta:hover{translateY(-1px)}`, and kyma.css re-declares several hover
   transforms with !important. Re-declaring either here would (a) duplicate
   work and (b) silently lose to kyma anyway. So this section deliberately
   only adds what genuinely does not exist: pressed state, disabled state,
   busy state, and a shared timing curve. */
.nx-cta,.nx-cta-blue,.nx-cta-ghost,.nx-cta-violet,
.nx-promo-cta,.nx-pkg-cta,.nx-adm-btn,.nx-plan-cta{
  transition:
    background var(--nxp-dur-fast) var(--nxp-ease-out),
    color var(--nxp-dur-fast) var(--nxp-ease-out),
    border-color var(--nxp-dur-fast) var(--nxp-ease-out),
    box-shadow var(--nxp-dur-base) var(--nxp-ease-out),
    transform var(--nxp-dur-fast) var(--nxp-ease-out);
}

/* The missing tactile beat: a genuine press. Nothing else in the codebase
   defines an :active state, so buttons felt inert on click. */
.nx-cta:active,.nx-cta-blue:active,.nx-cta-ghost:active,.nx-cta-violet:active,
.nx-promo-cta:active,.nx-pkg-cta:active,.nx-adm-btn:active,.nx-plan-cta:active{
  transform:translateY(0) scale(.985) !important;
  transition-duration:var(--nxp-dur-instant);
}

/* Disabled / busy states — previously undefined, so disabled buttons looked
   identical to live ones. */
.nx-cta[disabled],.nx-cta-blue[disabled],.nx-cta-ghost[disabled],
.nx-adm-btn[disabled],button[disabled],.is-disabled{
  opacity:.42 !important;
  cursor:not-allowed !important;
  transform:none !important;
  box-shadow:none !important;
  filter:grayscale(.5);
}
.is-busy{position:relative;pointer-events:none;color:transparent !important}
.is-busy::before{
  content:"";position:absolute;inset:0;margin:auto;
  width:16px;height:16px;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  color:var(--nx-accent);
  animation:nxSpin .62s linear infinite;
}
@keyframes nxSpin{to{transform:rotate(360deg)}}

/* Minimum hit target — WCAG 2.2 target size (24×24 CSS px absolute minimum;
   we hold 40px for primary controls). */
.nx-icon-btn,.nx-cta,.nx-cta-blue,.nx-cta-ghost{min-height:40px}

/* ---------------------------------------------------------------------------
   6 · CARD SYSTEM
   Cards already got their surface treatment in kyma block 37/41. This adds the
   interaction layer: a precise lift, an accent edge that wipes in, and a
   focus-within state so keyboard users see the whole card highlight.
   --------------------------------------------------------------------------- */
/* Hover lift and shadow are ALREADY owned by kyma.css (blocks 37/41, with
   !important) and style.css:930 — this file must not fight them or cards
   across 235 pages shift by a pixel for no reason. What is genuinely missing
   is :focus-within, so a keyboard user tabbing to a link inside a card can
   see which card they are in. */
.nx-card,.nx-adm-card,.nxv-card,.nxsolv-card,.nx-cat{
  transition:
    transform var(--nxp-dur-base) var(--nxp-ease-out),
    box-shadow var(--nxp-dur-base) var(--nxp-ease-out),
    border-color var(--nxp-dur-base) var(--nxp-ease-out);
}
.nx-card:focus-within,.nx-cat:focus-within,.nxv-card:focus-within{
  box-shadow:var(--nx-elev-3), 0 0 0 2px var(--nx-accent) !important;
}

/* ---------------------------------------------------------------------------
   7 · FORM SYSTEM
   Consistent control height and a single focus treatment, replacing the six
   different :focus rules scattered across three stylesheets.
   --------------------------------------------------------------------------- */
input:not([type=checkbox]):not([type=radio]):not([type=range]),
select,textarea{
  font-family:var(--font-sans);
  font-size:var(--nx-fs-body);
  transition:
    border-color var(--nxp-dur-fast) var(--nxp-ease-out),
    box-shadow var(--nxp-dur-fast) var(--nxp-ease-out),
    background var(--nxp-dur-fast) var(--nxp-ease-out);
}
input::placeholder,textarea::placeholder{color:var(--nx-text-muted);opacity:1}

/* Invalid state — only after the user has actually typed something, so empty
   required fields don't scream red on first paint. */
input:not(:placeholder-shown):invalid,
textarea:not(:placeholder-shown):invalid{
  border-color:var(--nxp-danger) !important;
  box-shadow:0 0 0 3px rgba(211,37,43,.18) !important;
}

/* ---------------------------------------------------------------------------
   8 · MOTION SYSTEM
   Scroll-reveal primitives used by motion.js, plus a stagger utility. These
   replace per-page ad-hoc keyframes.
   --------------------------------------------------------------------------- */
.nx-scroll-rise{
  opacity:0;transform:translateY(22px);
  transition:opacity var(--nxp-dur-slower) var(--nxp-ease-out),
             transform var(--nxp-dur-slower) var(--nxp-ease-out);
}
.nx-scroll-rise.is-in,.nx-scroll-rise.in,.nx-scroll-rise.visible{
  opacity:1;transform:none;
}
/* Stagger children by index — set --i on the child, or let :nth-child do it. */
.nx-stagger > *{
  opacity:0;transform:translateY(16px);
  transition:opacity var(--nxp-dur-slow) var(--nxp-ease-out),
             transform var(--nxp-dur-slow) var(--nxp-ease-out);
}
.nx-stagger.is-in > *,.nx-stagger.in > *,.nx-stagger.visible > *{opacity:1;transform:none}
.nx-stagger.is-in > *:nth-child(1),.nx-stagger.in > *:nth-child(1){transition-delay:0ms}
.nx-stagger.is-in > *:nth-child(2),.nx-stagger.in > *:nth-child(2){transition-delay:60ms}
.nx-stagger.is-in > *:nth-child(3),.nx-stagger.in > *:nth-child(3){transition-delay:120ms}
.nx-stagger.is-in > *:nth-child(4),.nx-stagger.in > *:nth-child(4){transition-delay:180ms}
.nx-stagger.is-in > *:nth-child(5),.nx-stagger.in > *:nth-child(5){transition-delay:240ms}
.nx-stagger.is-in > *:nth-child(6),.nx-stagger.in > *:nth-child(6){transition-delay:300ms}
.nx-stagger.is-in > *:nth-child(n+7),.nx-stagger.in > *:nth-child(n+7){transition-delay:360ms}

/* Link underline that grows from the left instead of a flat text-decoration. */
.nx-link-anim{
  position:relative;text-decoration:none;
  background-image:linear-gradient(var(--nx-accent),var(--nx-accent));
  background-size:0% 2px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size var(--nxp-dur-base) var(--nxp-ease-out);
}
.nx-link-anim:hover{background-size:100% 2px}

/* ---------------------------------------------------------------------------
   8b · NAVBAR — THE SELLER CTA (V2026.153)
   "Become a Seller" is the highest-value conversion on the site (it creates
   supply, and supply is what a marketplace is short of). It used to be the
   second item inside the Pricing dropdown. It is now the ONE highlighted
   element in the nav.

   Constraint that shaped this: the header already overflowed at 1366–1600px
   once (kyma blocks 44–46 exist purely to claw back width), so this control
   is deliberately compact and sheds its label before it can overflow again.
   --------------------------------------------------------------------------- */
html body .nx-header a.nx-nav-sell{
  display:inline-flex;align-items:center;gap:7px;
  margin-left:6px;padding:0 14px;height:32px;
  background:var(--nx-accent) !important;
  color:var(--nxp-ink-900) !important;
  border:0 !important;border-radius:var(--nx-r-xs);
  font:800 11.5px/1 var(--font-mono);
  letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;
  box-shadow:0 0 0 0 rgba(198,255,52,.55);
  transition:background var(--nxp-dur-fast) var(--nxp-ease-out),
             color var(--nxp-dur-fast) var(--nxp-ease-out),
             box-shadow var(--nxp-dur-base) var(--nxp-ease-out),
             transform var(--nxp-dur-fast) var(--nxp-ease-out);
}
/* The nav gives every <a> a square ::before marker dot — wrong on a pill. */
html body .nx-header a.nx-nav-sell::before{display:none !important}

html body .nx-header a.nx-nav-sell:hover,
html body .nx-header a.nx-nav-sell.active{
  background:var(--nxp-ink-900) !important;
  color:var(--nx-accent) !important;
  transform:translateY(-1px);
  box-shadow:0 6px 22px rgba(198,255,52,.30);
}
html body .nx-header a.nx-nav-sell:active{transform:translateY(0) scale(.97)}

/* Two instances exist (see shell.js): the drawer copy inside .nx-nav and the
   bar copy inside .nx-actions. Exactly one is ever visible.

   The breakpoint is 900px because that is where THIS site's drawer actually
   lives — the vertical drawer layout (kyma block 49 + style.css) is gated at
   ≤900px, so moving the hamburger up to 1024px produced an open "drawer" that
   was still a clipped horizontal row. The 901–1279px band is handled by
   compaction instead (see WIDTH BUDGET below). */
html body .nx-header a.nx-nav-sell--drawer{display:none !important}
@media (max-width:1129px){
  html body .nx-header a.nx-nav-sell--bar{display:none !important}
  html body .nx-header a.nx-nav-sell--drawer{display:flex !important}
}

/* A slow "live" pulse on the leading dot. One subtle signal, not a carnival —
   and it stops entirely for reduced-motion users. */
.nx-nav-sell-dot{
  width:6px;height:6px;border-radius:50%;
  background:var(--nxp-ink-900);
  flex:0 0 auto;
  animation:nxSellPulse 2.6s var(--nxp-ease-in-out) infinite;
}
html body .nx-header .nx-nav a.nx-nav-sell:hover .nx-nav-sell-dot{background:var(--nx-accent)}
@keyframes nxSellPulse{
  0%,100%{transform:scale(1);opacity:1}
  50%{transform:scale(1.45);opacity:.45}
}
@media (prefers-reduced-motion:reduce){.nx-nav-sell-dot{animation:none}}

/* ---- NAV DROPDOWNS: CLICK ONLY (V2026.162) --------------------------------
   The founder asked for click-only menus back in V2026.093, and shell.js
   wireNavDrops was rewritten then to remove its hover-intent handlers. But two
   CSS rules in style-extra.css (added as a "pure-CSS fallback in case JS is
   broken") kept opening them anyway:

     style-extra.css:1171  .nx-nav-drop:hover .nx-nav-menu       → opens on hover
     style-extra.css:1167  .nx-nav-drop:focus-within .nx-nav-menu → opens on focus

   The :hover one is the irritation while moving the cursor across the nav.
   The :focus-within one is subtler and worse: clicking a trigger to CLOSE the
   menu leaves the button focused, so focus-within immediately re-opens it —
   the menu that "comes up without hovering".

   Both carry !important, so they are overridden here with higher specificity.
   The menu now shows only when shell.js adds .is-open on a real click.

   Keyboard access is unaffected: .nx-nav-trigger is a real <button>, so Enter
   and Space fire a click and open the menu through the same path. */
@media (min-width:1130px){
  html body .nx-header .nx-nav-drop:not(.is-open):hover .nx-nav-menu,
  html body .nx-header .nx-nav-drop:not(.is-open):focus-within .nx-nav-menu{
    opacity:0 !important;
    visibility:hidden !important;
    transform:translateY(-6px) !important;
    pointer-events:none !important;
  }
}

/* Pricing is no longer a lime pill, so kyma:1063 (which forced its label to
   near-black for legibility ON the lime) would now paint dark-on-black.
   Restore the standard light nav colour. */
html body .nx-header .nx-nav-pricedrop .nx-nav-trigger,
html body .nx-header .nx-nav-pricedrop .nx-nav-trigger .nx-caret{
  color:rgba(244,244,232,.82) !important;
}
html body .nx-header .nx-nav-pricedrop .nx-nav-trigger:hover,
html body .nx-header .nx-nav-pricedrop .nx-nav-trigger.active{
  color:var(--nx-accent) !important;
}
html body .nx-header .nx-nav-pricedrop .nx-nav-trigger::before{display:none !important}

/* Small tag chip used inside the dropdown ("POPULAR"). */
.nx-nav-tag{
  display:inline-block;margin-left:6px;vertical-align:middle;
  background:var(--nx-accent);color:var(--nxp-ink-900);
  font:800 8px/1 var(--font-mono);letter-spacing:.06em;
  padding:3px 5px;border-radius:var(--nx-r-xs);
}

/* WIDTH BUDGET (901–1279px).
   Measured on this build at 1100px: logo 209 + nav 523 + actions 325 = 1057,
   leaving only ~43px of slack — so adding a 131px pill overflowed and .nx-nav
   (overflow:hidden) silently ate the last nav items. Rather than drop the CTA,
   reclaim the width: shorten the pill label and tighten nav metrics in this
   band only. Desktop ≥1280px is untouched. */
/* Label shortening runs across the whole 1130–1599 band, wider than the rest
   of the compaction. Reason: kyma block 45 brings the "AI AUTOMATION
   MARKETPLACE" tagline back at ≥1440 (138px), which the founder explicitly
   asked for in V2026.143 — so at 1440–1699 the tagline and a full-length
   "Become a Seller" pill cannot both fit, and JOIN FREE was being clipped by
   32px. Shortening the pill to "SELLER" frees ~56px and keeps the tagline. */
@media (max-width:1699px) and (min-width:1130px){
  html body .nx-header a.nx-nav-sell .nx-nav-sell-label-long{display:none}
}
@media (max-width:1279px) and (min-width:1130px){
  html body .nx-header a.nx-nav-sell{padding:0 10px;font-size:10.5px;margin-left:4px}
  html body .nx-header .nx-nav{gap:0;padding:0 6px}
  html body .nx-header .nx-nav > a,
  html body .nx-header .nx-nav .nx-nav-trigger{padding:8px 7px;font-size:11px}
  html body .nx-header .nx-actions{gap:4px}
  html body .nx-header .nx-header-tools{gap:2px}
}
/* Order of yielding, least-used first. Both of these remain reachable — the
   currency chip is duplicated in the drawer, Orders lives in the account
   menu and the mobile bottom nav. */
@media (max-width:1199px) and (min-width:1130px){
  html body .nx-header #curBtn{display:none !important}
}
@media (max-width:1149px) and (min-width:1130px){
  html body .nx-header #ordersLink{display:none !important}
}

/* ---- BUGFIX: mega-menus stuck open, and header overflow, at 901–980px ------
   Pre-existing on the live site, not introduced here. Three breakpoints
   disagreed about where the desktop nav ends and the drawer begins:

     style-extra.css:370  @media (max-width:980px) → .nx-nav-drop{width:100%},
                          .nx-nav-trigger{width:100%;text-align:left},
                          .nx-nav-menu{position:static;opacity:1;visible}
                          …i.e. the full vertical DRAWER treatment.
     style.css:1586       @media (max-width:900px) → .nx-nav{display:none}
     kyma.css:1118        @media (max-width:900px) → hamburger + dark drawer

   So the drawer STYLING starts at 980 but the drawer SWITCH starts at 900.
   In the 901–980px band the horizontal nav therefore stayed on screen with
   every dropdown permanently expanded — four mega-menus painting over the
   hero at once — while the action buttons overflowed the viewport by ~113px.

   The fix is to honour what the drawer CSS was clearly written for and move
   the switch to 980, then carry kyma's dark-drawer skin up to match (without
   it, 901–980 would render light-cream drawer + light text = invisible, the
   exact bug fixed back in V2026.148). */
@media (max-width:1129px){
  /* ---- THE DRAWER CONTAINER ITSELF -------------------------------------
     style.css:1587 gives .nx-nav.open its position:fixed, height and
     overflow-y:auto — but only inside @media (max-width:900px). When the
     drawer breakpoint moved to 1129px those container rules did NOT come
     with it, so on tablets (768–1129px) the drawer opened as a static,
     non-scrollable block whose top sat ~475px ABOVE the viewport: the first
     items were unreachable and the panel would not scroll at all.

     Redeclared here for the whole band, with two improvements over the
     original: the top edge follows the REAL header bottom (--nx-drawer-top,
     set by shell.js) instead of a hardcoded 72px that ignored the announce
     bar, and the bottom padding clears both the iOS home indicator and the
     fixed mobile bottom nav. */
  html body .nx-header .nx-nav.open{
    display:flex !important;
    flex-direction:column;
    align-items:stretch;
    gap:0;
    /* ABSOLUTE, not FIXED, and anchored to the header.
       .nx-header has backdrop-filter (the glass effect), which makes it the
       containing block for any position:fixed descendant. So `top: 115px` on a
       fixed drawer was measured from the HEADER's top edge (y=43), not the
       viewport, and the panel rendered 43px too low. Absolute + top:100% pins
       it to the header's bottom edge automatically — correct whether or not
       the announce bar is on screen, and it keeps working if the glass effect
       is ever removed, because .nx-header is position:sticky and therefore a
       positioned ancestor either way. */
    position:absolute;
    left:0; right:0;
    top:100%;
    /* An EXPLICIT height, not auto. style.css:1589 already warns about this:
       "Force the drawer to fill the visible viewport below the header.
        Without this, the flex layout shrinks to content height." A column
       flex container in an absolutely-positioned box collapses to roughly its
       padding (measured: 111px tall with 2,980px of content inside), so the
       panel looked like a thin sliver. dvh (not vh) so mobile browser chrome
       showing/hiding does not leave the drawer over- or under-sized. */
    height:calc(100dvh - var(--nx-drawer-top, 72px));
    max-height:calc(100dvh - var(--nx-drawer-top, 72px));
    /* !important is required, not stylistic: style-extra.css declares
       `.nx-header,.nx-nav{overflow:visible !important}` globally (no media
       query), which silently beat overflow-y:auto and was the actual reason
       the drawer would not scroll on any tablet or phone. */
    overflow-y:auto !important;
    overflow-x:hidden !important;
    -webkit-overflow-scrolling:touch;
    /* Stops the page behind the drawer from scrolling when you reach the end
       of the drawer's own scroll — the classic "scroll chaining" annoyance. */
    overscroll-behavior:contain;
    padding:14px 22px calc(96px + env(safe-area-inset-bottom, 0px));
    padding-left:max(22px, env(safe-area-inset-left, 0px));
    padding-right:max(22px, env(safe-area-inset-right, 0px));
    z-index:var(--nxp-z-overlay);
    box-shadow:0 16px 32px rgba(8,8,8,.18);
  }
  /* Above 900px there is no fixed bottom nav to clear. */
  @media (min-width:901px){
    html body .nx-header .nx-nav.open{padding-bottom:calc(40px + env(safe-area-inset-bottom, 0px))}
  }

  /* Comfortable touch targets — WCAG 2.2 asks for 24px minimum; 48 is kind. */
  html body .nx-nav.open > a,
  html body .nx-nav.open .nx-nav-trigger{
    min-height:48px;
    display:flex;
    align-items:center;
  }

  /* Sub-menu rows inside the drawer.
     `.nx-nav a{align-items:center}` (style.css) combined with the mega-menu's
     column flex direction was centring the title and description of every
     item — fine for a centred desktop card, wrong for a list you scan down
     the left edge of. Reset to a plain left-aligned row. */
  /* kyma.css styles .nx-nav-menu as a floating card with !important on the
     background, border and shadow. Inside the drawer it is an inline list, so
     those have to be matched with !important to be undone. */
  html body .nx-nav.open .nx-nav-menu{
    min-width:0;
    padding:0 0 6px 14px !important;
    border:0 !important;
    border-radius:0 !important;
    box-shadow:none !important;
    background:transparent !important;
  }
  html body .nx-nav.open .nx-nav-menu a{
    align-items:flex-start;
    text-align:left;
    min-height:44px;
    justify-content:center;
    padding:10px 12px !important;
    border-left:1px solid rgba(255,255,255,.10);
  }
  html body .nx-nav.open .nx-nav-menu a b{text-align:left;width:100%}
  html body .nx-nav.open .nx-nav-menu a small{text-align:left;width:100%}

  /* The group label ("Build", "Discover") should read as a heading, not a row. */
  html body .nx-nav.open .nx-nav-trigger{
    justify-content:space-between;
    font-weight:600;
    opacity:.92;
  }

  /* Layout half of the drawer. style-extra.css:370 only declares these up to
     980px, so they must be repeated for the widened band or 981–1129 would
     render the drawer as a clipped horizontal row. */
  html body .nx-nav.open .nx-nav-drop{display:block;width:100%}
  html body .nx-nav.open .nx-nav-trigger{width:100%;text-align:left;padding:10px 14px}
  html body .nx-nav.open .nx-nav-menu{
    position:static;opacity:1;visibility:visible;transform:none;pointer-events:auto;
    box-shadow:none;border:none;background:transparent;
    padding:0 0 6px 30px;min-width:0;
  }
  html body .nx-nav.open .nx-nav-menu a{padding:6px 12px}
  html body .nx-nav.open .nx-caret{display:none}

  html body .nx-header .nx-nav:not(.open){display:none !important}
  html body .nx-header .nx-menu{
    display:flex !important;
    background:transparent !important;
    border-color:rgba(255,255,255,.22) !important;
  }
  html body .nx-header .nx-menu i,
  html body .nx-header .nx-menu i::before,
  html body .nx-header .nx-menu i::after{background:#f4f4e8 !important}

  /* Dark drawer — matches the black app bar it slides out of. */
  html body .nx-nav.open{
    background:#0a0a0c !important;
    border-top:1px solid rgba(255,255,255,.08) !important;
    box-shadow:0 22px 44px rgba(0,0,0,.55) !important;
  }
  html body .nx-nav.open > a,
  html body .nx-nav.open .nx-nav-trigger{
    color:#f4f4e8 !important;
    border-bottom-color:rgba(255,255,255,.08) !important;
  }
  html body .nx-nav.open > a:hover,
  html body .nx-nav.open > a.active,
  html body .nx-nav.open .nx-nav-trigger:hover{color:#c6ff34 !important}
  html body .nx-nav.open .nx-nav-menu a,
  html body .nx-nav.open .nx-nav-menu a b{color:#f4f4e8 !important}
  html body .nx-nav.open .nx-nav-menu a small{color:rgba(244,244,232,.6) !important}

  /* The seller CTA is a LIME block, so it must opt out of the drawer's
     light-on-dark link colour — `.nx-nav.open > a` has identical specificity
     to the pill's own rule and, being later in this file, would otherwise win
     and paint ivory text on lime (contrast ~1.4:1, unreadable). */
  html body .nx-nav.open > a.nx-nav-sell{color:var(--nxp-ink-900) !important}
  html body .nx-nav.open > a.nx-nav-sell .nx-nav-sell-dot{background:var(--nxp-ink-900) !important}
}

/* In the mobile drawer the nav is vertical — the CTA becomes a full width,
   unmissable block, which is where most first-time sellers convert. */
@media (max-width:1129px){
  html body .nx-header a.nx-nav-sell--drawer{
    width:100%;justify-content:center;
    height:46px;margin:10px 0 4px;font-size:13px;letter-spacing:.08em;
  }
}

/* ---------------------------------------------------------------------------
   8c · SIGN IN WITH APPLE (V2026.153)
   Apple's Human Interface Guidelines are prescriptive about this control, and
   getting it wrong is a common App-Review / brand-compliance failure:
     · the button must be its own full-width control, not a third-width chip
       sitting anonymously between Google and GitHub;
     · the label must be exactly "Sign in with Apple" / "Sign up with Apple",
       matching the action, in the system font;
     · the Apple logo must keep its clear space and never be recoloured;
     · minimum height 44px, and it must not be visually subordinate to the
       other providers.
   Black is the correct variant on this cream canvas.
   --------------------------------------------------------------------------- */
.nx-apple-btn{
  display:flex;align-items:center;justify-content:center;gap:8px;
  width:100%;height:46px;margin:0 0 10px;
  background:#000;color:#fff;
  border:1px solid #000;border-radius:11px;
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Arial,sans-serif;
  font-size:16px;font-weight:500;letter-spacing:-.01em;
  cursor:pointer;
  transition:background var(--nxp-dur-fast) var(--nxp-ease-out),
             transform var(--nxp-dur-fast) var(--nxp-ease-out),
             box-shadow var(--nxp-dur-base) var(--nxp-ease-out);
}
.nx-apple-btn:hover{background:#161617;border-color:#161617;transform:translateY(-1px);box-shadow:var(--nx-elev-2)}
.nx-apple-btn:active{transform:translateY(0) scale(.99)}
.nx-apple-btn:focus-visible{box-shadow:var(--nx-focus-ring)}
.nx-apple-btn[disabled]{opacity:.55;cursor:progress}
/* The logo is optically ~1px high relative to cap height; nudge it to sit on
   the text baseline. Never recolour it — currentColor keeps it pure white. */
.nx-apple-glyph{flex:0 0 auto;margin-top:-2px}
.nx-apple-label{white-space:nowrap}

/* Divider so the Apple button reads as a peer of the provider row, not a
   header for it. */
.nx-apple-btn + .nx-oauth-row{margin-top:2px}

/* The provider row is declared repeat(3,1fr) in style-extra.css (445 and 863)
   from when Apple was a third chip. Apple now has its own full-width button,
   so two buttons were sitting in a three-column grid — leaving an empty third
   column and making the pair look shoved to the left. Size the columns to the
   number of buttons actually present instead of hard-coding three. */
html body .nx-oauth-row{
  grid-template-columns:repeat(auto-fit, minmax(0, 1fr));
  align-items:stretch;
}
html body .nx-oauth-btn{
  display:flex;
  align-items:center;
  justify-content:center;   /* icon + label centred within each button */
  gap:8px;
  text-align:center;
}

@media (max-width:480px){
  .nx-apple-btn{height:44px;font-size:15px}
}

/* ---------------------------------------------------------------------------
   8d · ADMIN CONSOLE (V2026.153)
   Components for the geography / acquisition views. Kept in the design-system
   layer (not inline in admin.html) so the admin inherits the same tokens,
   spacing and motion as the public site instead of drifting into its own look.
   --------------------------------------------------------------------------- */
.nx-adm-2col{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:var(--nxp-space-4);align-items:start;
}
.nx-adm-card-head{
  display:flex;align-items:center;justify-content:space-between;gap:var(--nxp-space-3);
  padding:14px 16px;border-bottom:1px solid var(--nx-border-soft);
}
.nx-adm-card-head h3{margin:0;font-size:15px;letter-spacing:-.02em}
.nx-adm-sub{
  font:600 10px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--nx-text-muted);margin-left:6px;
}
.nx-adm-note{color:var(--nx-text-muted);font-style:italic}
.nx-adm-btn.sm{height:28px;padding:0 10px;font-size:10.5px}

/* Numeric columns are right-aligned and tabular so digits line up — the
   single biggest readability win in any data table. */
.nx-adm-tbl th.num,.nx-adm-tbl td.num{text-align:right;font-variant-numeric:tabular-nums}
.nx-adm-tbl tbody tr{transition:background var(--nxp-dur-fast) var(--nxp-ease-out)}
.nx-adm-tbl tbody tr:hover{background:rgba(5,5,5,.035)}

/* Inline share bar. No chart library — one div, reads instantly.
   The label sits BESIDE the bar (flex sibling) rather than absolutely
   positioned over it, because inside a <td> an absolute label is clipped by
   the cell and the percentage silently disappears. */
.nx-adm-bar-wrap{display:flex;align-items:center;gap:10px;min-width:120px}
.nx-adm-bar{
  position:relative;flex:1 1 auto;
  height:8px;min-width:60px;
  background:rgba(5,5,5,.08);border-radius:var(--nx-r-pill);
  overflow:hidden;
}
.nx-adm-bar > span{
  display:block;height:100%;
  background:var(--nx-accent);border-radius:var(--nx-r-pill);
  transition:width var(--nxp-dur-slow) var(--nxp-ease-out);
}
.nx-adm-bar-wrap > em{
  flex:0 0 auto;min-width:42px;text-align:right;
  font:700 10.5px/1 var(--font-mono);font-style:normal;color:var(--nx-text-secondary);
}

/* Funnel */
.nx-adm-funnel{display:grid;gap:14px;padding:18px 16px}
.nx-adm-funnel-step{
  display:grid;grid-template-columns:130px 1fr 72px 128px;
  align-items:center;gap:12px;
}
.nx-adm-funnel-step .lbl{
  font:700 11px/1 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;
}
.nx-adm-funnel-step .nx-adm-bar{height:12px}
.nx-adm-funnel-step b{font-size:16px;font-variant-numeric:tabular-nums;text-align:right}
.nx-adm-funnel-step em{
  font:600 10.5px/1 var(--font-mono);font-style:normal;color:var(--nx-text-muted);
}
@media (max-width:720px){
  .nx-adm-funnel-step{grid-template-columns:1fr 64px;grid-template-areas:"lbl val" "bar bar" "conv conv"}
  .nx-adm-funnel-step .lbl{grid-area:lbl}
  .nx-adm-funnel-step .nx-adm-bar{grid-area:bar}
  .nx-adm-funnel-step b{grid-area:val}
  .nx-adm-funnel-step em{grid-area:conv}
}

.pill-lime{background:var(--nx-accent);color:var(--nxp-ink-900);font-weight:800}

/* ============================================================================
   8e · MINIMAL DISCIPLINE PASS (V2026.153)
   ============================================================================
   Brief: "make it minimal and perfect like Fiverr — professional, understandable,
   fix the font gaps and typography."

   The identity stays (cream / ink / lime). What changes is RESTRAINT. Three
   things were making the site read as busy rather than premium:

     1. BADGE INFLATION — 11 lime NEW/LIVE/HOT/FREE chips in the nav dropdowns,
        one on nearly every item. When everything is urgent, nothing is. Those
        are removed in shell.js; only the single Studio "AI" mark survives, so
        the nav has exactly ONE accent.
     2. SHOUTING TYPE — nav and countless labels were uppercase + letterspaced.
        Fiverr's nav is sentence case; it reads as confident rather than loud.
     3. UNEVEN RHYTHM — spacing was set ad-hoc per section, so the vertical
        gaps between blocks did not relate to each other.
   ============================================================================ */

/* ---- Nav: sentence case, comfortable spacing ------------------------------ */
html body .nx-header .nx-nav > a,
html body .nx-header .nx-nav .nx-nav-trigger{
  text-transform:none;
  letter-spacing:-.006em;
  font-size:14.5px;
  font-weight:500;
}
/* Uppercase mono is right for eyebrows and data labels — it is NOT right for
   primary navigation, which people read as words, not as labels. */
@media (min-width:1130px){
  html body .nx-header .nx-nav{gap:2px}
  html body .nx-header .nx-nav > a,
  html body .nx-header .nx-nav .nx-nav-trigger{padding:8px 12px}
}

/* ---- Dropdowns: give them room to breathe --------------------------------
   Scoped to the DESKTOP nav only. Below 1130px the same elements are rendered
   inline inside the drawer, where a 328px min-width, a floating-card shadow
   and a rounded border make them look like stray boxes rather than list rows. */
@media (min-width:1130px){
  html body .nx-nav-menu{
    min-width:328px;
    padding:10px;
    border-radius:var(--nx-r-md);
    box-shadow:var(--nx-elev-4);
  }
}
html body .nx-nav .nx-nav-menu a{
  padding:11px 14px !important;
  border-radius:var(--nx-r-sm);
  letter-spacing:-.008em;
}
html body .nx-nav .nx-nav-menu a b{
  font-size:14.5px;
  font-weight:600;
  letter-spacing:-.012em;
}
html body .nx-nav .nx-nav-menu a small{
  display:block;
  margin-top:3px;
  font-size:12.5px;
  line-height:1.45;
  text-transform:none;      /* several were uppercase mono — unreadable at 12px */
  letter-spacing:0;
  font-family:var(--font-sans);
}

/* ---- Vertical rhythm ------------------------------------------------------
   One scale, derived from the spacing primitives, instead of per-section
   guesses. Fluid so phones don't get 108px of dead air. */
.nx-section{padding:clamp(56px, 7vw, 112px) 0}
.nx-section + .nx-section{padding-top:clamp(48px, 6vw, 96px)}
.nx-section-head{margin-bottom:clamp(28px, 3.4vw, 52px)}

/* ---- Headings: confident, not heavy --------------------------------------
   Display weights above ~800 at large sizes read as shouty and close up the
   counters. 700 with tight tracking is the premium-editorial setting. */
h1,h2{font-weight:700}
h3,h4{font-weight:600}
.nx-section-head h2{margin:0 0 8px}
.nx-section-head p{
  color:var(--nx-text-secondary);
  font-size:var(--nx-fs-body-lg);
  line-height:var(--nx-lh-relaxed);
  max-width:62ch;
  margin:0;
}

/* ---- Body copy: the single biggest readability win -----------------------
   Base body was 15.5px/1.5 with default tracking. 16px at 1.6 with a slight
   negative track is the setting Fiverr, Stripe and Linear all converge on. */
body{font-size:16px;line-height:1.6}
p{line-height:var(--nx-lh-relaxed)}
p + p{margin-top:.9em}

/* ---- Eyebrows: keep the mono, drop the shout ----------------------------- */
.nx-eyebrow{font-size:10.5px;letter-spacing:.12em;opacity:.72}

/* ---- Restraint on accents ------------------------------------------------
   Lime is a POINTER, not a decoration. It belongs on the primary action and
   the live-status dots — not on every chip, tag and underline at once. */
.nx-tag-btn,.nx-chip,.nx-trend-chip{
  text-transform:none;
  letter-spacing:-.004em;
  font-weight:500;
}

/* ---- Badge triage --------------------------------------------------------
   "NEW" and "HOT" are novelty signals: they decay to noise within weeks and
   say nothing about the thing they label. "FREE" and "LIVE" are FUNCTIONAL —
   they change whether a user clicks. So the novelty ones go, the informative
   ones stay. (Applies to the JS-injected category strip, which is why this is
   CSS rather than a markup edit.) */
.nx-trend-mega-badge.b-new,
.nx-trend-mega-badge.b-hot,
.nx-trend-chip .b-new,
.nx-trend-chip .b-hot{display:none !important}

/* ---- Focus the announcement bar -----------------------------------------
   It sits above the logo, so it is the first thing read on every page. Keep
   it quiet: one line, no competing weights. */
.nxa-announce{font-size:13px;letter-spacing:-.004em}
.nxa-announce-tag{letter-spacing:.1em;font-size:9.5px}

/* ---------------------------------------------------------------------------
   8f · TOUCH & SMALL-SCREEN POLISH (V2026.155)
   --------------------------------------------------------------------------- */
@media (max-width:1129px){
  /* WCAG 2.2 "Target Size (Minimum)" wants 24×24 CSS px. Rather than resizing
     the visible control (which would change the design), expand the hit area
     with a pseudo-element — the link looks identical, but the tappable region
     is finger-sized. */
  .nx-footer a,
  .nx-card-tags a,
  .nx-trend-chip,
  .nxfs-btn{position:relative}
  .nx-footer a::after,
  .nx-card-tags a::after{
    content:"";position:absolute;
    left:0;right:0;top:50%;
    height:44px;transform:translateY(-50%);
    /* Purely a hit area — never paints, never blocks siblings visually. */
  }

  /* Decorative oversized watermarks (the giant "Questions & Answers" behind the
     FAQ) are wider than a phone and were being clipped mid-word. Scale them to
     the viewport instead. */
  .nxv-faq-bg{
    max-width:100%;
    font-size:clamp(38px, 13vw, 132px) !important;
    overflow:hidden;
    word-break:break-word;
  }

  /* Anything that must scroll sideways does it inside its own box, never by
     moving the page. */
  .nx-cmp-table,
  .nx-adm-tbl{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}

  /* iOS zooms the page when a focused input is under 16px. */
  input,select,textarea{font-size:max(16px, 1rem)}
}

/* Respect the notch / home indicator on the fixed bottom nav. */
@media (max-width:900px){
  .nx-mobile-bottom-nav{padding-bottom:env(safe-area-inset-bottom, 0px)}
}

/* NO SCROLL LOCK ON THE PAGE — deliberately.
   Two attempts at one both broke something visible:
     · body{position:fixed}  re-promoted the backdrop-filtered header and the
       fixed .nx-mesh background, so the whole page painted TWICE, offset
       sideways. That is the "double menu" bug.
     · html{overflow:hidden} silently kills position:sticky, so the sticky
       header (and the drawer anchored to it) jumped to its static position
       and flew off-screen once the page had been scrolled.
   Neither is necessary: the drawer covers the whole viewport below the header
   and already carries overscroll-behavior:contain, which is what actually
   stops scroll-chaining when you drag inside it. The class is kept purely as
   a styling/state hook. */
body.nx-drawer-open{background:var(--nx-surface)}

/* ---------------------------------------------------------------------------
   8g · HERO VIDEO — FULL BLEED (V2026.155)
   The background videos were absolutely positioned with inset:0 and an
   explicit width but height:auto, so the browser sized them from the clip's
   own 16:9 ratio. On a 390×794 phone hero that meant a 390×219 strip of video
   with 575px of empty background beneath it — the video only covered the top
   quarter of the hero. object-fit:cover was already set and doing nothing,
   because the box itself was the wrong size.

   Giving the element a real height lets cover do its job: fill the hero,
   crop the overflow, never distort.
   --------------------------------------------------------------------------- */
.nx-hero-video,
.nxv-hv,
.nx-bh-video,
.nx-mb-video,
.nxa-hero-video,
.nx-hero > video,
.nx-doc-hero > video{
  position:absolute;
  inset:0;
  width:100% !important;
  height:100% !important;
  min-width:100%;
  min-height:100%;
  object-fit:cover !important;
  object-position:center center;
}
/* The poster image behind a not-yet-playing video must match, or you get a
   visible jump the moment the clip starts. */
.nx-hero-video[poster],
.nxv-hv[poster],
.nx-bh-video[poster],
.nx-mb-video[poster]{background-size:cover;background-position:center}

/* On short phone heroes, bias the crop upward so faces / product stay in frame
   rather than being cut off at the top. */
@media (max-width:640px){
  .nx-hero-video,.nxv-hv,.nx-bh-video,.nx-mb-video,.nxa-hero-video{
    object-position:center 35%;
  }
}

/* ---- Tools directory: secondary "Try demo" button ------------------------- */
.nx-tool-foot .nx-tool-demo{
  background:transparent;
  border:1px solid var(--nx-border-strong);
  color:var(--nx-text);
  padding:0 12px;height:36px;
  border-radius:var(--nx-r-xs);
  font:700 11.5px var(--font-mono);
  letter-spacing:.05em;text-transform:uppercase;
  cursor:pointer;white-space:nowrap;
  transition:background var(--nxp-dur-fast) var(--nxp-ease-out),
             color var(--nxp-dur-fast) var(--nxp-ease-out);
}
.nx-tool-foot .nx-tool-demo:hover{background:var(--nxp-ink-900);color:var(--nx-accent);border-color:var(--nxp-ink-900)}
@media (max-width:520px){
  .nx-tool-foot{flex-wrap:wrap;gap:10px}
  .nx-tool-foot .nx-tool-demo{flex:1 1 auto}
}

/* ---------------------------------------------------------------------------
   8h · APP STORE / GOOGLE PLAY BADGES (V2026.163)
   Official-proportion lockups: dark tile, thin light hairline, small caption
   over a larger wordmark. Sizing follows Apple's guidance that the badge is
   never shown smaller than 40px tall.
   --------------------------------------------------------------------------- */
/* Stacked, directly under the newsletter "Join" field in the first footer
   column. That column is narrow, so the two badges sit one above the other
   and match the field's width rather than spilling across the footer. */
.nx-appbadges{
  display:flex;flex-direction:column;align-items:flex-start;gap:10px;
  margin:18px 0 0;
  max-width:320px;
}
.nx-appbadges-lbl{
  font:700 10.5px/1 var(--font-mono);
  letter-spacing:.14em;text-transform:uppercase;
  color:rgba(244,244,232,.5);
}
.nx-appbadges-row{
  display:flex;flex-direction:column;   /* stacked, not side by side */
  gap:10px;
  width:100%;
}
.nx-appbadges-row > .nx-appbadge{width:100%}

.nx-appbadge{
  position:relative;
  display:inline-flex;align-items:center;gap:10px;
  min-height:46px;padding:0 16px;
  background:#000;
  border:1px solid rgba(255,255,255,.30);
  border-radius:9px;
  color:#fff;text-decoration:none;cursor:pointer;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  transition:border-color var(--nxp-dur-fast) var(--nxp-ease-out),
             transform var(--nxp-dur-fast) var(--nxp-ease-out),
             box-shadow var(--nxp-dur-base) var(--nxp-ease-out);
}
.nx-appbadge:hover{border-color:rgba(255,255,255,.75);transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,.45)}
.nx-appbadge:active{transform:translateY(0) scale(.985)}
.nx-appbadge:focus-visible{box-shadow:var(--nx-focus-ring)}

.nx-appbadge-txt{display:flex;flex-direction:column;justify-content:center;line-height:1.05;text-align:left}
.nx-appbadge-txt small{font-size:10.5px;font-weight:400;letter-spacing:.01em;opacity:.92}
.nx-appbadge-txt b{font-size:17px;font-weight:600;letter-spacing:-.02em;margin-top:1px}

/* Not-yet-published state — visibly different so it never reads as a live
   download link. */
.nx-appbadge.is-soon{opacity:.72}
.nx-appbadge.is-soon:hover{opacity:1}
.nx-appbadge-soon{
  position:absolute;top:-7px;right:-7px;
  font:800 8.5px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;
  font-style:normal;
  background:var(--nx-accent);color:var(--nxp-ink-900);
  padding:3px 5px;border-radius:var(--nx-r-xs);
}

/* The footer is dark, but these badges also appear on cream surfaces on some
   pages — keep the tile black either way, that is the official treatment. */
@media (max-width:480px){
  .nx-appbadges{max-width:none}
  .nx-appbadge{justify-content:center}
}

/* ---------------------------------------------------------------------------
   9 · PERFORMANCE
   content-visibility is a big Core-Web-Vitals win on long pages, but applied
   blanket it can fight scroll-reveal and make the scrollbar jump. It is
   therefore OPT-IN via .nx-defer, applied per-section after measuring —
   never automatically across 235 pages.
   --------------------------------------------------------------------------- */
.nx-defer{
  content-visibility:auto;
  contain-intrinsic-size:auto 640px;
}
/* Images: never let a missing width/height cause layout shift. */
img{max-width:100%;height:auto}
img[loading="lazy"]{background:var(--nx-surface-sunken)}

/* ---------------------------------------------------------------------------
   10 · PRINT
   Invoices, certificates and blueprints get printed. Previously the dark bands
   burned a whole ink cartridge.
   --------------------------------------------------------------------------- */
@media print{
  .nx-header,.nxa-announce,.nx-footer,.nx-menu,.nx-mobile-nav,
  .nx-actions,video,.nx-hero-video,[data-nx-noprint]{display:none !important}
  *{background:#fff !important;color:#000 !important;box-shadow:none !important}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:10px;color:#555}
  .nx-container{max-width:none;padding:0}
}
