/* ══════════════════════════════════════════════════════════════════════
   Nebryx — SITE.CSS
   The marketing surface: landing + the two entrances (/employer, /candidate).

   Layered ON TOP of app.css, which owns the product UI. This file never
   restyles a product component; it adds the marketing vocabulary and
   scopes all of it under `body.nx` so the two can never collide.

   ── The one idea worth knowing ──────────────────────────────────────
   Everything audience-specific reads from ONE variable, --acc. Set it
   on <body data-audience>, override it on a section, and the whole
   subtree — buttons, icons, rules, glows, focus rings — retunes. No
   `.is-employer` variants of anything, anywhere.

   Two temperatures:
     employer  → cool indigo   (authority, procurement, budget)
     candidate → warm teal     (the existing brand accent, human side)

   ── Contents ────────────────────────────────────────────────────────
     1. Tokens + audience accents + dark mode
     2. Motion primitives (reveal, stagger) — all reduced-motion gated
     3. Icons
     4. Nav: bar, mega-menu, split login, mobile drawer
     5. Audience toggle
     6. Hero
     7. Marquee
     8. Steps + pinned scrub media
     9. Showcase
    10. Cards / resources
    11. CTA band
    12. Footer
    13. Responsive
   ══════════════════════════════════════════════════════════════════════ */

/* ══ 1. TOKENS ══════════════════════════════════════════════════════ */

/* Nav height lives on :root, not on body.nx, because <html> needs it too:
   scroll-padding-top is what stops an in-page anchor from landing behind
   the fixed bar, and it can only be set on the scroll container. A custom
   property declared on <body> cannot be read by its own parent. */
:root{
  --nav:96px;              /* nav height over the hero */
  --nav-sm:80px;           /* …after it shrinks */
}
/* Marketing pages only — app.css keeps its own --nav-h for the product
   shell, whose bar is a different height. */
html:has(body.nx){scroll-padding-top:calc(var(--nav-sm) + 18px);}

body.nx{
  /* neutral base — deliberately cooler than app.css so accents sing */
  --ink:#0b1120;
  --ink-2:#1e293b;
  --mu:#5a6779;
  --dim:#94a3b8;
  --paper:#ffffff;
  --paper-2:#f7f9fb;
  --paper-3:#eef2f7;
  --edge:#e3e9f0;          /* 1px hairline */
  --edge-soft:#eef2f7;

  /* the two temperatures.
     The -lt pair is the accent as it must appear ON a dark surface: the
     base indigo sits at ~3:1 against the solid nav and reads as muddy, so
     anything that lands on dark reaches for -lt instead of -2. */
  --employer:#4f46e5;      --employer-2:#6366f1;  --employer-soft:#eef0fe;  --employer-lt:#a5b4fc;
  --candidate:#0d9488;     --candidate-2:#14b8a6; --candidate-soft:#e6f7f4; --candidate-lt:#5eead4;

  /* active accent — overridden per audience + per section */
  --acc:var(--employer);
  --acc-2:var(--employer-2);
  --acc-soft:var(--employer-soft);
  --acc-lt:var(--employer-lt);

  /* the solid nav's own ground — a true neutral black. Not --ink (#0b1120),
     which is a navy: against the white page it reads blue, and next to the
     mint logo it pushes the whole bar cold. */
  --nav-ink:#121212;

  /* ── brand green ──────────────────────────────────────────────────
     One action colour for the whole site: the logo's accent letter and
     every filled button. It sits OUTSIDE the audience system on purpose
     — the two path temperatures still tint their own sections, but the
     thing you click is the same colour on every page, which is what
     makes a brand colour a brand colour.

     It ships as a PAIR because a mint this bright cannot do both jobs.
     --brand is a fill: gorgeous behind dark text, and about 1.7:1 as
     text on white, i.e. unreadable. --brand-dp is the same hue pushed
     down until it clears 3:1 on paper, so anything drawn AS the colour
     (the logo's x on a light bar) uses that instead. Reaching for
     --brand there would leave the letter a pale smear on white. */
  --brand:#2fe39b;         /* fills, and anything sitting on dark */
  --brand-2:#22cf8b;       /* the fill, pressed */
  --brand-dp:#0b9a68;      /* the green made legible ON light */
  --brand-ink:#04231a;     /* the label ON a brand fill — never #fff */
  --brand-soft:#e7fbf2;

  /* The wordmark at rest. A slate charcoal, not --ink (#0b1120): at logo
     weight the near-black navy reads heavier and colder than the mark
     wants, and the reference render is plainly a soft dark grey. */
  --mark:#363c47;

  --r-xs:8px; --r-sm:12px; --r:16px; --r-lg:22px; --r-xl:30px;

  /* soft layered shadows — two-part: contact + ambient */
  --sh-1:0 1px 2px rgba(11,17,32,.04), 0 4px 12px rgba(11,17,32,.04);
  --sh-2:0 2px 4px rgba(11,17,32,.05), 0 12px 28px rgba(11,17,32,.07);
  --sh-3:0 4px 8px rgba(11,17,32,.06), 0 24px 56px rgba(11,17,32,.10);

  /* --nav / --nav-sm now live on :root (below) so that html can read them
     for scroll-padding — a custom property set on <body> is invisible to
     its own parent. body.nx inherits them either way. */
  --gut:clamp(20px,4.2vw,60px);
  --max:1280px;

  --ease:cubic-bezier(.16,.84,.28,1);

  /* Type and control radius now live in app.css so the product pages
     share them — a different typeface either side of the sign-in page
     reads as two different companies. Nothing to override here. */

  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-optical-sizing:auto;
}

body.nx[data-audience="employer"] { --acc:var(--employer);  --acc-2:var(--employer-2);  --acc-soft:var(--employer-soft);  --acc-lt:var(--employer-lt); }
body.nx[data-audience="candidate"]{ --acc:var(--candidate); --acc-2:var(--candidate-2); --acc-soft:var(--candidate-soft); --acc-lt:var(--candidate-lt); }

/* Section-level accent overrides — a client section stays cool even
   while the candidate path is active, so the mirrored pair below the
   fold always reads as two distinct territories. */
body.nx .acc-employer { --acc:var(--employer);  --acc-2:var(--employer-2);  --acc-soft:var(--employer-soft);  --acc-lt:var(--employer-lt); }
body.nx .acc-candidate{ --acc:var(--candidate); --acc-2:var(--candidate-2); --acc-soft:var(--candidate-soft); --acc-lt:var(--candidate-lt); }

/* ── dark ──
   Opt-in only. Light is the default everywhere, so this no longer keys
   off the OS preference — it needs an explicit html[data-theme="dark"],
   which only the HR dashboard sets, on itself. Keeping the palette costs
   nothing and means a future theme switch is one attribute, not a
   re-derivation. */
:root[data-theme="dark"] body.nx{
  color-scheme:dark;
  --ink:#f1f5f9; --ink-2:#cbd5e1; --mu:#94a3b8; --dim:#64748b;
  --paper:#0b1120; --paper-2:#111827; --paper-3:#182236;
  --edge:#1e293b; --edge-soft:#172033;
  --employer-soft:#1b1f43; --candidate-soft:#0d2b2a;
  --employer:#818cf8; --employer-2:#a5b4fc;
  --candidate:#2dd4bf; --candidate-2:#5eead4;
  --sh-1:0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
  --sh-2:0 2px 4px rgba(0,0,0,.45),0 12px 28px rgba(0,0,0,.38);
  --sh-3:0 4px 8px rgba(0,0,0,.5), 0 24px 56px rgba(0,0,0,.45);
}

/* Selection stays the classic browser blue rather than the section accent.
   Tying it to --acc meant the highlight changed colour halfway down a dark
   page, and on the mint sections it read as a marker pen through the text
   instead of as a selection. Blue is the one highlight everybody parses
   without thinking. */
body.nx ::selection{background:#3297fd;color:#fff;}
body.nx :focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:4px;}
/* [hidden] is a UA rule (display:none) and loses to any class that sets
   display — .btn is inline-flex, so a hidden button would still show.
   State beats layout: make the attribute authoritative. */
body.nx [hidden]{display:none !important;}

/* type
   Space Grotesk is drawn with its display spacing already built in —
   hackajob sets letter-spacing:normal even at 80px. Piling negative
   tracking on top (as a Helvetica-ish face needs) closes the counters
   and kills the thing you picked it for, so tracking stays at zero and
   only the very largest size gets a hair of tightening. */
body.nx h1,body.nx h2,body.nx h3,body.nx h4{
  color:var(--ink);letter-spacing:normal;line-height:1.1;
  font-weight:700;text-wrap:balance;
}
body.nx h1{font-size:clamp(38px,6.4vw,76px);letter-spacing:-.01em;line-height:1.08;}
body.nx h2{font-size:clamp(28px,4.2vw,50px);}
body.nx h3{font-size:clamp(19px,2.2vw,26px);}
body.nx h4{font-size:17px;font-weight:600;}
body.nx p{text-wrap:pretty;}
body.nx .lead{font-size:clamp(16px,1.5vw,19px);line-height:1.62;color:var(--mu);max-width:60ch;}
body.nx .sm{font-size:14.5px;line-height:1.6;color:var(--mu);}
body.nx .eyebrow{
  display:inline-flex;align-items:center;gap:9px;
  font-size:11.5px;font-weight:700;letter-spacing:1.6px;
  text-transform:uppercase;color:var(--acc);
}
body.nx .eyebrow::before{content:'';width:20px;height:1.5px;background:currentColor;border-radius:2px;}

body.nx .wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);}
body.nx .sec{padding:clamp(64px,9vw,124px) 0;position:relative;}
body.nx .sec-tint{background:var(--paper-2);}
body.nx .sec-head{max-width:680px;margin-bottom:clamp(40px,6vw,68px);}
body.nx .sec-head.center{margin-inline:auto;text-align:center;}
/* .lead carries its own 60ch measure, which without this sits flush left
   inside the centred head — centred text above a left-anchored paragraph.
   Saves an inline margin-inline:auto at every call site. */
body.nx .sec-head.center .lead{margin-inline:auto;}
body.nx .sec-head h2{margin:14px 0 16px;}
body.nx .rule{height:1px;background:var(--edge);border:0;}

/* buttons — pill, restrained */
body.nx .btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:13px 24px;border-radius:999px;cursor:pointer;
  font-size:15px;font-weight:600;letter-spacing:normal;white-space:nowrap;
  border:1.5px solid var(--edge);background:var(--paper);color:var(--ink);
  transition:background .18s var(--ease),border-color .18s var(--ease),
             color .18s var(--ease),box-shadow .22s var(--ease),transform .18s var(--ease);
}
/* Secondary buttons fill dark on hover rather than tinting grey. Next to a
   green primary the pair then reads as two solid buttons, which is what
   the reference does — a barely-shifted grey outline looks like nothing
   happened. Placed BEFORE the variants below so each of them (primary,
   ghost, pass) still overrides it at equal specificity by source order. */
body.nx .btn:hover{background:var(--ink);border-color:var(--ink);color:var(--paper);}
/* Dark label, not white. White on this mint is ~1.7:1 and illegible; the
   near-black reads at well over 10:1 and is what the reference does too. */
body.nx .btn-primary{background:var(--brand);border-color:var(--brand);color:var(--brand-ink);}
body.nx .btn-primary:hover{
  background:var(--brand-2);border-color:var(--brand-2);color:var(--brand-ink);
  box-shadow:0 10px 26px color-mix(in srgb,var(--brand) 40%,transparent);
  transform:translateY(-1px);
}
body.nx .btn-ghost{background:transparent;border-color:transparent;color:var(--mu);}
/* border-color is restated for the same reason as the label above: .btn:hover
   now darkens the border, and a ghost button must stay borderless in both
   states or the nav's "Log in" sprouts an outline on hover. */
body.nx .btn-ghost:hover{background:var(--paper-2);border-color:transparent;color:var(--ink);}
body.nx .btn-sm{padding:9px 17px;font-size:14px;}
body.nx .btn .ico{width:18px;height:18px;}

/* ══ 2. MOTION PRIMITIVES ═══════════════════════════════════════════ */
/* Default state is VISIBLE. JS adds .motion to <html> only when motion
   is allowed, and only then does anything start hidden — so no-JS and
   reduced-motion users can never end up staring at a blank page. */
html.motion body.nx [data-reveal]{
  opacity:0;transform:translateY(24px);
  transition:opacity .78s var(--ease) var(--d,0ms),
             transform .78s var(--ease) var(--d,0ms);
  will-change:opacity,transform;
}
html.motion body.nx [data-reveal].in{opacity:1;transform:none;}

/* hero headline: per-word rise */
html.motion body.nx .word{
  display:inline-block;opacity:0;transform:translateY(.5em) rotate(1.2deg);
  transition:opacity .82s var(--ease) var(--d,0ms),transform .82s var(--ease) var(--d,0ms);
}
html.motion body.nx .lit .word{opacity:1;transform:none;}

@media (prefers-reduced-motion:reduce){
  body.nx *,body.nx *::before,body.nx *::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important;
  }
}

/* ══ 3. ICONS ═══════════════════════════════════════════════════════ */
body.nx .ico{
  width:24px;height:24px;flex:none;display:block;
  color:inherit;vector-effect:non-scaling-stroke;
}
body.nx .ico-sm{width:18px;height:18px;}
body.nx .ico-lg{width:32px;height:32px;}
/* the standard icon plate — square, soft, accent-tinted */
body.nx .ico-plate{
  width:48px;height:48px;border-radius:14px;flex:none;
  display:grid;place-items:center;
  background:var(--acc-soft);color:var(--acc);
  border:1px solid color-mix(in srgb,var(--acc) 16%,transparent);
}
body.nx .ico-plate-sm{width:38px;height:38px;border-radius:11px;}
body.nx .ico-plate-lg{width:60px;height:60px;border-radius:18px;}
body.nx .ico-plate-lg .ico{width:28px;height:28px;}
/* Outlined variant: a hairline tile on the card's own ground, with only
   the glyph carrying the accent. The filled plate is right when the tile
   is the focal point; in a three-card row it is not, and three tinted
   blocks compete with the headings for the first look. */
body.nx .plate-quiet{
  background:var(--paper);
  border-color:var(--edge);
  color:var(--acc);
}

/* ══ 4. NAV ═════════════════════════════════════════════════════════ */
/* Two states, and the swap between them is done with FOUR local tokens
   rather than a parallel set of `.is-solid .thing` rules. Every control in
   the bar already reads --nav-fg / --nav-mark,
   so flipping the bar's ground is a four-line override and nothing can be
   left behind in the old colour when a control is added later.

   The tokens stop at the bar. The dropdown panels are children of .nav but
   deliberately keep the page palette — a dark bar with a light sheet under
   it is the reference's behaviour, and re-tinting --ink here would drag
   every panel link dark along with it. */
body.nx .nav{
  --nav-fg:var(--ink-2);
  --nav-mark:var(--mark);         /* the mark is ONE colour now — see .wordmark */

  position:fixed;inset:0 0 auto 0;z-index:200;height:var(--nav);
  display:flex;align-items:center;
  background:transparent;border-bottom:1px solid transparent;
  transition:height .32s var(--ease),background .32s var(--ease),
             border-color .32s var(--ease),box-shadow .32s var(--ease),
             backdrop-filter .32s var(--ease);
}
body.nx .nav.is-solid{
  --nav-fg:#e8edf6;
  --nav-mark:var(--brand);        /* on the dark bar the whole mark goes mint */

  height:var(--nav-sm);
  background:var(--nav-ink);
  border-bottom-color:rgba(255,255,255,.09);
  box-shadow:0 10px 34px rgba(11,17,32,.30);
}
body.nx .nav-in{
  width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);
  display:flex;align-items:center;gap:10px;
}
/* Everything but the wordmark rides to the right edge. Done with `order`
   so the SOURCE keeps reading wordmark → menus → login → CTA, which is the
   order a keyboard and a screen reader want; only the spacer moves. */
body.nx .nav-spacer{order:1;}
body.nx .mega{order:2;}
body.nx .nav-right{order:3;}
body.nx .burger{order:4;}
/* Wordmark. The supplied artwork, not a drawing of it — two files, one per
   state, cropped to their ink so they share an aspect ratio and overlay
   exactly (2.980 vs 2.972, a 0.3% difference nobody can see).

   Both are stacked in the SAME grid cell rather than one being display:none.
   That is what allows a cross-fade between the two states, and it also means
   the box never collapses mid-transition — swapping display would snap the
   nav's width as the mark changed. Sized by HEIGHT; width follows. */
body.nx .wordmark{
  display:inline-grid;align-items:center;margin-right:8px;
}
body.nx .wordmark img{
  grid-area:1/1;
  display:block;height:58px;width:auto;
  transition:opacity .32s var(--ease),height .32s var(--ease);
}
body.nx .wordmark .wm-alt{opacity:0;}          /* mint: hidden over the hero */
/* The mark shrinks with the bar, so the two scale together instead of the
   logo suddenly looking oversized in the shorter bar. */
body.nx .nav.is-solid .wordmark img{height:48px;}
body.nx .nav.is-solid .wordmark .wm-rest{opacity:0;}
body.nx .nav.is-solid .wordmark .wm-alt{opacity:1;}

/* The footer mark sits on white, so it is the dark file only. */
body.nx .foot-mark img{display:block;height:68px;width:auto;}

/* ── mega menu ────────────────────────────────────────────────────
   A wide sheet that drops flush from the bar and runs to the right
   edge of the window, rather than a small box tethered under its
   trigger. Plain text links, generously spaced, a hairline, then one
   CTA row — the panel sells by being easy to read, not by decorating
   every row with an icon.

   Anchoring: .mega-item is intentionally STATIC so the absolutely
   positioned panel resolves against .nav (which is fixed, and so is
   its own containing block). That gives `right:0` = window edge and
   `top:100%` = the bar's bottom for free — including while the bar
   animates its height on scroll, with no second rule to keep in sync. */
body.nx .mega{display:flex;align-items:center;gap:10px;}
body.nx .mega-item{position:static;}
body.nx .mega-btn{
  display:inline-flex;align-items:center;gap:6px;padding:9px 14px;
  border:0;background:none;cursor:pointer;border-radius:10px;
  font-size:15px;font-weight:550;color:var(--nav-fg);
  transition:background .16s,color .32s var(--ease);
}
/* No plate. The panel dropping open is already an unmistakable state
   change, and a filled pill behind the trigger draws a hard-edged box
   against the bar that competes with the sheet below it. Colour alone
   carries hover; the chevron rotation carries open. */
body.nx .mega-btn:hover,body.nx .mega-item.open .mega-btn{
  background:transparent;color:var(--nav-mark);
}
body.nx .mega-btn .ico{width:16px;height:16px;transition:transform .24s var(--ease);}
body.nx .mega-item.open .mega-btn .ico{transform:rotate(180deg);}

body.nx .mega-panel{
  position:absolute;top:100%;left:auto;z-index:210;
  /* Stops at the content container's edge rather than bleeding off the
     window — on a wide monitor a full-bleed sheet reads as a broken
     overlay rather than a menu. Falls back to the page gutter once the
     window is narrower than the container. */
  right:max(var(--gut),(100vw - var(--max))/2);
  width:min(1000px,calc(100vw - var(--gut)*2));
  padding:44px clamp(32px,4.4vw,56px) 38px;
  border-radius:0 0 var(--r-lg) var(--r-lg);
  background:var(--paper);
  border:1px solid var(--edge);border-top:0;
  box-shadow:var(--sh-3);
  opacity:0;visibility:hidden;transform:translateY(-10px);
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility 0s .22s;
}
body.nx .mega-item.open .mega-panel{
  opacity:1;visibility:visible;transform:none;transition-delay:0s;
}
/* Both panels occupy the same slot, so fading one out while the other
   fades in renders two sets of links on top of each other. Sliding
   straight from one trigger to the next cuts instead.

   The login dropdown is a [data-menu] too, and the JS closes it through
   the same path — so it needs the same rule, or moving from Log in to a
   mega trigger ghosts the sign-in links over the panel. */
body.nx .mega-item.snap .mega-panel,
body.nx .login-split.snap .login-panel{transition:none;}

/* three explicit columns, so the fill order is ours to choose rather
   than whatever grid auto-flow decides when the counts are uneven */
body.nx .mega-cols{display:grid;grid-template-columns:repeat(3,1fr);gap:0 clamp(24px,3vw,48px);}
/* MEASURED on hackajob's .megamenu__column: the heading is 22/500 at
   line-height 1.2, every link is 18/500 at 1.2, and the rhythm is a flat
   40px — head to first item and between every item after it, carried on
   the list items rather than as a container gap. */
body.nx .mega-col{display:grid;gap:40px;align-content:start;}
body.nx .mega-col a{
  font-size:18px;font-weight:500;line-height:1.2;color:var(--ink);
  justify-self:start;position:relative;transition:color .16s;
}
/* underline grows from the left instead of a background swatch — keeps
   the panel as quiet as the reference */
body.nx .mega-col a::after{
  content:'';position:absolute;left:0;right:0;bottom:-5px;height:1.5px;
  background:currentColor;border-radius:2px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--ease);
}
body.nx .mega-col a:hover{color:var(--acc);}
body.nx .mega-col a:hover::after,
body.nx .mega-col a:focus-visible::after{transform:scaleX(1);}

body.nx .mega-foot{
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  margin-top:clamp(28px,3.4vw,42px);padding-top:clamp(22px,2.6vw,30px);
  border-top:1px solid var(--edge);
}
body.nx .mega-foot b{font-size:clamp(18px,1.7vw,22px);font-weight:500;color:var(--ink);}

body.nx .nav-spacer{flex:1;}
body.nx .nav-right{display:flex;align-items:center;gap:8px;}

/* split login */
/* Log in behaves exactly like the mega menus now: the panel drops flush
   from the BAR rather than floating under its button, the trigger takes
   the same open-state treatment, and the links use the same underline.
   Same anchoring trick — .login-split is static, so the absolutely
   positioned panel resolves against .nav (fixed, therefore its own
   containing block). top:100% is the bar's bottom edge for free, and it
   keeps following while the bar shrinks on scroll. */
body.nx .login-split{position:static;}

/* trigger: matches .mega-btn's hover/open states, chevron included */
body.nx .nav-right .btn-ghost{color:var(--nav-fg);transition:background .16s,color .32s var(--ease);}
body.nx .nav-right .btn-ghost:hover,
body.nx .login-split.open > .btn{background:transparent;color:var(--nav-mark);}
body.nx .login-split > .btn .ico{transition:transform .24s var(--ease);}
body.nx .login-split.open > .btn .ico{transform:rotate(180deg);}

/* Signed in, the whole right-hand side collapses to one word. The pair it
   replaces — a Log in menu and a Create-a-profile pill — are both offers
   to do something already done, and a filled CTA aimed at an existing
   account is the nav shouting at the person who already said yes. Set as
   a plain link at .mega-btn's weight so it reads as the last item in the
   menu row rather than as a button parked beside it. */
body.nx .nav-dash{
  padding:9px 14px;border-radius:10px;
  font-size:15px;font-weight:550;color:var(--nav-fg);
  transition:color .32s var(--ease);
}
body.nx .nav-dash:hover{color:var(--nav-mark);}

body.nx .login-panel{
  position:absolute;top:100%;left:auto;z-index:210;
  right:max(var(--gut),(100vw - var(--max))/2);
  width:238px;padding:14px 18px;text-align:center;
  border-radius:0 0 var(--r-lg) var(--r-lg);
  background:var(--paper);
  border:1px solid var(--edge);border-top:0;
  box-shadow:var(--sh-3);
  opacity:0;visibility:hidden;transform:translateY(-10px);
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility 0s .22s;
}
body.nx .login-split.open .login-panel{
  opacity:1;visibility:visible;transform:none;transition-delay:0s;
}
body.nx .login-panel a{
  display:block;padding:15px 8px;
  font-size:17px;font-weight:500;color:var(--ink);
  position:relative;transition:color .16s;
}
/* the mega panels' grow-from-left underline, not a background swatch */
body.nx .login-panel a::after{
  content:'';position:absolute;left:8px;right:8px;bottom:8px;height:1.5px;
  background:currentColor;border-radius:2px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--ease);
}
body.nx .login-panel a:hover::after,
body.nx .login-panel a:focus-visible::after{transform:scaleX(1);}
body.nx .login-panel a.c-employer:hover{color:var(--employer);}
body.nx .login-panel a.c-candidate:hover{color:var(--candidate);}

/* burger + drawer */
body.nx .burger{
  display:none;width:42px;height:42px;border-radius:12px;place-items:center;
  border:1px solid var(--edge);background:transparent;color:var(--nav-mark);cursor:pointer;
  transition:color .32s var(--ease),border-color .32s var(--ease);
}
body.nx .nav.is-solid .burger{border-color:rgba(255,255,255,.18);}
body.nx .drawer{
  position:fixed;inset:0;z-index:300;display:none;
  background:var(--paper);padding:calc(var(--nav-sm) + 20px) var(--gut) 40px;
  overflow-y:auto;overscroll-behavior:contain;
}
body.nx .drawer.open{display:block;}
body.nx .drawer-close{position:absolute;top:14px;right:var(--gut);
  width:42px;height:42px;border-radius:12px;display:grid;place-items:center;
  border:1px solid var(--edge);background:var(--paper);color:var(--ink);cursor:pointer;}
body.nx .drawer h5{font-size:11px;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--dim);margin:26px 0 8px;}
body.nx .drawer a{display:block;padding:13px 0;font-size:17px;font-weight:550;
  border-bottom:1px solid var(--edge-soft);}
body.nx .drawer .btn{width:100%;margin-top:12px;}
/* Was `body.nx body.nav-locked` — a body inside a body, which never
   matches, so the drawer never actually locked the page behind it. */
body.nx.nav-locked{overflow:hidden;}

/* ══ 5. AUDIENCE TOGGLE ═════════════════════════════════════════════ */
body.nx .toggle{
  display:inline-flex;padding:4px;gap:4px;border-radius:999px;
  background:var(--paper-2);border:1px solid var(--edge);
  box-shadow:inset 0 1px 2px rgba(11,17,32,.03);
}
/* Two forms of the same control: buttons on the landing (they retune the
   page in place) and links on the entrances (they navigate between the
   two routes). Identical to look at, so the control reads as persistent
   even though its mechanics change. */
body.nx .toggle button,body.nx .toggle a{
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 20px;border:0;border-radius:999px;cursor:pointer;
  background:transparent;color:var(--mu);
  font-size:14.5px;font-weight:600;letter-spacing:normal;
  transition:background .32s var(--ease),color .32s var(--ease),box-shadow .32s var(--ease);
}
body.nx .toggle button .ico,body.nx .toggle a .ico{width:18px;height:18px;}
body.nx .toggle button[aria-selected="true"],
body.nx .toggle a[aria-current="page"]{
  background:var(--paper);color:var(--ink);box-shadow:var(--sh-1);
}
body.nx .toggle button[aria-selected="true"] .ico,
body.nx .toggle a[aria-current="page"] .ico{color:var(--acc);}
body.nx .toggle a:not([aria-current="page"]):hover{color:var(--ink);}
body.nx .toggle-sm button,body.nx .toggle-sm a{padding:7px 14px;font-size:13.5px;}
body.nx .toggle-sm button .ico,body.nx .toggle-sm a .ico{width:16px;height:16px;}

/* The two path sections, in a fixed order set by the markup. This was a
   reorderable region — the `.swapping` fade and the `order` juggling that
   went with it are gone along with the reorder itself. */
body.nx .paths{display:flex;flex-direction:column;}

/* Per-audience hero framing. Both blocks ship in the markup; only the
   active one occupies layout, so switching cannot reflow anything above
   it and the headline keeps its <em> (no textContent surgery). */
body.nx [data-hero]{display:none;}
body.nx[data-audience="employer"]  [data-hero="employer"],
body.nx[data-audience="candidate"] [data-hero="candidate"]{display:block;}
html.motion body.nx [data-hero]{animation:nx-fade .4s var(--ease) both;}
@keyframes nx-fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ══ 6. HERO ════════════════════════════════════════════════════════ */
body.nx .hero{
  position:relative;isolation:isolate;overflow:hidden;
  padding:calc(var(--nav) + clamp(56px,8vw,104px)) 0 clamp(56px,8vw,96px);
}
/* gradient mesh — three blooms that retint with the active accent */
body.nx .hero-bg{
  position:absolute;inset:-20% 0 -10%;z-index:-1;pointer-events:none;
  background:
    radial-gradient(760px 480px at 14% 6%, color-mix(in srgb,var(--acc) 20%,transparent), transparent 62%),
    radial-gradient(680px 460px at 88% 0%, color-mix(in srgb,var(--acc-2) 15%,transparent), transparent 60%),
    radial-gradient(900px 560px at 50% 108%, var(--acc-soft), transparent 58%);
  transition:background 1s var(--ease);
  will-change:transform;
}
/* faint grid so the mesh has something to sit on */
body.nx .hero::before{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:linear-gradient(var(--edge-soft) 1px,transparent 1px),
                   linear-gradient(90deg,var(--edge-soft) 1px,transparent 1px);
  background-size:72px 72px;
  mask-image:radial-gradient(720px 420px at 50% 30%,#000,transparent 75%);
  -webkit-mask-image:radial-gradient(720px 420px at 50% 30%,#000,transparent 75%);
  opacity:.6;
}
body.nx .hero-in{position:relative;max-width:940px;margin-inline:auto;text-align:center;}
body.nx .hero h1{margin:26px auto 20px;max-width:15ch;}
body.nx .hero h1 em{
  font-style:normal;
  background:linear-gradient(100deg,var(--acc),var(--acc-2) 60%,var(--acc));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* The word-splitter wraps each word in an inline-block, and an
   inline-block child is its own box — the parent's background-clip:text
   no longer paints through it, so the text renders transparent on
   transparent (i.e. invisible). Re-apply the gradient per word. */
body.nx .hero h1 em .word{
  background:linear-gradient(100deg,var(--acc),var(--acc-2) 70%,var(--acc));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
body.nx .hero .lead{margin:0 auto 34px;max-width:56ch;}
body.nx .hero-cta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-bottom:44px;}
body.nx .hero-cta .btn{padding:15px 30px;font-size:15.5px;}

/* stat strip */
body.nx .stats{
  display:grid;grid-template-columns:repeat(3,1fr);
  max-width:760px;margin-inline:auto;
  border:1px solid var(--edge);border-radius:var(--r-lg);
  background:color-mix(in srgb,var(--paper) 76%,transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:var(--sh-1);overflow:hidden;
}
body.nx .stats div{padding:22px 18px;text-align:center;border-right:1px solid var(--edge);}
body.nx .stats div:last-child{border-right:0;}
body.nx .stats b{
  display:block;font-size:clamp(28px,3.6vw,40px);font-weight:700;
  letter-spacing:normal;color:var(--ink);line-height:1;
  font-variant-numeric:tabular-nums;
}
body.nx .stats b .u{color:var(--acc);}
body.nx .stats span{display:block;margin-top:7px;font-size:13px;color:var(--mu);line-height:1.4;}

/* badge */
body.nx .badge{
  display:inline-flex;align-items:center;gap:9px;padding:6px 16px 6px 7px;
  border-radius:999px;background:var(--paper);border:1px solid var(--edge);
  box-shadow:var(--sh-1);font-size:13.5px;color:var(--mu);
}
body.nx .badge b{
  padding:3px 10px;border-radius:999px;background:var(--acc-soft);color:var(--acc);
  font-size:10.5px;font-weight:700;letter-spacing:1.1px;text-transform:uppercase;
}

/* ══ 7. MARQUEE ═════════════════════════════════════════════════════ */
body.nx .proof{padding:44px 0;border-block:1px solid var(--edge);background:var(--paper);}
body.nx .proof p{text-align:center;font-size:13.5px;color:var(--mu);margin-bottom:26px;}
/* Wide edge fade. The reference ramps a logo from invisible to solid over
   roughly a fifth of the strip, so names dissolve rather than getting
   clipped at a hard edge — that long dissolve is most of what makes the
   motion read as continuous instead of as a list sliding under a window.
   8% was too tight to see: a logo went from cut-off to opaque inside its
   own width. */
body.nx .marquee{
  position:relative;overflow:hidden;
  --fade:20%;
  mask-image:linear-gradient(90deg,transparent,#000 var(--fade),#000 calc(100% - var(--fade)),transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 var(--fade),#000 calc(100% - var(--fade)),transparent);
}
/* On a phone a 20% ramp either side leaves almost nothing solid in the
   middle, so the fade tightens as the strip narrows. */
@media (max-width:700px){ body.nx .marquee{--fade:12%;} }
body.nx .marquee-track{display:flex;width:max-content;}
html.motion body.nx .marquee-track{animation:nx-marquee var(--speed,42s) linear infinite;}
body.nx .marquee:hover .marquee-track,
body.nx .marquee:focus-within .marquee-track{animation-play-state:paused;}
/* Track holds the list twice; -50% lands exactly on the seam. */
@keyframes nx-marquee{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
body.nx .marquee-track ul{
  display:flex;align-items:center;gap:clamp(38px,6vw,76px);
  padding-right:clamp(38px,6vw,76px);list-style:none;margin:0;
}
/* Logo lockups: a filled mark beside a wordmark, the way a real client
   strip is built. One uniform grey for the whole row — a client strip
   is a list of names, and letting eight brand colours in turns the
   quietest band on the page into the loudest. Colour arrives on hover. */
body.nx .marquee-track li{
  color:var(--dim);white-space:nowrap;
  opacity:.9;transition:color .2s,opacity .2s;
}
body.nx .marquee-track li:hover{color:var(--ink-2);opacity:1;}
body.nx .lockup{display:inline-flex;align-items:center;gap:10px;}
/* Sized off the cap height of the name beside it, so mark and word look
   like one object rather than an icon with a caption. */
body.nx .lk-mark{width:26px;height:26px;flex:none;fill:currentColor;}
body.nx .lk-name{
  font-size:20px;font-weight:600;letter-spacing:normal;line-height:1;
}
/* Per-brand typographic variation. Without it eight names in one weight
   read as a menu, not as eight different companies' logos — that
   sameness is the giveaway that a strip is placeholder text. */
body.nx .lk-strong .lk-name{font-weight:700;letter-spacing:-.02em;}
body.nx .lk-light  .lk-name{font-weight:400;font-size:21px;}
body.nx .lk-wide   .lk-name{font-weight:500;letter-spacing:.14em;}
body.nx .lk-caps   .lk-name{font-weight:700;text-transform:uppercase;font-size:17px;letter-spacing:.06em;}

/* ══ 8. STEPS + PINNED MEDIA ════════════════════════════════════════ */
body.nx .pinned{
  display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:clamp(32px,5vw,80px);align-items:start;
}
body.nx .pinned.mirror{direction:rtl;}
body.nx .pinned.mirror>*{direction:ltr;}

body.nx .steps{display:flex;flex-direction:column;gap:8px;}
body.nx .step{
  position:relative;display:grid;grid-template-columns:auto 1fr;gap:18px;
  padding:22px 22px 22px 20px;border-radius:var(--r);
  border:1px solid transparent;
  transition:background .4s var(--ease),border-color .4s var(--ease),box-shadow .4s var(--ease);
}
body.nx .step.on{
  background:var(--paper);border-color:var(--edge);box-shadow:var(--sh-1);
}
body.nx .step-n{
  width:40px;height:40px;border-radius:12px;display:grid;place-items:center;
  font-size:14px;font-weight:700;font-variant-numeric:tabular-nums;
  background:var(--paper-3);color:var(--dim);
  border:1px solid var(--edge);
  transition:background .4s var(--ease),color .4s var(--ease),border-color .4s var(--ease);
}
body.nx .step.on .step-n{background:var(--acc);color:#fff;border-color:var(--acc);}
body.nx .step h3{margin-bottom:7px;font-size:20px;}
body.nx .step p{font-size:14.5px;line-height:1.62;color:var(--mu);}
body.nx .step ul{margin:12px 0 0;padding:0;list-style:none;display:grid;gap:7px;}
body.nx .step li{display:flex;gap:9px;align-items:flex-start;font-size:13.5px;color:var(--mu);}
body.nx .step li .ico{width:16px;height:16px;color:var(--acc);margin-top:2px;}
/* progress rail — fills as the steps scrub past */
body.nx .rail{
  position:absolute;left:0;top:0;bottom:0;width:2px;border-radius:2px;
  background:var(--edge);overflow:hidden;
}
body.nx .rail i{
  display:block;width:100%;height:var(--p,0%);background:var(--acc);
  border-radius:2px;transition:height .18s linear;
}

/* the pinned column */
body.nx .pin-media{
  position:sticky;top:calc(var(--nav-sm) + 28px);
  border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--edge);background:var(--paper);box-shadow:var(--sh-2);
}
body.nx .pin-stage{position:relative;aspect-ratio:4/3.15;background:var(--paper-2);}
body.nx .pin-state{
  position:absolute;inset:0;padding:clamp(18px,2.6vw,30px);
  display:flex;flex-direction:column;gap:12px;
  opacity:0;transform:scale(.985);
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
body.nx .pin-state.on{opacity:1;transform:none;}
body.nx .pin-bar{
  display:flex;align-items:center;gap:8px;padding:11px 14px;
  border-bottom:1px solid var(--edge);background:var(--paper);
}
body.nx .pin-bar i{width:10px;height:10px;border-radius:999px;background:var(--paper-3);display:block;}
body.nx .pin-bar span{
  margin-left:8px;font-size:12px;color:var(--dim);
  padding:4px 12px;border-radius:999px;background:var(--paper-2);border:1px solid var(--edge);
}

/* mock UI atoms used inside the stage */
body.nx .m-card{
  background:var(--paper);border:1px solid var(--edge);border-radius:14px;
  padding:15px 16px;box-shadow:var(--sh-1);
}
body.nx .m-row{display:flex;align-items:center;gap:12px;}
body.nx .m-av{
  width:36px;height:36px;border-radius:999px;flex:none;display:grid;place-items:center;
  background:var(--acc-soft);color:var(--acc);font-size:13px;font-weight:700;
}
body.nx .m-t{font-size:14px;font-weight:650;color:var(--ink);}
body.nx .m-s{font-size:12px;color:var(--mu);margin-top:1px;}
body.nx .m-score{margin-left:auto;font-size:20px;font-weight:700;color:var(--acc);
  font-variant-numeric:tabular-nums;letter-spacing:normal;}
body.nx .m-bars{display:grid;gap:9px;margin-top:14px;}
body.nx .m-bar{display:grid;grid-template-columns:74px 1fr 30px;align-items:center;gap:11px;
  font-size:12px;color:var(--mu);}
body.nx .m-track{height:7px;border-radius:99px;background:var(--paper-3);overflow:hidden;}
body.nx .m-fill{height:100%;border-radius:99px;background:var(--acc);
  transition:width .9s var(--ease);}
body.nx .m-bar b{text-align:right;color:var(--ink);font-weight:650;font-variant-numeric:tabular-nums;}
body.nx .m-line{height:9px;border-radius:99px;background:var(--paper-3);}
body.nx .m-chip{
  display:inline-flex;align-items:center;gap:7px;padding:6px 13px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc);font-size:12px;font-weight:600;
}
body.nx .m-chip .ico{width:15px;height:15px;}

/* ══ 9. SHOWCASE ════════════════════════════════════════════════════ */
body.nx .showcase{
  display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(34px,5vw,74px);align-items:center;
}
body.nx .device{
  position:relative;border-radius:var(--r-xl);padding:12px;
  background:linear-gradient(150deg,color-mix(in srgb,var(--acc) 24%,transparent),transparent 55%),var(--paper-2);
  border:1px solid var(--edge);box-shadow:var(--sh-3);
}
body.nx .device-screen{
  border-radius:calc(var(--r-xl) - 12px);overflow:hidden;
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .device-body{padding:18px;display:grid;gap:11px;}
body.nx .callouts{display:grid;gap:14px;margin-top:34px;}
body.nx .callout{
  display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:center;
  padding:20px 22px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-1);
}
body.nx .callout b{
  display:block;font-size:clamp(26px,3vw,34px);font-weight:700;letter-spacing:normal;
  color:var(--ink);line-height:1;font-variant-numeric:tabular-nums;
}
body.nx .callout b .u{color:var(--acc);}
body.nx .callout span{display:block;font-size:13.5px;color:var(--mu);margin-top:5px;}

/* ══ 10. CARDS ══════════════════════════════════════════════════════ */
body.nx .cards{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;}
body.nx .card-x{
  display:flex;flex-direction:column;padding:30px 28px;border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-1);
  transform-style:preserve-3d;
  transition:box-shadow .32s var(--ease),border-color .32s var(--ease),transform .32s var(--ease);
}
body.nx .card-x:hover{box-shadow:var(--sh-3);border-color:color-mix(in srgb,var(--acc) 30%,var(--edge));}
body.nx .card-x>*{transform:translateZ(24px);}
body.nx .card-x h4{margin:20px 0 9px;font-size:19px;}
body.nx .card-x p{font-size:14px;line-height:1.62;color:var(--mu);flex:1;margin-bottom:22px;}
/* The card closes on a real bordered button rather than an arrow link.
   `align-self` keeps it at its own width instead of stretching across the
   card — a full-width button in a three-up row reads as the primary action
   of the page, which it is not. `margin-top:auto` is what lines the three
   buttons up with each other when the copy runs to different lengths. */
body.nx .card-x .btn{align-self:flex-start;margin-top:auto;}
body.nx .card-x .tagx{
  align-self:flex-start;padding:4px 11px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc);
  font-size:10.5px;font-weight:700;letter-spacing:.9px;text-transform:uppercase;
}
body.nx .card-x .go{
  display:inline-flex;align-items:center;gap:8px;font-size:14.5px;font-weight:600;color:var(--acc);
}
body.nx .card-x .go .ico{width:18px;height:18px;transition:transform .24s var(--ease);}
body.nx .card-x:hover .go .ico{transform:translateX(4px);}

/* value grid (entrances) */
body.nx .vgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
/* Exactly four items go to a single four-up row. At three columns the
   fourth drops alone onto a second row, and a lone card under a full row
   reads as something that failed to load rather than as the fourth of
   four. Counts of 3 and 6 already divide evenly, so they keep three.
   Browsers without :has() simply ignore this and get today's layout. */
body.nx .vgrid:has(> .vitem:nth-child(4):last-child){grid-template-columns:repeat(4,1fr);}
body.nx .vitem{
  padding:26px 24px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-1);
}
body.nx .vitem h4{margin:16px 0 8px;}
body.nx .vitem p{font-size:14px;line-height:1.6;color:var(--mu);}

/* faq */
body.nx .faq{border-top:1px solid var(--edge);max-width:820px;}
body.nx .faq details{border-bottom:1px solid var(--edge);}
body.nx .faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:20px 2px;cursor:pointer;list-style:none;
  font-size:17px;font-weight:600;color:var(--ink);
}
body.nx .faq summary::-webkit-details-marker{display:none;}
/* Same rule as .accordion above: the marker carries the state, the type
   stays one colour. */
body.nx .faq .pm{
  width:28px;height:28px;flex:none;border-radius:999px;display:grid;place-items:center;
  border:1px solid var(--edge);color:var(--mu);
  transition:transform .26s var(--ease),background .26s,color .18s;
}
body.nx .faq summary:hover .pm{color:var(--ink);}
body.nx .faq details[open] .pm{transform:rotate(45deg);background:var(--paper-3);color:var(--ink);}
body.nx .faq details p{padding:0 2px 22px;font-size:14.5px;line-height:1.65;color:var(--mu);max-width:62ch;}

/* ══ 11. CTA BAND ═══════════════════════════════════════════════════
   A white card inside a thick gradient rule. The border is painted with
   two backgrounds and two clip boxes — the flat one fills the padding-box
   (the card face), the gradient fills the border-box, and the transparent
   border lets the gradient show only in the ring. One element, no wrapper
   div, and the radius stays continuous because a border curves with it.

   `background-clip` is the whole trick: without the padding-box layer the
   gradient would sit behind the text too. */
body.nx .band{
  --band-ring:6px;
  position:relative;border-radius:clamp(28px,3.2vw,44px);
  /* Shallow on purpose. The reference card is close to 3:1, and the deep
     padding that suits a full-width section makes a bordered card read as
     a box with a lot of nothing in it. */
  padding:clamp(44px,5.4vw,64px) clamp(24px,4vw,64px);text-align:center;
  border:var(--band-ring) solid transparent;
  background:
    linear-gradient(var(--paper),var(--paper)) padding-box,
    /* The pale stop near the middle is doing real work: a ring that stays
       saturated the whole way round draws a hard racetrack and pulls the
       eye around the edge instead of into the card. Letting it wash out
       where the headline sits keeps the colour at the corners. */
    linear-gradient(100deg,
      #2dd4bf 0%, #4f8ef7 15%, #e8edf4 38%, #ecf0f5 58%, #c9b6f8 82%, #9061f9 100%) border-box;
  box-shadow:var(--sh-2);
}
/* Aria's mark, centred above the headline. It reuses the standard icon
   plate rather than inventing a third avatar treatment — same tile as the
   cards, only centred. */
body.nx .band-avatar{margin:0 auto 24px;}
/* Wide enough that the only line break is the authored <br> before the
   agent's name. A tighter measure re-wraps the first line and the name
   stops reading as its own beat. */
body.nx .band h2{max-width:34ch;margin:0 auto 18px;}
/* The agent's name in the brand green running to blue — the same sweep the
   ring opens with, so the card reads as one object rather than a frame
   with unrelated text inside. */
body.nx .band h2 em{
  font-style:normal;
  background:linear-gradient(95deg,#22c07f,#3b82f6);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
}
body.nx .band .lead{margin:0 auto 32px;max-width:64ch;}
body.nx .band-cta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;}

/* ══ 12. FOOTER ═════════════════════════════════════════════════════ */
/* Quiet by design: no tinted ground, no divider rules, no bottom bar. The
   footer separates from the page by whitespace alone — every hairline that
   was in here previously was drawing a box around content that is already
   obviously a footer. */
/* One full-bleed rule closes the page and opens the footer. It sits on the
   footer rather than on the last section so it lands in the same place no
   matter which section a page happens to end on, and it runs edge to edge
   because .foot is full-width — putting it inside .wrap would stop it at
   the content column and read as a divider between two blocks instead of
   the boundary of the page. Everything inside the footer stays ruleless. */
/* Measured off hackajob's live footer at a 1440 viewport, not sampled
   from a screenshot:
     footer          border-top 4px solid #000, white, padding 50px 0
     .footer__inner  full-bleed, 15px gutters (their max-width is 2560)
     .footer__logo   216x46, 40px of air beneath
     .footer__row    flex, three columns at exactly 33.3333%, bottom-
                     aligned so the socials land on the row's baseline
     .footer__link   18px / 36px / weight 300 / #656565 / no underline
     .footer__office 18px / 24px / weight 300, 22.5px apart
     .footer__social flex-end, 45px circles, 2px border, 9px apart
   The rule that closes the page is theirs too — 4px, not the hairline we
   had. The dark variant keeps every measurement and moves only the ink. */
body.nx .foot{
  --foot-ink:#656565;
  background:#fff;
  border-top:4px solid #000;
  padding:50px 0;
}
/* Their footer runs edge to edge while the pages above it stay in a
   column, so the 15px gutter is the whole inset. Ours has to opt out of
   .wrap's max-width to land in the same place. */
body.nx .foot > .wrap{max-width:none;padding:0 15px;}

body.nx .foot-mark{display:block;margin:0 0 40px;}
body.nx .foot-mark img{display:block;height:46px;width:auto;}

/* Columns stretch so their content starts at the top of the row, as the
   reference's address stack does. Only the socials opt out and drop to
   the baseline — align-self:flex-end shrinks that one column to its own
   height, which is what puts the icons on the bottom-right corner. */
body.nx .foot-grid{display:flex;align-items:stretch;gap:0;}
body.nx .foot-grid > *{flex:0 0 33.3333%;min-width:0;}
body.nx .foot-grid .socials{align-self:flex-end;}

body.nx .foot ul{list-style:none;display:block;margin:0;padding:0;}
body.nx .foot li{line-height:36px;}
body.nx .foot li a{
  font-size:18px;line-height:36px;font-weight:300;
  color:var(--foot-ink);text-decoration:none;transition:color .15s;
}
body.nx .foot li a:hover{color:#1c1c1c;text-decoration:underline;}

body.nx .foot-contact address,
body.nx .foot-copy{
  font-style:normal;font-size:18px;line-height:24px;font-weight:300;
  color:var(--foot-ink);margin:0 0 22.5px;
}
body.nx .foot-copy{margin-bottom:0;}

/* Borderless, at the foot of the link column like the reference's lone
   globe. The language name stays visible — a bare globe gives no clue
   which language is currently active. */
body.nx .locale{
  display:inline-flex;align-items:center;gap:8px;margin-top:10px;
  color:var(--foot-ink);font-size:18px;font-weight:300;cursor:pointer;
}
body.nx .locale .ico{width:19px;height:19px;}
/* The markup has carried this class since the first build but it was never
   defined, so "Language" printed next to the globe instead of being read
   only by assistive tech. */
body.nx .visually-hidden-label{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}
body.nx .locale select{border:0;background:none;font:inherit;color:inherit;cursor:pointer;}

body.nx .socials{display:flex;justify-content:flex-end;gap:9px;margin-bottom:18px;}
body.nx .socials a{
  width:45px;height:45px;display:grid;place-items:center;
  border:2px solid var(--foot-ink);background:none;color:var(--foot-ink);
  transition:color .16s,border-color .16s;
}
body.nx .socials a:hover{color:#1c1c1c;border-color:#1c1c1c;}

/* skip link */
body.nx .skip{
  position:absolute;left:-9999px;top:8px;z-index:400;padding:12px 20px;
  background:var(--acc);color:#fff;border-radius:999px;font-weight:600;
}
body.nx .skip:focus{left:var(--gut);}

/* ══ 13. RESPONSIVE ═════════════════════════════════════════════════ */
@media (max-width:1080px){
  /* Socials drop out of the row and sit under the addresses rather than
     being squeezed into a third track that has no room left. */
  body.nx .foot-grid{flex-wrap:wrap;row-gap:40px;}
  body.nx .foot-grid > *{flex:0 0 50%;}
  body.nx .foot-grid .socials{justify-content:flex-start;}
}
@media (max-width:960px){
  body.nx .mega,body.nx .nav-right .login-split,
  body.nx .nav-right .btn-primary{display:none;}
  body.nx .burger{display:grid;}
  body.nx .nav-spacer{flex:1;}
  body.nx .pinned{grid-template-columns:1fr;}
  body.nx .pinned.mirror{direction:ltr;}
  body.nx .pin-media{position:relative;top:0;order:-1;margin-bottom:26px;}
  body.nx .showcase{grid-template-columns:1fr;}
  body.nx .cards,body.nx .vgrid{grid-template-columns:1fr 1fr;}
}
@media (max-width:640px){
  /* The taller desktop bar eats too much of a phone screen, so both states
     come back down together — keeping the pair in step, or the mark jumps
     size on scroll. */
  :root{--nav:72px;--nav-sm:64px;}
  body.nx .wordmark img{height:40px;}
  body.nx .nav.is-solid .wordmark img{height:34px;}
  body.nx .stats{grid-template-columns:1fr;}
  body.nx .stats div{border-right:0;border-bottom:1px solid var(--edge);}
  body.nx .stats div:last-child{border-bottom:0;}
  body.nx .cards,body.nx .vgrid{grid-template-columns:1fr;}
  body.nx .foot-grid > *{flex:0 0 100%;}
  body.nx .hero-cta{flex-direction:column;align-items:stretch;}
  body.nx .hero-cta .btn{width:100%;}
  body.nx .toggle{width:100%;}
  body.nx .toggle button{flex:1;justify-content:center;padding:11px 12px;}
  body.nx .m-bar{grid-template-columns:62px 1fr 26px;}
}

/* ══ 14. SUB-PAGES ══════════════════════════════════════════════════
   The entrance pages own the big cinematic hero; the pages hanging off
   the menu are reference material, so they get a compact head and lean
   on tables and prose instead. Everything below still reads --acc, so
   a jobseeker page is teal and an employer page indigo with no variants. */
body.nx .hero-sm{padding:calc(var(--nav) + clamp(38px,5vw,64px)) 0 clamp(34px,4.4vw,56px);}
body.nx .hero-sm h1{font-size:clamp(32px,4.8vw,58px);}

/* standalone check list (the one inside .step is scoped to it) */
body.nx .checks{margin:14px 0 0;padding:0;list-style:none;display:grid;gap:8px;}
body.nx .checks li{display:flex;gap:10px;align-items:flex-start;font-size:14.5px;color:var(--mu);line-height:1.55;}
body.nx .checks li .ico{width:17px;height:17px;color:var(--acc);margin-top:2px;flex:none;}

/* data table — salary bands, stage breakdowns. Scrolls in its own box
   rather than pushing the page sideways on a phone. */
body.nx .tbl-wrap{overflow-x:auto;border:1px solid var(--edge);border-radius:var(--r);background:var(--paper);}
body.nx .tbl{width:100%;border-collapse:collapse;min-width:560px;font-size:14.5px;}
body.nx .tbl th,body.nx .tbl td{padding:14px 18px;text-align:left;border-bottom:1px solid var(--edge-soft);}
body.nx .tbl th{
  font-size:11.5px;font-weight:700;letter-spacing:1.2px;text-transform:uppercase;
  color:var(--dim);background:var(--paper-2);white-space:nowrap;
}
body.nx .tbl tr:last-child td{border-bottom:0;}
body.nx .tbl td b{color:var(--ink);font-weight:600;}
body.nx .tbl .num{font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink);font-weight:600;}

/* prose — blog bodies and long-form guidance */
body.nx .prose{max-width:68ch;}
body.nx .prose h3{margin:38px 0 12px;}
body.nx .prose p{margin:0 0 16px;font-size:16.5px;line-height:1.7;color:var(--mu);}
body.nx .prose p b,body.nx .prose strong{color:var(--ink);font-weight:600;}

/* pricing */
body.nx .plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px;}
body.nx .plan{
  display:flex;flex-direction:column;gap:14px;padding:28px;
  border:1px solid var(--edge);border-radius:var(--r-lg);background:var(--paper);
  box-shadow:var(--sh-1);
}
body.nx .plan.feature{border-color:var(--acc);box-shadow:var(--sh-2);}
/* The cap is 36px, not 42px, because the cap has to fit the longest
   price on the row rather than the shortest. A column is ~217px
   inside its padding, and at 42px "Договорная" needs 250px: it
   overflowed the card and "Бесплатно / всегда" wrapped to two
   lines, which pushed that card's feature list out of step with
   the others. Every price is the same size either way — this is
   the size at which they all look it. */
body.nx .plan .price{font-size:clamp(26px,2.4vw,30px);font-weight:700;color:var(--ink);
  line-height:1;white-space:nowrap;}
body.nx .plan .price small{font-size:14px;font-weight:500;color:var(--mu);margin-left:4px;}
body.nx .plan .btn{margin-top:auto;}

/* ══ 15. MEGA PANEL — GROUPED VARIANT ═══════════════════════════════
   The employer panel is a different animal from the jobseeker one: four
   titled groups, and the lead group carries rich items (icon tile +
   name + one line of what it is) rather than bare links. Both variants
   share .mega-panel, so the open/close/keyboard logic is untouched. */
body.nx .mega-cols.cols-4{
  grid-template-columns:1.55fr 1fr 1fr 1fr;
  gap:0 clamp(20px,2.4vw,40px);
}
body.nx .mega-col h5{
  font-size:22px;font-weight:500;line-height:1.2;color:var(--ink);
  margin:0;letter-spacing:normal;
}

body.nx .mega-rich{display:flex;gap:14px;align-items:flex-start;}
/* When the tile holds Aria's portrait it drops the gradient and clips the
   image; the neighbouring Talent-intelligence tile still gets the tinted
   plate and its glyph. Keeping the rounded-SQUARE shape is deliberate — the
   shape belongs to the menu row, the content belongs to Aria, and a lone
   circle beside a squircle would break the row. */
body.nx .mega-rich .tile:has(img){background:none;border:0;overflow:hidden;}
body.nx .mega-rich .tile img{width:100%;height:100%;object-fit:cover;display:block;}
body.nx .mega-rich .tile{
  flex:none;width:46px;height:46px;border-radius:13px;
  display:grid;place-items:center;color:var(--acc);
  background:linear-gradient(150deg,var(--acc-soft),color-mix(in srgb,var(--acc) 20%,transparent));
  border:1px solid color-mix(in srgb,var(--acc) 20%,transparent);
  transition:transform .22s var(--ease),box-shadow .22s var(--ease);
}
body.nx .mega-rich .tile .ico{width:22px;height:22px;}
body.nx .mega-rich b{display:block;font-size:16px;font-weight:600;color:var(--ink);}
body.nx .mega-rich span{
  display:block;font-size:14px;color:var(--mu);margin-top:3px;line-height:1.45;
}
/* The rich rows are whole-block targets, so the underline used on bare
   links would be wrong here — lift the tile instead. */
body.nx .mega-rich::after{display:none;}
body.nx .mega-rich:hover{color:inherit;}
body.nx .mega-rich:hover b{color:var(--acc);}
body.nx .mega-rich:hover .tile{
  transform:translateY(-2px);
  box-shadow:0 8px 20px color-mix(in srgb,var(--acc) 26%,transparent);
}

@media (max-width:1100px){
  body.nx .mega-cols.cols-4{grid-template-columns:1.4fr 1fr 1fr;}
  body.nx .mega-cols.cols-4 .mega-col:last-child{grid-column:2 / -1;}
}

/* ══ 16. SQUARED CONTROLS ═══════════════════════════════════════════
   Every interactive control drops the pill for a squared corner, per
   the reference. One token so the whole set moves together — set
   --r-btn to 0 for hard corners, or back to 999px to undo.

   Scope note: this squares CONTROLS (things you press), not the
   decorative pills — status chips, tags and the score badges stay
   rounded, because they are labels and squaring them would make them
   read as buttons. */
body.nx .btn,
body.nx .skip,
body.nx .locale,
body.nx .burger,
body.nx .drawer-close{border-radius:var(--r-btn);}
/* app.css re-pills the nav buttons; this is the marketing surface, so
   it wins here without touching the product pages. */
body.nx .nav-right .btn{border-radius:var(--r-btn);}

body.nx .toggle{border-radius:calc(var(--r-btn) + 3px);}
body.nx .toggle button,body.nx .toggle a{border-radius:calc(var(--r-btn) - 2px);}

/* The socials are the one exception to the squared set: the reference draws
   them as circles, and they are icon links rather than controls you press. */
body.nx .socials a{border-radius:999px;}

/* ══ 18. SCROLL-LINKED MOTION ═══════════════════════════════════════
   CSS scroll-driven animations: the progress of each effect is tied to
   where the element sits in the viewport, so it tracks the scrollbar
   exactly and reverses when you scroll back up.

   This is deliberately NOT the old wheel-lerp. Nothing here intercepts
   input or moves the page — the browser scrolls at whatever speed the
   reader's hardware and OS settings say, and these animations just read
   that position. Zero scroll listeners, zero rAF loops; it runs on the
   compositor.

   Gated three ways:
     @supports        → browsers without scroll timelines get nothing
     html.motion      → set only after the reduced-motion check
   so the fallback everywhere else is a fully readable static page. */
@supports (animation-timeline: view()) {

  /* ── rise: enters as it crosses the lower third, settles by mid-screen.
     Range ends at cover 42% so the element is fully resolved while it is
     still being read, not still animating under the reader's eye. ── */
  html.motion [data-scroll-fx="rise"]{
    animation:nx-rise linear both;
    animation-timeline:view(block);
    animation-range:entry 8% cover 42%;
  }
  @keyframes nx-rise{
    from{opacity:0;transform:translateY(34px) scale(.985)}
    to  {opacity:1;transform:none}
  }

  /* ── zoom: media resolves from a slight overscale. Reads as the shot
     settling into place rather than sliding around. ── */
  html.motion [data-scroll-fx="zoom"]{
    animation:nx-zoom linear both;
    animation-timeline:view(block);
    animation-range:entry 0% cover 55%;
  }
  @keyframes nx-zoom{
    from{opacity:.4;transform:scale(1.06)}
    to  {opacity:1;transform:none}
  }

  /* ── drift: continuous parallax across the element's whole pass, for
     decorative layers only. Never put text in one — it moves the entire
     time it is on screen. ── */
  html.motion [data-scroll-fx="drift"]{
    animation:nx-drift linear both;
    animation-timeline:view(block);
    animation-range:cover 0% cover 100%;
  }
  @keyframes nx-drift{
    from{transform:translateY(-22px)}
    to  {transform:translateY(22px)}
  }

  /* A `sink` effect (section head receding on exit) was here and is
     removed. With animation-range on the exit phase plus fill:both, a
     tall viewport leaves the element already past the range start, so
     it resolves to the `to` keyframe — opacity 0 — while the heading is
     still fully on screen. Verified: two headings on /customers were
     invisible in view. An effect that can hide readable text is not
     worth a flourish, so it is gone rather than tuned.

     The lesson generalises: only animate opacity toward 1 on anything
     containing text, never away from it. `rise` and `zoom` both end at
     fully-visible, which is why they are safe. */
}

/* Reduced motion: strip every one of them. */
@media (prefers-reduced-motion:reduce){
  [data-scroll-fx]{animation:none !important;opacity:1 !important;transform:none !important;}
}

/* ══ 19. HERO — CENTRED VARIANT ═════════════════════════════════════
   One headline for both audiences, with the path choice made by the two
   buttons underneath rather than by a segmented control above. The
   buttons are still the audience switch: choosing one retunes --acc and
   reorders the sections below. */
body.nx .hero-centred{
  display:flex;flex-direction:column;align-items:center;text-align:center;
}
body.nx .hero-centred h1{max-width:16ch;margin:0 0 22px;}
body.nx .hero-centred .lead{max-width:56ch;margin:0 auto 34px;}

/* NEW: Meet Aria */
body.nx .hero-badge{
  display:inline-flex;align-items:center;gap:10px;
  padding:7px 18px 7px 7px;margin-bottom:clamp(24px,3vw,38px);
  border-radius:999px;                     /* a label, not a control */
  background:var(--paper);border:1px solid var(--edge);
  box-shadow:var(--sh-1);
  font-size:15px;font-weight:500;color:var(--ink);
  transition:box-shadow .22s var(--ease),transform .22s var(--ease),border-color .18s;
}
body.nx .hero-badge:hover{
  transform:translateY(-1px);box-shadow:var(--sh-2);border-color:var(--dim);
}
body.nx .hero-badge b{color:var(--acc);font-weight:700;}
body.nx .hero-badge .avatar{
  width:30px;height:30px;border-radius:999px;flex:none;
  display:grid;place-items:center;color:#fff;
  background:linear-gradient(150deg,var(--acc-2),var(--acc));
}
body.nx .hero-badge .avatar .ico{width:17px;height:17px;}

/* the two paths */
body.nx .hero-paths{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;}
body.nx .hero-paths .btn{min-width:168px;}
/* The unchosen side must still read as a real option, so it keeps a full
   border rather than fading to a ghost. */
body.nx .hero-paths .btn[aria-selected="false"]{
  background:var(--paper);border-color:var(--ink-2);color:var(--ink);
}
/* Same dark fill as every other secondary button. This selector outranks
   the generic .btn:hover, so it has to restate it or the hero would be the
   one place the new hover does not happen. */
body.nx .hero-paths .btn[aria-selected="false"]:hover{
  background:var(--ink);border-color:var(--ink);color:var(--paper);
}
/* Selected takes the brand fill like every other primary button. The
   chosen path is already signalled by fill-vs-outline here and by the
   whole page below retuning to that temperature, so this does not need to
   carry the accent as well — and one indigo button in a green button
   system reads as a mistake, not as meaning. */
body.nx .hero-paths .btn[aria-selected="true"]{
  background:var(--brand);border-color:var(--brand);color:var(--brand-ink);
}

/* proof strip — one pill, three checks */
body.nx .proof-pill{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:6px clamp(14px,2vw,26px);
  margin-top:clamp(28px,3.4vw,44px);padding:10px 22px;
  border-radius:999px;background:var(--paper);border:1px solid var(--edge);
  box-shadow:var(--sh-1);
}
body.nx .proof-pill span{
  display:inline-flex;align-items:center;gap:8px;
  font-size:13.5px;font-weight:500;color:var(--mu);white-space:nowrap;
}
body.nx .proof-pill .ico{width:15px;height:15px;color:var(--acc);}

@media (max-width:640px){
  body.nx .proof-pill{border-radius:var(--r-lg);padding:14px 18px;}
  body.nx .hero-paths .btn{min-width:0;flex:1 1 auto;}
}

/* ══ 20. THE TOUR ═══════════════════════════════════════════════════
   A gradient-framed player. The border runs teal → indigo: the two
   audience temperatures meeting, which is the product's whole premise,
   so the frame carries meaning rather than just colour.

   Built as padding on the outer element with the gradient as its
   background, and an opaque inner — a real gradient border, not four
   borders faked with pseudo-elements, so it survives any radius. */
body.nx .tour-sec{padding-top:0;}
body.nx .tour-frame{
  padding:3px;border-radius:calc(var(--r-xl) + 3px);
  background:linear-gradient(120deg,var(--candidate) 0%,var(--candidate-2) 22%,var(--employer-2) 72%,var(--employer) 100%);
  box-shadow:var(--sh-3);
}
body.nx .tour-inner{
  position:relative;border-radius:var(--r-xl);overflow:hidden;
  background:var(--paper-2);
  aspect-ratio:16/9;
  display:grid;place-items:center;
}
/* The still is the product, scaled to sit inside the frame. Replaced
   wholesale the moment a real <video poster> is dropped in. */
body.nx .tour-still{
  position:absolute;inset:0;display:grid;place-items:center;
  padding:clamp(18px,4vw,54px);
  background:
    radial-gradient(680px 420px at 22% 12%, var(--acc-soft), transparent 62%),
    radial-gradient(560px 400px at 82% 88%, color-mix(in srgb,var(--employer) 12%,transparent), transparent 60%),
    var(--paper-2);
}
body.nx .tour-mock{
  width:min(760px,100%);box-shadow:var(--sh-2);
  display:flex;flex-direction:column;gap:14px;
}
body.nx .tour-mock .m-score{margin-left:auto;}
body.nx .tour-inner video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
/* The film cross-fades over the still on play rather than replacing it
   in the markup, so the section still reads as the product before a
   click and there is no empty black box while the file loads. Once live
   it stays live: pausing brings the button back over a held frame, not
   back to the mock. */
body.nx .tour-still,
body.nx .tour-inner video{opacity:1;}

body.nx .tour-play::before{
  content:'';position:absolute;inset:-26px;border-radius:999px;
  background:radial-gradient(closest-side,rgba(11,17,32,.16),transparent 72%);
  pointer-events:none;
}
body.nx .tour-play{
  position:relative;z-index:2;
  width:clamp(64px,7vw,88px);aspect-ratio:1;border-radius:999px;
  display:grid;place-items:center;cursor:pointer;
  border:0;background:rgba(255,255,255,.94);color:var(--ink);
  box-shadow:0 10px 34px rgba(11,17,32,.24);
  transition:transform .22s var(--ease),box-shadow .22s var(--ease),background .18s;
}
body.nx .tour-play .ico{width:34%;height:34%;margin-left:8%;} /* optical centring */
body.nx .tour-play:hover{
  transform:scale(1.06);background:#fff;
  box-shadow:0 16px 44px rgba(11,17,32,.3);
}
body.nx .tour-play.is-playing{opacity:0;pointer-events:none;transform:scale(.9);}

body.nx .tour-cap{
  margin-top:22px;text-align:center;font-size:14.5px;color:var(--mu);
}

@media (prefers-reduced-motion:reduce){
  body.nx .tour-play{transition:none;}
  body.nx .tour-play:hover{transform:none;}
  body.nx .tour-still,
  body.nx .tour-inner video{transition:none;}
}

/* ══ 21. SPLIT SECTION — accordion + product card ═══════════════════ */
body.nx .pill-tag{
  display:inline-block;padding:7px 18px;margin-bottom:20px;
  border-radius:999px;                       /* a label, so it stays a pill */
  background:var(--acc-soft);border:1px solid color-mix(in srgb,var(--acc) 22%,transparent);
  font-size:14px;font-weight:500;color:var(--acc);
}
body.nx .split{
  display:grid;grid-template-columns:1fr 1.05fr;
  gap:clamp(32px,5vw,72px);align-items:center;
}

/* accordion — native <details>, so it survives with JS deleted.
   No divider rules: the reference separates the items with space and
   weight alone, and lines would fight the card sitting beside them. */
body.nx .accordion summary{
  display:flex;align-items:flex-start;justify-content:space-between;gap:24px;
  padding:18px 0;cursor:pointer;list-style:none;
  font-size:clamp(21px,2.2vw,27px);font-weight:700;line-height:1.25;color:var(--ink);
  transition:color .18s;
}
body.nx .accordion summary::-webkit-details-marker{display:none;}
/* Headings hold ONE colour in every state. Tinting the hovered or open row
   accent made a single line in the stack read as a different kind of thing
   — a link, or an error — rather than as the row you happen to be on. The
   state is already carried by the chevron rotating and the panel opening,
   which is unambiguous without recolouring the type. */
body.nx .accordion summary .ico{
  width:24px;height:24px;flex:none;margin-top:4px;color:var(--mu);
  transition:transform .28s var(--ease),color .18s;
}
body.nx .accordion summary:hover .ico{color:var(--ink);}
body.nx .accordion details[open] summary .ico{transform:rotate(180deg);color:var(--ink);}
body.nx .accordion p{
  margin:0 0 22px;padding-right:48px;
  font-size:15.5px;line-height:1.65;color:var(--mu);
}
/* Checks carried over from the numbered steps this section replaced. The
   employer panels have them and the jobseeker ones do not — that is the
   content differing, not the component: an employer is evaluating a
   process and wants the guarantees; a jobseeker is reading a story. */
body.nx .accordion .acc-checks{
  list-style:none;margin:-8px 0 22px;padding:0;display:grid;gap:9px;
}
body.nx .accordion .acc-checks li{
  display:flex;gap:10px;align-items:flex-start;padding-right:48px;
  font-size:14.5px;line-height:1.5;color:var(--ink-2);
}
body.nx .accordion .acc-checks .ico{
  width:17px;height:17px;flex:none;margin-top:2px;color:var(--acc);
}

/* The glow sits BEHIND and offset down-right, so the card looks lit from
   off-frame rather than outlined — the reference's soft lavender bloom. */
body.nx .glow-frame{position:relative;padding:0;background:none;box-shadow:none;}
body.nx .glow-frame::before{
  content:'';position:absolute;inset:26px -18px -22px 34px;z-index:0;
  border-radius:var(--r-xl);
  background:linear-gradient(150deg,color-mix(in srgb,var(--employer) 55%,transparent),color-mix(in srgb,var(--acc) 45%,transparent));
  filter:blur(2px);
}
body.nx .glow-card{
  position:relative;z-index:1;
  padding:clamp(16px,2vw,26px);border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);
  box-shadow:var(--sh-3);
  display:flex;flex-direction:column;
  /* The reference leaves about 6% of the card's width between the role and
     Aria's reply — roughly double what this had. The gap is what separates
     "the job" from "what Aria thinks of it"; at 3% they read as one block. */
  gap:clamp(20px,2.6vw,34px);
}

/* the role card itself */
body.nx .role-card{
  padding:18px;border-radius:var(--r);
  border:1px solid var(--edge);background:var(--paper);
  display:flex;flex-direction:column;gap:16px;
}
body.nx .role-top{display:flex;gap:16px;align-items:flex-start;}
/* A proper company logo tile, not an avatar chip. The reference sets it at
   roughly the height of the three lines beside it, which is what makes the
   row read as "employer + role" rather than "icon + text". */
body.nx .role-logo{
  width:64px;height:64px;border-radius:14px;flex:none;
  display:grid;place-items:center;
  background:linear-gradient(150deg,var(--acc-2),var(--acc));
  color:#fff;font-size:19px;font-weight:700;letter-spacing:.02em;
}
body.nx .role-flag{
  display:inline-block;margin-bottom:7px;padding:4px 11px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc);font-size:12px;font-weight:600;
}
body.nx .role-name{font-size:19px;font-weight:700;color:var(--ink);line-height:1.25;}
body.nx .role-co{font-size:14px;color:var(--mu);margin-top:3px;}

body.nx .role-meta{
  display:grid;grid-template-columns:1fr 1fr;gap:11px 16px;
  padding-top:2px;
}
body.nx .role-meta span{
  display:inline-flex;align-items:center;gap:8px;
  font-size:13px;color:var(--ink-2);
}
body.nx .role-meta .ico{width:16px;height:16px;color:var(--mu);flex:none;}

body.nx .role-act{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
/* "Not interested" is a real choice, not a danger — bordered in the
   warm end of the palette so it reads as declining, never as delete. */
body.nx .btn-pass{
  background:var(--paper);border-color:#f0a675;color:#c2691f;
}
body.nx .btn-pass:hover{background:#fff7f0;border-color:#e2854a;color:#a5540f;}
:root[data-theme="dark"] body.nx .btn-pass{border-color:#7c4a22;color:#f0a675;background:transparent;}
:root[data-theme="dark"] body.nx .btn-pass:hover{background:#2a1a10;color:#f7c49a;}

/* Aria's note on a match.
   The avatar sits OUTSIDE the bubble, as in the reference — Aria is the
   speaker, not part of what she said. Inside a shared box the two read as
   one panel with a decorative icon; separated, the bubble reads as speech
   and the disc reads as who is talking. */
body.nx .aria-note{
  display:flex;gap:16px;align-items:flex-start;
  padding:0;border:0;background:none;
}
/* Sized as a SHARE of the note, not a fixed px, because the reference's
   avatar is ~27% of the card width — a proportion, not a measurement. It
   now holds a portrait rather than a glyph, which is what earns that size:
   a face fills the disc, where an abstract mark at 27% left a large empty
   ring. aspect-ratio keeps it round as the width flexes. */
body.nx .aria-note .avatar{
  width:clamp(64px,27%,132px);aspect-ratio:1;height:auto;
  border-radius:999px;flex:none;overflow:hidden;
  display:grid;place-items:center;
  box-shadow:0 8px 22px rgba(11,17,32,.10);
}
/* object-fit:cover, so a portrait that is not exactly square still fills
   the circle instead of letterboxing inside it. */
body.nx .aria-note .avatar img{
  width:100%;height:100%;object-fit:cover;display:block;
}
/* Kept for any .aria-note still using the glyph. */
body.nx .aria-note .avatar .ico{width:42%;height:42%;}
/* The paragraph IS the bubble — a wrapper div would only exist to be
   styled, and the text is the whole content. */
body.nx .aria-note p{
  margin:0;flex:1;padding:15px 18px;border-radius:14px;
  border:1.5px solid color-mix(in srgb,var(--acc) 45%,transparent);
  background:linear-gradient(150deg,var(--acc-soft),color-mix(in srgb,var(--acc) 7%,var(--paper)));
  font-size:14.5px;line-height:1.6;color:var(--ink-2);
}
@media (max-width:520px){
  body.nx .aria-note{gap:12px;}
  body.nx .aria-note .avatar{width:clamp(44px,17%,60px);}
}

/* gradient-edged closing band */
body.nx .edge-band{
  margin-top:clamp(40px,5vw,72px);
  padding:2px;border-radius:calc(var(--r-lg) + 2px);
  background:linear-gradient(120deg,var(--candidate),var(--employer));
}
body.nx .edge-inner{
  display:flex;align-items:center;justify-content:center;gap:clamp(16px,3vw,32px);
  flex-wrap:wrap;text-align:center;
  padding:22px clamp(20px,3vw,34px);border-radius:var(--r-lg);
  background:var(--paper);
}
body.nx .edge-inner b{font-size:clamp(17px,2vw,23px);font-weight:700;color:var(--ink);}
body.nx .btn-dark{background:var(--ink);border-color:var(--ink);color:var(--paper);}
body.nx .btn-dark:hover{background:var(--ink-2);border-color:var(--ink-2);color:var(--paper);}

@media (max-width:900px){
  body.nx .split{grid-template-columns:1fr;}
}

/* ══ 22. REVIEWS ════════════════════════════════════════════════════
   Rating summary over a card grid. The star colour is the accent, not
   a borrowed platform green — this is Nebryx's own surface, and using
   another service's brand colour would imply their endorsement. */
body.nx .rating-head{text-align:center;margin-bottom:clamp(34px,4vw,54px);}
body.nx .rating-line{
  display:inline-flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:center;
}
body.nx .rating-line strong{font-size:clamp(24px,3vw,34px);font-weight:700;color:var(--ink);}
body.nx .rating-sub{margin-top:12px;font-size:14.5px;color:var(--mu);}

body.nx .stars{display:inline-flex;gap:4px;}
body.nx .stars .s{
  width:26px;height:26px;border-radius:5px;display:grid;place-items:center;
  background:var(--acc);color:#fff;
}
body.nx .stars .s.off{background:var(--paper-3);color:var(--dim);}
body.nx .stars .ico{width:16px;height:16px;}
body.nx .stars-lg .s{width:34px;height:34px;}
body.nx .stars-lg .ico{width:21px;height:21px;}

body.nx .review-grid{
  display:grid;grid-template-columns:repeat(4,1fr);gap:16px;
}
body.nx .review{
  display:flex;flex-direction:column;gap:9px;
  padding:20px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .review-top{display:flex;align-items:center;justify-content:space-between;gap:10px;}
body.nx .review-top .stars .s{width:19px;height:19px;border-radius:4px;}
body.nx .review-top .stars .ico{width:12px;height:12px;}
body.nx .verified{
  display:inline-flex;align-items:center;gap:5px;
  font-size:12px;font-weight:500;color:var(--mu);
}
body.nx .verified .ico{width:13px;height:13px;color:var(--acc);}
body.nx .review-who{font-size:12.5px;color:var(--dim);margin:0;}
body.nx .review-who b{color:var(--ink-2);font-weight:600;}
body.nx .review h4{margin:0;font-size:15px;line-height:1.3;}
body.nx .review-body{margin:0;font-size:13.5px;line-height:1.55;color:var(--mu);}

@media (max-width:1080px){ body.nx .review-grid{grid-template-columns:repeat(2,1fr);} }
@media (max-width:560px){  body.nx .review-grid{grid-template-columns:1fr;} }

/* ══ 23. FEATURE ROWS ═══════════════════════════════════════════════
   Centred head, then alternating text/media rows. The media sits in a
   soft gradient bloom rather than a hard frame, so the two rows read as
   one family with the match card in the jobseeker section. */
body.nx .feat{
  display:grid;grid-template-columns:1fr 1.08fr;
  gap:clamp(32px,5vw,80px);align-items:center;
  margin-top:clamp(48px,6vw,88px);
}
/* Mirrored row. Source order stays text-then-media so the reading order
   is identical on mobile and to a screen reader; only the visual columns
   swap. */
body.nx .feat-flip .feat-media{order:-1;}
/* The columns are 1fr / 1.08fr, and `order` only swaps which CONTENT lands
   in which track — so in a flipped row the media inherited the narrower
   column. Mirroring the tracks gives the media the wider one in both rows,
   which is what the sourcing panel needs to fit a card without truncating. */
body.nx .feat-flip{grid-template-columns:1.08fr 1fr;}

body.nx .feat-tag{
  display:inline-flex;align-items:center;gap:9px;margin-bottom:16px;
  font-size:14px;font-weight:600;color:var(--ink-2);
}
body.nx .feat-tag .avatar{
  width:26px;height:26px;border-radius:999px;flex:none;
  display:grid;place-items:center;color:#fff;
  background:linear-gradient(150deg,var(--acc-2),var(--acc));
}
body.nx .feat-tag .avatar .ico{width:15px;height:15px;}

/* ── Aria's face ──────────────────────────────────────────────────────
   Wherever a disc stands in for Aria herself, it holds the portrait. One
   rule covering every mount point rather than a per-site override, so the
   avatar can never end up square in one place and round in another.

   `background:none` matters: these discs all carried an accent gradient
   for the glyph to sit on, and a photo over a gradient shows a coloured
   rim wherever the image edge doesn't perfectly meet the circle. */
body.nx .hero-badge .avatar:has(img),
body.nx .feat-tag .avatar:has(img),
body.nx .band-avatar:has(img){
  background:none;border:0;padding:0;overflow:hidden;box-shadow:none;
}
body.nx .hero-badge .avatar img,
body.nx .feat-tag .avatar img,
body.nx .band-avatar img{
  width:100%;height:100%;object-fit:cover;display:block;border-radius:999px;
}
/* The band's mark is the largest of the three and is the page's sign-off,
   so it keeps a soft lift the inline ones don't need.

   `display:block` is load-bearing: this is a <span>, and it previously got
   its box from the .ico-plate class that no longer applies. Inline elements
   ignore width and height, so without it the avatar collapses to 0×0 —
   present in the DOM, invisible on the page. */
body.nx .band-avatar{
  display:block;
  width:56px;height:56px;border-radius:999px;overflow:hidden;
  box-shadow:0 8px 22px rgba(11,17,32,.12);
}

body.nx .feat-text h3{
  font-size:clamp(26px,3.2vw,38px);line-height:1.12;margin:0 0 18px;
}
body.nx .feat-text p{
  margin:0 0 14px;font-size:15.5px;line-height:1.66;color:var(--mu);max-width:46ch;
}
body.nx .feat-cta{display:flex;gap:10px;flex-wrap:wrap;margin:22px 0 4px;}
body.nx .feat-text .checks{margin-top:18px;}

/* the bloom behind each media card */
body.nx .feat-media{position:relative;}
body.nx .feat-media::before{
  content:'';position:absolute;inset:14px -14px -16px 20px;z-index:0;
  border-radius:var(--r-xl);
  background:linear-gradient(150deg,color-mix(in srgb,var(--acc) 42%,transparent),color-mix(in srgb,var(--employer) 38%,transparent));
  filter:blur(3px);
}
body.nx .feat-flip .feat-media::before{inset:14px 20px -16px -14px;}

/* ── sourcing pool ────────────────────────────────────────────────────
   Proportions measured off the reference, not eyeballed:
     panel aspect   1.23
     card width     59% of panel width
     card height    15% of panel width
     rows occupy    40% of panel HEIGHT — 29% empty above and below
     avatar         64% of card height

   That whitespace is the design, and it is what every earlier attempt
   here was missing. Cards packed to the panel edges read as a list of
   six. The same cards floating in the middle of a large frame read as a
   window onto something much bigger — which is the section's whole
   claim. So the panel is sized by aspect-ratio and the rows are centred
   in it, rather than the panel shrink-wrapping the content. */

/* Reuses .feat-media's bloom rather than disabling it — .feat-flip already
   offsets that to the left edge, which is where the reference's is. */
body.nx .pool-media::before{
  background:linear-gradient(118deg,
    color-mix(in srgb,var(--candidate) 58%,transparent),
    color-mix(in srgb,var(--employer) 26%,transparent) 62%, transparent);
  filter:blur(7px);
}
body.nx .pool-frame{
  position:relative;z-index:1;          /* above the bloom */
  padding:clamp(11px,1.5vw,22px);
  border-radius:var(--r-xl);
  background:var(--paper);border:1px solid var(--edge);
  box-shadow:var(--sh-2);
}
body.nx .pool-inner{
  aspect-ratio:1.23;
  border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);
  overflow:hidden;                       /* cards are cut by the panel */
  display:grid;align-content:center;
  grid-template-rows:18.9% 18.9%;gap:2.2%;
}

/* Row geometry. A flex-basis in % resolves against the ROW, not the panel —
   so the row carries the arithmetic (3 cards + 2 gaps) and the cards just
   split it evenly, while margin-left (which DOES resolve against the panel)
   pulls the row left by half its overhang. */
/* More overhang, not less. The reference's card is 59% of a 922px panel =
   542px; this panel is only ~520px, so the same 59% gives a 307px card with
   about 86px left for text after the avatar and the score column — which is
   why every label was ellipsising no matter how the type was tuned.

   Widening the row to 231% makes each card 77% of the panel (~400px), enough
   for name + role on one line. The trade is that the flanking cards show as
   slivers rather than halves — the right call, since the middle card is the
   one anyone actually reads and the slivers only have to say "there is more". */
body.nx .pool-row{
  display:flex;gap:16px;
  width:calc(231% + 32px);
  margin-left:calc(-65.5% - 16px);
}
/* Reference offsets the SECOND row to the right, not the first. */
body.nx .pool-row:last-child{margin-left:calc(-62.5% - 16px);}

/* container-type makes the CARD the sizing reference, so cqw below is a
   share of the card rather than of the viewport. Sizing this type in vw
   was the bug: at 1440px the name resolved to 19px inside a 408px card
   and pushed the role into an ellipsis. */
body.nx .pool-card{
  container-type:inline-size;
  flex:1 1 0;min-width:0;height:100%;
  display:grid;grid-template-columns:auto 1fr auto;
  align-items:center;gap:clamp(10px,1.2vw,18px);
  padding:0 clamp(12px,1.4vw,20px);
  border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
  box-shadow:none;                       /* reference cards are flat */
}
body.nx .pool-av{
  height:64%;aspect-ratio:1;border-radius:12px;
  display:grid;place-items:center;flex:none;
  background:var(--acc-soft);color:var(--acc);
  font-size:clamp(11px,1.1vw,15px);font-weight:700;
}
body.nx .pool-body{display:grid;gap:3px;min-width:0;}
/* Name and role share a line, as in the reference. The name holds its width;
   the role is the one that gives way, so a long job title truncates instead
   of shoving the score out of the card. */
body.nx .pool-head{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden;}
body.nx .pool-head b{
  font-size:max(12px,4.06cqw);font-weight:700;color:var(--ink);
  white-space:nowrap;flex:none;
}
body.nx .pool-head i{
  font-style:normal;font-size:max(11px,4.06cqw);color:var(--ink-2);
  white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis;
}
/* "Previously at [mark] Company" — the mark inline with the text, sized off
   the line rather than fixed, so it stays optically level as the card scales. */
body.nx .pool-sub{
  display:flex;align-items:center;gap:5px;min-width:0;overflow:hidden;
  font-size:max(9.5px,2.8cqw);color:var(--mu);white-space:nowrap;
}
body.nx .pool-ex{flex:none;color:var(--dim);}
body.nx .pool-logo{
  width:1.25em;height:1.25em;flex:none;fill:var(--ink-2);
}
body.nx .pool-sub em{
  font-style:normal;font-weight:600;color:var(--ink-2);
  min-width:0;overflow:hidden;text-overflow:ellipsis;
}
body.nx .pool-right{display:grid;justify-items:end;gap:6px;flex:none;min-width:max-content;}
body.nx .pool-score{
  font-size:max(12px,3.5cqw);font-weight:700;color:var(--acc);
  font-variant-numeric:tabular-nums;line-height:1;
}
body.nx .pool-act{
  padding:clamp(4px,.5vw,8px) clamp(10px,1.2vw,17px);border-radius:999px;
  background:var(--ink);color:var(--paper);
  font-size:max(10px,2.7cqw);font-weight:600;white-space:nowrap;
}
/* Two backgrounds, two clip boxes — the 2px rule replaces the 1px border
   without moving the card by a pixel. */
body.nx .pool-card.on{
  border:2px solid transparent;
  background:
    linear-gradient(var(--paper),var(--paper)) padding-box,
    linear-gradient(115deg,var(--brand),#3b82f6) border-box;
}
body.nx .pool-card.on .pool-act{background:var(--brand);color:var(--brand-ink);}

body.nx .pool-lock{
  display:inline-flex;align-items:center;gap:8px;margin-top:20px;
  padding:8px 14px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc);
  border:1px solid color-mix(in srgb,var(--acc) 22%,transparent);
  font-size:13px;font-weight:600;
}
body.nx .pool-lock .ico{width:16px;height:16px;}

/* Narrow: less overhang, then none. A card clipped both sides is legible
   across 560px of column and unreadable across 300px. The aspect-ratio also
   has to go, or a stacked panel becomes absurdly tall. */
@media (max-width:900px){
  body.nx .pool-row,
  body.nx .pool-row:last-child{width:calc(126% + 32px);margin-left:calc(-13% - 16px);}
}
@media (max-width:620px){
  body.nx .pool-inner{aspect-ratio:auto;grid-template-rows:none;gap:12px;padding:18px 14px;}
  body.nx .pool-row,
  body.nx .pool-row:last-child{width:100%;margin-left:0;flex-wrap:wrap;}
  body.nx .pool-card{flex:1 1 100%;height:auto;padding:14px;}
  body.nx .pool-av{height:auto;width:44px;}
  body.nx .pool-row .pool-card:nth-child(3){display:none;}
}

/* ── chart card ───────────────────────────────────────────────────────
   Hand-drawn SVG rather than a charting library: two polylines and a
   gradient is the whole thing, and pulling in a runtime for it would cost
   more than the section it decorates. The viewBox scales with the column,
   so nothing here is measured in pixels the layout has to agree with. */
body.nx .chart-card{
  position:relative;z-index:1;
  padding:clamp(20px,2.4vw,30px);border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-3);
}
body.nx .chart-title{
  text-align:center;font-size:16px;font-weight:600;color:var(--ink);margin-bottom:18px;
}
body.nx .chart{position:relative;margin:0;}
body.nx .chart svg{display:block;width:100%;height:auto;overflow:visible;}
body.nx .chart-grid line{stroke:var(--edge-soft);stroke-width:1;}
body.nx .chart-axis{stroke:var(--edge);stroke-width:1;}
/* vector-effect keeps the stroke at 2px however far the viewBox is scaled —
   without it a wide column thins the line and a narrow one fattens it. */
body.nx .chart-line{
  fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
}
body.nx .chart-line-aria{stroke:var(--acc);}
body.nx .chart-line-ads{stroke:color-mix(in srgb,var(--employer) 55%,var(--paper));}

/* Chips sit on the lines, positioned in % so they track the plot as it
   scales rather than drifting off it at another width. */
body.nx .chart-chip{
  position:absolute;display:inline-flex;align-items:center;gap:7px;
  padding:6px 12px 6px 6px;border-radius:999px;
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-1);
  font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;
}
body.nx .chart-chip img{width:24px;height:24px;border-radius:999px;object-fit:cover;}
body.nx .chart-chip .ico{width:20px;height:20px;margin-left:5px;color:var(--mu);}
body.nx .chip-aria{top:14%;right:2%;}
body.nx .chip-ads{top:52%;right:14%;}
body.nx .chart-note{
  margin-top:14px;text-align:center;font-size:12px;color:var(--dim);
}
@media (max-width:520px){
  body.nx .chart-chip{font-size:12px;padding:4px 10px 4px 4px;}
  body.nx .chart-chip img{width:20px;height:20px;}
}
body.nx .feat-media .device{position:relative;z-index:1;}

@media (max-width:900px){
  body.nx .feat{grid-template-columns:1fr;}
  /* Undo the visual swap: stacked, the media must follow its own text. */
  body.nx .feat-flip .feat-media{order:0;}
}

/* ══ 26. HOW IT WORKS — the jobseeker walkthrough ════════════════════
   The menu pages were built as reference material: a compact head, a
   card grid, a table. That is the right register for a guide and the
   wrong one for the page that has to explain what the product does —
   so this one gets its own vocabulary.

   Two rules hold it together:

   1. It shows, then tells. Every step carries a small piece of the real
      interface beside the prose, built from the same mock atoms the
      landing page uses (.m-card, .m-chip, .role-card), so the panels
      cannot drift away from the product's actual look.

   2. NOTHING HERE SHOWS THE CANDIDATE A SCORE. The FAQ two sections
      below promises they are never shown a number for themselves, and a
      mock that leaks one would make the page contradict itself. The
      factor rows carry a verdict and a reason instead — which is what
      the candidate is actually given. If you add a panel here, keep it
      numberless.
   ═══════════════════════════════════════════════════════════════════ */

/* ── the numbered spine ─────────────────────────────────────────────
   Number, prose and panel on one row, with a hairline running down
   through the numbers so four separate rows read as one sequence. */
body.nx .hiw-steps{list-style:none;margin:0;padding:0;display:grid;}
body.nx .hiw-step{
  position:relative;
  display:grid;grid-template-columns:52px minmax(0,1fr) minmax(0,1.02fr);
  gap:clamp(20px,3vw,44px);align-items:start;
  padding-bottom:clamp(38px,5vw,68px);
}
body.nx .hiw-step:last-child{padding-bottom:0;}
/* The rail starts below the badge and stops at the next one. It is
   decoration, so it never appears in the accessibility tree — the <ol>
   already says these are ordered. */
body.nx .hiw-step::before{
  content:'';position:absolute;left:25px;top:56px;bottom:0;width:1.5px;
  background:linear-gradient(var(--edge),color-mix(in srgb,var(--edge) 30%,transparent));
}
body.nx .hiw-step:last-child::before{display:none;}
body.nx .hiw-num{
  width:52px;height:52px;border-radius:999px;flex:none;
  display:grid;place-items:center;
  font-size:19px;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--acc);background:var(--paper);
  border:1.5px solid color-mix(in srgb,var(--acc) 30%,transparent);
  box-shadow:0 0 0 6px color-mix(in srgb,var(--acc) 7%,transparent);
}
body.nx .hiw-copy h3{margin:10px 0 12px;}
body.nx .hiw-copy p{font-size:15.5px;line-height:1.66;color:var(--mu);margin:0 0 14px;max-width:46ch;}
body.nx .hiw-copy .checks li{color:var(--ink-2);}

/* ── mock panel ─────────────────────────────────────────────────────
   One shell for every step's screenshot-in-miniature. */
body.nx .mock{
  display:grid;gap:12px;padding:clamp(14px,1.7vw,20px);
  border-radius:var(--r-lg);background:var(--paper);
  border:1px solid var(--edge);box-shadow:var(--sh-2);
}
body.nx .mock-top{
  display:flex;align-items:center;gap:10px;
  padding-bottom:12px;border-bottom:1px solid var(--edge-soft);
}
body.nx .mock-top .m-chip{padding:5px 11px;font-size:11.5px;}
body.nx .mock-note{margin-left:auto;font-size:12px;color:var(--dim);}
body.nx .mock-foot{font-size:12px;color:var(--dim);display:flex;align-items:center;gap:8px;}
body.nx .mock-foot .ico{width:14px;height:14px;flex:none;}

/* skill rows with a level meter — step 1 */
body.nx .lv-row{
  display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:12px;
  font-size:13.5px;color:var(--ink);
}
body.nx .lv-row em{font-style:normal;font-size:12px;color:var(--mu);width:62px;text-align:right;}
body.nx .lv{display:inline-flex;gap:3px;}
body.nx .lv i{width:17px;height:6px;border-radius:99px;background:var(--acc);}
body.nx .lv i.off{background:var(--paper-3);}
body.nx .tagset{display:flex;flex-wrap:wrap;gap:7px;}
body.nx .tag-q{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px;border-radius:999px;
  background:var(--paper-2);border:1px solid var(--edge);
  font-size:12px;font-weight:500;color:var(--mu);
}
body.nx .tag-q .ico{width:13px;height:13px;}

/* ranked role rows — step 2 */
body.nx .rank-row{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;
  padding:10px 12px;border-radius:12px;border:1px solid var(--edge-soft);background:var(--paper-2);
}
body.nx .rank-row.top{
  border-color:color-mix(in srgb,var(--acc) 34%,transparent);
  background:linear-gradient(120deg,var(--acc-soft),var(--paper));
}
body.nx .rank-i{
  width:26px;height:26px;border-radius:8px;flex:none;display:grid;place-items:center;
  background:var(--paper);border:1px solid var(--edge);
  font-size:12px;font-weight:700;color:var(--mu);font-variant-numeric:tabular-nums;
}
body.nx .rank-row.top .rank-i{color:var(--acc);border-color:color-mix(in srgb,var(--acc) 34%,transparent);}
body.nx .rank-row b{display:block;font-size:13.5px;font-weight:650;color:var(--ink);}
body.nx .rank-row small{display:block;font-size:11.5px;color:var(--mu);margin-top:2px;}
body.nx .rank-tag{
  font-size:11px;font-weight:600;padding:4px 10px;border-radius:999px;white-space:nowrap;
  background:var(--paper);border:1px solid var(--edge);color:var(--mu);
}
body.nx .rank-row.top .rank-tag{
  background:var(--acc);border-color:var(--acc);color:#fff;
}

/* factor verdicts — the six factors as the candidate is shown them:
   a state, a name and the sentence explaining it. Never a number. */
body.nx .fx{display:grid;gap:8px;}
body.nx .fx-row{
  display:grid;grid-template-columns:20px minmax(0,1fr);gap:11px;align-items:start;
  padding:11px 13px;border-radius:12px;
  background:var(--paper-2);border:1px solid var(--edge-soft);
}
body.nx .fx-row .ico{width:18px;height:18px;margin-top:1px;color:var(--dim);}
body.nx .fx-row b{display:block;font-size:13px;font-weight:650;color:var(--ink);}
body.nx .fx-row span{display:block;font-size:12.5px;line-height:1.5;color:var(--mu);margin-top:2px;}
body.nx .fx-row.ok .ico{color:var(--acc);}
body.nx .fx-row.ok{border-color:color-mix(in srgb,var(--acc) 22%,transparent);background:var(--acc-soft);}
/* Amber, not red: "you are asking near the top of the band" is a thing
   to know before you apply, not a failure. */
body.nx .fx-row.watch .ico{color:#b45309;}
body.nx .fx-row.watch{border-color:#fcd9a4;background:#fffaf1;}
body.nx .fx-row.gap .ico{color:var(--ink-2);}
body.nx .fx-row.gap{border-style:dashed;border-color:var(--edge);}

/* application trail — step 4 */
body.nx .trail{display:grid;}
body.nx .trail-step{
  position:relative;display:grid;grid-template-columns:16px minmax(0,1fr) auto;
  align-items:center;gap:14px;padding:9px 0;
}
body.nx .trail-step::before{
  content:'';position:absolute;left:7px;top:26px;height:calc(100% - 16px);width:1.5px;
  background:var(--edge);
}
body.nx .trail-step:last-child::before{display:none;}
body.nx .trail-step .dot{
  width:15px;height:15px;border-radius:999px;
  background:var(--paper);border:2px solid var(--edge);position:relative;z-index:1;
}
body.nx .trail-step.done .dot{background:var(--acc);border-color:var(--acc);}
body.nx .trail-step.now .dot{
  border-color:var(--acc);
  box-shadow:0 0 0 4px color-mix(in srgb,var(--acc) 16%,transparent);
}
body.nx .trail-step.done::before{background:var(--acc);}
body.nx .trail-step b{font-size:13.5px;font-weight:600;color:var(--ink);}
body.nx .trail-step.upcoming b{color:var(--dim);font-weight:500;}
body.nx .trail-step i{font-style:normal;font-size:11.5px;color:var(--mu);}
body.nx .trail-step.now i{color:var(--acc);font-weight:600;}

/* ── the six factors, as cards ──────────────────────────────────────
   This replaced a three-column table. The table held the same three
   fields, but a factor is a thing rather than a row of a dataset, and
   the weighting note is a footnote to it — which a cell cannot say. */
body.nx .facts{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
body.nx .fact{
  display:flex;flex-direction:column;gap:10px;
  padding:24px;border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);box-shadow:var(--sh-1);
  transition:transform .24s var(--ease),box-shadow .24s var(--ease),border-color .18s;
}
body.nx .fact:hover{
  transform:translateY(-3px);box-shadow:var(--sh-2);
  border-color:color-mix(in srgb,var(--acc) 30%,var(--edge));
}
body.nx .fact h4{font-size:18px;}
body.nx .fact p{font-size:14px;line-height:1.6;color:var(--mu);margin:0;flex:1;}
body.nx .fact .note{
  display:block;margin-top:4px;padding-top:12px;border-top:1px dashed var(--edge);
  font-size:12.5px;line-height:1.5;color:var(--ink-2);
}
body.nx .fact .note b{
  display:block;font-size:10.5px;font-weight:700;letter-spacing:1.1px;
  text-transform:uppercase;color:var(--dim);margin-bottom:4px;
}

/* ── the three guarantees ───────────────────────────────────────────
   Stated as limits on the product, so they read as commitments rather
   than features. Dark ground: this is the one place on the page that
   should stop the eye. */
body.nx .guards{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;
  border-radius:var(--r-lg);overflow:hidden;background:var(--edge);}
body.nx .guard{
  display:flex;flex-direction:column;gap:12px;
  padding:clamp(24px,3vw,34px);background:var(--nav-ink);
}
body.nx .guard .ico-plate{
  background:color-mix(in srgb,var(--acc) 20%,transparent);
  border-color:color-mix(in srgb,var(--acc-lt) 34%,transparent);
  color:var(--acc-lt);
}
body.nx .guard b{font-size:17px;font-weight:650;color:#fff;}
body.nx .guard p{font-size:14px;line-height:1.62;color:#a8b0bd;margin:0;}
body.nx .guard em{font-style:normal;color:var(--acc-lt);}

@media (max-width:1000px){
  body.nx .facts{grid-template-columns:1fr 1fr;}
  body.nx .guards{grid-template-columns:1fr;}
}
@media (max-width:900px){
  /* Stacked, the panel drops under its own prose and both clear the
     rail — the number column stays so the sequence survives. */
  body.nx .hiw-step{grid-template-columns:44px minmax(0,1fr);gap:18px;}
  body.nx .hiw-media{grid-column:2;}
  body.nx .hiw-step::before{left:21px;top:48px;}
  body.nx .hiw-num{width:44px;height:44px;font-size:17px;}
  body.nx .hiw-copy h3{margin-top:6px;}
}
@media (max-width:640px){
  body.nx .facts{grid-template-columns:1fr;}
  body.nx .lv-row{grid-template-columns:1fr auto;}
  body.nx .lv-row em{display:none;}
}

/* ══ 27. DARK HERO ══════════════════════════════════════════════════
   An opt-in dark opening for a page whose job is to sell rather than to
   explain: near-black ground, two coloured blooms, and the second line
   of the headline running mint → indigo.

   It is a SECTION variant, not a theme. The page under it stays light,
   so nothing here touches --ink or --paper — every rule paints its own
   colour and stops at the band's edge. That keeps one dark hero from
   quietly restyling the mega panels, which are children of .nav and
   must stay light sheets.

   Adding `.hero-dark` to a page is all it takes: the nav reads it with
   :has() below and flips to its light-on-dark tokens for free. */
/* The ground is a token on the BODY, not on .hero-dark: the strip below
   the hero is a sibling, and a custom property declared on the hero would
   not resolve there — the band would fall back to transparent. */
body.nx{--hero-ground:#0a0b0d;}
body.nx .hero-dark{
  background:var(--hero-ground);
  color:#fff;
}
/* Two blooms, warm violet top-left and brand green right, on a ground
   dark enough that neither reads as a colour cast. */
body.nx .hero-dark .hero-bg{
  background:
    radial-gradient(820px 520px at 8% 2%,  rgba(124,58,237,.30), transparent 62%),
    radial-gradient(760px 520px at 96% 14%, rgba(16,185,129,.20), transparent 60%),
    radial-gradient(900px 620px at 62% 104%, rgba(37,99,235,.16), transparent 62%);
}
/* The faint grid belongs to the light hero; on black it turns into visible
   banding, so it is dropped rather than re-tinted. */
body.nx .hero-dark::before{display:none;}

body.nx .hero-dark h1{color:#fff;max-width:17ch;}
/* A headline written to sit on one line gets no measure — 17ch is there to
   force a break in a two-line hero, and it would break this one mid-phrase. */
body.nx .hero-dark.hero-1line h1{max-width:none;}
/* The label above a dark hero is a chip like the badge, not the accent-tinted
   pill the light sections use — that one turns into a glowing lozenge here. */
body.nx .hero-dark .pill-tag{
  background:rgba(255,255,255,.06);
  border-color:rgba(255,255,255,.12);
  color:#e7ebf1;
}
body.nx .hero-dark h1 em,
body.nx .hero-dark h1 em .word{
  background:linear-gradient(96deg,var(--brand) 0%,#3ad0c0 34%,#4f6bf5 78%,#4f46e5 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
body.nx .hero-dark .lead{color:#a9b2be;}

/* badge — a dark chip, not the white card the light hero uses */
body.nx .hero-dark .hero-badge{
  background:rgba(255,255,255,.06);
  border-color:rgba(255,255,255,.12);
  color:#f2f5f9;box-shadow:none;
  backdrop-filter:blur(6px);
}
body.nx .hero-dark .hero-badge:hover{
  background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.22);box-shadow:none;
}
body.nx .hero-dark .hero-badge b{color:var(--brand);}

/* The filled button already carries the brand mint, which is drawn for a
   dark ground. Only the secondary needs restating: on black the default
   light-page outline disappears. */
body.nx .hero-dark .hero-cta .btn:not(.btn-primary){
  background:transparent;border-color:rgba(255,255,255,.32);color:#fff;
}
body.nx .hero-dark .hero-cta .btn:not(.btn-primary):hover{
  background:#fff;border-color:#fff;color:var(--nav-ink);
}

/* proof strip — an outline, not a card */
body.nx .hero-dark .proof-pill{
  background:rgba(255,255,255,.04);
  border-color:rgba(255,255,255,.14);
  box-shadow:none;
}
body.nx .hero-dark .proof-pill span{color:#c4ccd8;}
body.nx .hero-dark .proof-pill .ico{color:var(--brand);}

/* ── the logo strip, continued on the same ground ──────────────────
   The band under the hero is part of the dark opening in the reference,
   so it keeps the ground and fades out at the bottom edge — a hard seam
   between two full-width grounds reads as a rendering fault. */
body.nx .proof-dark{
  position:relative;background:var(--hero-ground);color:#fff;
  border-block-color:rgba(255,255,255,.08);
  padding-bottom:clamp(40px,4.6vw,60px);
}
/* No ramp into the light page. A dark→white gradient under the logos
   reads as a grey wash sitting on top of them; the dark opening is a
   BAND, and a band is allowed to end. */
body.nx .proof-dark p{color:#8f98a5;}
body.nx .proof-dark .lockup{color:#78808d;}

/* ── nav over a dark hero ──────────────────────────────────────────
   Detected, not declared: any page whose hero is dark gets the bar's
   light-on-dark tokens at rest, and the mint wordmark that the solid bar
   already uses. Without this the transparent bar keeps its dark ink and
   the whole menu vanishes into the hero. */
body.nx:has(.hero-dark) .nav{
  --nav-fg:#e8edf6;
  --nav-mark:var(--brand);
}
body.nx:has(.hero-dark) .wordmark .wm-rest{opacity:0;}
body.nx:has(.hero-dark) .wordmark .wm-alt{opacity:1;}
body.nx:has(.hero-dark) .burger{border-color:rgba(255,255,255,.22);}

/* ══ 28. DARK PROMISE BAND — mascot, claim, three beats ═════════════
   The second beat of the dark opening: Aria says something, the claim
   lands, and three cards summarise the journey the four-step spine
   below then walks through properly.

   The frame around the trio is a gradient the cards sit ON — one
   background, revealed by the container's padding and the gaps between
   its children. No per-card borders, so the dividers and the outer edge
   can never drift out of alignment. */
/* The ground, and the palette that goes with it.

   Every component on this site paints from the same handful of tokens, so
   a dark section is a token swap rather than a parallel set of `.dark .x`
   rules: the match card, its buttons, the factor rows and the chips all
   flip because --paper/--edge/--ink changed under them. Restating --acc*
   is not optional — those are computed on <body> from --candidate-*, so
   an inherited value would keep the light mint here. */
body.nx .band-dark,
body.nx .foot-dark{
  background:var(--hero-ground);color:#fff;

  --ink:#f4f7fb; --ink-2:#d6dce5; --mu:#a2abb8; --dim:#79828f;
  --paper:#111317; --paper-2:#161a1f; --paper-3:#1e232a;
  --edge:#282e36; --edge-soft:#1f242b;
  --acc:#2dd4bf; --acc-2:#5eead4; --acc-lt:#5eead4; --acc-soft:#0e2b2a;
  --sh-1:0 1px 2px rgba(0,0,0,.45), 0 4px 12px rgba(0,0,0,.35);
  --sh-2:0 2px 4px rgba(0,0,0,.5),  0 12px 28px rgba(0,0,0,.42);
  --sh-3:0 4px 8px rgba(0,0,0,.55), 0 24px 56px rgba(0,0,0,.5);
}
body.nx .promise{padding:clamp(56px,7vw,104px) 0 clamp(64px,8vw,116px);}
/* The footer keeps every measurement from the reference and moves only
   the ink: the grey that reads as quiet on white would vanish on this
   ground, and the 4px black rule has to become its own inverse. */
body.nx .foot-dark{
  --foot-ink:rgba(255,255,255,.62);
  background:var(--hero-ground);
  border-top-color:#fff;
}
body.nx .foot-dark li a:hover,
body.nx .foot-dark .socials a:hover{color:#fff;border-color:#fff;}

/* ── Aria, with something to say ── */
body.nx .mascot-say{
  display:flex;align-items:flex-end;justify-content:center;
  margin-bottom:clamp(26px,3vw,40px);
}
body.nx .mascot{
  position:relative;z-index:1;                 /* Aria sits IN FRONT of her bubble */
  width:clamp(72px,7vw,96px);aspect-ratio:1;flex:none;
  border-radius:22px;overflow:hidden;display:block;
  box-shadow:0 18px 40px rgba(0,0,0,.5);
}
body.nx .mascot img{width:100%;height:100%;object-fit:cover;display:block;}
/* Overlaps the avatar's lower-right corner, as a speech bubble from a
   character standing beside it would. */
body.nx .say{
  position:relative;z-index:0;margin:0 0 12px -26px;
  padding:14px 24px 14px 42px;border-radius:14px;
  background:#1c1e22;border:1px solid rgba(255,255,255,.07);
  font-size:clamp(14px,1.4vw,16px);color:#e7ebf1;
}

body.nx .promise h2{color:#fff;text-align:center;max-width:18ch;margin:0 auto;}
body.nx .promise h2 em{
  font-style:normal;
  background:linear-gradient(96deg,var(--brand) 0%,#3ad0c0 38%,#4f6bf5 82%,#4f46e5 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
body.nx .promise .lead{
  color:#a9b2be;text-align:center;max-width:70ch;
  margin:clamp(18px,2vw,26px) auto 0;
}

/* ── the three beats ── */
body.nx .trio{
  list-style:none;margin:clamp(38px,4.6vw,64px) 0 0;
  padding:5px;border-radius:22px;
  display:grid;grid-template-columns:repeat(3,1fr);gap:4px;
  background:linear-gradient(102deg,#1fbf9c 0%,#3d8fd6 34%,#6366f1 68%,#8b5cf6 100%);
  box-shadow:0 30px 70px rgba(0,0,0,.45);
}
body.nx .trio li{
  display:flex;flex-direction:column;gap:14px;
  padding:clamp(22px,2.4vw,32px);border-radius:17px;
  background:#0f1013;
}
body.nx .trio-n{
  width:28px;height:28px;border-radius:999px;display:grid;place-items:center;
  border:1.5px solid rgba(255,255,255,.45);
  font-size:13px;font-weight:600;color:#fff;font-variant-numeric:tabular-nums;
}
body.nx .trio h3{color:#fff;font-size:clamp(18px,1.9vw,22px);line-height:1.25;margin:0;}
body.nx .trio p{margin:0;font-size:14.5px;line-height:1.62;color:#a7afba;}

@media (max-width:900px){
  body.nx .trio{grid-template-columns:1fr;}
}
@media (max-width:520px){
  /* Stacked, the bubble beside a shrinking avatar runs out of room before
     the sentence does — so it drops under and centres. */
  body.nx .mascot-say{flex-direction:column;align-items:center;}
  body.nx .say{margin:-8px 0 0;padding:12px 18px;text-align:center;}
}

/* ══ 29. CATEGORY BAND + DARK CTA BAR ═══════════════════════════════
   Two pill rows drifting in opposite directions, then the one-line
   argument with the button attached. Both ride on .band-dark, so the
   palette comes from there and nothing below repeats a colour.

   The rows reuse .marquee wholesale — same duplicated-list trick, same
   hover pause, same edge mask. Only the direction and the speed differ,
   which is a variable, not a second implementation. */
body.nx .cats{padding:clamp(52px,6.5vw,92px) 0 clamp(56px,7vw,104px);}
body.nx .cats h2{
  color:#fff;text-align:center;max-width:30ch;margin:0 auto clamp(30px,3.6vw,48px);
  font-size:clamp(24px,3.1vw,38px);
}
body.nx .cat-rows{display:grid;gap:14px;}
/* The lists here are pills, not lockups — reset the lockup spacing that
   the client strip sets on the shared track. */
body.nx .cats .marquee-track ul{gap:14px;padding-right:14px;}
body.nx .cats .marquee-track li{opacity:1;}
body.nx .cat{
  display:inline-flex;align-items:center;
  padding:13px 26px;border-radius:999px;white-space:nowrap;
  background:#16191e;border:1px solid rgba(255,255,255,.07);
  font-size:15px;font-weight:500;color:#c3cad4;
  transition:border-color .18s,color .18s,background .18s;
}
body.nx .cats .marquee-track li:hover .cat{
  background:#1c2026;border-color:rgba(255,255,255,.18);color:#fff;
}
/* Second row runs the other way, so the two never read as one block
   sliding sideways. */
html.motion body.nx .marquee-rev .marquee-track{animation-direction:reverse;}

/* the argument, framed */
body.nx .cats .edge-band{max-width:980px;margin-inline:auto;}
/* The claim and its button are one sentence with a control on the end —
   wrapping them onto two rows turns the bar into a small card. Only a
   phone is allowed to stack it. */
@media (min-width:760px){
  body.nx .cats .edge-inner{flex-wrap:nowrap;}
  body.nx .cats .edge-inner .btn{flex:none;}
}
body.nx .band-dark .edge-inner{
  background:#0d0f13;color:#fff;
  gap:clamp(14px,2.4vw,26px);padding:16px 18px 16px clamp(20px,3vw,32px);
}
body.nx .band-dark .edge-inner b{color:#fff;}

/* ── the match section, on the dark ground ───────────────────────────
   Everything inside is already token-driven, so this is only about the
   two things that are not: the bloom behind the card (which would glow
   pale on black) and the copy colour of the standalone check list. */
body.nx .band-dark .glow-frame::before{
  filter:blur(24px);opacity:.55;
}
body.nx .band-dark .checks li{color:var(--ink-2);}
/* The amber "worth knowing" row is the one factor state painted in raw
   hex rather than tokens — it has no dark equivalent to inherit, so it
   gets one here. Same meaning, same warmth, a ground that belongs. */
body.nx .band-dark .fx-row.watch{background:#241b0b;border-color:#4b3614;}
body.nx .band-dark .fx-row.watch .ico{color:#f0b45f;}
body.nx .band-dark .eyebrow{color:var(--acc-lt);}
body.nx .band-dark .pill-tag{color:var(--acc-lt);}

/* ══ 30. COMPARISON TABLE ═══════════════════════════════════════════
   Two columns of claims, ours lit and theirs quiet. Built as a real
   <table> with row headers, because that is what it is — a screen
   reader should be able to say "Salary fit: shown up front" without the
   user having to hold the column in their head.

   The only decoration is a hairline grid. Boxes around the winning
   column would do the arguing for the copy. */
body.nx .vs-wrap{overflow-x:auto;margin-top:clamp(34px,4.4vw,58px);}
body.nx .vs{
  width:100%;min-width:660px;border-collapse:collapse;
  font-size:14.5px;
}
body.nx .vs th,body.nx .vs td{
  padding:17px 24px;text-align:center;vertical-align:middle;
  border-bottom:1px solid var(--edge-soft);
}
/* The label column is a quiet stub: left-aligned, unemphasised, and
   without the vertical rule that separates the two answers. */
body.nx .vs tbody th{
  text-align:left;font-weight:400;color:var(--mu);width:32%;
  padding-left:0;
}
body.nx .vs thead td{border-bottom:1px solid var(--edge);}
body.nx .vs thead th{
  border-bottom:1px solid var(--edge);
  padding-top:0;font-size:15px;
}
body.nx .vs .col-us,body.nx .vs .col-them{border-left:1px solid var(--edge-soft);}
body.nx .vs thead .col-us,body.nx .vs thead .col-them{border-left:1px solid var(--edge);}
body.nx .vs .col-us{color:var(--ink);font-weight:500;}
body.nx .vs .col-them{color:var(--dim);}
body.nx .vs tbody tr:last-child th,body.nx .vs tbody tr:last-child td{border-bottom:0;}
body.nx .vs-head{
  display:inline-flex;align-items:center;gap:9px;
  font-size:clamp(17px,1.9vw,21px);font-weight:700;color:var(--ink);
}
body.nx .vs-head img{width:26px;height:26px;border-radius:8px;object-fit:cover;}
body.nx .vs-sub{
  display:block;margin-top:5px;font-size:12.5px;font-weight:400;color:var(--dim);
}
/* inline-flex, not inline: an inline box wrapping an icon reports the whole
   line box, which parks the tick at the start of a two-line cell instead of
   beside the words it belongs to. */
body.nx .vs .yes,body.nx .vs .no{
  display:inline-flex;vertical-align:middle;margin-right:7px;
}
body.nx .vs .yes{color:var(--acc);}
body.nx .vs .no{color:var(--dim);opacity:.7;margin-right:0;}
body.nx .vs .ico{width:19px;height:19px;}
@media (max-width:640px){
  body.nx .vs th,body.nx .vs td{padding:14px 16px;}
}

/* the closing argument, same framed bar as the category band */
body.nx .vs-cta{max-width:900px;margin:clamp(34px,4vw,54px) auto 0;}
@media (min-width:760px){
  body.nx .vs-cta .edge-inner{flex-wrap:nowrap;}
  body.nx .vs-cta .edge-inner .btn{flex:none;}
}

/* ── FAQ, centred ──
   The label sits above a centred heading here rather than the left-hung
   eyebrow the reference pages use, so the questions below read as the
   page's closing conversation rather than another section of argument. */
body.nx .faq-centred .faq{margin-inline:auto;}
body.nx .faq-centred .sec-head{margin-inline:auto;text-align:center;}

/* ── dark-band corrections for components that ship their own ground ──
   Both of these paint a colour rather than a token, so neither notices
   that the section around it went dark. */
body.nx .band-dark .guards{background:#20252c;}
body.nx .band-dark .guard{background:#131720;}
body.nx .band-dark .mock-foot .btn{background:var(--paper-2);}

/* ══ 31. FAQ — CARD VARIANT ═════════════════════════════════════════
   The hairline list becomes a stack of rounded cards: each question is
   its own object, and the open one grows rather than pushing a rule
   down the page. Same <details> underneath — no script, and the browser
   still owns the open/close semantics.

   Everything here paints from tokens, so the stack works on the light
   page too; it is only dark on this page because the section is. */
body.nx .faq-cards{border-top:0;display:grid;gap:10px;max-width:760px;margin-inline:auto;}
/* No border. The card is separated from the page by its own lift — a
   step in lightness — and an outline on top of that draws a second
   boundary a few pixels outside the first one. The lift is mixed from
   --ink rather than hardcoded so the stack works on the light pages too:
   the same 7% reads as a pale grey card there and a raised one here. */
body.nx .faq-cards details{
  border:0;border-radius:16px;overflow:hidden;
  background:color-mix(in srgb,var(--ink) 7%,var(--paper));
  transition:background .2s var(--ease);
}
body.nx .faq-cards details:hover{background:color-mix(in srgb,var(--ink) 10%,var(--paper));}
/* Open keeps the same ground. Recolouring it makes the answer read as a
   different kind of surface from the question that opened it. */
body.nx .faq-cards summary{
  padding:21px clamp(18px,2vw,26px);font-size:16px;font-weight:600;
}
/* The marker loses its ring here — inside a card the plus is already
   sitting on its own surface, and a second outline round it reads as a
   button you can press separately from the row. */
body.nx .faq-cards .pm{border-color:transparent;width:22px;height:22px;color:var(--dim);}
body.nx .faq-cards summary:hover .pm{color:var(--ink);}
body.nx .faq-cards details[open] .pm{background:none;color:var(--mu);}
body.nx .faq-cards details p{
  padding:0 clamp(18px,2vw,26px) 24px;margin:0;max-width:76ch;
  font-size:14px;line-height:1.62;
}

/* ══ 32. ROLE INDEX ═════════════════════════════════════════════════
   A directory: every category listed once at the top as a jump link,
   then a block per category with the titles under it.

   The index links are underlined rather than coloured. Twenty links in
   the accent turns the top of the section into a wall of teal, and the
   underline is the thing that says "link" without spending colour on
   it — colour arrives on hover. */
body.nx .index-head{
  font-size:clamp(19px,2vw,23px);font-weight:700;color:var(--ink);
  margin:0 0 clamp(22px,2.6vw,32px);
}
body.nx .skillset{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:18px clamp(20px,3vw,44px);margin:0 0 clamp(48px,6vw,86px);padding:0;
  list-style:none;
}
body.nx .skillset a{
  font-size:15px;color:var(--ink-2);
  text-decoration:underline;text-underline-offset:4px;
  text-decoration-color:color-mix(in srgb,var(--ink) 35%,transparent);
  transition:color .16s,text-decoration-color .16s;
}
body.nx .skillset a:hover{color:var(--acc);text-decoration-color:currentColor;}

/* one category */
body.nx .rolecat{
  padding-top:clamp(26px,3vw,38px);margin-top:clamp(26px,3vw,38px);
  border-top:1px solid var(--edge);
}
body.nx .rolecat:first-of-type{border-top:0;margin-top:0;padding-top:0;}
body.nx .rolecat-top{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  margin-bottom:clamp(18px,2vw,26px);
}
/* Category names carry their own colour — the pale rose from Aria's own
   plate, which is the one hue on the site that belongs to neither audience
   temperature. It marks 25 headings as one class of thing without spending
   the teal (which means "accent, click me") or the white (which every other
   heading on the page already uses). */
body.nx{--cat-key:#edb7d4;}
body.nx .rolecat-top h3{font-size:clamp(18px,2vw,22px);margin:0;color:var(--cat-key);}
/* Titles, not links: the board is what you search, and twenty dead links
   per category is worse than a list that plainly is a list. */
/* One column, alphabetical. A four-across grid packs more titles into the
   fold, but the eye has to scan in two directions to find a word it half
   remembers — a single alphabetical column is a directory you can run a
   finger down. */
body.nx .rolelist{
  display:grid;grid-template-columns:minmax(0,1fr);
  gap:11px;margin:0;padding:0;list-style:none;max-width:520px;
}
body.nx .rolelist li{font-size:14.5px;line-height:1.45;color:var(--mu);}

@media (max-width:900px){
  body.nx .skillset{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:560px){
  body.nx .skillset{grid-template-columns:1fr;}
  body.nx .rolecat-top{flex-direction:column;align-items:flex-start;gap:12px;}
}

/* ══ 33. HERO — LEFT-ALIGNED, WITH A CRUMB ══════════════════════════
   A guide's opening, not a landing page's: the headline is set large on
   a narrow measure so it stacks, sits left in the content column, and
   carries a breadcrumb underneath instead of a pair of buttons.

   The measure is what makes it look like the reference — set the same
   words across the full column and it reads as a banner. */
body.nx .hero-doc .hero-in{text-align:left;margin-inline:auto;}
body.nx .hero-doc h1{
  max-width:13ch;margin:0 0 clamp(22px,2.6vw,32px);
  font-size:clamp(40px,7.2vw,82px);line-height:1.04;
}
body.nx .hero-doc .lead{margin:0 0 clamp(22px,2.6vw,30px);}
body.nx .hero-doc .hero-cta{justify-content:flex-start;}

/* breadcrumb */
body.nx .crumb{
  display:flex;align-items:center;flex-wrap:wrap;gap:9px;
  font-size:13.5px;color:var(--dim);
}
body.nx .crumb a{color:var(--mu);transition:color .16s;}
body.nx .crumb a:hover{color:var(--acc-lt,var(--acc));}
body.nx .crumb .sep{color:var(--dim);opacity:.7;}
body.nx .hero-dark .crumb{color:#8b93a0;}
body.nx .hero-dark .crumb a{color:#b8c0cc;}

/* ══ 34. GUIDE INDEX — a pinned sign-up card beside the track cards ══
   The reference guide index keeps ONE dark sign-up card in a left rail
   while the guides run two-up beside it, so the offer stays on screen
   for the whole scroll instead of waiting at the bottom of the page.
   Same structure here, in our palette.

   Grid rather than a float: the rail is a fixed measure and the cards
   take what is left, so every card keeps the same width at every
   viewport. `minmax(0,1fr)` on the second track is load-bearing — a
   grid track floors at min-content, and one long unbroken word in a
   card would otherwise widen the grid past the page instead of
   wrapping inside it. */
body.nx .guide-index{
  display:grid;
  grid-template-columns:clamp(272px,24vw,336px) minmax(0,1fr);
  gap:clamp(22px,3vw,40px);
  align-items:start;                  /* the rail needs room to travel */
}
body.nx .guide-index .cards{grid-template-columns:repeat(2,1fr);}
/* The aside travels with the nine cards rather than leaving a column of
   dead space beside the last row. It needs the wrapper: a sticky grid
   item is confined to its grid AREA, and `align-items:start` above
   shrinks that area to the card's own height, so it has nowhere to go.
   The rail stretches to the full row; the card sticks inside it. */
body.nx .guide-index .join-rail{align-self:stretch;}
body.nx .guide-index .join{position:sticky;top:calc(var(--nav-sm) + 24px);}

/* ── the guide card ──
   Plainer than .card-x on purpose, and a SEPARATE class because card-x
   is shared by eight other pages. No category pill and no icon: on an
   index whose whole job is "which of these do I read", a row of tags and
   glyphs competes with the only thing that answers that — the title. So
   the title carries the weight and everything else recedes. */
body.nx .gcard{
  display:flex;flex-direction:column;
  padding:clamp(22px,2vw,28px);border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
body.nx .gcard:hover{
  border-color:color-mix(in srgb,var(--acc) 42%,var(--edge));
  box-shadow:var(--sh-1);
}
body.nx .gcard h4{
  margin:0 0 12px;font-size:clamp(19px,1.7vw,23px);line-height:1.22;
  letter-spacing:-.012em;color:var(--ink);text-wrap:balance;
}
body.nx .gcard p{
  margin:0 0 18px;font-size:13.5px;line-height:1.6;color:var(--mu);
}
/* Pushes the link to the bottom so a short card and a long one still
   line their links up across a row. */
/* The link styles live under .card-x, so .gcard inherits none of them —
   without this the arrow wraps onto its own line and the link renders as
   plain body text. Restated here rather than widening the .card-x
   selector, which eight other pages depend on. */
body.nx .gcard .go{
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  margin-top:auto;align-self:flex-start;
  font-size:13.5px;font-weight:600;color:var(--acc);
}
body.nx .gcard .go .ico{
  width:16px;height:16px;flex:none;transition:transform .24s var(--ease);
}
body.nx .gcard:hover .go .ico{transform:translateX(4px);}

@media (max-width:900px){
  body.nx .guide-index{grid-template-columns:minmax(0,1fr);}
  body.nx .guide-index .join{position:static;}
  body.nx .guide-index .join-rail{align-self:start;}
  body.nx .join{position:static;}
  body.nx .guide-index .cards{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:620px){
  body.nx .guide-index .cards{grid-template-columns:minmax(0,1fr);}
}

/* The card is dark on a light page, so it takes the same palette SWAP
   the dark band uses rather than a parallel set of overrides — the
   type, the hairlines, the field and the checkbox all repaint from
   tokens they already read. --acc comes down to its own light variant
   instead of a hardcoded teal, so the card follows the audience the
   page is set to: mint for a jobseeker, indigo for an employer. */
body.nx .join{
  position:sticky;top:calc(var(--nav-sm) + 28px);
  padding:clamp(24px,2.5vw,32px);border-radius:var(--r-lg);
  background:var(--hero-ground);box-shadow:var(--sh-2);
  --ink:#f4f7fb; --ink-2:#d6dce5; --mu:#a2abb8; --dim:#79828f;
  --paper:#111317; --paper-2:#161a1f; --paper-3:#1e232a;
  --edge:#2b323b; --edge-soft:#1f242b;
  --acc:var(--acc-lt);
}
body.nx .join h3{margin:0 0 10px;font-size:clamp(20px,1.9vw,24px);color:var(--ink);}
body.nx .join>p{margin:0 0 20px;font-size:14px;line-height:1.6;color:var(--mu);}
body.nx .join-form{display:grid;gap:11px;}
body.nx .join-form .btn{width:100%;justify-content:center;margin-top:3px;}
body.nx .join-label{font-size:12.5px;font-weight:600;color:var(--ink-2);}
body.nx .join-label .req{color:var(--acc);}
body.nx .join-form input[type=email]{
  width:100%;padding:11px 13px;border-radius:var(--r-btn);
  background:var(--paper-2);border:1px solid var(--edge);color:var(--ink);
  font:inherit;font-size:14.5px;
  transition:border-color .18s,box-shadow .18s;
}
body.nx .join-form input[type=email]::placeholder{color:var(--dim);}
body.nx .join-form input[type=email]:focus{
  outline:none;border-color:var(--acc);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--acc) 26%,transparent);
}
/* The consent row is a control, not a caption: the box holds its target
   size at every text size and the line wraps beside it, never under. */
body.nx .join-check{
  display:flex;gap:10px;align-items:flex-start;cursor:pointer;
  font-size:12.5px;line-height:1.5;font-weight:400;color:var(--mu);
}
body.nx .join-check input{
  appearance:none;flex:none;width:17px;height:17px;margin-top:1px;
  border:1px solid var(--edge);border-radius:5px;background:var(--paper-2);
  cursor:pointer;transition:background .15s,border-color .15s;
}
body.nx .join-check input:checked{background:var(--acc);border-color:var(--acc);}
body.nx .join-check input:checked::after{
  content:'';display:block;width:5px;height:9px;margin:1px auto 0;
  border:solid var(--hero-ground);border-width:0 2px 2px 0;transform:rotate(45deg);
}
body.nx .join-check a{color:var(--ink-2);text-decoration:underline;text-underline-offset:2px;}
body.nx .join-check a:hover{color:var(--acc);}
body.nx .join-note{margin:15px 0 0;font-size:12px;color:var(--dim);}

@media (max-width:1040px){
  /* Stacked, the card has nothing left to stick to — and a pinned block
     on a narrow screen is just a header that eats the viewport. */
  body.nx .guide-index{grid-template-columns:minmax(0,1fr);}
  body.nx .guide-index .join{position:static;}
  body.nx .guide-index .join-rail{align-self:start;}
  body.nx .join{position:static;}
}
@media (max-width:640px){
  body.nx .guide-index .cards{grid-template-columns:1fr;}
}


/* ══ 35. AUTH — the split sign-up ═══════════════════════════════════
   The conversion page sits between the two surfaces: it uses the
   marketing type and tokens, but the CONTROLS inside it are app.css
   components (.field, .input, .seg, .alert) and stay that way. So this
   block does not restyle those components — it swaps the app tokens
   they already read, page-scoped, and dark. One consequence worth the
   trade: the nav that api.js injects sits inside the same scope and
   repaints with everything else, so there is no second nav to build.

   Scoped on body.auth-page rather than a wrapper, because the nav is
   inserted as the body's first child and has to be inside the swap.

   Unlike the marketing dark band, the card face here is LIFTED off the
   ground rather than matching it. A near-black card on a near-black
   page has only its border to separate the two, and the form then
   reads as part of the page instead of as an object sitting on it. */
/* app.css owns the form controls — .field, .input, .select, .seg, .alert —
   and every one of them is drawn for a light page. Both dark surfaces on
   this site (the sign-up card and the setup flow) need the same answer,
   so the token swap lives once, here, and each of them opts in. Without
   it a label is near-black type on a near-black panel: invisible, and
   invisible in a way that only shows up on a real screen. */
body.auth-page,
body.nx .setup-main{
  --bg:#0a0c0e; --bg-2:#2b3036; --bg-3:#333940;
  --surface:#1e2226;
  --line:#333940; --line-soft:#282d33;
  --tx:#f4f7fb; --tx-mu:#a8b2bd; --tx-dim:#7c8794;
  /* app.css draws links and menu hovers from the teal set; on this ground
     the light variants are the legible ones. */
  --teal:#2dd4bf; --teal-dk:#5eead4; --teal-lt:#2dd4bf; --teal-soft:#12312e;
}
/* Two hardcoded whites a token swap cannot reach, and the alert, which is
   a pale pink card on light and a highlighter stripe on this ground. */
body.auth-page .input, body.nx .setup-main .input,
body.auth-page .select, body.nx .setup-main .select,
body.auth-page .textarea, body.nx .setup-main .textarea{
  background:var(--bg-2);border-color:transparent;padding:13px 15px;
}
body.auth-page .input:focus, body.nx .setup-main .input:focus,
body.auth-page .select:focus, body.nx .setup-main .select:focus,
body.auth-page .textarea:focus, body.nx .setup-main .textarea:focus{
  border-color:var(--acc-lt);box-shadow:0 0 0 3px color-mix(in srgb,var(--acc-lt) 22%,transparent);
}
body.auth-page .input::placeholder, body.nx .setup-main .input::placeholder{color:var(--dim);}
body.auth-page .seg, body.nx .setup-main .seg{background:var(--bg-2);border-color:transparent;}
body.auth-page .alert-err, body.nx .setup-main .alert-err{
  background:#2f1319;border-color:#5c2230;color:#ffb1bf;
}

body.auth-page{
  /* The marketing side of the same swap. --paper is the card FACE, two
     steps above the ground; --paper-2 is the field fill on top of it. */
  --ink:#f4f7fb; --ink-2:#d6dce5; --mu:#a8b2bd; --dim:#7c8794;
  --paper:#1e2226; --paper-2:#2b3036; --paper-3:#333940;
  --edge:#333940; --edge-soft:#282d33;
  color:var(--ink-2);
  /* Two low glows keep the ground from reading as flat black — one in the
     accent, one in the other audience's, both far enough down in alpha to
     stay atmosphere rather than colour. They live on the BODY so they do
     not scroll away from a tall form. */
  background:
    radial-gradient(900px 620px at 12% 8%, color-mix(in srgb,var(--acc-lt) 11%,transparent), transparent 70%),
    radial-gradient(760px 560px at 88% 96%, color-mix(in srgb,#6366f1 9%,transparent), transparent 72%),
    var(--bg);
  background-attachment:fixed;
}
/* Hardcoded whites in app.css that a token swap cannot reach. */
body.auth-page .nav{background:rgba(10,12,14,.7);}
body.auth-page .nav.scrolled{
  background:rgba(10,12,14,.92);box-shadow:0 10px 30px rgba(0,0,0,.5);
}
body.auth-page .nav-panel{background:var(--surface);}

body.nx.auth-page .auth-split{
  min-height:100vh;display:flex;align-items:flex-start;
  padding:calc(var(--nav) + clamp(20px,3vw,44px)) var(--gut) clamp(40px,6vw,80px);
}
body.nx.auth-page .auth-grid{
  width:100%;max-width:1280px;margin-inline:auto;
  display:grid;grid-template-columns:minmax(0,520px) minmax(0,1fr);
  gap:clamp(30px,5vw,84px);
  /* Top-aligned, not centred: the column beside the card is read while
     the form is being filled, so its first line belongs level with the
     form's first line rather than floating at the card's midpoint. */
  align-items:start;
}
/* Sign-in has nothing to prove alongside it — one column, centred. */
body.nx.auth-page .auth-grid.solo{grid-template-columns:minmax(0,520px);justify-content:center;}
/* …and short enough to sit in the middle of the screen. The split page
   is top-aligned because its right column is read alongside the form;
   with no column there is nothing to align to. */
body.nx.auth-page .auth-split:has(.auth-grid.solo){align-items:center;}

/* The frame is a real band, not a hairline: an outer element carrying the
   gradient with the card inset inside it. The gradient runs from the
   audience accent into the other audience's and then dies into the
   ground, so it is thick and lit along the top-left and gone by the
   bottom-right — this card is the fork between the two doors, and the
   segmented control above the form is what picks a side. */
body.nx.auth-page .auth-card{
  padding:clamp(9px,1vw,14px);border-radius:clamp(22px,2.4vw,30px);
  background:linear-gradient(142deg,
    var(--acc-lt) 0%,
    color-mix(in srgb,var(--acc-lt) 45%, #6366f1) 26%,
    color-mix(in srgb,#6366f1 32%, var(--bg)) 46%,
    var(--bg) 68%);
  box-shadow:0 40px 110px rgba(0,0,0,.6);
}
body.nx.auth-page .auth-face{
  background:var(--paper);border-radius:clamp(14px,1.6vw,19px);
  padding:clamp(24px,2.8vw,36px);
}
body.nx.auth-page .auth-face h1{
  font-size:clamp(24px,2.4vw,29px);line-height:1.15;margin:0 0 8px;
}
body.nx.auth-page .auth-sub{
  margin:0 0 26px;font-size:14.5px;line-height:1.55;color:var(--mu);
}
body.nx.auth-page .req{color:#f97362;}
/* Seven fields plus a segment is a tall card. app.css spaces its fields
   for a short form on its own page; here they close up a little so the
   whole card lands inside a laptop viewport without a scroll. */
body.nx.auth-page .auth-face .field{margin-bottom:15px;gap:7px;}
body.nx.auth-page .auth-face .hint{font-size:12px;}

/* The one gradient control on the site. It is reserved for this button
   because this is the only page with a single action worth that weight —
   everywhere else the flat brand fill keeps its meaning by not competing
   with it. The sweep ends in the audience accent, so the button and the
   frame around the card are lit by the same two colours. */
body.nx.auth-page .auth-face .btn-primary{
  width:100%;padding:15px 22px;font-size:15.5px;border:0;
  color:var(--brand-ink);
  background:linear-gradient(97deg,var(--brand) 0%,
    color-mix(in srgb,var(--brand) 55%, var(--acc-lt)) 62%,
    var(--acc-lt) 100%);
}
body.nx.auth-page .auth-face .btn-primary:hover{
  filter:brightness(1.06);box-shadow:0 12px 34px color-mix(in srgb,var(--brand) 26%,transparent);
}
body.nx.auth-page .auth-alt{
  margin-top:24px;padding-top:20px;border-top:1px solid var(--edge);
  text-align:center;font-size:14px;color:var(--mu);
}
body.nx.auth-page .auth-alt a{color:var(--acc-lt);font-weight:600;}
body.nx.auth-page .auth-alt a:hover{text-decoration:underline;}
/* The other door, on its own line under the sign-in link. Quieter than
   the line above it: most people arriving here are on the right page
   already, and this is the exit for the few who are not. */
body.nx.auth-page .auth-swap{display:block;margin-top:8px;font-size:13px;color:var(--dim);}
body.nx.auth-page .auth-swap a{color:var(--mu);font-weight:500;text-decoration:underline;text-underline-offset:2px;}
body.nx.auth-page .auth-swap a:hover{color:var(--acc-lt);}

/* ── the column beside it ── */
body.nx.auth-page .auth-proof{padding-top:clamp(4px,1vw,14px);}
body.nx.auth-page .auth-proof h2{
  font-size:clamp(21px,2vw,26px);margin:0 0 clamp(18px,2vw,26px);
}
/* Cards in a two-up grid, matching the card the form sits in: same face,
   same radius, one step in from its padding. */
body.nx.auth-page .proof-list{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;
}
body.nx.auth-page .proof-list li{
  display:flex;flex-direction:column;gap:12px;
  padding:22px;border-radius:var(--r-lg);
  background:var(--paper);border:1px solid var(--edge);
}
body.nx.auth-page .proof-list b{
  display:block;font-size:15.5px;font-weight:600;color:var(--ink);
}
body.nx.auth-page .proof-list p{
  margin:7px 0 0;font-size:13.5px;line-height:1.6;color:var(--mu);
}
body.nx.auth-page .proof-list .ico-plate{flex:none;}
body.nx.auth-page .proof-foot{
  margin:clamp(20px,2.4vw,28px) 0 0;padding-top:18px;
  border-top:1px solid var(--edge);font-size:13px;color:var(--dim);
}

@media (max-width:1080px){
  body.nx.auth-page .proof-list{grid-template-columns:minmax(0,1fr);}
}
@media (max-width:980px){
  /* Stacked, the form leads — the proof is what you read while deciding,
     not what you scroll past to reach the fields. */
  body.nx.auth-page .auth-grid{grid-template-columns:minmax(0,1fr);max-width:560px;}
  body.nx.auth-page .proof-list{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:620px){
  body.nx.auth-page .proof-list{grid-template-columns:minmax(0,1fr);}
}
@media (max-width:420px){
  /* "Looking for work" wraps to two lines at app.css's 14px, which turns
     the segment into a two-storey block above the first field. */
  body.auth-page .seg button{padding:9px 6px;font-size:13px;}
}

/* ── the two sections under the sign-up form ──
   The client strip and the FAQ are the landing page's components reused
   verbatim; only their grounds need saying again, because both are drawn
   for a light page and this one is not. */
body.auth-page .proof{background:transparent;border-color:var(--edge);}
/* .faq-cards lifts its cards off --paper, which here is the FORM card's
   face — a card that light would sit two steps above the ground it is
   actually on. Mixed off --bg instead, the stack lands just clear of the
   page, the way the reference draws it. */
body.auth-page .faq-cards details{background:color-mix(in srgb,var(--ink) 6%,var(--bg));}
body.auth-page .faq-cards details:hover{background:color-mix(in srgb,var(--ink) 9%,var(--bg));}
/* The pill stays neutral. An accent one directly under a gradient-framed
   card is a third colour arriving with nothing to say. */
body.auth-page .pill-tag{
  background:var(--paper-2);border-color:var(--edge);color:var(--mu);
}
body.nx.auth-page .faq-centred h2{max-width:18ch;margin-inline:auto;}
/* .foot-dark brings its own palette, but its ground is the marketing
   hero's black and this page's is a hair warmer — take the page's, or the
   footer reads as a separate slab pasted under the FAQ. */
body.auth-page .foot-dark{background:var(--bg);}

/* ══ 36. SETUP — the onboarding steps ═══════════════════════════════
   Two panels, one screen: the step on a dark ground and a light panel
   beside it. No nav bar on purpose — this is a flow with one thing to
   do per screen, and a menu here is an invitation to leave it.

   The dark palette is scoped to the LEFT panel rather than the body,
   because the right one is the page's normal light surface. Same token
   swap the dark band uses, so every component inside repaints itself. */
body.nx.setup-page{background:var(--paper);}
body.nx .setup{
  min-height:100vh;
  display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);
}
body.nx .setup-main{
  display:flex;flex-direction:column;
  padding:clamp(28px,3.4vw,52px) clamp(24px,4vw,72px) clamp(24px,3vw,40px);
  background:#0a0c0e;
  --ink:#f4f7fb; --ink-2:#d6dce5; --mu:#a8b2bd; --dim:#7c8794;
  --paper:#14181c; --paper-2:#1e2226; --paper-3:#272c32;
  --edge:#2b323b; --edge-soft:#222831;
  --acc:var(--acc-lt);
  color:var(--ink-2);
}
body.nx .setup-mark{display:inline-block;flex:none;}
body.nx .setup-mark img{height:38px;width:auto;display:block;}

/* ── progress ──
   One continuous track with a leading fill, per the reference, rather
   than a segment per step. The fill sits at the MIDDLE of the current
   step — a bar that reads full while you are still answering the last
   question says the work is done when it is not.

   The step names stay in the markup for a screen reader; they are what
   makes an <ol> of bars mean anything without sight of the page. */
body.nx .steps-bar{
  position:relative;list-style:none;margin:clamp(26px,3vw,44px) 0 0;padding:0;
  height:3px;border-radius:3px;background:var(--paper-3);overflow:hidden;
}
body.nx .steps-bar::after{
  content:'';position:absolute;inset:0 auto 0 0;width:var(--p,0%);
  border-radius:3px;background:var(--brand);
  transition:width .6s var(--ease);
}
body.nx .steps-bar li{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);}

/* ── the step ── */
body.nx .setup-body{
  flex:1;display:flex;flex-direction:column;justify-content:center;
  padding:clamp(28px,4vw,56px) 0;max-width:620px;
}
body.nx .setup-body h1{font-size:clamp(30px,3.6vw,46px);line-height:1.08;margin:0 0 14px;}
body.nx .setup-body .lead{margin:0 0 clamp(26px,3vw,38px);}

/* The tab sits ON the frame's edge rather than above it, so the label
   and the box it names are one object — the reference's detail, and the
   thing that stops it reading as a stray caption. */
body.nx .drop-frame{
  position:relative;
  border:1px solid color-mix(in srgb,var(--brand) 45%,transparent);
  border-radius:var(--r-lg);padding:clamp(14px,1.6vw,20px);
  background:var(--paper);
}
body.nx .drop-tab{
  position:absolute;top:0;left:clamp(14px,1.6vw,20px);transform:translateY(-50%);
  padding:4px 11px;border-radius:7px;background:var(--brand);color:var(--brand-ink);
  font-size:11px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;
}
body.nx .drop{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:clamp(28px,3.6vw,46px) 24px;cursor:pointer;
  border:1.5px dashed var(--edge);border-radius:var(--r);
  background:var(--paper-2);text-align:center;
  transition:border-color .18s,background .18s;
}
body.nx .drop:hover{border-color:color-mix(in srgb,var(--brand) 50%,var(--edge));}
/* Dragging over is a state worth showing loudly: the cursor is carrying
   something and the question is whether letting go will work. */
body.nx .drop.is-over{
  border-color:var(--brand);background:color-mix(in srgb,var(--brand) 8%,var(--paper-2));
}
body.nx .drop.is-bad{border-color:#f9736255;}
body.nx .drop-title{margin:6px 0 0;font-size:15.5px;color:var(--ink);}
body.nx .drop-sub{margin:0;font-size:13px;color:var(--dim);}
body.nx .linkish{
  background:none;border:0;padding:0;cursor:pointer;font:inherit;
  color:var(--brand);text-decoration:underline;text-underline-offset:2px;
}
body.nx .drop-err{margin:12px 2px 0;font-size:13px;color:#f97362;}

body.nx .file-card{
  display:flex;align-items:center;gap:14px;
  padding:16px 18px;border-radius:var(--r);
  background:var(--paper-2);border:1px solid var(--edge);
}
body.nx .file-meta{min-width:0;flex:1;}
body.nx .file-meta b{
  display:block;font-size:15px;color:var(--ink);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
body.nx .file-meta span{font-size:12.5px;color:var(--dim);font-variant-numeric:tabular-nums;}

body.nx .setup-actions{
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex:none;
}
/* "Not ready yet", one convention for the whole flow. Dimmed rather than
   `disabled`, because the click still has something to say: a dead
   button cannot tell you which answer is missing, and that sentence is
   the entire reason the warning under the field exists. */
body.nx .setup-actions .btn-primary{transition:opacity .2s var(--ease),box-shadow .2s var(--ease);}
body.nx .setup-actions .btn-primary.is-off{opacity:.42;box-shadow:none;}
body.nx .setup-actions .btn-primary.is-off:hover{opacity:.55;}

/* ── the light panel ── */
body.nx .setup-aside{
  display:flex;align-items:center;justify-content:center;
  padding:clamp(28px,4vw,64px);background:var(--paper-2);
}
body.nx .aside-card{
  max-width:420px;padding:clamp(26px,2.6vw,36px);
  background:var(--paper);border:1px solid var(--edge);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);
}
body.nx .aside-steps{
  list-style:none;counter-reset:s;margin:22px 0 0;padding:0;display:grid;gap:20px;
}
body.nx .aside-steps li{counter-increment:s;padding-left:38px;position:relative;}
body.nx .aside-steps li::before{
  content:counter(s);position:absolute;left:0;top:-1px;
  width:26px;height:26px;border-radius:8px;display:grid;place-items:center;
  background:var(--acc-soft);color:var(--acc);
  font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;
}
body.nx .aside-steps b{display:block;font-size:15.5px;color:var(--ink);margin-bottom:4px;}
body.nx .aside-steps p{margin:0;font-size:13.5px;line-height:1.6;color:var(--mu);}
body.nx .aside-foot{
  margin:26px 0 0;padding-top:20px;border-top:1px solid var(--edge);
  font-size:12.5px;line-height:1.6;color:var(--dim);
}

@media (max-width:900px){
  /* Stacked, the panel goes under the step: it is context for the flow,
     and context above the thing it explains pushes the actual task off
     the first screen. */
  body.nx .setup{grid-template-columns:minmax(0,1fr);}
  body.nx .setup-main{min-height:100vh;}
  body.nx .aside-card{max-width:none;}
}

/* ── setup: the reading screen ──
   Same two panels as the upload step; what changes is that the middle of
   the left one is a list that moves on its own. Every state here is
   driven by a line arriving from the server, so nothing below is on a
   timer except the spinner's own rotation. */
body.nx .read-body{justify-content:center;}
body.nx .reader{text-align:center;margin-bottom:clamp(26px,3vw,38px);}
/* The ring reads as attention on the face rather than as a progress
   circle: it is continuous and unmoving, so it cannot be mistaken for a
   percentage that has stopped. */
body.nx .reader-face{
  display:inline-grid;place-items:center;width:86px;height:86px;border-radius:999px;
  background:var(--paper-2);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--brand) 34%,transparent),
             0 0 0 9px color-mix(in srgb,var(--brand) 7%,transparent),
             0 18px 44px rgba(0,0,0,.5);
}
body.nx .reader-face img{width:64px;height:64px;border-radius:999px;display:block;object-fit:cover;}
body.nx .reader-name{
  display:block;margin-top:14px;
  font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--brand);
}
body.nx .read-body h1{font-size:clamp(26px,3vw,38px);margin:12px 0 12px;}
body.nx .read-body .lead{margin:0 auto;max-width:46ch;}
body.nx .reader + .tasks{margin-top:0;}

body.nx .tasks{
  list-style:none;margin:0;padding:8px;display:grid;gap:2px;
  background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-lg);
}
body.nx .tasks li{
  display:flex;align-items:center;gap:14px;
  padding:15px 14px;border-radius:var(--r);
  opacity:.42;transition:opacity .3s var(--ease),background .3s var(--ease);
}
/* Pending rows are dimmed rather than hidden: the list is also a promise
   about how much is left, and a row that appears only when it starts
   makes the end of the list impossible to see. */
body.nx .tasks li.is-active{opacity:1;background:color-mix(in srgb,var(--brand) 7%,transparent);}
body.nx .tasks li.is-done{opacity:1;}
body.nx .task-ico{
  width:38px;height:38px;border-radius:11px;flex:none;display:grid;place-items:center;
  background:var(--paper-2);color:var(--mu);border:1px solid var(--edge);
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease);
}
body.nx .tasks li.is-active .task-ico,
body.nx .tasks li.is-done .task-ico{
  background:var(--brand);color:var(--brand-ink);border-color:var(--brand);
}
body.nx .task-txt{min-width:0;flex:1;}
body.nx .task-txt b{display:block;font-size:15px;font-weight:600;color:var(--ink);}
body.nx .task-txt span{
  display:block;margin-top:2px;font-size:13px;line-height:1.45;color:var(--mu);
}
/* The state cell holds its size whatever is in it, so nothing shifts
   sideways when a spinner becomes a tick. */
body.nx .task-state{width:20px;height:20px;flex:none;position:relative;}
body.nx .tasks li.is-active .task-state::before{
  content:'';position:absolute;inset:0;border-radius:999px;
  border:2px solid color-mix(in srgb,var(--brand) 28%,transparent);
  border-top-color:var(--brand);
  animation:nx-spin .7s linear infinite;
}
body.nx .tasks li.is-done .task-state::after{
  content:'';position:absolute;left:6px;top:1px;width:6px;height:12px;
  border:solid var(--brand);border-width:0 2px 2px 0;transform:rotate(45deg);
}
@keyframes nx-spin{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion:reduce){
  body.nx .tasks li.is-active .task-state::before{animation-duration:2.4s;}
}

body.nx .read-foot{margin:clamp(20px,2.4vw,28px) 0 0;font-size:13.5px;color:var(--dim);text-align:center;}
body.nx .read-fail{margin-top:22px;text-align:center;}
body.nx .read-fail p{margin:0 auto 18px;max-width:52ch;font-size:14.5px;line-height:1.6;color:var(--mu);}
body.nx .read-fail-cta{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;}
body.nx .aside-lede{margin:18px 0 0;font-size:14px;line-height:1.65;color:var(--mu);}

/* Arriving on the reading step. The upload step navigates here, so the
   screen has to announce itself as the NEXT thing rather than as the same
   page redrawn — the rows then read as a list being worked through, not
   as a table that was already finished when you got here. Gated on the
   motion class like every other entrance on the site, and skipped whole
   under prefers-reduced-motion. */
html.motion body.nx [data-enter]{animation:nx-enter .5s var(--ease) both;}
body.nx [data-enter] .tasks li{animation:nx-enter .42s var(--ease) both;}
body.nx [data-enter] .tasks li:nth-child(1){animation-delay:.10s;}
body.nx [data-enter] .tasks li:nth-child(2){animation-delay:.17s;}
body.nx [data-enter] .tasks li:nth-child(3){animation-delay:.24s;}
body.nx [data-enter] .tasks li:nth-child(4){animation-delay:.31s;}
@keyframes nx-enter{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}
/* The row's own opacity is state (pending is dimmed), so the entrance
   must not leave its `to` opacity fighting it — end at the class's value. */
body.nx [data-enter] .tasks li{opacity:.42;}
body.nx [data-enter] .tasks li.is-active,
body.nx [data-enter] .tasks li.is-done{opacity:1;}
@media (prefers-reduced-motion:reduce){
  html.motion body.nx [data-enter],
  body.nx [data-enter] .tasks li{animation:none;}
}
/* Continue pressed with an empty picker: one pulse of the frame, then
   back. Long enough to say "here", short enough not to be a state. */
body.nx .drop.is-asking{
  animation:nx-ask .9s var(--ease);
  border-color:color-mix(in srgb,var(--brand) 70%,transparent);
}
@keyframes nx-ask{
  0%,100%{transform:none;}
  25%{transform:translateX(-4px);}
  60%{transform:translateX(3px);}
}
@media (prefers-reduced-motion:reduce){ body.nx .drop.is-asking{animation:none;} }

/* ── setup: the location step ── */
body.nx .loc-grid{
  display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);
  gap:18px;align-items:start;
}
/* The field is one object: a search glyph, the input, and the pin, with
   the input's own border drawn around all three. Sizing the input to the
   full width and floating the two controls over it keeps the native
   list-picker behaviour, which a bespoke wrapper would have to rebuild. */
body.nx .loc-input{position:relative;display:flex;align-items:center;}
body.nx .loc-input .input{padding-left:42px;padding-right:46px;}
body.nx .loc-lead{
  position:absolute;left:14px;color:var(--dim);pointer-events:none;
}
body.nx .loc-pin{
  position:absolute;right:6px;width:34px;height:34px;border-radius:9px;
  display:grid;place-items:center;cursor:pointer;
  background:transparent;border:0;color:var(--mu);
  transition:background .16s,color .16s;
}
body.nx .loc-pin:hover{background:var(--paper-3);color:var(--ink);}
body.nx .loc-pin.is-busy{color:var(--brand);animation:nx-pulse 1s ease-in-out infinite;}
@keyframes nx-pulse{50%{opacity:.45;}}
@media (prefers-reduced-motion:reduce){ body.nx .loc-pin.is-busy{animation:none;} }

body.nx .loc-move{border:0;padding:0;margin:clamp(20px,2.4vw,28px) 0 0;}
body.nx .loc-move legend{
  padding:0;margin-bottom:9px;
  font-family:var(--sans);font-size:13px;font-weight:600;color:var(--ink-2);
}
body.nx .loc-move .seg{max-width:420px;}

@media (max-width:620px){
  body.nx .loc-grid{grid-template-columns:minmax(0,1fr);}
}

/* The reference's little (?) beside a label. A button, not an icon in a
   span: it opens something, so it has to be reachable by keyboard and
   announce itself as pressable. */
body.nx .hintdot{
  width:15px;height:15px;margin-left:5px;padding:0;vertical-align:1px;
  border-radius:999px;border:1px solid var(--edge);background:transparent;
  color:var(--dim);font-size:10px;font-weight:700;line-height:1;cursor:pointer;
  transition:color .16s,border-color .16s;
}
body.nx .hintdot:hover,body.nx .hintdot[aria-expanded="true"]{color:var(--ink);border-color:var(--mu);}
/* Location wide, postcode narrow — the reference's proportions. */
body.nx .loc-grid{grid-template-columns:minmax(0,1fr) 148px;}
@media (max-width:620px){
  /* Declared after the two-column rule above, which would otherwise win
     on source order and leave "Khujand, Tajikistan" clipped inside a
     200px field on a phone. */
  body.nx .loc-grid{grid-template-columns:minmax(0,1fr);}
}

/* ── setup: desired roles ── */
body.nx .rolesearch{position:relative;max-width:620px;}
/* The suggestion list overlays what follows rather than pushing it down —
   a list that shoves the chips around while you type makes the thing you
   were about to click move under the cursor. */
body.nx .opts{
  position:absolute;z-index:5;left:0;right:0;top:calc(100% + 6px);
  list-style:none;margin:0;padding:6px;max-height:296px;overflow:auto;
  background:var(--paper);border:1px solid var(--edge);border-radius:var(--r);
  box-shadow:0 22px 50px rgba(0,0,0,.55);
}
body.nx .opts li{
  padding:11px 13px;border-radius:9px;cursor:pointer;
  font-size:14.5px;color:var(--ink-2);
}
body.nx .opts li:hover,body.nx .opts li.on{background:var(--paper-3);color:var(--ink);}
body.nx .opts .opt-none{cursor:default;color:var(--dim);font-size:13.5px;}
body.nx .opts .opt-none:hover{background:none;color:var(--dim);}

/* The warning is amber, not red: nothing is broken and nothing was lost —
   there is one answer still missing before this can move on. */
body.nx .warn{
  display:flex;align-items:center;gap:10px;
  margin:22px 0 0;padding:12px 15px;border-radius:var(--r-sm);
  background:#3a2a12;border:1px solid #6b4d1d;color:#f7c98b;
  font-size:14px;line-height:1.45;max-width:620px;
}
body.nx .warn .ico{flex:none;color:#f0b45f;}

body.nx .picked-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin:clamp(24px,3vw,34px) 0 12px;max-width:620px;
}
body.nx .picked-head h2{font-size:15px;font-weight:600;margin:0;letter-spacing:normal;}

body.nx .rolechips{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:10px;}
/* One pill holds three things: the title, the years, and the way out.
   Bordered in the accent so a chosen role reads as an object you now own
   rather than as another button to press. */
body.nx .rolechip{
  display:inline-flex;align-items:center;gap:10px;
  padding:7px 8px 7px 15px;border-radius:999px;
  background:var(--paper);border:1px solid color-mix(in srgb,var(--brand) 55%,transparent);
}
/* Still missing its years: amber, matching the warning that names it. */
body.nx .rolechip.is-open{border-color:#6b4d1d;}
body.nx .rc-name{font-size:14.5px;font-weight:600;color:var(--ink);}
body.nx .rc-years select{
  appearance:none;cursor:pointer;
  padding:5px 26px 5px 12px;border-radius:999px;
  background:var(--paper-3);border:1px solid var(--edge);color:var(--ink-2);
  font-family:var(--sans);font-size:12.5px;
  background-image:linear-gradient(45deg,transparent 50%,var(--mu) 50%),
                   linear-gradient(135deg,var(--mu) 50%,transparent 50%);
  background-position:calc(100% - 15px) 50%,calc(100% - 10px) 50%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;
}
body.nx .rolechip.is-open .rc-years select{
  border-color:#6b4d1d;color:#f7c98b;background-color:#3a2a12;
}
body.nx .rc-years select:focus{outline:2px solid var(--brand);outline-offset:2px;}
body.nx .rc-x{
  width:26px;height:26px;flex:none;border-radius:999px;cursor:pointer;
  display:grid;place-items:center;
  background:transparent;border:0;color:var(--mu);font-size:17px;line-height:1;
  transition:background .16s,color .16s;
}
body.nx .rc-x:hover{background:var(--paper-3);color:var(--ink);}

/* ── setup: the overview ──
   Four rows, each the whole link. The row states are the point: done,
   next, not yet, locked — and each is carried by two signals (the marker
   and the chip) rather than by colour alone. */
body.nx .steplist{
  list-style:none;counter-reset:sl;margin:clamp(24px,3vw,34px) 0 0;padding:0;
  display:grid;gap:10px;max-width:620px;
}
body.nx .sl-in{
  display:flex;align-items:center;gap:14px;
  padding:15px 16px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
  transition:border-color .18s,background .18s,transform .18s var(--ease);
}
body.nx a.sl-in:hover{
  border-color:color-mix(in srgb,var(--brand) 45%,var(--edge));
  background:var(--paper-2);transform:translateX(2px);
}
body.nx .sl-n{
  width:30px;height:30px;flex:none;border-radius:9px;display:grid;place-items:center;
  background:var(--paper-3);color:var(--dim);
  font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;
}
body.nx .steprow.is-done .sl-n{background:var(--brand);color:var(--brand-ink);}
body.nx .steprow.is-next .sl-n{
  background:color-mix(in srgb,var(--brand) 16%,transparent);
  color:var(--brand);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--brand) 40%,transparent);
}
body.nx .steprow.is-next .sl-in{border-color:color-mix(in srgb,var(--brand) 45%,var(--edge));}
body.nx .steprow.is-locked .sl-in{opacity:.5;}
body.nx .sl-txt{min-width:0;flex:1;}
body.nx .sl-txt b{display:block;font-size:15px;font-weight:600;color:var(--ink);}
body.nx .sl-txt span{
  display:block;margin-top:2px;font-size:13px;line-height:1.45;color:var(--mu);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
body.nx .sl-chip{
  flex:none;padding:4px 10px;border-radius:999px;
  font-size:10.5px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;
  background:var(--paper-3);color:var(--dim);
}
body.nx .steprow.is-done .sl-chip{background:color-mix(in srgb,var(--brand) 15%,transparent);color:var(--brand);}
body.nx .steprow.is-next .sl-chip{background:color-mix(in srgb,var(--brand) 15%,transparent);color:var(--brand);}
body.nx .sl-go{flex:none;color:var(--dim);transition:transform .2s var(--ease),color .2s;}
body.nx a.sl-in:hover .sl-go{color:var(--ink);transform:translateX(3px);}
@media (max-width:520px){
  body.nx .sl-chip{display:none;}   /* the marker already says the state */
}
/* A grid item floors at min-content, and the one-line blurb inside these
   rows is nowrap — so without this the row refuses to shrink below the
   longest description and pushes the page sideways on a phone. */
body.nx .steplist li{min-width:0;}
body.nx .sl-in{min-width:0;}

/* ── setup: how you want to work ── */
body.nx .modes{border:0;padding:0;margin:0 0 clamp(24px,3vw,32px);}
body.nx .modeset{display:flex;flex-wrap:wrap;gap:10px;}
/* Checkboxes drawn as pills. The box stays a real box inside the pill —
   a filled pill alone reads as "selected one of a set", and these are
   independent answers where two can be true at once. */
body.nx .mode{
  display:inline-flex;align-items:center;gap:11px;cursor:pointer;
  padding:11px 18px 11px 14px;border-radius:999px;
  background:var(--paper);border:1px solid var(--edge);
  text-align:left;transition:background .16s,border-color .16s;
}
body.nx .mode:hover{border-color:color-mix(in srgb,var(--brand) 40%,var(--edge));}
body.nx .mode-box{
  width:18px;height:18px;flex:none;border-radius:5px;
  border:1.5px solid var(--mu);background:transparent;
  transition:background .16s,border-color .16s;
}
body.nx .mode.on{background:var(--brand);border-color:var(--brand);}
body.nx .mode.on .mode-box{background:var(--brand-ink);border-color:var(--brand-ink);position:relative;}
body.nx .mode.on .mode-box::after{
  content:'';position:absolute;left:5px;top:1px;width:5px;height:10px;
  border:solid var(--brand);border-width:0 2px 2px 0;transform:rotate(45deg);
}
body.nx .mode-txt b{display:block;font-size:14.5px;font-weight:600;color:var(--ink);}
body.nx .mode-txt span{display:block;font-size:12px;color:var(--mu);margin-top:1px;}
body.nx .mode.on .mode-txt b,body.nx .mode.on .mode-txt span{color:var(--brand-ink);}

body.nx .suggest-lead{margin:18px 0 10px;font-size:13px;color:var(--mu);}
body.nx .suggests{display:flex;flex-wrap:wrap;gap:8px;}
body.nx .suggest{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  padding:8px 14px;border-radius:999px;
  background:transparent;border:1px solid var(--edge);color:var(--ink-2);
  font-family:var(--sans);font-size:13.5px;
  transition:background .16s,border-color .16s,color .16s;
}
body.nx .suggest:hover{background:var(--paper-2);border-color:var(--mu);color:var(--ink);}
/* The count is the evidence for the suggestion, so it travels with it. */
body.nx .suggest-n{
  margin-left:3px;padding:1px 7px;border-radius:999px;
  background:var(--paper-3);color:var(--dim);
  font-size:11px;font-variant-numeric:tabular-nums;
}
/* Says something true about the answer just given, in the accent rather
   than the warning colour — nothing is wrong, there is a consequence. */
body.nx .note{
  display:flex;align-items:flex-start;gap:10px;
  margin:20px 0 0;padding:12px 15px;border-radius:var(--r-sm);max-width:620px;
  background:color-mix(in srgb,var(--acc-lt) 9%,transparent);
  border:1px solid color-mix(in srgb,var(--acc-lt) 26%,transparent);
  color:var(--ink-2);font-size:13.5px;line-height:1.5;
}
body.nx .note .ico{flex:none;color:var(--acc-lt);margin-top:1px;}

/* ── setup: right to work ── */
body.nx .visas{display:grid;gap:16px;max-width:620px;}
body.nx .visa-row{margin:0;}
/* Says which row is about the country they live in, so the list reads as
   "you, then the others" rather than as five equal strangers. */
body.nx .visa-tag{
  margin-left:9px;padding:2px 8px;border-radius:999px;
  background:var(--paper-3);color:var(--dim);
  font-size:10.5px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
}
body.nx .addc{margin:22px 0 0;max-width:620px;}
body.nx .addc label{
  display:block;margin-bottom:7px;
  font-family:var(--sans);font-size:13px;font-weight:600;color:var(--ink-2);
}
body.nx .addc-row{display:flex;gap:10px;align-items:center;}
body.nx .addc-row .select{flex:1;min-width:0;}
body.nx .addc-row .btn{flex:none;}

/* ── setup: review your profile ──────────────────────────────────────
   The one screen in the flow that is centred rather than split: there is
   no aside, because nothing here needs explaining — every value on it is
   an answer the person already gave, and the only question is whether it
   is right. Wide, so a long employer name is not wrapped into a column.
   ------------------------------------------------------------------ */
/* Full bleed. The dark ground is painted by .setup-main, so capping THAT
   width leaves the page framed by whatever is behind it — the content is
   what wants a measure, not the panel. The panel now runs edge to edge
   and each block inside it is centred on its own. */
body.nx .setup.is-review{grid-template-columns:1fr;}
/* The review step reads light where every step before it reads dark, and
   that is the point: the flow has been a form on a dark ground, and this
   is the document that form produced. The switch is a token swap on the
   same panel — no parallel rules, no second stylesheet. */
body.nx .is-review .setup-main{
  width:100%;max-width:none;
  padding-inline:clamp(20px,4vw,56px);
  padding-bottom:clamp(28px,3vw,44px);
  background:#f6f8fa;
  --ink:#0d1117; --ink-2:#39414d; --mu:#5f6873; --dim:#8792a0;
  --paper:#ffffff; --paper-2:#f0f3f6; --paper-3:#eceff3;
  --edge:#e1e6eb; --edge-soft:#eef1f4;
  color:var(--ink-2);
}
/* The mint mark is drawn for a dark ground; on white the page ships the
   dark one instead. */
body.nx .is-review .setup-mark img{content:url("/brand/nebryx-dark.png");}




/* Cards sit on a tinted page, so they need a shadow as well as a border
   — a white card on near-white with a hairline alone reads as a seam. */
body.nx .is-review .rvcard{
  border-color:var(--edge);
  box-shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);
}
body.nx .is-review .rv-note{
  background:color-mix(in srgb,var(--teal) 8%,#fff);
  border-color:color-mix(in srgb,var(--teal) 22%,transparent);
  color:var(--ink-2);
}
body.nx .is-review .rv-note .ico,
body.nx .is-review .rv-gen .ico{color:var(--teal);}
body.nx .is-review .rv-ava{background:var(--paper-3);color:var(--mu);}
body.nx .is-review .rv-jico{background:var(--paper-3);color:var(--mu);}
/* Per-job skills take the same tinted pill the reference uses — read as
   data attached to the job, not as another neutral chip. */
body.nx .is-review .rv-jtag{
  background:color-mix(in srgb,var(--teal) 9%,#fff);
  border-color:color-mix(in srgb,var(--teal) 20%,transparent);
  color:#155e58;
}
body.nx .is-review .rv-tag{background:var(--paper-3);color:var(--ink-2);}
body.nx .is-review .rv-about{background:#fff;border-color:var(--edge);color:var(--ink);}
body.nx .is-review .input,
body.nx .is-review .select,
body.nx .is-review .textarea{background:#fff;border-color:var(--edge);color:var(--ink);}
body.nx .is-review .opts{background:#fff;border-color:var(--edge);}
body.nx .is-review .skillchip{background:var(--paper-3);color:var(--ink-2);border-color:var(--edge);}
body.nx .is-review .rv-gen{background:#fff;border-color:var(--edge);color:var(--ink-2);}
body.nx .is-review .rv-gen:hover:not(:disabled){background:var(--paper-2);color:var(--ink);}
/* A label and its value, the way the reference writes them: the key is
   the dark half and carries the colon, the value sits under it in grey. */
body.nx .is-review .rv-k::after{content:':';}
/* app.css colours form labels for the light product pages; inside the
   dark flow they are re-tinted, and this card is light again — so they
   go back to the ink token rather than inheriting the dark panel's. */
body.nx .is-review .field label,
body.nx .is-review .rv-sec h2{color:var(--ink);}
body.nx .is-review .opts li{color:var(--ink-2);}
body.nx .is-review .opts li.on,
body.nx .is-review .opts li:hover{background:var(--paper-2);}
/* Filled discs, as the reference has them. */
body.nx .rv-duties{list-style:disc;}
body.nx .is-review .setup-body,
body.nx .is-review .setup-actions,
body.nx .is-review .warn{
  width:100%;max-width:980px;margin-inline:auto;
}
/* Three bands: a heading that stays, a profile that scrolls, and the two
   buttons. The page itself does not scroll — the panel does — so Finish
   is reachable from anywhere in a long profile without hunting for it. */
body.nx .setup.is-review{height:100dvh;}
body.nx .is-review .setup-main{overflow:hidden;}
body.nx .is-review .rv-head-block{flex:none;}
body.nx .is-review h1{
  font-size:clamp(32px,3.6vw,46px);line-height:1.08;margin-bottom:10px;
}
body.nx .rvwrap{
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  width:100%;max-width:980px;margin:clamp(18px,2vw,26px) auto 0;
  padding:clamp(14px,1.5vw,20px);
  background:#fff;border:1px solid var(--edge);border-radius:var(--r);
  box-shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);
  scrollbar-gutter:stable;
}
body.nx .rvwrap:focus-visible{outline:2px solid var(--teal);outline-offset:2px;}
/* Inside the panel the cards are nested, so they lose the outer shadow
   and keep only their hairline — two stacked shadows read as a mistake. */
body.nx .is-review .rvwrap .rvcard{box-shadow:none;}
body.nx .is-review .rvcard{margin-top:0;}
body.nx .is-review .rvcard + .rvcard{margin-top:14px;}
body.nx .is-review .setup-actions{
  flex:none;padding-top:clamp(16px,1.8vw,22px);
}
@media (max-width:720px){
  /* On a phone the panel-inside-a-page scroll is a trap — two scrollers,
     one thumb. The page takes it back. */
  body.nx .setup.is-review{height:auto;}
  body.nx .is-review .setup-main{overflow:visible;}
  body.nx .rvwrap{overflow:visible;max-height:none;padding:0;border:0;background:none;box-shadow:none;}
  body.nx .is-review .rvwrap .rvcard{
    box-shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);
  }
}
/* The mark stays where it is on every other step — top left of the page,
   not centred over the column. */
body.nx .is-review .setup-mark{align-self:flex-start;}
body.nx .is-review .setup-body{text-align:center;}
body.nx .is-review h1{margin-bottom:12px;}
body.nx .is-review .lead{margin-inline:auto;max-width:640px;}
/* Room earned by the full width goes to the fact grid, which is the part
   that was wrapping long employer names into two lines. */
@media (min-width:1100px){
  body.nx .is-review .rvgrid{gap:22px 40px;}
  body.nx .is-review .rvcard{padding:30px 34px;}
}

body.nx .rv-note{
  display:inline-flex;align-items:center;gap:9px;margin:18px 0 0;
  padding:9px 16px;border-radius:999px;
  background:color-mix(in srgb,var(--acc-lt) 11%,transparent);
  border:1px solid color-mix(in srgb,var(--acc-lt) 26%,transparent);
  color:var(--ink-2);font-size:13px;
}
body.nx .rv-note .ico{flex:none;color:var(--acc-lt);}

body.nx .rvcard{
  margin:26px 0 0;padding:26px 28px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);text-align:left;
}
body.nx .rvcard + .rvcard{margin-top:16px;}
body.nx .rv-head{
  display:flex;align-items:flex-start;gap:16px;
  padding-bottom:20px;border-bottom:1px solid var(--edge);
}
body.nx .rv-ava{
  width:56px;height:56px;flex:none;border-radius:14px;display:grid;place-items:center;
  background:var(--paper-3);color:var(--mu);
  font-size:19px;font-weight:600;letter-spacing:.5px;
}
body.nx .rv-name{flex:1;min-width:0;}
body.nx .rv-name b{display:block;font-size:19px;font-weight:600;color:var(--ink);}
body.nx .rv-name span{
  display:block;margin-top:4px;font-size:14px;color:var(--mu);line-height:1.5;
}
body.nx .rv-name span em{font-style:normal;font-weight:600;color:var(--ink-2);}

/* Two columns of facts. Each one carries the step that owns it, so the
   pencil goes back to the screen that can change it rather than opening
   a second editor here that could disagree with the first. */
body.nx .rvgrid{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:20px 28px;padding-top:20px;
}
body.nx .rv-item{display:flex;gap:11px;min-width:0;}
body.nx .rv-item .ico{flex:none;color:var(--mu);margin-top:2px;}
body.nx .rv-body{min-width:0;flex:1;}
body.nx .rv-k{
  display:block;font-size:13px;font-weight:600;color:var(--ink);margin-bottom:3px;
}
body.nx .rv-v{
  display:block;font-size:14px;color:var(--mu);line-height:1.5;
  overflow-wrap:anywhere;
}
body.nx .rv-v.is-empty{color:var(--dim);font-style:italic;}
body.nx .rv-edit{
  flex:none;width:30px;height:30px;border-radius:8px;display:grid;place-items:center;
  background:transparent;border:0;cursor:pointer;color:var(--dim);
  transition:background .16s,color .16s;
}
body.nx .rv-edit:hover{background:var(--paper-3);color:var(--ink);}
body.nx .rv-sec{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:14px;
}
body.nx .rv-sec h2{
  margin:0;font-size:15px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .rv-list{list-style:none;margin:0;padding:0;display:grid;gap:9px;}
body.nx .rv-list li{
  display:flex;gap:11px;align-items:flex-start;
  font-size:14px;color:var(--ink-2);line-height:1.5;
}
body.nx .rv-list li .ico{flex:none;color:var(--mu);margin-top:2px;}
body.nx .rv-list li span{color:var(--mu);}
/* ── the profile template: a job, an education, a wanted role ──────── */
body.nx .rv-jobs{list-style:none;margin:0;padding:0;display:grid;gap:22px;}
body.nx .rv-jobs > li{display:flex;gap:15px;min-width:0;}
body.nx .rv-jico{
  width:42px;height:42px;flex:none;border-radius:11px;display:grid;place-items:center;
  background:var(--paper-3);color:var(--mu);
}
body.nx .rv-jbody{min-width:0;flex:1;}
/* Employer first and heaviest: it is the thing an employer scanning this
   recognises, and the title under it is what the person did there. */
body.nx .rv-jorg{
  display:block;font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.45;
}
body.nx .rv-jmeta{display:block;font-size:13.5px;color:var(--mu);line-height:1.6;}
body.nx .rv-jsub{
  margin:13px 0 0;font-size:12.5px;font-weight:600;color:var(--ink-2);
  display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;
}
body.nx .rv-jsub .rv-tags{display:contents;}
/* The per-job skill chips read as data about this job, so they take the
   accent rather than the neutral fill the profile-wide list uses. */
body.nx .rv-jtag{
  padding:4px 11px;border-radius:999px;
  background:color-mix(in srgb,var(--acc-lt) 13%,transparent);
  border:1px solid color-mix(in srgb,var(--acc-lt) 22%,transparent);
  color:var(--ink-2);font-size:12px;font-weight:500;
}
body.nx .rv-duties{margin:9px 0 0;padding-left:19px;display:grid;gap:5px;}
body.nx .rv-duties li{font-size:13.5px;color:var(--mu);line-height:1.55;}
body.nx .rv-duties li::marker{color:var(--dim);}

/* Wanted roles as pills, with the years inside the pill — the role and
   the experience in it are one answer and read wrong when split. */
body.nx .rv-roles{display:flex;flex-wrap:wrap;gap:9px;}
body.nx .rv-role{
  display:inline-flex;align-items:baseline;gap:7px;
  padding:8px 15px;border-radius:999px;
  background:var(--paper-3);border:1px solid var(--edge);
  font-size:13px;color:var(--ink-2);
}
body.nx .rv-role b{font-weight:600;color:var(--ink);}
body.nx .rv-role span{color:var(--dim);font-size:12px;}

body.nx .rv-tags{display:flex;flex-wrap:wrap;gap:7px;}
body.nx .rv-tag{
  padding:5px 12px;border-radius:999px;
  background:var(--paper-3);color:var(--ink-2);font-size:12.5px;
}
body.nx .rv-skillsearch{margin-bottom:16px;}
body.nx .rv-skillsearch label{margin-bottom:0;}
body.nx .rvcard .skillchips{margin:0;}
/* "Write it from my CV" sits with the label, not under the box: it is an
   alternative to typing, and a control below the field reads as an
   action on text that is already there. */
body.nx .rv-gen{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  padding:7px 14px;border-radius:999px;
  background:transparent;border:1px solid var(--edge);color:var(--ink-2);
  font-family:var(--sans);font-size:12.5px;font-weight:600;
  transition:background .16s,border-color .16s,color .16s;
}
body.nx .rv-gen:hover:not(:disabled){
  background:var(--paper-3);border-color:var(--mu);color:var(--ink);
}
body.nx .rv-gen:disabled{opacity:.55;cursor:default;}
body.nx .rv-gen .ico{flex:none;color:var(--acc-lt);}
body.nx .rv-gen.is-busy .ico{animation:nx-spin 1s linear infinite;}
body.nx .rv-genrow{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
body.nx .rv-gennote{font-size:12.5px;color:var(--dim);}
body.nx .rv-about{
  width:100%;min-height:120px;resize:vertical;
  font-family:var(--sans);font-size:14px;line-height:1.6;
}
body.nx .rv-count{font-size:12px;color:var(--dim);font-variant-numeric:tabular-nums;}
@media (max-width:640px){
  body.nx .rvgrid{grid-template-columns:1fr;}
  body.nx .rvcard{padding:20px 18px;}
}

/* ── the edit dialogs ────────────────────────────────────────────────
   A pencil on the review screen opens the fields for that section here
   rather than navigating back into the flow. Same routes underneath —
   this is a second way into them, not a second copy of the logic.
   ------------------------------------------------------------------ */
body.nx .rvdlg{
  border:0;padding:0;background:transparent;
  width:min(680px,calc(100vw - 32px));max-height:min(86dvh,860px);
  color:var(--ink-2);
}
body.nx .rvdlg::backdrop{background:rgba(9,13,18,.55);backdrop-filter:blur(2px);}
body.nx .rvdlg-in{
  display:flex;flex-direction:column;max-height:inherit;
  background:#fff;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--edge);
  box-shadow:0 18px 48px rgba(12,18,28,.22);
  --ink:#0d1117; --ink-2:#39414d; --mu:#5f6873; --dim:#8792a0;
  --paper:#ffffff; --paper-2:#f0f3f6; --paper-3:#eceff3;
  --edge:#e1e6eb; --edge-soft:#eef1f4;
}
body.nx .rvdlg-head{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px 22px;border-bottom:1px solid var(--edge);flex:none;
}
body.nx .rvdlg-head h2{
  margin:0;font-size:16px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .rvdlg-x{
  width:32px;height:32px;flex:none;display:grid;place-items:center;
  border:0;border-radius:8px;background:transparent;cursor:pointer;color:var(--mu);
  font-size:18px;line-height:1;transition:background .15s,color .15s;
}
body.nx .rvdlg-x:hover{background:var(--paper-3);color:var(--ink);}
body.nx .rvdlg-body{
  padding:22px;overflow-y:auto;flex:1 1 auto;min-height:0;
  background:var(--paper-2);
}
/* Each block inside the dialog is a titled group with a rule under the
   title, as in the reference — it is a form of several small forms. */
body.nx .dgroup{
  background:#fff;border:1px solid var(--edge);border-radius:var(--r-sm);
  padding:18px 20px;
}
body.nx .dgroup + .dgroup{margin-top:14px;}
body.nx .dgroup > h3{
  margin:0 0 14px;padding-bottom:12px;border-bottom:1px solid var(--edge);
  font-size:13.5px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .dgroup .field{margin-bottom:0;}
body.nx .dgroup .field label{color:var(--ink);}
body.nx .dgroup .input,body.nx .dgroup .select,body.nx .dgroup .textarea{
  background:#fff;border-color:var(--edge);color:var(--ink);
}
body.nx .drow{display:grid;gap:14px;}
body.nx .drow.is-2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
body.nx .drow.is-phone{grid-template-columns:150px minmax(0,1fr);}
body.nx .drow.is-loc{grid-template-columns:minmax(0,1fr) 170px;}
body.nx .drow + .drow,body.nx .dgroup .modeset + .drow{margin-top:16px;}
body.nx .dgroup .modeset{margin-bottom:0;}
/* Rows that can be added and removed: a role, a school, a job. */
body.nx .dlist{display:grid;gap:10px;}
body.nx .dlist-row{
  display:grid;grid-template-columns:minmax(0,1fr) 118px 38px;gap:10px;align-items:start;
}
body.nx .dlist-row.is-wide{grid-template-columns:minmax(0,1fr) 38px;}
body.nx .dlist-row .input,body.nx .dlist-row .select{width:100%;}
/* The button that removes a row. It was called .drop — the same name the
   CV drop zone above uses — and being declared second it won, so every
   uploader on the site rendered as a 38px icon button. Renamed rather
   than reordered: two different components cannot share one class and
   stay correct, whichever order they happen to be written in. */
body.nx .drow-x{
  width:38px;height:38px;flex:none;display:grid;place-items:center;
  border:1px solid var(--edge);border-radius:var(--r-sm);background:#fff;
  cursor:pointer;color:var(--mu);font-size:16px;line-height:1;
  transition:border-color .15s,color .15s,background .15s;
}
body.nx .drow-x:hover{border-color:#e4a3a3;color:#b4453f;background:#fff6f5;}
body.nx .dadd{
  margin-top:12px;padding:9px 15px;border-radius:999px;cursor:pointer;
  border:1px dashed var(--edge);background:transparent;color:var(--mu);
  font-family:var(--sans);font-size:13px;font-weight:600;
  transition:border-color .15s,color .15s;
}
body.nx .dadd:hover{border-color:var(--teal);color:var(--teal);}
body.nx .dhint{margin:9px 0 0;font-size:12.5px;color:var(--dim);}
body.nx .dsuggests{display:flex;flex-wrap:wrap;gap:8px;margin-top:11px;}
body.nx .rvdlg-foot{
  display:flex;align-items:center;justify-content:flex-end;gap:10px;
  padding:16px 22px;border-top:1px solid var(--edge);flex:none;background:#fff;
}
body.nx .rvdlg-err{
  margin:0 auto 0 0;font-size:13px;color:#b4453f;max-width:60%;
}
/* The chosen office city, removable, as the reference shows it. */
body.nx .dchip{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 8px 6px 14px;border-radius:999px;
  background:var(--brand);color:var(--brand-ink);font-size:13px;font-weight:600;
}
body.nx .dchip button{
  border:0;background:transparent;cursor:pointer;color:inherit;
  font-size:15px;line-height:1;padding:0 2px;opacity:.8;
}
body.nx .dchip button:hover{opacity:1;}
body.nx .dpicked{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;}
@media (max-width:560px){
  body.nx .drow.is-2,body.nx .drow.is-loc,body.nx .drow.is-phone{grid-template-columns:1fr;}
  body.nx .dlist-row{grid-template-columns:minmax(0,1fr) 38px;}
}

/* ── setup: contract and pay ── */
/* The label and the month/year switch share one line, so the two field
   labels below still start level with each other — the switch is a
   property of this field, not a row of its own above the form. */
body.nx .pay-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:14px;flex-wrap:wrap;min-height:34px;
}
body.nx .pay-head label{margin:0;}
body.nx .payrow{
  display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:14px;
  max-width:620px;align-items:end;
}
body.nx .payrow .field{margin:0;}
/* The amount sits between two fixed marks — the currency on the left and
   the period on the right — so the number itself is the only part that
   moves, and nobody has to type "per month" into a number field. */
body.nx .money{position:relative;}
body.nx .money .input{
  padding-left:46px;padding-right:76px;
  font-variant-numeric:tabular-nums;
}
body.nx .money-sym,body.nx .money-per{
  position:absolute;top:50%;transform:translateY(-50%);
  font-size:13.5px;pointer-events:none;
}
body.nx .money-sym{left:16px;font-weight:600;color:var(--ink-2);}
body.nx .money-per{right:16px;color:var(--mu);}
/* Month or year. Roles in this market are posted monthly and people
   often think in yearly, so both are offered and the matcher converts —
   a single fixed period would be wrong for half of everyone. */
body.nx .periods{
  display:inline-flex;padding:3px;border-radius:999px;
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .period{
  border:0;background:transparent;cursor:pointer;color:var(--mu);
  font-family:var(--sans);font-size:12.5px;font-weight:600;
  padding:6px 14px;border-radius:999px;
  transition:background .16s,color .16s;
}
body.nx .period:hover{color:var(--ink);}
body.nx .period.on{background:var(--brand);color:var(--brand-ink);}
body.nx .pay-conv{
  margin:11px 0 0;max-width:620px;
  font-size:13px;color:var(--dim);font-variant-numeric:tabular-nums;
}
@media (max-width:560px){
  body.nx .payrow{grid-template-columns:1fr;}
}

/* ── setup: confirm where you've worked ── */
body.nx .jobs{list-style:none;margin:0;padding:0;display:grid;gap:10px;max-width:620px;}
body.nx .job{
  display:flex;align-items:center;gap:14px;
  padding:14px 14px 14px 16px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
  transition:border-color .18s;
}
body.nx .job.is-editing{border-color:color-mix(in srgb,var(--brand) 45%,var(--edge));}
body.nx .job-ico{
  width:34px;height:34px;flex:none;border-radius:10px;display:grid;place-items:center;
  background:var(--paper-3);color:var(--mu);
}
body.nx .job-txt{min-width:0;flex:1;}
/* The parser's line can be a whole official title, so it wraps rather
   than being cut — the long ones are exactly the ones worth reading
   before you decide whether they are right. */
body.nx .job-txt b{
  display:block;font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.35;
}
body.nx .job-txt span{display:block;margin-top:2px;font-size:12.5px;color:var(--mu);}
body.nx .job-edit{flex:1;min-width:0;display:grid;gap:8px;grid-template-columns:1fr 150px;}
body.nx .job-edit .input{padding:9px 12px;font-size:14px;}
body.nx .job-btn{
  width:32px;height:32px;flex:none;border-radius:9px;cursor:pointer;
  display:grid;place-items:center;
  background:transparent;border:0;color:var(--mu);font-size:16px;line-height:1;
  transition:background .16s,color .16s;
}
body.nx .job-btn:hover{background:var(--paper-3);color:var(--ink);}
body.nx .addrow{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  margin:14px 0 0;padding:10px 16px;border-radius:999px;
  background:transparent;border:1px dashed var(--edge);color:var(--mu);
  font-family:var(--sans);font-size:13.5px;
  transition:border-color .16s,color .16s;
}
body.nx .addrow:hover{border-color:var(--mu);color:var(--ink);}
@media (max-width:560px){
  body.nx .job-edit{grid-template-columns:1fr;}
}

/* ── setup: skills ── */
body.nx .skillsearch{position:relative;max-width:620px;}
body.nx .skillchips{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px;max-width:620px;}
body.nx .skillchip{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 8px 7px 14px;border-radius:999px;
  background:var(--paper);border:1px solid color-mix(in srgb,var(--brand) 45%,transparent);
  font-size:13.5px;color:var(--ink);
}
body.nx .skillchip button{
  width:20px;height:20px;flex:none;border-radius:999px;cursor:pointer;
  display:grid;place-items:center;
  background:transparent;border:0;color:var(--mu);font-size:15px;line-height:1;
  transition:background .16s,color .16s;
}
body.nx .skillchip button:hover{background:var(--paper-3);color:var(--ink);}

/* ══ 37. DASHBOARD — the signed-in home ══════════════════════════════
   A rail of destinations on the left, the person's own state on the
   right. Light, like the review screen it follows: the dark ground was
   the setup flow's, and the flow is over.

   Every number on this page is counted from this database. The reference
   says "checked 12,051 roles in the last 24 hours"; a market with forty
   open roles cannot say that, so nothing here says it.
   ------------------------------------------------------------------ */
body.nx.dash-page{background:#f6f8fa;}
body.nx .dash{
  min-height:100dvh;display:grid;grid-template-columns:248px minmax(0,1fr);
  --ink:#0d1117; --ink-2:#39414d; --mu:#5f6873; --dim:#8792a0;
  --paper:#ffffff; --paper-2:#f0f3f6; --paper-3:#eceff3;
  --edge:#e1e6eb; --edge-soft:#eef1f4;
  color:var(--ink-2);
}

/* ── the rail ── */
body.nx .drail{
  background:#0a0c0e;color:#c9d1da;
  display:flex;flex-direction:column;gap:4px;
  padding:26px 16px;position:sticky;top:0;height:100dvh;overflow-y:auto;
}
body.nx .drail-mark{display:block;margin:0 8px 26px;}
body.nx .drail-mark img{height:30px;width:auto;display:block;}
body.nx .drail-h{
  margin:20px 8px 8px;font-size:11px;font-weight:600;letter-spacing:.6px;
  text-transform:uppercase;color:#5d6772;
}
body.nx .drail a:not(.btn):not(.drail-mark){
  display:flex;align-items:center;gap:12px;
  padding:10px 12px;border-radius:9px;color:#c9d1da;
  font-size:14px;font-weight:500;text-decoration:none;
  transition:background .15s,color .15s;
}
body.nx .drail a:not(.btn):not(.drail-mark):hover{background:#171b20;color:#fff;}
body.nx .drail a:not(.btn).on{background:#15271f;color:var(--brand);}
body.nx .drail a:not(.btn) .ico{flex:none;opacity:.85;}
body.nx .drail-pill{
  margin-left:auto;padding:2px 9px;border-radius:999px;
  background:#1d2a24;color:var(--brand);
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;
}
/* A rule between groups, as the reference has them — the groups are
   different KINDS of destination, not one long list. */
body.nx .drail-rule{
  height:1px;margin:16px 8px;background:#262e37;border:0;flex:none;
}
/* Pushes everything after it to the bottom of the rail. */
body.nx .drail-gap{flex:1 1 auto;min-height:14px;}
body.nx .drail-card{
  margin:0 4px 4px;padding:14px;border-radius:12px;
  background:#12171c;border:1px solid #232a32;
}
body.nx .drail-card p{
  display:flex;align-items:center;gap:9px;
  margin:0 0 11px;font-size:13px;font-weight:600;color:#e6ebf1;
}
body.nx .drail-card p .ico{flex:none;color:var(--brand);}
body.nx .drail-card small{
  display:block;margin:-6px 0 11px;font-size:12px;line-height:1.45;color:#7c8794;
}
body.nx .drail-card .btn{width:100%;justify-content:center;}
body.nx .drail-foot{flex:none;}
body.nx .drail-copy{
  margin:14px 8px 0;font-size:11.5px;color:#4d5661;
}
/* The completeness badge doubles as a progress read, so it dims when
   there is nothing left to do rather than shouting 100%. */
body.nx .drail-pill.is-done{background:#1b2b22;color:#6f7d75;}

/* ── the page ── */
body.nx .dmain{padding:clamp(22px,2.6vw,38px) clamp(20px,2.8vw,42px);min-width:0;}
body.nx .dtop{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:20px;flex-wrap:wrap;margin-bottom:clamp(20px,2.4vw,30px);
}
body.nx .dtop h1{
  margin:0 0 5px;font-size:clamp(24px,2.4vw,30px);line-height:1.1;color:var(--ink);
}
body.nx .dtop p{margin:0;font-size:14px;color:var(--mu);}
body.nx .dwho{display:flex;align-items:center;gap:14px;}
/* An outlined avatar rather than a photo: the flow never asked for one,
   and a stock face would be the page telling its first small lie. */
body.nx .dwho-ava{
  width:34px;height:34px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:#fff;border:1px solid var(--edge);color:var(--mu);
}
/* Left-aligned, per the reference — the label sits over the name rather
   than the two being ragged against the pill. */
body.nx .dwho-n{text-align:left;line-height:1.3;}
body.nx .dwho-n span{display:block;font-size:12px;color:var(--dim);}
body.nx .dwho-n b{display:block;font-size:14.5px;color:var(--ink);font-weight:600;}

/* The status pill is a control, not a badge: the chevron promises a menu
   and there is one behind it. */
body.nx .dlive-wrap{position:relative;}
body.nx .dlive{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  padding:9px 13px;border-radius:9px;border:0;
  background:color-mix(in srgb,var(--brand) 26%,#fff);
  color:#0f4536;font-family:var(--sans);font-size:13.5px;font-weight:600;
  transition:background .15s;
}
body.nx .dlive:hover{background:color-mix(in srgb,var(--brand) 38%,#fff);}
body.nx .dlive .ico{flex:none;opacity:.9;}
body.nx .dlive-caret{margin-left:1px;transition:transform .18s var(--ease);}
body.nx .dlive[aria-expanded="true"] .dlive-caret{transform:rotate(180deg);}
body.nx .dlive.is-off{background:var(--paper-3);color:var(--mu);}

body.nx .dlive-menu{
  position:absolute;right:0;top:calc(100% + 8px);z-index:40;
  min-width:270px;padding:6px;border-radius:12px;
  background:#fff;border:1px solid var(--edge);
  box-shadow:0 14px 34px rgba(12,18,28,.16);
}
body.nx .dlive-menu[hidden]{display:none;}
body.nx .dlive-opt{
  display:flex;align-items:flex-start;gap:10px;width:100%;
  padding:11px 12px;border:0;border-radius:8px;background:transparent;cursor:pointer;
  font-family:var(--sans);text-align:left;color:var(--ink-2);
  transition:background .14s;
}
body.nx .dlive-opt:hover{background:var(--paper-2);}
body.nx .dlive-opt b{display:block;font-size:13.5px;color:var(--ink);font-weight:600;}
body.nx .dlive-opt small{display:block;font-size:12px;color:var(--mu);margin-top:2px;
  line-height:1.45;}
body.nx .dlive-opt .dlive-dot{margin-top:5px;}
body.nx .dlive-opt .ico{margin-left:auto;flex:none;color:var(--brand);opacity:0;}
body.nx .dlive-opt.on .ico{opacity:1;}
body.nx .dlive-dot{
  width:9px;height:9px;border-radius:50%;background:var(--brand);flex:none;
}
body.nx .dlive.is-off .dlive-dot,
body.nx .dlive-opt[data-v="0"] .dlive-dot{background:var(--dim);}

/* One white sheet holding both columns, the way the reference frames it
   — the page is a document about you, not a scatter of widgets. */
body.nx .dsheet{
  background:#fff;border:1px solid var(--edge);border-radius:var(--r);
  box-shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.05);
  overflow:hidden;
}
body.nx .dgrid{
  display:grid;grid-template-columns:352px minmax(0,1fr);align-items:stretch;
}
/* The left column is Aria's side of the page and takes a tint of the
   accent to say so; the right side is yours and stays white. */
body.nx .dside{
  padding:26px;background:color-mix(in srgb,var(--acc-lt) 7%,#fff);
  border-right:1px solid var(--edge);
}
body.nx .dbody{padding:26px 28px;min-width:0;}
body.nx .dbody > h2:first-child{margin-top:0;font-size:20px;}
body.nx .dsub-lede{margin:0 0 22px;font-size:14px;color:var(--mu);line-height:1.6;}
/* Cards inside the sheet are nested, so they take a hairline only. */
body.nx .dsheet .dcard{box-shadow:none;}
body.nx .dside .dcard{margin-top:18px;padding:18px;}
body.nx .dside .dcard h2{font-size:14px;margin-bottom:12px;
  display:flex;align-items:center;gap:9px;}
body.nx .dside .dcard h2 .ico{flex:none;color:var(--acc-lt);}
body.nx .dhr{height:1px;background:var(--edge);border:0;margin:18px 0;}
/* The summary sits in its own ruled box with Aria's face beside it. */
body.nx .dlearnt{
  display:flex;gap:13px;padding:15px 17px;border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--acc-lt) 6%,#fff);
  border:1px solid color-mix(in srgb,var(--acc-lt) 30%,transparent);
}
body.nx .dlearnt-face{
  width:30px;height:30px;flex:none;border-radius:9px;overflow:hidden;
  background:linear-gradient(150deg,#dff7ec,#f3e8ff);
}
body.nx .dlearnt-face img{width:100%;height:100%;object-fit:cover;display:block;}
body.nx .dlearnt-txt{min-width:0;flex:1;font-size:13.5px;line-height:1.6;color:var(--ink-2);}
body.nx .dlearnt-txt.is-clamped p{
  display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;
}
body.nx .dlearnt-txt p{margin:0;}
body.nx .dbig{
  display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  padding:13px 18px;border-radius:var(--r-sm);
  border:1px solid var(--ink);background:#fff;color:var(--ink);
  font-family:var(--sans);font-size:14px;font-weight:600;cursor:pointer;
  text-decoration:none;transition:background .15s,color .15s;
}
body.nx .dbig:hover{background:var(--ink);color:#fff;}
body.nx .dbig:hover .ico{color:#fff;}
body.nx .dbig .ico{color:var(--ink);}
@media (max-width:1080px){
  body.nx .dgrid{grid-template-columns:1fr;}
  body.nx .dside{border-right:0;border-bottom:1px solid var(--edge);}
}
body.nx .dcard{
  background:#fff;border:1px solid var(--edge);border-radius:var(--r);
  padding:22px;box-shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.05);
}
body.nx .dcard + .dcard{margin-top:18px;}
body.nx .dcard h2{
  margin:0 0 16px;font-size:16px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .dcard h3{
  margin:0;font-size:14.5px;font-weight:600;color:var(--ink);letter-spacing:0;
}

/* Aria, and what she is saying right now. */
body.nx .daria{display:flex;align-items:flex-start;gap:14px;margin-bottom:20px;}
body.nx .daria-face{
  width:72px;height:72px;flex:none;border-radius:16px;overflow:hidden;
  background:linear-gradient(150deg,#dff7ec,#f3e8ff);
  display:grid;place-items:center;
}
body.nx .daria-face img{width:100%;height:100%;object-fit:cover;display:block;}
body.nx .daria-say{
  position:relative;flex:1;min-width:0;
  padding:12px 15px;border-radius:12px;
  background:var(--paper-2);border:1px solid var(--edge);
  font-size:13px;line-height:1.5;color:var(--ink-2);
}
body.nx .daria-say::before{
  content:'';position:absolute;left:-6px;top:20px;width:10px;height:10px;
  background:var(--paper-2);border-left:1px solid var(--edge);
  border-bottom:1px solid var(--edge);transform:rotate(45deg);
}
body.nx .dstatus{
  display:flex;align-items:center;gap:9px;
  font-size:13px;font-weight:600;color:var(--ink);margin-bottom:4px;
}
body.nx .drow-kv{
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:11px 0;border-top:1px solid var(--edge);
  font-size:13.5px;
}
body.nx .drow-kv span{color:var(--mu);}
body.nx .drow-kv b{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;}
body.nx .dchips{display:flex;flex-wrap:wrap;gap:8px;}
body.nx .dchip-q{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 13px;border-radius:999px;
  background:var(--paper-2);border:1px solid var(--edge);
  font-size:12.5px;color:var(--ink-2);
}
body.nx .dchip-q .ico{color:var(--mu);}
body.nx .dnote{margin:14px 0 0;font-size:13px;line-height:1.55;color:var(--mu);}

/* The summary Aria wrote, clamped until asked to open. */
body.nx .dsummary{
  padding:16px 18px;border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--acc-lt) 7%,#fff);
  border:1px solid color-mix(in srgb,var(--acc-lt) 26%,transparent);
  font-size:13.5px;line-height:1.62;color:var(--ink-2);
}
body.nx .dsummary.is-clamped p{
  display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;
}
body.nx .dsummary p{margin:0;}
body.nx .dmore{
  display:block;margin:8px 0 0 auto;border:0;background:transparent;cursor:pointer;
  color:var(--teal);font-family:var(--sans);font-size:13px;font-weight:600;
}
body.nx .dactions{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:14px;}
body.nx .dsub{margin:12px 0 0;font-size:12.5px;color:var(--dim);}
body.nx .dsub a{color:var(--teal);}

/* "What I'm looking for" — a block per answer, each with its own Update. */
body.nx .dlook + .dlook{margin-top:14px;}
body.nx .dlook{
  border:1px solid var(--edge);border-radius:var(--r-sm);padding:18px 20px;background:#fff;
}
body.nx .dlook-h{
  display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:14px;
}
body.nx .dupdate{
  border:0;background:transparent;cursor:pointer;padding:0;
  color:var(--teal);font-family:var(--sans);font-size:13px;font-weight:600;
  text-decoration:underline;text-underline-offset:3px;
}
body.nx .dupdate:hover{color:var(--ink);}
body.nx .dkv{display:grid;grid-template-columns:auto 1fr;gap:8px 22px;font-size:13.5px;}
body.nx .dkv dt{font-weight:600;color:var(--ink);}
body.nx .dkv dd{margin:0;color:var(--mu);}
body.nx .dempty{margin:0;font-size:13.5px;color:var(--dim);font-style:italic;}

@media (max-width:1080px){
  body.nx .dgrid{grid-template-columns:1fr;}
}
@media (max-width:860px){
  body.nx .dash{grid-template-columns:1fr;}
  body.nx .drail{
    position:static;height:auto;flex-direction:row;flex-wrap:wrap;
    align-items:center;gap:6px;padding:14px 16px;
  }
  body.nx .drail-mark{margin:0 14px 0 0;}
  /* Headings, rules, the gap and the profile card are all shape for a
     vertical rail and nonsense in a horizontal one. The FOOTER is not —
     it holds Log out, and hiding the group hid the only way to sign out
     on a phone. It flattens into the row instead. */
  body.nx .drail-h,body.nx .drail-rule,body.nx .drail-gap,
  body.nx .drail-card,body.nx .drail-copy{display:none;}
  body.nx .drail-foot{display:contents;}
  body.nx .drail a:not(.btn):not(.drail-mark){padding:8px 11px;font-size:13px;}
  body.nx .dactions{grid-template-columns:1fr;}
}

/* ── the first-visit welcome ────────────────────────────────────────
   Shown once per PERSON, not per browser: the server holds the flag, so
   signing in on a phone after a laptop does not run it again. */
body.nx .wdlg{
  border:0;padding:0;background:transparent;
  width:min(560px,calc(100vw - 32px));
}
body.nx .wdlg::backdrop{background:rgba(9,13,18,.6);backdrop-filter:blur(3px);}
body.nx .wdlg-in{
  background:#fff;border-radius:var(--r);overflow:hidden;
  box-shadow:0 22px 60px rgba(12,18,28,.3);
  --ink:#0d1117; --ink-2:#39414d; --mu:#5f6873; --dim:#8792a0;
  --paper-2:#f0f3f6; --paper-3:#eceff3; --edge:#e1e6eb;
}
body.nx .wart{
  height:190px;display:grid;place-items:center;
  background:linear-gradient(150deg,#e6faf1,#f1e9ff);
}
body.nx .wart img{height:118px;width:auto;display:block;}
body.nx .wart .wmark{
  width:84px;height:84px;border-radius:20px;display:grid;place-items:center;
  background:var(--brand);color:var(--brand-ink);font-size:34px;font-weight:700;
}
body.nx .wdots{display:flex;justify-content:center;gap:7px;padding:18px 0 0;}
body.nx .wdot{width:7px;height:7px;border-radius:50%;background:var(--edge);}
body.nx .wdot.on{background:var(--brand);}
body.nx .wbody{padding:16px 30px 26px;text-align:center;}
body.nx .wbody h2{
  margin:6px 0 12px;font-size:23px;line-height:1.2;color:var(--ink);letter-spacing:-.01em;
}
body.nx .wbody p{margin:0 0 12px;font-size:14px;line-height:1.6;color:var(--ink-2);}
body.nx .wlist{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:10px;text-align:left;}
body.nx .wlist li{display:flex;align-items:flex-start;gap:10px;font-size:14px;color:var(--ink-2);}
body.nx .wtick{
  width:20px;height:20px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:var(--brand);color:var(--brand-ink);margin-top:1px;
}
body.nx .wtip{
  margin:14px 0 0;padding:11px 14px;border-radius:var(--r-sm);text-align:left;
  background:color-mix(in srgb,var(--acc-lt) 10%,#fff);
  border:1px solid color-mix(in srgb,var(--acc-lt) 24%,transparent);
  font-size:13px;color:var(--ink-2);
}
body.nx .wbars{display:flex;gap:10px;margin:20px 0 16px;}
body.nx .wbar{
  flex:1;height:3px;border-radius:3px;background:var(--edge);overflow:hidden;position:relative;
}
body.nx .wbar::after{
  content:'';position:absolute;inset:0 100% 0 0;background:var(--brand);
}
body.nx .wbar.done::after{inset:0;}
html.motion body.nx .wbar.run::after{animation:w-fill 1.1s var(--ease) forwards;}
@keyframes w-fill{to{inset:0;}}
body.nx .wopts{display:grid;gap:10px;margin:4px 0 18px;text-align:left;}
body.nx .wopt{
  display:flex;align-items:center;gap:11px;cursor:pointer;
  padding:13px 16px;border-radius:999px;
  background:var(--paper-2);border:1px solid var(--edge);
  font-family:var(--sans);font-size:14px;color:var(--ink-2);
  transition:border-color .15s,background .15s;
}
body.nx .wopt:hover{border-color:var(--mu);}
body.nx .wopt.on{background:color-mix(in srgb,var(--brand) 14%,#fff);border-color:var(--brand);color:var(--ink);}
body.nx .wradio{
  width:18px;height:18px;flex:none;border-radius:50%;
  border:1.5px solid var(--mu);position:relative;
}
body.nx .wopt.on .wradio{border-color:var(--brand);}
body.nx .wopt.on .wradio::after{
  content:'';position:absolute;inset:3px;border-radius:50%;background:var(--brand);
}
body.nx .wfoot{display:flex;justify-content:flex-end;gap:10px;}
body.nx .wskip{
  margin-right:auto;border:0;background:transparent;cursor:pointer;
  color:var(--dim);font-family:var(--sans);font-size:13px;
}
body.nx .wskip:hover{color:var(--ink-2);}

/* ══ 38. PROFILE — the record, its sections, and how strong it is ═════
   Three columns: which part you are looking at, the part itself, and an
   honest read of what is still missing. The strength list is not a score
   out of ten — every line names a thing and links to where it is filled.
   ------------------------------------------------------------------ */
body.nx .pcols{
  display:grid;grid-template-columns:214px minmax(0,1fr) 288px;
  gap:22px;align-items:start;
}
body.nx .pnav{display:grid;gap:2px;position:sticky;top:22px;}
body.nx .pnav a{
  display:flex;align-items:center;gap:9px;
  padding:11px 14px;border-radius:9px;text-decoration:none;
  font-size:14px;font-weight:500;color:var(--ink-2);
  transition:background .15s,color .15s;
}
body.nx .pnav a:hover{background:var(--paper-2);color:var(--ink);}
body.nx .pnav a.on{background:color-mix(in srgb,var(--brand) 20%,#fff);color:#0f4536;font-weight:600;}
body.nx .pnav .warn-dot{
  margin-left:auto;width:16px;height:16px;border-radius:50%;flex:none;
  display:grid;place-items:center;background:#fdeee7;color:#b4552f;
  font-size:10px;font-weight:700;
}
body.nx .pcard{
  background:#fff;border:1px solid var(--edge);border-radius:var(--r);
  padding:20px 22px;box-shadow:0 1px 2px rgba(16,24,40,.04);
}
body.nx .pcard + .pcard{margin-top:16px;}
body.nx .pcard-h{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding-bottom:14px;margin-bottom:16px;border-bottom:1px solid var(--edge);
}
body.nx .pcard-h h2{margin:0;font-size:15px;font-weight:600;color:var(--ink);letter-spacing:0;}
body.nx .psec-h{margin:26px 0 6px;font-size:19px;color:var(--ink);}
body.nx .psec-p{margin:0 0 14px;font-size:13.5px;color:var(--mu);line-height:1.6;max-width:62ch;}
/* Label left, value right, on one grid so every row lines up. */
body.nx .pkv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:11px 26px;font-size:14px;}
body.nx .pkv dt{font-weight:600;color:var(--ink);}
body.nx .pkv dd{margin:0;color:var(--mu);overflow-wrap:anywhere;}
body.nx .pkv dd.is-empty{color:var(--dim);font-style:italic;}
body.nx .pkv a{color:var(--teal);}

body.nx .pava-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap;}
body.nx .pava{
  width:74px;height:74px;flex:none;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:var(--paper-3);color:var(--mu);
  border:1px solid var(--edge);
}
body.nx .pava img{width:100%;height:100%;object-fit:cover;display:block;}
body.nx .pmissing{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 10px;border-radius:999px;background:#fdeee7;color:#a8492a;
  font-size:11.5px;font-weight:600;
}
body.nx .phint{margin:10px 0 0;font-size:12.5px;color:var(--dim);}

/* Profile strength: a percentage, a bar, and the list behind the number. */
body.nx .pstr{
  position:sticky;top:22px;background:#fff;border:1px solid var(--edge);
  border-radius:var(--r);padding:20px;box-shadow:0 1px 2px rgba(16,24,40,.04);
}
body.nx .pstr-n{margin:0;font-size:34px;font-weight:700;color:var(--ink);line-height:1;
  font-variant-numeric:tabular-nums;}
body.nx .pstr-bar{
  height:5px;border-radius:5px;background:var(--paper-3);margin:12px 0 6px;overflow:hidden;
}
body.nx .pstr-bar span{display:block;height:100%;background:var(--brand);border-radius:5px;
  transition:width .5s var(--ease);}
body.nx .pstr-h{margin:0 0 14px;font-size:14px;font-weight:600;color:var(--ink);}
body.nx .pstr-list{list-style:none;margin:0;padding:0;display:grid;gap:11px;}
body.nx .pstr-list li{display:flex;align-items:flex-start;gap:10px;font-size:13px;
  line-height:1.4;color:var(--ink-2);}
body.nx .pstr-list a{color:inherit;text-decoration:none;}
body.nx .pstr-list a:hover{color:var(--ink);text-decoration:underline;}
body.nx .pstr-tick{
  width:18px;height:18px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:var(--brand);color:var(--brand-ink);margin-top:1px;
}
body.nx .pstr-list li.off{color:var(--dim);}
body.nx .pstr-list li.off .pstr-tick{background:transparent;border:1.5px solid var(--edge);}
body.nx .pstr-list li.off .pstr-tick svg{display:none;}
@media (max-width:1180px){
  body.nx .pcols{grid-template-columns:196px minmax(0,1fr);}
  body.nx .pstr{grid-column:1 / -1;position:static;}
}
@media (max-width:820px){
  body.nx .pcols{grid-template-columns:1fr;}
  body.nx .pnav{position:static;grid-auto-flow:column;overflow-x:auto;}
  body.nx .pnav a{white-space:nowrap;}
}

/* ══ 39. GUIDE ARTICLE — one interview guide ═════════════════════════
   A long read with a rail: contents on the left that tracks the scroll,
   the article in the middle at a real measure. The rail is the reason
   someone can use this as a reference instead of reading it once —
   most people arrive for one section, not for the whole thing.
   ------------------------------------------------------------------ */
body.nx .gart{
  display:grid;grid-template-columns:clamp(210px,18vw,262px) minmax(0,1fr);
  gap:clamp(28px,4vw,60px);align-items:start;
}
/* The rail rests as marks, not as a menu.

   Ten section titles standing beside a long article compete with it the
   whole way down, and the reader pays that cost on every screen to get
   an answer they need twice. Ten short rules carry the same two facts —
   how many sections there are, which one you are in — and carry them
   without asking to be read. The titles are not removed: they are one
   hover or one Tab away, which is the moment somebody is actually
   looking for them.

   The marks are drawn with pseudo-elements rather than added to the
   markup on purpose. Each link's text run IS its key in the translation
   catalogue, so a <span> inside the <a> would silently orphan ten
   Russian strings. Nothing in this section touches the HTML. */
body.nx .gtoc{
  position:sticky;top:calc(var(--nav-sm) + 28px);
  --tick:20px;        /* a section at rest */
  --tick-on:34px;     /* the one you are reading */
  --rail:16px;        /* gutter left clear for the progress bar */
}
body.nx .gtoc-h{
  margin:0 0 12px;font-family:var(--mono);font-size:11px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--acc);
  opacity:0;transform:translateX(-4px);
  transition:opacity .18s ease,transform .18s ease;
}
body.nx .gtoc ol{
  list-style:none;margin:0;padding:0;display:grid;gap:2px;
  transition:background-color .18s ease,box-shadow .18s ease;
}
body.nx .gtoc li{position:relative;height:26px;overflow:hidden;}
body.nx .gtoc li::before{
  content:"";position:absolute;top:50%;right:var(--rail);margin-top:-1px;
  width:var(--tick);height:2px;border-radius:1px;background:var(--edge);
  transition:width .22s ease,background-color .22s ease,opacity .16s ease;
}
body.nx .gtoc li.on::before{width:var(--tick-on);background:var(--ink);}
body.nx .gtoc a{
  display:block;padding:7px 12px;border-radius:8px;
  font-size:13.5px;line-height:1.4;color:var(--mu);text-decoration:none;
  opacity:0;transform:translateX(-4px);
  transition:opacity .18s ease,transform .18s ease,background-color .15s,color .15s;
}
/* Opacity, not display or visibility: the link stays in the
   accessibility tree, stays focusable, and a click on the mark still
   jumps to the section without the labels ever being shown. */
body.nx .gtoc:hover li,
body.nx .gtoc:focus-within li{height:auto;overflow:visible;}
body.nx .gtoc:hover li::before,
body.nx .gtoc:focus-within li::before{opacity:0;}
body.nx .gtoc:hover .gtoc-h,   body.nx .gtoc:focus-within .gtoc-h,
body.nx .gtoc:hover a,         body.nx .gtoc:focus-within a{
  opacity:1;transform:none;
}
body.nx .gtoc:hover ol,
body.nx .gtoc:focus-within ol{
  background:var(--paper-2);box-shadow:0 0 0 1px var(--edge);
  border-radius:12px;padding:6px;margin:-6px;
}
body.nx .gtoc a:hover{background:var(--paper);color:var(--ink);}
body.nx .gtoc li.on a{color:var(--ink);font-weight:600;}

/* Reading progress, in the gutter the marks leave free. Measured over
   the article rather than the document: the reader is being told how
   much of THIS is left, and the footer is not part of the answer. */
body.nx .gtoc::after{
  content:"";position:absolute;right:0;top:0;width:3px;border-radius:3px;
  background:var(--dim);opacity:.45;
  height:var(--th,0px);transform:translateY(var(--ty,0px));
  transition:opacity .16s ease;
}
body.nx .gtoc:hover::after,
body.nx .gtoc:focus-within::after{opacity:0;}

@media (prefers-reduced-motion:reduce){
  body.nx .gtoc-h,body.nx .gtoc a,body.nx .gtoc li::before,
  body.nx .gtoc ol,body.nx .gtoc::after{transition:none;}
}

body.nx .gbody{max-width:70ch;}
body.nx .gbody h2{
  margin:44px 0 14px;font-size:clamp(22px,2.2vw,28px);line-height:1.2;
  letter-spacing:-.014em;color:var(--ink);scroll-margin-top:calc(var(--nav-sm) + 28px);
}
body.nx .gbody h2:first-child{margin-top:0;}
body.nx .gbody h3{
  margin:26px 0 10px;font-size:16.5px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .gbody p{margin:0 0 16px;font-size:15.5px;line-height:1.72;color:var(--ink-2);}
body.nx .gbody ul{margin:0 0 18px;padding-left:22px;display:grid;gap:8px;}
body.nx .gbody li{font-size:15px;line-height:1.65;color:var(--ink-2);}
body.nx .gbody li::marker{color:var(--dim);}
body.nx .gbody strong{color:var(--ink);font-weight:600;}

/* A question the way it actually gets asked, set apart from the prose
   that explains how to answer it. */
body.nx .gq{
  margin:0 0 18px;padding:15px 18px;border-radius:var(--r-sm);
  background:var(--paper-2);border-left:3px solid var(--acc);
}
body.nx .gq b{
  display:block;font-family:var(--mono);font-size:10.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--acc);margin-bottom:6px;
}
body.nx .gq p{margin:0;font-size:15px;color:var(--ink);font-weight:500;}

/* The three bands, side by side — the section people jump straight to. */
body.nx .gbands{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:0 0 20px;}
body.nx .gband{
  padding:18px;border-radius:var(--r-sm);
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .gband h4{
  margin:0 0 9px;font-size:14px;font-weight:600;color:var(--ink);letter-spacing:0;
}
body.nx .gband p{margin:0;font-size:13.5px;line-height:1.6;color:var(--mu);}

body.nx .gfaq{border-top:1px solid var(--edge);}
body.nx .gfaq details{border-bottom:1px solid var(--edge);padding:4px 0;}
body.nx .gfaq summary{
  cursor:pointer;padding:15px 0;list-style:none;
  font-size:15.5px;font-weight:600;color:var(--ink);
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
}
body.nx .gfaq summary::-webkit-details-marker{display:none;}
body.nx .gfaq summary::after{
  content:'+';flex:none;color:var(--acc);font-size:20px;line-height:1;
  transition:transform .2s var(--ease);
}
body.nx .gfaq details[open] summary::after{transform:rotate(45deg);}
body.nx .gfaq details p{margin:0 0 16px;font-size:15px;line-height:1.7;color:var(--mu);}

/* Live roles, read from the database rather than written into the page.
   An empty result says so instead of showing a fabricated list. */
body.nx .glive{display:grid;gap:10px;margin:0 0 18px;}
body.nx .glive-row{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:15px 18px;border-radius:var(--r-sm);
  background:var(--paper);border:1px solid var(--edge);
  text-decoration:none;transition:border-color .16s;
}
body.nx .glive-row:hover{border-color:color-mix(in srgb,var(--acc) 45%,var(--edge));}
body.nx .glive-t{min-width:0;}
body.nx .glive-t b{display:block;font-size:15px;color:var(--ink);font-weight:600;}
body.nx .glive-t span{display:block;font-size:13px;color:var(--mu);margin-top:2px;}
body.nx .glive-go{flex:none;color:var(--acc);font-size:13.5px;font-weight:600;}
body.nx .gnone{
  margin:0 0 18px;padding:16px 18px;border-radius:var(--r-sm);
  background:var(--paper-2);border:1px solid var(--edge);
  font-size:14px;color:var(--mu);
}

@media (max-width:900px){
  body.nx .gart{grid-template-columns:minmax(0,1fr);}
  /* No marks on a phone: there is no rail beside the text to put them
     in, and a row of dashes above an article explains nothing. The
     labels come back and scroll sideways, as before. */
  body.nx .gtoc{position:static;}
  body.nx .gtoc-h{opacity:1;transform:none;}
  body.nx .gtoc ol{grid-auto-flow:column;grid-auto-columns:max-content;overflow-x:auto;gap:6px;}
  body.nx .gtoc li{height:auto;overflow:visible;}
  body.nx .gtoc li::before{display:none;}
  body.nx .gtoc::after{display:none;}
  body.nx .gtoc a{
    opacity:1;transform:none;
    border-left:0;border-bottom:2px solid transparent;white-space:nowrap;
  }
  body.nx .gtoc li.on a{border-left:0;border-bottom-color:var(--acc);}
  body.nx .gbands{grid-template-columns:1fr;}
}

/* ══ 40. GUIDE HUB — the long read that sits under the card index ═════
   Same rail and measure as section 39, plus the three devices the hub
   needs and a single guide does not: full-width figures, the boxed
   prep tips that follow each format, and one comparison table.
   ------------------------------------------------------------------ */

/* The prose keeps a 70ch measure; the illustrations and the table do not.
   Both carry data that is genuinely unreadable when squeezed to a reading
   column, so they run to the full width of the article column instead. */
body.nx .gbody-wide{max-width:none;}
body.nx .gbody-wide > *{max-width:70ch;}
body.nx .gbody-wide > .gfig,
body.nx .gbody-wide > .gtable-wrap{max-width:none;}

body.nx .gfig{
  margin:26px 0 26px;border-radius:var(--r-sm);overflow:hidden;
  border:1px solid var(--edge);background:var(--paper-2);
}
body.nx .gfig-x{overflow-x:auto;-webkit-overflow-scrolling:touch;}
body.nx .gfig-x img{display:block;width:100%;height:auto;}
body.nx .gfig figcaption{
  padding:11px 16px;border-top:1px solid var(--edge);background:var(--paper);
  font-size:12.5px;line-height:1.55;color:var(--mu);
}
body.nx .gfig-hint{display:none;}

/* Below this width the labels inside the illustrations fall under about
   6px, which is not a diagram any more. Hold them at a legible size and
   let the figure scroll sideways instead — the caption stays put. */
@media (max-width:760px){
  body.nx .gfig-x img{width:660px;max-width:none;}
  body.nx .gfig-hint{display:block;margin-top:4px;color:var(--acc);font-weight:600;}
}

/* What to do about the format just described. Deliberately a different
   shape from .gq so a scanner can tell a question from an instruction. */
body.nx .gtip{
  margin:0 0 20px;padding:16px 18px 4px;border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--acc) 6%,var(--paper-2));
  border:1px solid color-mix(in srgb,var(--acc) 18%,var(--edge));
}
body.nx .gtip b{
  display:block;font-family:var(--mono);font-size:10.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--acc);margin-bottom:9px;
}
body.nx .gtip ul{margin:0 0 14px;padding-left:20px;display:grid;gap:6px;}
body.nx .gtip li{font-size:14.5px;line-height:1.6;color:var(--ink-2);}

body.nx .gtable-wrap{overflow-x:auto;margin:0 0 20px;-webkit-overflow-scrolling:touch;}
body.nx .gtable{
  width:100%;min-width:520px;border-collapse:collapse;
  font-size:14px;font-variant-numeric:tabular-nums;
}
body.nx .gtable th,body.nx .gtable td{
  padding:11px 14px;text-align:right;border-bottom:1px solid var(--edge);
}
body.nx .gtable th:first-child,body.nx .gtable td:first-child{text-align:left;}
body.nx .gtable thead th{
  font-size:11.5px;font-weight:700;letter-spacing:.04em;color:var(--mu);
  text-transform:uppercase;border-bottom:1px solid var(--ink);vertical-align:bottom;
}
body.nx .gtable tbody th{font-weight:600;color:var(--ink);}
body.nx .gtable tbody tr:last-child th,
body.nx .gtable tbody tr:last-child td{border-bottom:0;}
body.nx .gtable caption{
  caption-side:bottom;padding-top:10px;text-align:left;
  font-size:12.5px;color:var(--mu);
}

/* A pull quote — one per page, used where an outside voice says the
   thing better than the surrounding prose does. */
body.nx .gpull{
  margin:26px 0;padding:0 0 0 22px;border-left:3px solid var(--acc);
}
body.nx .gpull p{margin:0 0 8px;font-size:19px;line-height:1.5;color:var(--ink);letter-spacing:-.01em;}
body.nx .gpull cite{font-style:normal;font-size:13px;color:var(--mu);}

/* ══ 41. DASHBOARD SECTIONS — requests, interviews, apply, companies ══
   The shared furniture the inner pages need and the dashboard itself
   does not: a row of counters, a tab strip, and a list row that carries
   an action rather than just reporting a fact.
   ------------------------------------------------------------------ */

/* A row of counts. Each one is a filter as well as a number — clicking
   it scopes the list below, which is why they are buttons. */
body.nx .dstats{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));
  gap:12px;margin-bottom:18px;
}
body.nx .dstat{
  display:block;width:100%;text-align:left;cursor:pointer;
  padding:16px 18px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
  font:inherit;transition:border-color .16s,background .16s;
}
body.nx .dstat:hover{border-color:color-mix(in srgb,var(--acc) 45%,var(--edge));}
body.nx .dstat.on{
  border-color:var(--acc);
  background:color-mix(in srgb,var(--acc) 6%,var(--paper));
}
body.nx .dstat b{
  display:block;font-size:26px;line-height:1.1;color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
}
body.nx .dstat span{
  display:block;margin-top:5px;font-size:12.5px;line-height:1.35;color:var(--mu);
}
/* Something waiting on the candidate is the one count that should catch
   the eye, so it is the only one that takes the accent. */
body.nx .dstat.is-due b{color:var(--acc);}

body.nx .dtabs{
  display:flex;gap:4px;margin-bottom:18px;
  border-bottom:1px solid var(--edge);
}
body.nx .dtab{
  padding:10px 14px;border:0;background:none;cursor:pointer;font:inherit;
  font-size:14px;font-weight:600;color:var(--mu);
  border-bottom:2px solid transparent;margin-bottom:-1px;
  transition:color .15s,border-color .15s;
}
body.nx .dtab:hover{color:var(--ink);}
body.nx .dtab.on{color:var(--ink);border-bottom-color:var(--acc);}
body.nx .dtab .n{
  margin-left:6px;font-variant-numeric:tabular-nums;color:var(--dim);font-weight:600;
}
body.nx .dtab.on .n{color:var(--acc);}

/* Controls above a list: a search box, and the selects that decide what
   is shown and in what order. */
body.nx .dbar{
  display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;margin-bottom:16px;
}
body.nx .dbar .grow{flex:1 1 220px;min-width:0;}
/* Field captions only. `.dtoggle` is itself a label and reads as a
   sentence, so it must not be caught by this. */
body.nx .dbar > div > label{
  display:block;margin-bottom:5px;font-family:var(--mono);font-size:10.5px;
  font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--mu);
}
body.nx .dbar input,body.nx .dbar select{
  width:100%;padding:9px 12px;border-radius:var(--r-xs);
  border:1px solid var(--edge);background:var(--paper);color:var(--ink);
  font:inherit;font-size:14px;
}
body.nx .dbar input:focus,body.nx .dbar select:focus{
  outline:2px solid color-mix(in srgb,var(--acc) 55%,transparent);outline-offset:1px;
}
body.nx .dtoggle{
  display:inline-flex;align-items:center;gap:8px;padding:9px 0;
  font-size:13.5px;color:var(--ink-2);cursor:pointer;white-space:nowrap;
}

/* A list row that asks for something. The buttons live inside the row
   because the answer belongs to that one application. */
body.nx .dlist{display:grid;gap:12px;}
body.nx .drow{
  padding:18px;border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .drow.is-due{border-color:color-mix(in srgb,var(--acc) 50%,var(--edge));}
body.nx .drow-top{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
}
body.nx .drow-t b{display:block;font-size:16px;font-weight:600;color:var(--ink);}
body.nx .drow-t span{display:block;margin-top:3px;font-size:13.5px;color:var(--mu);}
body.nx .dstate{
  flex:none;padding:4px 11px;border-radius:999px;font-size:11.5px;font-weight:600;
  background:var(--paper-2);border:1px solid var(--edge);color:var(--mu);
  white-space:nowrap;
}
body.nx .dstate.is-due{
  background:color-mix(in srgb,var(--acc) 12%,var(--paper));
  border-color:color-mix(in srgb,var(--acc) 40%,var(--edge));color:var(--acc);
}
body.nx .dask{
  margin-top:14px;padding-top:14px;border-top:1px solid var(--edge);
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;
}
body.nx .dask p{margin:0 auto 0 0;font-size:13px;color:var(--mu);max-width:46ch;}
body.nx .drow-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px;}
body.nx .drow-tag{
  padding:3px 9px;border-radius:999px;font-size:11.5px;color:var(--mu);
  background:var(--paper-2);border:1px solid var(--edge);
}

/* Follow is a two-state control, so it looks like one rather than
   swapping between two differently-shaped buttons. */
body.nx .dfollow{
  flex:none;display:inline-flex;align-items:center;gap:6px;
  padding:7px 14px;border-radius:999px;cursor:pointer;font:inherit;
  font-size:13px;font-weight:600;
  background:var(--paper);border:1px solid var(--edge);color:var(--ink);
  transition:background .15s,border-color .15s,color .15s;
}
body.nx .dfollow:hover{border-color:color-mix(in srgb,var(--acc) 50%,var(--edge));}
body.nx .dfollow.on{
  background:var(--acc);border-color:var(--acc);color:#fff;
}
body.nx .dfollow[disabled]{opacity:.55;cursor:default;}

/* The strip an employer sees on their own company page: it is the same
   page a candidate reads, so it has to say whose view this is. */
body.nx .own-note{display:flex;flex-wrap:wrap;gap:12px 16px;align-items:center;
  margin:0 0 18px;padding:12px 16px;border:1px solid var(--edge);background:var(--paper-2);}
body.nx .own-note p{margin:0;flex:1 1 240px;font-size:13.5px;color:var(--mu);}

body.nx .dempty{
  padding:34px 24px;border-radius:var(--r);text-align:center;
  background:var(--paper);border:1px dashed var(--edge);
}
body.nx .dempty h2{margin:0 0 8px;font-size:17px;color:var(--ink);}
body.nx .dempty p{margin:0 auto;max-width:52ch;font-size:14px;line-height:1.6;color:var(--mu);}
body.nx .dempty .btn{margin-top:16px;}

@media (max-width:640px){
  body.nx .dstats{grid-template-columns:repeat(2,1fr);}
  body.nx .dtabs{overflow-x:auto;}
  body.nx .dask p{margin-bottom:4px;}
}

/* ══ 42. COMPANY CARDS ═══════════════════════════════════════════════
   A three-up grid of company cards: a tinted band, a mark, the facts a
   jobseeker actually decides on, and the two actions.
   ------------------------------------------------------------------ */

/* The search box and the preference switch stay put while the grid
   scrolls — on a long list the control you want is the one you just
   scrolled away from. */
body.nx .cofilter{
  position:sticky;top:calc(var(--nav-sm) - 24px);z-index:5;
  padding:16px 0 14px;margin-bottom:4px;
  background:var(--paper-2);border-bottom:1px solid var(--edge);
}
body.nx .cosearch{position:relative;}
body.nx .cosearch .ico{
  position:absolute;left:14px;top:50%;transform:translateY(-50%);
  color:var(--dim);pointer-events:none;
}
body.nx .cosearch input{
  width:100%;padding:12px 14px 12px 42px;border-radius:999px;
  border:1px solid var(--edge);background:var(--paper);color:var(--ink);
  font:inherit;font-size:14.5px;
}
body.nx .cosearch input:focus{
  outline:2px solid color-mix(in srgb,var(--acc) 55%,transparent);outline-offset:1px;
}
body.nx .coprefs{display:flex;align-items:center;gap:10px;margin-top:14px;flex-wrap:wrap;}
body.nx .coprefs b{font-size:14.5px;font-weight:600;color:var(--ink);}
body.nx .coprefs small{font-size:13px;color:var(--mu);}
body.nx .coprefs a{font-size:13.5px;font-weight:600;color:var(--acc);}

/* The switch itself. A real checkbox underneath, so it is focusable and
   announces its state without any ARIA bolted on. */
body.nx .swi{position:relative;flex:none;width:44px;height:24px;}
body.nx .swi input{
  position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;
}
body.nx .swi span{
  display:block;width:100%;height:100%;border-radius:999px;
  background:var(--paper-3);border:1px solid var(--edge);
  transition:background .18s,border-color .18s;pointer-events:none;
}
body.nx .swi span::after{
  content:'';position:absolute;top:3px;left:3px;width:18px;height:18px;
  border-radius:50%;background:var(--paper);
  box-shadow:0 1px 3px rgba(0,0,0,.25);transition:transform .18s;
}
body.nx .swi input:checked + span{background:var(--acc);border-color:var(--acc);}
body.nx .swi input:checked + span::after{transform:translateX(20px);}
body.nx .swi input:focus-visible + span{
  outline:2px solid color-mix(in srgb,var(--acc) 60%,transparent);outline-offset:2px;
}

body.nx .cosec{margin-top:26px;}
body.nx .cosec h2{
  margin:0 0 16px;font-size:19px;letter-spacing:-.01em;color:var(--ink);
}
body.nx .cogrid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:18px;
}
body.nx .cocard{
  display:flex;flex-direction:column;border-radius:var(--r);overflow:hidden;
  background:var(--paper);border:1px solid var(--edge);
  transition:border-color .16s,transform .16s;
}
body.nx .cocard:hover{
  border-color:color-mix(in srgb,var(--acc) 40%,var(--edge));transform:translateY(-2px);
}
/* A tinted band, not a photograph. Nebryx has no cover images and a
   stock photo of somebody else's office is a claim about the company. */
body.nx .coband{display:block;height:78px;position:relative;}
body.nx .comark{
  position:absolute;left:16px;bottom:-24px;width:56px;height:56px;
  border-radius:14px;display:grid;place-items:center;overflow:hidden;
  background:var(--paper);border:1px solid var(--edge);
  box-shadow:0 2px 8px rgba(11,17,32,.10);
}
body.nx .comark img{width:100%;height:100%;object-fit:contain;padding:6px;}
/* Initials, when no logo has been uploaded. Deliberately reads as a
   placeholder rather than as the company's own mark. */
body.nx .comark b{
  font-size:19px;font-weight:600;letter-spacing:.01em;color:var(--ink);
}
body.nx .cohot{
  position:absolute;right:12px;bottom:-11px;
  padding:4px 10px;border-radius:999px;font-size:11px;font-weight:600;
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap;
  background:var(--paper);border:1px solid color-mix(in srgb,var(--acc) 45%,var(--edge));
  color:var(--acc);
}
body.nx .cobody{padding:36px 18px 0;flex:1;}
body.nx .cobody h3{
  margin:0 0 8px;font-size:17px;font-weight:600;letter-spacing:-.01em;color:var(--ink);
}
body.nx .coabout{
  margin:0 0 14px;font-size:13.5px;line-height:1.55;color:var(--mu);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
body.nx .cofact{
  display:flex;gap:9px;align-items:flex-start;margin-bottom:9px;
  font-size:13px;line-height:1.5;color:var(--ink-2);
}
body.nx .cofact .ico{flex:none;color:var(--dim);margin-top:2px;}
body.nx .cofact .more{color:var(--acc);font-weight:600;}
body.nx .cofoot{
  display:flex;gap:10px;padding:16px 18px 18px;margin-top:14px;
  border-top:1px solid var(--edge);
}
body.nx .cofoot .btn{flex:1;justify-content:center;}

body.nx .copage,
body.nx .bpage{
  display:flex;align-items:center;justify-content:center;gap:6px;margin-top:20px;
}
body.nx .copage button,
body.nx .bpage button{
  min-width:34px;height:34px;padding:0 9px;border-radius:9px;cursor:pointer;font:inherit;
  font-size:13.5px;font-weight:600;font-variant-numeric:tabular-nums;
  background:var(--paper);border:1px solid var(--edge);color:var(--ink);
}
body.nx .copage button:hover:not([disabled]),
body.nx .bpage button:hover:not([disabled]){
  border-color:color-mix(in srgb,var(--acc) 45%,var(--edge));
}
body.nx .copage button.on,
body.nx .bpage button.on{background:var(--acc);border-color:var(--acc);color:#fff;}
body.nx .copage button[disabled],
body.nx .bpage button[disabled]{opacity:.4;cursor:default;}
body.nx .copage .gap,
body.nx .bpage .gap{color:var(--dim);padding:0 2px;}

/* One company, in full. */
body.nx .cohero{
  border-radius:var(--r);overflow:hidden;margin-bottom:18px;
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .cohero .coband{height:120px;}
body.nx .cohero .comark{width:76px;height:76px;border-radius:18px;left:22px;bottom:-30px;}
body.nx .cohero .comark b{font-size:26px;}
body.nx .cohero-in{padding:44px 22px 22px;}
body.nx .cohero-in h2{margin:0 0 6px;font-size:24px;letter-spacing:-.02em;color:var(--ink);}
body.nx .cohero-in .coabout{-webkit-line-clamp:none;max-width:68ch;font-size:14.5px;}
body.nx .cohero-act{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px;}

@media (max-width:560px){
  body.nx .cogrid{grid-template-columns:1fr;}
  body.nx .cofilter{position:static;}
}

/* ══ 43. BLOG ════════════════════════════════════════════════════════
   A dark opening, then a light band carrying dark cards: one post leads
   at full width and the rest go three-up, filtered by tag and by search.

   No stock photography. Each post gets a tinted panel whose hue is
   derived from its own title, so the grid has rhythm and a post keeps
   the same colour everywhere it appears — rather than a picture of
   somebody else's office standing in for an article nobody has read yet.
   ------------------------------------------------------------------ */

/* ── the opening: a headline beside the illustration ───────────────── */
body.nx .hero-blog{padding-bottom:clamp(48px,6vw,80px);}
body.nx .hero-blog .hero-in{
  max-width:none;text-align:left;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,clamp(300px,36vw,500px));
  gap:clamp(26px,5vw,64px);align-items:center;
}
body.nx .hero-blog h1{
  margin:16px 0 20px;max-width:11ch;
  font-size:clamp(40px,6.6vw,78px);line-height:1.02;letter-spacing:-.035em;
}
body.nx .hero-blog .lead{margin:0;max-width:46ch;}
body.nx .hero-art{
  width:100%;height:auto;display:block;border-radius:var(--r-lg);
  box-shadow:0 24px 60px rgba(0,0,0,.45);
}
@media (max-width:860px){
  body.nx .hero-blog .hero-in{grid-template-columns:minmax(0,1fr);}
  body.nx .hero-blog h1{max-width:none;}
}

/* ── filters ───────────────────────────────────────────────────────── */
body.nx .btools{
  display:flex;flex-wrap:wrap;gap:14px;align-items:flex-start;
  justify-content:space-between;margin-bottom:26px;
}
body.nx .bchips{display:flex;flex-wrap:wrap;gap:8px;max-width:720px;}
body.nx .bchip{
  padding:5px 13px;border-radius:999px;cursor:pointer;font:inherit;
  font-size:12.5px;font-weight:500;white-space:nowrap;
  background:transparent;color:var(--acc);
  border:1px solid color-mix(in srgb,var(--acc) 42%,transparent);
  transition:border-color .15s,color .15s,background .15s;
}
body.nx .bchip:hover{background:var(--acc-soft);border-color:var(--acc);}
body.nx .bchip.on{background:var(--acc);border-color:var(--acc);color:#fff;}
body.nx .bchip .n{opacity:.62;margin-left:6px;font-variant-numeric:tabular-nums;}

body.nx .bsearch{position:relative;flex:0 1 300px;min-width:210px;}
body.nx .bsearch .ico{
  position:absolute;right:14px;top:50%;transform:translateY(-50%);
  color:var(--dim);pointer-events:none;
}
body.nx .bsearch input{
  width:100%;padding:9px 40px 9px 15px;border-radius:var(--r-xs);
  border:1px solid var(--edge);background:var(--paper);color:var(--ink);
  font:inherit;font-size:14px;
}
body.nx .bsearch input:focus{
  outline:2px solid color-mix(in srgb,var(--acc) 55%,transparent);outline-offset:1px;
}
body.nx .bcount{
  margin:0 0 14px;font-family:var(--mono);font-size:12px;letter-spacing:.06em;
  color:var(--mu);
}

/* ── the cards ─────────────────────────────────────────────────────
   Dark cards on a light page. They carry their own token set rather
   than a parallel sheet of `.dark .x` rules — the panel, the tags and
   the meta line all repaint because --paper/--edge/--ink changed under
   them, exactly the way .band-dark works one section up. */
body.nx .bfeat,
body.nx .bcard{
  --ink:#f4f7fb; --ink-2:#d6dce5; --mu:#a2abb8; --dim:#79828f;
  --paper:#111317; --paper-2:#161a1f; --paper-3:#1e232a;
  --edge:#272d35;
  --acc:#2dd4bf; --acc-2:#5eead4;
  display:flex;flex-direction:column;overflow:hidden;
  background:#0f1114;border:1px solid var(--edge);border-radius:var(--r);
  color:var(--ink);text-decoration:none;
  transition:border-color .16s,transform .16s,box-shadow .16s;
}
body.nx .bfeat:hover,
body.nx .bcard:hover{
  border-color:color-mix(in srgb,var(--acc) 50%,var(--edge));
  transform:translateY(-2px);box-shadow:0 16px 40px rgba(11,17,32,.16);
}

/* the strip along the top: when it was written, how long it takes */
body.nx .bstrip{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  padding:10px 16px;background:#15181d;border-bottom:1px solid var(--edge);
  font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--acc);
}
body.nx .bstrip .dot{opacity:.55;}

/* The panel that stands in for a photograph. */
body.nx .bpanel{
  position:relative;display:grid;place-items:center;aspect-ratio:16/9;
  border-radius:var(--r-sm);overflow:hidden;
}
body.nx .bpanel span{
  font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:#ffffff;opacity:.62;padding:0 14px;
  text-align:center;
}
body.nx .btags{
  margin:0 0 8px;font-size:12.5px;line-height:1.45;color:var(--acc);font-weight:500;
}
body.nx .by{margin-top:auto;padding-top:12px;font-size:12.5px;color:var(--acc);}

/* one post, leading */
body.nx .bfeat{margin-bottom:22px;}
body.nx .bfeat-in{
  display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,1fr);
  gap:clamp(18px,2.8vw,34px);padding:clamp(16px,2vw,22px);align-items:center;
}
body.nx .bfeat-txt{display:flex;flex-direction:column;}
body.nx .bfeat h2{
  margin:0 0 12px;font-size:clamp(20px,2.2vw,27px);line-height:1.2;
  letter-spacing:-.02em;color:var(--ink);
}
body.nx .bfeat p{margin:0 0 14px;font-size:14.5px;line-height:1.65;color:var(--mu);}

/* the rest, three-up */
body.nx .bgrid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:20px;
}
body.nx .bcard .bpanel{margin:14px 16px 0;}
body.nx .bbody{display:flex;flex-direction:column;flex:1;padding:14px 16px 16px;}
body.nx .bcard h3{
  margin:0 0 10px;font-size:15.5px;line-height:1.35;letter-spacing:-.01em;color:var(--ink);
}

/* ── pagination — words, not arrows: "next" is a promise an arrow only
   implies, and the reference's own control says so out loud. ───────── */
body.nx .bpage{
  display:flex;align-items:center;justify-content:center;gap:6px;
  margin-top:clamp(28px,4vw,46px);
}
body.nx .bpage button{
  min-width:34px;height:34px;padding:0 10px;border-radius:8px;cursor:pointer;font:inherit;
  font-size:13.5px;font-weight:500;font-variant-numeric:tabular-nums;
  background:transparent;border:1px solid transparent;color:var(--mu);
  transition:color .15s,background .15s;
}
body.nx .bpage button:hover:not([disabled]){color:var(--acc);background:var(--acc-soft);}
body.nx .bpage button.on{
  background:var(--acc);border-color:var(--acc);color:#fff;font-weight:600;
}
body.nx .bpage button[disabled]{opacity:.35;cursor:default;}
body.nx .bpage .gap{color:var(--dim);padding:0 2px;}

/* ── the two closing panels ───────────────────────────────────────── */
body.nx .bcta{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px;
}
body.nx .bcta > div{
  padding:clamp(24px,3vw,38px);border-radius:var(--r);
  background:var(--paper);border:1px solid var(--edge);
}
body.nx .bcta h2{
  margin:0 0 12px;font-size:clamp(21px,2.2vw,27px);line-height:1.18;
  letter-spacing:-.02em;color:var(--ink);
}
body.nx .bcta p{margin:0 0 20px;font-size:14.5px;line-height:1.65;color:var(--mu);}

/* ── the standing invitation ───────────────────────────────────────
   Fixed, and therefore taking viewport away from the thing the reader
   came for — so it closes, and it is only ever shown to somebody who
   does not already have a profile. */
body.nx .sticky-cta{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap;
  padding:12px var(--gut);
  background:var(--nav-ink);color:#e8edf6;
  border-top:1px solid rgba(255,255,255,.1);
  font-size:14px;
}
body.nx .sticky-cta b{color:var(--brand);font-weight:600;}
body.nx .sticky-cta .btn{padding:8px 18px;font-size:13.5px;}
body.nx .sticky-cta .x{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);
  width:30px;height:30px;display:grid;place-items:center;cursor:pointer;
  background:transparent;border:0;color:#8f98a5;border-radius:8px;
}
body.nx .sticky-cta .x:hover{color:#fff;background:rgba(255,255,255,.1);}
/* On a phone the full sentence runs to three lines and takes a quarter
   of the viewport away from the article the reader came for. The claim
   stays; the explanation goes. */
@media (max-width:640px){
  body.nx .sticky-cta{font-size:13px;padding:10px 46px 10px var(--gut);gap:10px;}
  body.nx .sticky-cta .more{display:none;}
}
/* A fixed bar sits ON the last thing on the page. The footer gives back
   exactly the height it takes, and stops doing so the moment the bar is
   dismissed — :has() re-evaluates when the element is removed. */
body.nx:has(.sticky-cta) .foot{padding-bottom:78px;}

/* ── one article. Narrow measure, no contents rail — these are short. */
body.nx .bart{max-width:70ch;margin:0 auto;}
body.nx .bart-head{margin-bottom:26px;}
body.nx .bart-head h1{
  margin:12px 0 14px;font-size:clamp(28px,3.6vw,42px);line-height:1.12;
  letter-spacing:-.028em;color:var(--ink);text-wrap:balance;
}
body.nx .bart .bmeta{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.05em;color:var(--mu);
}
body.nx .bart .bmeta .dot{opacity:.5;}
/* Wider than the card's 16:9. At a 70ch measure a 16:9 block is a lot
   of empty colour before the first sentence. */
body.nx .bart .bpanel{margin:22px 0 30px;aspect-ratio:21/9;}
body.nx .bart-back{
  display:inline-block;margin-bottom:20px;font-size:13.5px;
  font-weight:600;color:var(--acc);
}

/* The prose reuses section 39's .gbody; these are the blocks an article
   uses that a guide never did. */
body.nx .gbody blockquote{
  margin:0 0 18px;padding:2px 0 2px 20px;border-left:3px solid var(--acc);
  font-size:17px;line-height:1.55;color:var(--ink);
}
body.nx .gbody ol{margin:0 0 18px;padding-left:22px;display:grid;gap:8px;}
body.nx .gbody pre{
  margin:0 0 18px;padding:14px 16px;border-radius:var(--r-sm);overflow-x:auto;
  background:var(--paper-2);border:1px solid var(--edge);
}
body.nx .gbody pre code{font-size:13px;line-height:1.6;color:var(--ink-2);}
body.nx .gbody code{
  font-family:var(--mono);font-size:.9em;padding:1px 5px;border-radius:5px;
  background:var(--paper-2);border:1px solid var(--edge);color:var(--ink);
}
body.nx .gbody hr{
  margin:26px 0;border:0;border-top:1px solid var(--edge);
}
body.nx .gbody a{color:var(--acc);}

@media (max-width:760px){
  body.nx .bfeat-in{grid-template-columns:minmax(0,1fr);}
  body.nx .bfeat-in .bpanel{order:-1;}
}

/* ══ PRODUCT BAR ══════════════════════════════════════════════════
   The second row on a product page: which product, and what else is
   in it. Shared by the HR cabinet and every generated product page,
   so the two cannot drift apart. Unscoped on purpose — the cabinet's
   body carries no .nx class. */
/* (placement note: the page sets .pbar{top} to clear its own nav)
   The product bar, directly under the site nav — the second row every
     enterprise product page carries: where you are, and what else is in
     the same product. It is not the tab strip further down; that one is
     this page's own sections. Two rows sound like one too many until you
     try to fit "which product" and "which section of it" into the same
     line, at which point neither is readable. */
  .pbar{position:sticky;top:0;z-index:90;background:var(--surface, #fff);
    border-bottom:1px solid var(--line);
    backdrop-filter:blur(12px) saturate(1.4);
    -webkit-backdrop-filter:blur(12px) saturate(1.4)}
  .pbar__crumb{max-width:var(--max);margin:0 auto;padding:8px var(--gut) 0;
    font-size:12.5px;opacity:.6}
  .pbar__crumb a{color:inherit;text-decoration:none}
  .pbar__crumb a:hover{text-decoration:underline}
  .pbar__in{max-width:var(--max);margin:0 auto;padding:0 var(--gut);
    display:flex;align-items:stretch;gap:20px;min-height:48px;
    /* Scrolls sideways on a narrow window. Wrapping puts a second row of
       links above the page on every phone. */
    overflow-x:auto;scrollbar-width:none}
  .pbar__in::-webkit-scrollbar{display:none}
  .pbar__name{display:flex;align-items:center;white-space:nowrap;
    font-weight:600;font-size:clamp(15px,1.6vw,19px);
    padding-right:20px;border-right:1px solid var(--line)}
  .pbar__links{display:flex;align-items:stretch;gap:2px}
  .pbar__links a{display:flex;align-items:center;padding:0 13px;font-size:14px;
    text-decoration:none;color:inherit;opacity:.62;white-space:nowrap;
    border-bottom:2px solid transparent}
  .pbar__links a:hover{opacity:1}
  .pbar__links a[aria-current="page"]{opacity:1;font-weight:600;
    border-bottom-color:var(--brand)}
  .pbar__end{margin-left:auto;display:flex;align-items:center;gap:10px;
    white-space:nowrap}
  /* Below this the company name is clipped mid-word by the scrolling
     strip, and it is already on the heading underneath. */
  @media (max-width:900px){ .pbar__end{display:none} }
  @media (max-width:640px){
    .pbar__name{font-size:14px;padding-right:13px}
    .pbar__in{gap:13px}
  }


/* ══ PRODUCT OVERVIEW PAGES ═════════════════════════════════════════
   The pages generated by tools/build_product_pages.py. One set of rules
   for all ten, for the same reason they are generated: ten copies of a
   layout is ten chances for one of them to be the odd one out. */
body.nx .pwrap{max-width:var(--max);margin:0 auto;padding:0 var(--gut) 96px}
body.nx .phero{padding:clamp(40px,6vw,72px) 0 clamp(28px,4vw,44px);max-width:46rem}
body.nx .peyebrow{font-size:12px;text-transform:uppercase;letter-spacing:.14em;
  opacity:.6;margin:0 0 10px}
body.nx .phero h1{font-size:clamp(34px,5vw,56px);line-height:1.08;margin:0 0 16px}
body.nx .plead{font-size:clamp(17px,2vw,21px);line-height:1.5;opacity:.82;margin:0}
body.nx .pcta{display:flex;flex-wrap:wrap;gap:12px;margin-top:28px}

body.nx .psec{padding:clamp(28px,4vw,44px) 0;border-top:1px solid var(--line);
  max-width:56rem}
body.nx .psec h2{font-size:clamp(22px,2.6vw,30px);margin:0 0 18px}
body.nx .plist{margin:0;padding-left:1.1em;line-height:1.65;font-size:16.5px}
body.nx .plist li{margin-bottom:9px}
body.nx .pnote{font-size:14.5px;opacity:.68;line-height:1.55;margin:0 0 24px;
  max-width:42rem}

/* Each decision is set apart with a rule down the side: they are the
   part of the page a sceptical reader came for, and a wall of even
   paragraphs hides them. */
body.nx .pdec{border-left:2px solid var(--brand);padding:2px 0 2px 18px;
  margin-bottom:26px}
body.nx .pdec h3{font-size:17px;margin:0 0 7px}
body.nx .pdec p{margin:0;line-height:1.6;opacity:.82;max-width:44rem}

body.nx .pgrid{display:grid;gap:14px;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr))}
body.nx .pcard{display:block;padding:18px 20px;border:1px solid var(--line);
  border-radius:var(--r,14px);text-decoration:none;color:inherit;
  transition:border-color .2s ease,transform .2s ease}
body.nx .pcard:hover{border-color:var(--brand);transform:translateY(-2px)}
body.nx .pcard b{display:block;font-size:17px;margin-bottom:6px}
body.nx .pcard span{display:block;font-size:14.5px;line-height:1.5;opacity:.72}
body.nx .pend{padding-bottom:0}

/* On the marketing pages the site nav is fixed and taller than the app's,
   and it shrinks on scroll. The product bar clears it by sitting after a
   spacer of exactly that height, then sticks to the shrunken height —
   so it never hides underneath the bar above it. */
body.nx .pbar{margin-top:var(--nav);top:var(--nav-sm)}

/* ── the film, and the one control it has ── */
/* A film frame again: 16:9, edge to edge, nothing inset. */
body.nx .tour-inner{padding:0}
body.nx .tour-inner .tour-play{
  position:absolute;right:clamp(16px,2.4vw,30px);bottom:clamp(16px,2.4vw,30px);
  z-index:3;width:clamp(52px,5vw,64px);
}
body.nx .tour-inner .tour-play::before{inset:-16px}
body.nx .tour-inner .tour-play.is-playing{
  opacity:.34;transform:scale(.88);
}
body.nx .tour-inner .tour-play.is-playing:hover{
  opacity:1;transform:scale(.96);
}
body.nx .tour-inner .tour-play.is-playing::before{opacity:.5}
/* A film is 16:9. Once it plays the frame goes back to that. */
body.nx .tour-inner{aspect-ratio:16/9}
body.nx .tour-inner video{z-index:2}
body.nx .tour-play__label{display:none}
@media (max-width:760px){
  body.nx .tour-inner{padding:16px 14px;display:flex;flex-direction:column}
  body.nx .tour-inner .tour-play{
    position:static;transform:none;margin:4px auto 0;
    width:auto;aspect-ratio:auto;padding:9px 18px 9px 15px;gap:8px;
    grid-auto-flow:column;font:inherit;font-size:13.5px;font-weight:600;
  }
  body.nx .tour-inner .tour-play:hover{transform:none}
  body.nx .tour-inner .tour-play .ico{width:15px;height:15px;margin:0}
  body.nx .tour-play__label{display:inline}
}

/* One circle, two states. Only one icon is ever drawn. */
body.nx .tour-play .ico-pause{display:none}
body.nx .tour-play.is-playing .ico-play{display:none}
body.nx .tour-play.is-playing .ico-pause{display:block;margin-left:0}
/* The native bar, belt and braces: a browser that shows controls
   without being asked does not get to draw them over the film. */
body.nx .tour-inner video::-webkit-media-controls{display:none!important}
body.nx .tour-inner video::-webkit-media-controls-enclosure{display:none!important}

/* The Aria film, where the ranked-queue diagram used to sit. Same box:
   it is the same thing, moving. muted + playsinline is what lets it
   start on its own, and preload="metadata" means a reader who never
   reaches this section pays for the header rather than the file. */
body.nx .aria-media .aria-film{
  display:block;width:100%;height:auto;border-radius:var(--r-lg,18px);
}

/* ── a film's own control ────────────────────────────────────────────
   The same circle the tour frame uses, for any other film on the site.
   It sits in the corner rather than the middle: centred, it lands on
   whatever the film is showing, which is the thing it is there to let
   you watch. */
body.nx .aria-media{position:relative}
body.nx .film-play{
  position:absolute;right:clamp(14px,2vw,24px);bottom:clamp(14px,2vw,24px);
  z-index:3;width:clamp(48px,4.4vw,58px);aspect-ratio:1;border-radius:999px;
  display:grid;place-items:center;cursor:pointer;
  border:0;background:rgba(255,255,255,.94);color:var(--ink);
  box-shadow:0 8px 26px rgba(11,17,32,.22);
  transition:transform .22s var(--ease),box-shadow .22s var(--ease),
             opacity .22s var(--ease);
}
body.nx .film-play::before{
  content:'';position:absolute;inset:-14px;border-radius:999px;
  background:radial-gradient(closest-side,rgba(11,17,32,.14),transparent 72%);
  pointer-events:none;
}
body.nx .film-play .ico{width:34%;height:34%;margin-left:8%}
body.nx .film-play .ico-pause{display:none;margin-left:0}
body.nx .film-play:hover{transform:scale(1.06);background:#fff}
/* While it runs the circle steps back rather than vanishing — it is the
   only way to stop the film, so it has to stay reachable. */
body.nx .film-play.is-playing{opacity:.36;transform:scale(.9)}
body.nx .film-play.is-playing:hover{opacity:1;transform:scale(.98)}
body.nx .film-play.is-playing .ico-play{display:none}
body.nx .film-play.is-playing .ico-pause{display:block}
@media (prefers-reduced-motion:reduce){
  body.nx .film-play{transition:none}
  body.nx .film-play:hover{transform:none}
}

/* ── an even ring ────────────────────────────────────────────────────
   The frame's ring is exactly 3px on all four sides — measured, at
   device-pixel precision. It did not look it, and the reason was
   luminance rather than geometry: against the near-white film the teal
   end sat at contrast 2.4 and the indigo end at 6.0, so the same three
   pixels read as a hairline on the left and a solid line on the right.

   The gradient still runs teal to indigo — that pairing is the two
   audiences meeting, and it stays. Both ends are just brought to the
   same weight, so the eye reads one ring instead of two edges.

   Scoped to this frame rather than fixed in the brand tokens: those
   colours are correct everywhere they carry text or fill a shape, and
   only a three-pixel ring against white has this problem. */
body.nx .tour-frame{
  background:linear-gradient(120deg,
    #0a665e 0%,      /* 6.5  every stop sits between 5.7 and 6.8    */
    #0b6f66 30%,     /* 5.7  contrast against the film, so the ring */
    #4f46e5 72%,     /* 6.0  reads as one weight instead of fading  */
    #483ed6 100%);   /* 6.8  out on the teal side                   */
}
