---
name: ai-glow-interface
description: Use when you want "AI-native, premium, futuristic" - Uses soft glowing gradients, radial lights, and dark UI accents.
---

# AI Glow Interface

> **Category:** Premium / Futuristic  -  **Personality:** AI-native, premium, futuristic
>
> **Best use:** AI tools, developer products
>
> **Ratings:** Professional 5/5 - Casual 3/5 - Exotic 4/5 - Visual impact 5/5 - Difficulty 3/5 - Performance cost 3/5

## What it is

An AI-native chat/composer surface: a dark panel lit by soft radial gradients, a model picker and context meter up top, a streaming conversation thread, and — the centrepiece — a **glowing input bar wrapped in an animated conic-gradient border** with a blurred halo twin. While the assistant "thinks" it shows a monospace `Reasoning` label over shimmering skeleton lines, then streams its reply word-by-word behind a glowing caret. It reads as a premium, futuristic AI product (think reasoning copilots and dev tools), and degrades to a calm **static glow** under `prefers-reduced-motion`.

## Dependencies / CDN

None for the effect itself — it is pure CSS glow plus a little vanilla JS for the chat. The demo only loads two Google Fonts (optional):

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
```

## HTML

```html
<div class="aig-stage">
  <div class="aig-lights" aria-hidden="true">
    <span class="aig-l aig-l1"></span><span class="aig-l aig-l2"></span><span class="aig-l aig-l3"></span>
  </div>

  <div class="aig-app">
    <div class="aig-thread" id="aigThread">
      <div class="aig-msg aig-bot">
        <span class="aig-ava"><!-- sparkle svg --></span>
        <div class="aig-bubble"><p>Hi, I'm <b>Halo</b> — your reasoning workspace.</p></div>
      </div>
    </div>

    <!-- the glowing composer -->
    <form class="aig-composer" id="aigForm">
      <span class="aig-glow" aria-hidden="true"></span>
      <div class="aig-field">
        <input class="aig-input" id="aigInput" type="text" placeholder="Message Halo…" aria-label="Message Halo">
        <button class="aig-send" type="submit" aria-label="Send">
          <svg viewBox="0 0 24 24"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
        </button>
      </div>
    </form>
  </div>
</div>
```

## CSS

```css
/* register the angle so it can be ANIMATED (not just set) */
@property --aig-angle{ syntax:'<angle>'; inherits:false; initial-value:0deg }

.aig-stage{
  --aig-i1:#6366f1; --aig-i2:#22d3ee; --aig-i3:#a855f7; --aig-i4:#ec4899;   /* glow palette */
  position:relative; overflow:hidden; isolation:isolate; border-radius:28px;
  min-height:600px; display:flex; align-items:center; justify-content:center;
  padding:46px 26px; background:#070811; color:#e9ebf5; font-family:'Sora',sans-serif;
}

/* 1) RADIAL LIGHTS — big blurred colour blobs drifting behind everything */
.aig-lights{position:absolute; inset:0; z-index:0}
.aig-l{position:absolute; border-radius:50%; filter:blur(72px); opacity:.5}
.aig-l1{width:46%; height:56%; background:var(--aig-i1); top:-15%; left:-8%;  animation:aig-drift 16s ease-in-out infinite}
.aig-l2{width:42%; height:52%; background:var(--aig-i3); bottom:-18%; right:-10%; animation:aig-drift 21s ease-in-out infinite reverse}
.aig-l3{width:40%; height:42%; background:var(--aig-i2); top:30%; right:26%; opacity:.34}
@keyframes aig-drift{0%,100%{transform:translate3d(0,0,0) scale(1)} 50%{transform:translate3d(0,-26px,0) scale(1.08)}}

/* this element forms the stacking context that lets the glow sit BEHIND the bar */
.aig-app{position:relative; z-index:1; width:100%; max-width:680px; display:flex; flex-direction:column; gap:16px}

/* 2) THE GLOWING BAR — conic gradient as a 1.6px "border" via padding + opaque inner field */
.aig-composer{
  --aig-angle:0deg;                 /* base value -> static border if @property is unsupported */
  position:relative; border-radius:18px; padding:1.6px;
  background:conic-gradient(from var(--aig-angle), var(--aig-i1),var(--aig-i2),var(--aig-i3),var(--aig-i4),var(--aig-i1));
  animation:aig-spin 5.5s linear infinite;
}
@keyframes aig-spin{ to{ --aig-angle:360deg } }

/* 3) THE HALO — a blurred clone of the same gradient, slightly larger, painted behind the bar */
.aig-glow{
  --aig-angle:0deg; position:absolute; inset:-5px; z-index:-1; border-radius:22px;
  background:conic-gradient(from var(--aig-angle), var(--aig-i1),var(--aig-i2),var(--aig-i3),var(--aig-i4),var(--aig-i1));
  filter:blur(17px); opacity:.45; animation:aig-spin 5.5s linear infinite; transition:opacity .3s;
}
.aig-field{position:relative; display:flex; align-items:center; gap:7px; background:#14161f; border-radius:16.4px; padding:7px 7px 7px 13px}
.aig-input{flex:1; min-width:0; background:none; border:0; outline:none; color:#e9ebf5; font-family:'Sora',sans-serif; font-size:14.5px; padding:7px 2px}

/* intensify on focus: faster spin, brighter halo */
.aig-composer:focus-within{animation-duration:3.4s}
.aig-composer:focus-within .aig-glow{opacity:.78; animation-duration:3.4s}

/* 4) "THINKING" SHIMMER — a moving highlight swept across skeleton bars + a clipped-text label */
.aig-thinking{font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:transparent; background:linear-gradient(90deg,#8b93ab,#fff,#8b93ab); background-size:200% 100%;
  -webkit-background-clip:text; background-clip:text; animation:aig-shim 1.7s linear infinite}
.aig-shim{height:9px; border-radius:6px;
  background:linear-gradient(100deg,rgba(255,255,255,.05) 30%,rgba(255,255,255,.17) 50%,rgba(255,255,255,.05) 70%);
  background-size:220% 100%; animation:aig-shim 1.4s linear infinite}
@keyframes aig-shim{ to{ background-position:-200% 0 } }

/* 5) STREAMING CARET */
.aig-caret{display:inline-block; width:7px; height:1.02em; vertical-align:-2px; border-radius:2px;
  background:linear-gradient(180deg,var(--aig-i2),var(--aig-i1)); box-shadow:0 0 9px var(--aig-i2);
  animation:aig-blink 1s steps(2) infinite}
@keyframes aig-blink{50%{opacity:0}}

/* 6) reduced motion = a calm STATIC glow (angle frozen at 0deg, halo steady) */
@media (prefers-reduced-motion:reduce){
  .aig-l,.aig-composer,.aig-glow,.aig-shim,.aig-thinking,.aig-caret{animation:none!important}
  .aig-glow{opacity:.62}
}
```

## JavaScript

Vanilla; drives the conversation only (the glow is pure CSS). Send → show the thinking shimmer → swap it for a bubble whose text streams word-by-word. Skips the animation entirely under reduced motion.

```js
var thread=document.getElementById('aigThread'),
    form=document.getElementById('aigForm'),
    input=document.getElementById('aigInput'),
    reduce=matchMedia('(prefers-reduced-motion: reduce)').matches, busy=false;

function el(cls,html){var d=document.createElement('div');d.className=cls;if(html)d.innerHTML=html;return d;}
function down(){thread.scrollTop=thread.scrollHeight;}

function stream(p,text,done){               // reveal one word at a time behind a caret
  var w=text.split(' '),i=0,caret=document.createElement('span');
  caret.className='aig-caret';p.appendChild(caret);
  (function next(){
    if(i>=w.length){caret.remove();return done&&done();}
    caret.insertAdjacentText('beforebegin',(i?' ':'')+w[i++]);down();
    setTimeout(next,28+Math.random()*40);    // jittered cadence feels organic
  })();
}

function reply(text){
  var msg = "Good question — here's how I'd approach it…";   // route on keywords in real use
  var bot = el('aig-msg aig-bot','<span class="aig-ava">✦</span><div class="aig-bubble"><p></p></div>');
  if(reduce){thread.appendChild(bot);bot.querySelector('p').textContent=msg;down();busy=false;return;}
  var think=el('aig-msg aig-bot aig-think',
    '<span class="aig-ava">✦</span><div class="aig-bubble"><span class="aig-thinking">Reasoning</span>'+
    '<span><i class="aig-shim"></i></span></div>');
  thread.appendChild(think);down();
  setTimeout(function(){think.remove();thread.appendChild(bot);down();
    stream(bot.querySelector('p'),msg,function(){busy=false;});},860);
}

form.addEventListener('submit',function(e){
  e.preventDefault(); var v=input.value.trim(); input.value='';
  if(busy||!v)return; busy=true;
  thread.appendChild(el('aig-msg aig-user','<div class="aig-bubble"><p></p></div>'));
  thread.lastChild.querySelector('p').textContent=v; down();
  reply(v);
});
```

## How it works

- **Animated conic border.** `@property --aig-angle{syntax:'<angle>'}` registers the variable as a real angle, so it can be *interpolated*. A keyframe ticks it `0deg → 360deg`, and `conic-gradient(from var(--aig-angle), …)` rotates the colours around the bar.
- **The "border" is padding.** The composer's background is the conic gradient; an opaque inner `.aig-field` covers everything except the `1.6px` of padding — that exposed ring *is* the gradient border. No mask compositing required.
- **The halo is a blurred twin.** `.aig-glow` is the same conic gradient, slightly larger (`inset:-5px`), `filter:blur(17px)`, painted at `z-index:-1` so the opaque bar hides its centre and only the soft bloom escapes around the edges. Both layers share the same spin, so border and halo turn in lockstep.
- **Radial lights** are oversized blurred blobs drifting behind the UI, clipped by the stage's `overflow:hidden`.
- **Thinking shimmer** sweeps a highlight across skeleton bars by animating `background-position` on an over-sized gradient; the `Reasoning` word uses the same trick with `background-clip:text`.
- **Streaming** appends one word per tick before a blinking gradient caret — cheap, and it sells the "live generation" feel.

## Customization

- **Palette:** change `--aig-i1…--aig-i4` on `.aig-stage`; every glow, gradient, avatar and caret derives from them.
- **Border weight:** the composer's `padding` (try `1px`–`3px`). **Halo size/softness:** `.aig-glow` `inset` + `blur()` + `opacity`.
- **Speed:** the `aig-spin` duration; the `:focus-within` rules already speed it up and brighten the halo when the user is typing.
- **Calmer look:** drop `--aig-i4` (pink) for a cooler indigo/cyan-only ring, or lower the lights' `opacity`.
- **Reuse the bar alone:** the composer + glow + field is self-contained — drop it onto any dark surface that has something behind it for the halo to bloom over.

## Accessibility & performance

- **Reduced motion:** the `@media (prefers-reduced-motion:reduce)` block freezes the angle at `0deg` (a still multi-hue ring) and steadies the halo — a *static glow*, no rotation, no shimmer; the JS also checks `matchMedia` and inserts replies instantly instead of streaming.
- **GPU cost:** `filter:blur()` and `backdrop`-style bloom are GPU-bound. Keep the number of large blurred layers small (a few lights + one halo) and animate `transform`/`opacity`/the registered angle — never animate `blur()` radius.
- **Decorative vs semantic:** lights, halo and icon SVGs are `aria-hidden`; inputs/buttons carry `aria-label`. Streamed text is set via text nodes (no `innerHTML`), so user input can't inject markup.
- **Contrast:** message bubbles sit on a near-opaque dark fill so text stays legible over the moving lights.

## Gotchas

- **`@property` is what makes it *move*.** Without it the angle can't interpolate and the border sits still. Always declare a plain `--aig-angle:0deg` fallback (as above) so unsupported browsers still render a static gradient border instead of breaking the `conic-gradient`.
- **Keep the halo's stacking right.** The `z-index:-1` trick only puts the glow *behind* the bar because a positioned **ancestor** (`.aig-app`, `z-index:1`) forms the stacking context. If you give `.aig-composer` its own stacking context (e.g. add `z-index`/`transform`/`opacity` to it), the negative-z glow flips to paint *over* the gradient and smears the border — keep the composer at `z-index:auto`.
- **The inner field must be opaque.** If `.aig-field`'s background is translucent, the conic gradient bleeds through and you lose the crisp border + readable input.
- **Contain the blur.** Radial lights overflow their boxes; without `overflow:hidden` on the stage they spill out and create horizontal scrollbars.
- **Don't animate the blur.** Pulsing `filter:blur()` tanks performance — pulse `opacity` instead (as `.aig-l3`/`:focus-within` do).
</content>
</invoke>
