/* ==========================================================================
   Assertica — New Era component layer
   --------------------------------------------------------------------------
   Every rule is scoped under `.ne`. Nothing here can leak into the existing
   theme: no bare element selectors, no `body {}`, no redefined brand tokens.
   Requires tokens.css to be loaded first.
   ========================================================================== */

/* --- the fixed stage ----------------------------------------------------- */

.ne {
  position: relative;
  background: var(--void);
  color: var(--ink-bright);
  font-family: var(--font-body);
}

/* The UA rule for [hidden] is `display: none`, but any author `display`
   declaration outranks it. `.ne-case` sets `display: block` and `.ne-post`
   sets `display: grid`, so filtering them set the attribute and changed
   nothing on screen. Anything hideable has to opt back in. */
.ne [hidden] { display: none !important; }

.ne-canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

/* Vignette + a faint warm/cool bloom so the void is never flat black.
   Also the entire visual fallback when WebGL is unavailable. */
.ne-atmosphere {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(58% 44% at 72% 22%, rgba(var(--field-warm), 0.14), transparent 70%),
    radial-gradient(56% 46% at 24% 74%, rgba(var(--field-cool), 0.16), transparent 72%),
    radial-gradient(125% 95% at 50% 50%, transparent 58%, rgba(4, 6, 13, 0.66) 100%);
}

.ne.no-webgl .ne-atmosphere {
  background:
    radial-gradient(46% 40% at 68% 30%, rgba(var(--field-warm), 0.30), transparent 66%),
    radial-gradient(48% 42% at 30% 68%, rgba(var(--field-cool), 0.34), transparent 68%),
    radial-gradient(38% 34% at 50% 50%, rgba(var(--field-mid), 0.20), transparent 70%),
    radial-gradient(120% 90% at 50% 50%, transparent 34%, rgba(4, 6, 13, 0.86) 100%);
}

.ne-stages {
  position: relative;
  z-index: 2;
}

/* One stage = one phase of the particle morph. */
.ne-stage {
  min-height: var(--ne-stage);
  display: grid;
  align-items: center;
  padding: clamp(4rem, 9vh, 8rem) var(--space-6, 2rem);
}

.ne-inner {
  width: 100%;
  max-width: var(--ne-container);
  margin: 0 auto;
}

.ne-inner.is-centred {
  max-width: var(--ne-narrow);
  text-align: center;
  justify-items: center;
}

/* Centred copy, full-width card grid — for the services orbit, where four
   cards will not fit inside the narrow measure. */
.ne-inner.is-centred.is-wide { max-width: var(--ne-container); }
.ne-inner.is-centred.is-wide .ne-h { max-width: 20ch; margin-inline: auto; }
.ne-inner.is-centred.is-wide .ne-lead { max-width: 56ch; }

.ne-split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

/* --- the veil: content fades as its stage enters and leaves -------------- */

.ne-veil {
  opacity: var(--veil, 1);
  transform: translate3d(0, calc((1 - var(--veil, 1)) * 26px), 0);
  transition: opacity var(--dur-veil) var(--ease-veil),
              transform var(--dur-veil) var(--ease-veil);
  will-change: opacity, transform;
}

/* --- eyebrow -------------------------------------------------------------
   The site's `.section-tag` is an uppercase 2px-tracked kicker with a leading
   hairline tick. On the void it becomes a glass pill and keeps the tick. */

.ne-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 1rem 0.5rem 0.85rem;
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-pill, 100px);
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  font-family: var(--font-body);
  font-size: var(--text-2xs, 0.75rem);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow, 2px);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.ne-eyebrow::before {
  content: '';
  width: 18px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--orange));
  flex: none;
}

.ne-eyebrow.is-cool::before { background: linear-gradient(90deg, transparent, var(--blue)); }
.ne-eyebrow.is-ai::before { background: linear-gradient(90deg, transparent, var(--purple)); }

/* --- cinematic headline --------------------------------------------------
   Space Grotesk stays the family — only the weight drops to 300 so the
   strokes do not fight the particle field. Words start dim and brighten in
   sequence as the stage enters. */

.ne-h {
  margin: 1.5rem 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display-cinematic);
  font-size: var(--text-cinematic);
  line-height: var(--leading-cinematic);
  letter-spacing: var(--tracking-cinematic);
  color: var(--ink-bright);
  text-wrap: balance;
}

/* Word spans are used by any headline in the direction — stage headlines, page
   headers and the closing CTA — so the base rules are scoped to `.ne`. */
.ne .w { display: inline-block; color: inherit; }
.ne .w.is-accent { color: var(--orange); }

.ne .w.is-ai {
  background: var(--grad-ai, linear-gradient(135deg, #8B5CF6, #A78BFA, #2563EB));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Inside a scroll stage the words start dim and brighten in sequence. Outside
   one — an inner-page header — they are simply bright. */
.ne-stage .ne-h,
.ne-stage .ne-h .w {
  color: var(--ink-dim);
  transition: color var(--dur-word) var(--ease-cine);
  transition-delay: calc(var(--i, 0) * var(--stagger-word));
}

.ne-stage.is-live .ne-h .w { color: var(--ink-bright); }

/* One highlighted word per headline — the brand's rule, carried over. The
   accent never dims with the rest of the stage. */
.ne-stage .ne-h .w.is-accent,
.ne-stage.is-live .ne-h .w.is-accent { color: var(--orange); }

.ne-lead {
  margin: 1.5rem 0 0;
  max-width: 48ch;
  font-size: var(--text-lead, 1.15rem);
  line-height: var(--leading-normal, 1.6);
  color: var(--ink-body);
}

.is-centred .ne-lead { margin-inline: auto; }

/* --- buttons -------------------------------------------------------------
   The theme's orange-glow primary would blow out over the field, so the
   primary here is a glass pill whose ARROW CHIP carries the orange. Same
   accent logic, dialled for a dark canvas. */

.ne-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.25rem;
}

.is-centred .ne-actions { justify-content: center; }

/* A divided control rather than a capsule: label, hairline, icon cell. The
   icon cell fills orange on hover, so the accent arrives as a state change
   instead of sitting there as a permanent round chip. */
.ne-btn {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-control, 12px);
  background: var(--glass-strong);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  overflow: hidden;
  font-family: var(--font-body);
  font-size: var(--text-base, 1rem);
  font-weight: 500;
  color: var(--ink-bright);
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--dur-base, 0.3s) var(--ease-cine),
              background var(--dur-base, 0.3s) var(--ease-cine),
              transform var(--dur-base, 0.3s) var(--ease-cine),
              box-shadow var(--dur-base, 0.3s) var(--ease-cine);
}

.ne-btn__label {
  display: flex;
  align-items: center;
  padding: 0.9rem 1.4rem;
  white-space: nowrap;
}

.ne-btn__icon {
  display: grid;
  place-items: center;
  width: 46px;
  flex: none;
  border-left: 1px solid var(--glass-border);
  color: var(--orange);
  transition: background var(--dur-base, 0.3s) var(--ease-cine),
              color var(--dur-base, 0.3s) var(--ease-cine),
              border-color var(--dur-base, 0.3s) var(--ease-cine);
}

.ne-btn__icon svg {
  width: 15px;
  height: 15px;
  transition: transform var(--dur-base, 0.3s) var(--ease-cine);
}

.ne-btn:hover {
  transform: translateY(-2px);
  border-color: rgba(249, 115, 22, 0.55);
  box-shadow: var(--shadow-orange, 0 8px 30px rgba(249, 115, 22, 0.35));
}

.ne-btn:hover .ne-btn__icon {
  background: var(--orange);
  border-left-color: var(--orange);
  color: var(--white);
}

.ne-btn:hover .ne-btn__icon svg { transform: translate(2px, -2px); }

.ne-btn:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

.ne-btn.is-ghost {
  background: transparent;
  box-shadow: none;
}

.ne-btn.is-ghost:hover {
  background: var(--glass);
  border-color: var(--glass-border-lit);
  box-shadow: none;
}

/* --- glass cards ---------------------------------------------------------
   The frosted stat/feature panels that float over the field. */

.ne-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1rem;
  margin-top: 2.5rem;
}

/* Index for staggered reveals — set in CSS so it works without JS. */
.ne-cards > *:nth-child(1) { --i: 0; }
.ne-cards > *:nth-child(2) { --i: 1; }
.ne-cards > *:nth-child(3) { --i: 2; }
.ne-cards > *:nth-child(4) { --i: 3; }
.ne-cards > *:nth-child(5) { --i: 4; }
.ne-cards > *:nth-child(6) { --i: 5; }

.ne-card {
  position: relative;
  overflow: hidden;
  padding: 1.75rem;
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-4xl, 20px);
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  text-align: left;
  transition: border-color var(--dur-base, 0.3s) ease,
              background var(--dur-base, 0.3s) ease,
              transform var(--dur-base, 0.3s) ease;
}

/* The brand's own card behaviour, carried over: a blue→orange bar wipes in on
   hover (`--grad-card-top`). It is the one piece of production card styling
   this direction had been missing. */
.ne-card::before,
.ne-case::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--grad-card-top, linear-gradient(90deg, #2563EB, #F97316));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease-cine);
}

.ne-card:hover::before,
.ne-card:focus-within::before,
.ne-case:hover::before,
.ne-case:focus-within::before { transform: scaleX(1); }

.ne-card:hover {
  transform: translateY(-4px);
  border-color: var(--glass-border-lit);
  background: var(--glass-strong);
}

/* Inside a scroll stage the cards stagger in behind the headline, driven by
   the stage's own `is-live` class — no extra observer. */
.ne-stage .ne-cards > * {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity 0.55s var(--ease-cine), transform 0.55s var(--ease-cine);
  transition-delay: calc(220ms + var(--i, 0) * 90ms);
}

.ne-stage.is-live .ne-cards > * { opacity: 1; transform: none; }

.ne-card .label {
  font-size: var(--text-2xs, 0.75rem);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow, 2px);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.ne-card .figure {
  margin: 0.75rem 0 0.5rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-stat, clamp(2.2rem, 3.5vw, 3rem));
  line-height: 1;
  letter-spacing: var(--tracking-section, -1px);
  background: linear-gradient(135deg, var(--orange), var(--orange-light));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.ne-card.is-cool .figure {
  background: linear-gradient(135deg, var(--blue-light), var(--blue));
  -webkit-background-clip: text;
  background-clip: text;
}

.ne-card.is-ai .figure {
  background: var(--grad-ai, linear-gradient(135deg, #8B5CF6, #A78BFA, #2563EB));
  -webkit-background-clip: text;
  background-clip: text;
}

/* Service variant — same glass panel, led by a name instead of a figure.
   Used for the services orbiting the platform. */
.ne-card .name {
  margin: 0.6rem 0 0.5rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.15rem;
  line-height: 1.2;
  letter-spacing: var(--tracking-tight, -0.5px);
  color: var(--ink-bright);
}

.ne-card p {
  margin: 0;
  font-size: var(--text-sm, 0.9rem);
  line-height: var(--leading-normal, 1.6);
  color: var(--ink-body);
}

/* --- phase rail — the scroll position indicator -------------------------- */

.ne-rail {
  position: fixed;
  right: clamp(1rem, 2.5vw, 2rem);
  top: 50%;
  z-index: 3;
  transform: translateY(-50%);
  display: grid;
  gap: 0.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.ne-rail li {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  transition: background var(--dur-base, 0.3s) ease,
              transform var(--dur-base, 0.3s) ease;
}

.ne-rail li.is-live {
  background: var(--orange);
  transform: scale(1.6);
}

/* --- responsive ---------------------------------------------------------- */

@media (max-width: 900px) {
  .ne-split { grid-template-columns: 1fr; }
  .ne-rail { display: none; }
  .ne-stage { padding-inline: 1.25rem; }
}

/* --- reduced motion ------------------------------------------------------
   Words arrive at full brightness, veils stop translating, the field stops
   orbiting (handled in particle-field.js) but still answers the scrollbar. */

@media (prefers-reduced-motion: reduce) {
  .ne-veil {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .ne-h,
  .ne-h .w {
    color: var(--ink-bright);
    transition: none;
  }
  .ne-h .w.is-accent { color: var(--orange); }
  .ne-btn,
  .ne-card,
  .ne-btn__icon,
  .ne-btn__icon svg,
  .ne-card::before,
  .ne-case::before { transition: none; }
  .ne-btn:hover,
  .ne-card:hover { transform: none; }
  .ne-stage .ne-cards > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
