/* neon-text v1.1.0 - scene styles
   Everything is scoped to .neon-scene and driven by custom properties set on
   that element (never on :root), so several signs can share a page. */

.neon-scene {
  position: relative;
  overflow: hidden;
  background: #070708;
  --nc: #ff2d95;      /* current glow colour            */
  --br: 55%;          /* bloom radius                   */
  --bx: 50%;          /* bloom centre, % across scene   */
  --px: 50%;          /* pool centre - the lit centroid, not the loudest letter */
  --pool: 0;          /* floor light intensity          */
  --room: 1;          /* wall/floor/vignette presence   */
  --wall: #17171b;    /* wall tint                      */
  --floor: 74%;       /* ground line, % down the scene  */
  --ref: .2;          /* reflection opacity             */
}
.neon-scene > * { position: absolute; }

/* back wall - neon needs a plane to fall on, not a void */
.neon-wall {
  inset: 0; z-index: 0;
  background:
    radial-gradient(120% 80% at 50% 38%, var(--wall) 0%, #0b0b0d 58%, #070708 100%),
    linear-gradient(#0a0a0c, #050506);
}
/* ground. No hard seam: it has to arrive as a gradient, or it reads as a
   rectangle pasted over the wall. */
.neon-floor {
  left: 0; right: 0; top: calc(var(--floor) - 9%); bottom: 0; z-index: 1;
  opacity: var(--room);
  background: linear-gradient(rgba(20,20,24,0) 0%, #0d0d10 26%, #08080a 60%, #050506 100%);
}
.neon-canvas { display: block; inset: 0; z-index: 2; }

/* the pool of light thrown onto the floor. Its top edge MUST be masked - a
   radial gradient clipped by a box edge draws a hard rule across the scene. */
.neon-pool {
  left: 0; right: 0; top: var(--floor); height: 52%; z-index: 3;
  pointer-events: none; mix-blend-mode: screen;
  opacity: calc(var(--pool) * var(--room));
  background: radial-gradient(58% 100% at var(--px) 0%, var(--nc) 0%, transparent 72%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 60%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 60%, transparent 100%);
}

/* the tube: real DOM text, one span per character, three stacked layers */
.neon-off, .neon-lit { inset: 0; z-index: 4; pointer-events: none; }
.neon-off span, .neon-lit span, .neon-ref span { position: absolute; white-space: pre; }
.neon-off span { color: #212125; text-shadow: 0 1px 0 rgba(255,255,255,.05); }
/* both start dark and are lit per frame by the engine. The reflection needs the
   same default as the lit layer - without it, any frame the engine doesn't
   reach renders the reflection at FULL strength over an unlit sign. */
.neon-lit span, .neon-ref span { opacity: 0; }

/* reflection: foreshortened about the ground line, blurred, masked to a fade */
.neon-refwrap {
  inset: 0; z-index: 3; pointer-events: none; opacity: var(--room);
  -webkit-mask-image: linear-gradient(to bottom, transparent var(--floor), #000 calc(var(--floor) + 2%), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent var(--floor), #000 calc(var(--floor) + 2%), transparent 100%);
}
.neon-ref { inset: 0; filter: blur(3.5px); opacity: var(--ref); }

.neon-vig {
  inset: 0; z-index: 6; pointer-events: none; opacity: var(--room);
  background: radial-gradient(75% 65% at 50% 45%, transparent 40%, rgba(0,0,0,.72) 100%);
}
.neon-grain {
  inset: 0; z-index: 7; pointer-events: none;
  opacity: calc(.045 * var(--room)); mix-blend-mode: overlay;
}
/* the sign lighting its surroundings. Scene-scoped by default - a library has
   no business flashing the host page. */
.neon-bloom {
  inset: 0; z-index: 8; pointer-events: none; opacity: 0; mix-blend-mode: screen;
  background: radial-gradient(circle at var(--bx) 44%, var(--nc) 0%, transparent var(--br));
}
