AI Prompt Composer
The prompt composer from an AI generation hero: video, image and agent modes with a sliding indicator. Example prompts type themselves in, first- and last-frame slots plus model and setting pills change with the mode, the send key lights up once there is input, and quick tags below fill in a prompt in one click.
Taken from the page template Ranzhen AI Video Studio Home. Use it on its own, or combine it with the other components from the same template to rebuild the full page.
Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds AI Prompt Composer to your project in your colors.
Where to use it
Search boxes, AI chat inputs, form fields, file uploads, verification codes and anywhere else people type.
Install
With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.
Code
Source for AI Prompt Composer. Motion uses only transform and opacity and respects the Reduce motion setting.
<div class="x-rzc"><div class="x-rzc__in" style="width:720px;height:330px">
<div class="x-rzc__seg" role="tablist" aria-label="Creation type"><i></i><button type="button" role="tab" aria-selected="true">Video</button><button type="button" role="tab" aria-selected="false">Image</button><button type="button" role="tab" aria-selected="false">Agent</button></div>
<div class="x-rzc__box">
<div class="x-rzc__top"><div class="x-rzc__slots"><span><button type="button" aria-label="Add first frame"><b>+</b>First frame</button>Optional</span><em aria-hidden="true">⇄</em><span><button type="button" aria-label="Add last frame"><b>+</b>Last frame</button>Optional</span></div>
<textarea rows="3" aria-label="Describe your idea" placeholder="Describe your idea…"></textarea></div>
<div class="x-rzc__ctl"><button type="button" class="x-rzc__c" data-k="0">Text / image to video ⌄</button><button type="button" class="x-rzc__c g" data-k="1">⚡ Ranzhen 3.0</button><button type="button" class="x-rzc__c g" data-k="2">Auto · 5s · 720p</button><span class="x-rzc__sp"></span><span class="x-rzc__cr">◆ 10</span><button type="button" class="x-rzc__go" aria-label="Generate" disabled><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 19V5M6 11l6-6 6 6"/></svg></button></div>
</div>
<div class="x-rzc__chips"><button type="button">Story short</button><button type="button">Motion design</button><button type="button">Recast</button><button type="button">Cinematic shots</button><button type="button">Digital twin</button></div>
</div></div>.x-rzc{position:relative;flex:none}
.x-rzc__in{position:absolute;left:0;top:0;transform-origin:0 0;display:flex;flex-direction:column;align-items:center;font-family:var(--d-font,system-ui,sans-serif);color:#fff;text-align:left}
.x-rzc__seg{position:relative;display:inline-flex;gap:2px;padding:4px;border-radius:999px;background:rgba(20,10,8,.9);box-shadow:inset 0 0 0 1px rgba(255,120,60,.4),0 6px 30px rgba(255,90,31,.25)}
.x-rzc__seg button{position:relative;z-index:1;height:32px;padding:0 18px;border:0;border-radius:999px;background:none;color:#b8b3b9;font:inherit;font-size:13.5px;cursor:pointer;transition:color .25s}
.x-rzc__seg button[aria-selected=true]{color:#fff}
.x-rzc__seg i{position:absolute;top:4px;left:4px;height:32px;border-radius:999px;background:linear-gradient(180deg,#3a1a10,#1c0d09);box-shadow:inset 0 0 0 1px rgba(255,140,80,.6),0 0 18px rgba(255,90,31,.35);transition:transform .4s cubic-bezier(.16,1,.3,1),width .4s cubic-bezier(.16,1,.3,1)}
.x-rzc__box{width:100%;margin-top:18px;padding:12px;border-radius:22px;background:linear-gradient(180deg,#151110,#0c0a0a);box-shadow:0 0 0 1px rgba(255,255,255,.08),0 -1px 0 rgba(255,140,80,.6),0 20px 60px rgba(255,80,20,.22)}
.x-rzc__top{display:flex;gap:14px;min-height:92px}
.x-rzc__slots{display:flex;align-items:flex-start;gap:6px;flex:none;transition:opacity .3s,width .3s}
.x-rzc__slots.off{display:none}
.x-rzc__slots span{display:flex;flex-direction:column;align-items:center;gap:5px;font-size:11px;color:#6e6b72}
.x-rzc__slots button{display:grid;align-content:center;justify-items:center;width:44px;height:52px;border-radius:10px;border:1px dashed rgba(255,255,255,.22);background:rgba(255,255,255,.03);color:#bdb8be;font:inherit;font-size:11px;cursor:pointer;transition:border-color .2s,background .2s}
…const init = (root) => {
const fit = (box, W, H) => {
const inner = box.firstElementChild;
const run = () => {
const cs = getComputedStyle(root);
const aw = root.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
const ah = root.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);
if (aw <= 0 || ah <= 0) return;
const s = Math.max(0.2, Math.min(aw / W, ah / H, 1));
box.style.width = W * s + 'px'; box.style.height = H * s + 'px'; inner.style.transform = `scale(${s})`;
};
const ro = new ResizeObserver(run); ro.observe(root); run();
…