/* ==========================================================================
   The orb — one fixed slot, three tenants.

   The site is otherwise restrained about glow: the phosphor is soft and the
   scanlines sit near invisibility. This is the single element allowed to be
   loud, and it earns that by being the only thing on screen that persists.
   It occupies one corner for the whole scroll and shows exactly one of:

     1. the 24/7 claim   — the opening pitch, on a timer, shown once
     2. the brain        — the site's mark while you read the argument
     3. the WhatsApp CTA — the last exit, once the form is in view

   Only one pane is ever mounted visually; the others stay in the DOM so a
   language flip keeps translating them and so switching costs no layout.
   ========================================================================== */

.orb {
  position: fixed;
  right: clamp(0.9rem, 3vw, 2rem);
  bottom: clamp(0.9rem, 3vw, 2rem);
  z-index: 60;
  display: grid;
  justify-items: end;
  pointer-events: none; /* the panes take pointer events back individually */
}

/* The language toast shares this corner from 48rem up, so the orb steps above
   it while it is open. `--orb-lift` is measured by js/hero-orb.js; below that
   breakpoint the toast is at the top of the screen and the lift is ignored.
   Set with `translate` rather than `transform` so it composes with, instead of
   overwriting, anything the panes are doing. */
@media (min-width: 48rem) {
  .orb {
    translate: 0 calc(-1 * var(--orb-lift, 0px));
    transition: translate 0.5s var(--ease, ease);
  }
}

/* Panes stack in one grid cell, so a swap is a cross-fade in place rather
   than a reflow of the corner. */
.orb__pane {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(0.94);
  transition: opacity 0.45s ease, transform 0.55s cubic-bezier(0.2, 0.9, 0.25, 1),
              visibility 0s linear 0.55s;
}

.orb__pane[data-active="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
  pointer-events: auto;
}

/* Snapshot mode: states change without a fade, so a capture can never land
   between two of them. */
.orb--instant .orb__pane { transition: none; }

/* --- 1. the claim --------------------------------------------------------
   Same content as the hero badge it replaces, lit. The neon is built from
   three layers — an inner rim, a tight halo and a wide bloom — because a
   single large shadow reads as blur where three read as light. */

.orb__badge {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  max-width: min(72vw, 20rem);
  padding: 0.85rem 1.35rem;
  border-radius: 0.6rem;
  border: 1px solid var(--accent);
  background: rgba(6, 24, 22, 0.82);
  backdrop-filter: blur(6px);
  color: var(--accent-lit);
  font-size: var(--step-0);
  box-shadow:
    inset 0 0 12px rgba(47, 220, 192, 0.35),
    0 0 10px rgba(47, 220, 192, 0.55),
    0 0 34px rgba(47, 220, 192, 0.28);
  animation: orb-flicker 6s steps(1, end) infinite;
}

.orb__badge .badge__lead {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-shadow: 0 0 8px rgba(47, 220, 192, 0.75), 0 0 20px rgba(47, 220, 192, 0.35);
}

.orb__badge .badge__sub {
  font-size: var(--step--2);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--accent);
  opacity: 0.85;
}

/* An old tube settling: two dropped frames early on, then steady. Steps, not
   easing — a flicker that fades in is not a flicker. */
@keyframes orb-flicker {
  0%, 3%, 6%, 100% { opacity: 1; }
  4%   { opacity: 0.55; }
  4.5% { opacity: 1; }
  5%   { opacity: 0.7; }
}

/* --- 2. the brain --------------------------------------------------------
   Drawn, not loaded: the contour is stroked on with a dash offset, the folds
   trail it, and the synapse nodes pulse out of phase so the thing reads as
   thinking rather than as a spinner. */

.orb__brain {
  display: grid;
  place-items: center;
  width: clamp(4.2rem, 13vw, 6rem);
  height: clamp(4.2rem, 13vw, 6rem);
  border-radius: 50%;
  border: 1px solid var(--accent-dim);
  background:
    radial-gradient(circle at 50% 50%, rgba(47, 220, 192, 0.16), rgba(3, 8, 10, 0.9) 70%);
  box-shadow:
    inset 0 0 18px rgba(47, 220, 192, 0.22),
    0 0 14px rgba(47, 220, 192, 0.35),
    0 0 44px rgba(47, 220, 192, 0.18);
  animation: orb-breathe 4.5s ease-in-out infinite;
}

@keyframes orb-breathe {
  0%, 100% { box-shadow: inset 0 0 18px rgba(47, 220, 192, 0.22),
                         0 0 14px rgba(47, 220, 192, 0.35),
                         0 0 44px rgba(47, 220, 192, 0.18); }
  50%      { box-shadow: inset 0 0 26px rgba(47, 220, 192, 0.34),
                         0 0 22px rgba(47, 220, 192, 0.55),
                         0 0 64px rgba(47, 220, 192, 0.3); }
}

.orb__brain-svg {
  width: 72%;
  height: 72%;
  overflow: visible;
  filter: drop-shadow(0 0 4px rgba(47, 220, 192, 0.8));
}

.orb__brain-svg path {
  fill: none;
  stroke: var(--accent-lit);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
  animation: orb-draw 5s ease-in-out infinite;
}

/* The folds are secondary strokes: thinner, dimmer, and started after the
   contour so the outline always leads. */
.orb__brain-svg .orb__fold {
  stroke: var(--accent);
  stroke-width: 2;
  opacity: 0.7;
  stroke-dasharray: 120;
  stroke-dashoffset: 120;
}

/* Their own keyframes, because the offsets are keyframed in absolute units:
   run the folds on the contour's 320 and a 120-long dash spends most of the
   cycle off the end of its own path, i.e. invisible. */
.orb__brain-svg .orb__fold { animation-name: orb-draw-fold; }
.orb__brain-svg .orb__fold:nth-of-type(odd)  { animation-delay: 0.5s; }
.orb__brain-svg .orb__fold:nth-of-type(even) { animation-delay: 0.9s; }

@keyframes orb-draw-fold {
  0%   { stroke-dashoffset: 120; opacity: 0.1; }
  35%  { stroke-dashoffset: 0;   opacity: 0.7; }
  75%  { stroke-dashoffset: 0;   opacity: 0.7; }
  100% { stroke-dashoffset: -120; opacity: 0.1; }
}

@keyframes orb-draw {
  0%   { stroke-dashoffset: 320; opacity: 0.15; }
  35%  { stroke-dashoffset: 0;   opacity: 1; }
  75%  { stroke-dashoffset: 0;   opacity: 1; }
  100% { stroke-dashoffset: -320; opacity: 0.15; }
}

/* Scaled by transform rather than by animating `r`: the SVG geometry
   properties are only animatable through CSS in newer engines, and a node that
   silently stops pulsing is worse than one that pulses everywhere. */
.orb__brain-svg circle {
  fill: var(--accent-lit);
  transform-box: fill-box;
  transform-origin: center;
  animation: orb-synapse 2.4s ease-in-out infinite;
}

.orb__brain-svg circle:nth-of-type(2) { animation-delay: 0.5s; }
.orb__brain-svg circle:nth-of-type(3) { animation-delay: 1.1s; }
.orb__brain-svg circle:nth-of-type(4) { animation-delay: 1.7s; }

@keyframes orb-synapse {
  0%, 100% { opacity: 0.2; transform: scale(0.55); }
  50%      { opacity: 1;   transform: scale(1.15); }
}

/* The brain is also a link back to the demo, so it answers to a pointer. */
.orb__brain:hover,
.orb__brain:focus-visible {
  border-color: var(--accent);
  transform: scale(1.06);
}

.orb__brain { transition: transform 0.3s ease, border-color 0.3s ease; }

/* --- 3. the WhatsApp exit ------------------------------------------------
   Green, not phosphor: this is the one control on the page that leaves it,
   and it should not be mistaken for more site. */

.orb__wa {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.35rem;
  border-radius: 999px;
  border: 1px solid var(--ok);
  background: rgba(6, 30, 22, 0.88);
  backdrop-filter: blur(6px);
  color: var(--ok);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  box-shadow:
    inset 0 0 12px rgba(61, 220, 151, 0.3),
    0 0 12px rgba(61, 220, 151, 0.55),
    0 0 38px rgba(61, 220, 151, 0.25);
  animation: orb-wa-pulse 2.8s ease-in-out infinite;
  transition: transform 0.25s ease, color 0.25s ease;
}

.orb__wa:hover,
.orb__wa:focus-visible {
  transform: translateY(-2px) scale(1.03);
  color: #7bf0bd;
}

.orb__wa svg { width: 1.15em; height: 1.15em; flex-shrink: 0; }

@keyframes orb-wa-pulse {
  0%, 100% { box-shadow: inset 0 0 12px rgba(61, 220, 151, 0.3),
                         0 0 12px rgba(61, 220, 151, 0.55),
                         0 0 38px rgba(61, 220, 151, 0.25); }
  50%      { box-shadow: inset 0 0 18px rgba(61, 220, 151, 0.45),
                         0 0 20px rgba(61, 220, 151, 0.75),
                         0 0 56px rgba(61, 220, 151, 0.4); }
}

/* On a phone the corner is crowded and the claim is the widest tenant, so it
   drops its sub-line rather than wrapping into a paragraph. */
@media (max-width: 30rem) {
  .orb__badge { font-size: var(--step--1); padding: 0.5rem 0.85rem; }
  .orb__badge .badge__sub { display: none; }
}

/* Everything above is decoration on top of a state machine that still works
   without it: reduced motion keeps the three states and the glow, and drops
   every loop. */
@media (prefers-reduced-motion: reduce) {
  .orb__pane { transition: opacity 0.2s linear; transform: none; }
  .orb__badge,
  .orb__brain,
  .orb__wa { animation: none; }
  .orb__brain-svg path,
  .orb__brain-svg .orb__fold { animation: none; stroke-dashoffset: 0; }
  .orb__brain-svg circle { animation: none; opacity: 0.9; }
}

/* --- The section-02 closer -------------------------------------------------
   The brain reappears here, in flow rather than fixed, at the end of the
   "two AIs" diagram: the same mark making the same claim explicit — one
   system, one brain. It keeps every one of its loops (`.orb__brain` and
   `.orb__brain-svg` are used unmodified), just bigger and un-linked. */

.section-close {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.75rem;
  width: 100%;
  max-width: none; /* overrides the global `p { max-width: var(--measure) }` — a
                       measure sized for reading lines is not what should centre
                       a one-line statement */
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding: clamp(2rem, 5vw, 3rem) 1rem 0;
  text-align: center;
}

.section-close .orb__brain {
  width: clamp(5rem, 12vw, 7rem);
  height: clamp(5rem, 12vw, 7rem);
  cursor: default;
}

.section-close__text {
  max-width: 42rem;
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--fg);
  /* Settles in after the brain has had a moment to draw itself, rather than
     arriving with everything else `data-anim` reveals at once — a brief
     phosphor glow that cools to the page's normal text colour and holds. */
  animation: section-close-settle 1.4s ease-out 0.6s 1 backwards;
}

@keyframes section-close-settle {
  0%   { opacity: 0; color: var(--accent-lit); text-shadow: 0 0 22px rgba(47, 220, 192, 0.6); }
  55%  { opacity: 1; color: var(--accent-lit); text-shadow: 0 0 22px rgba(47, 220, 192, 0.6); }
  100% { opacity: 1; color: var(--fg); text-shadow: 0 0 0 rgba(47, 220, 192, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .section-close__text { animation: none; color: var(--fg); }
}
