1<!DOCTYPE html><html lang="en" dir="ltr" class="bg-ink-950 text-zinc-100"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><meta name="theme-color" content="#07070b"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="canonical" href="https://www.ai-geminiomni.com/prompt-generator/"><title>Gemini Omni video prompt generator · turn a brief into a shot-by-shot script</title><meta name="description" content="A free prompt generator tuned for the Gemini Omni video model. Drop in a one-line brief and get a structured prompt with camera, pacing, lighting and audio cues. 8 ready-to-use video script templates, 1000-character input, 27 languages, sign in to generate."><meta name="generator" content="Astro v5.18.1"><meta name="robots" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1"><meta name="google-adsense-account" content="ca-pub-1916766675410622"><link rel="alternate" hreflang="en" href="https://www.ai-geminiomni.com/prompt-generator/"><link rel="alternate" hreflang="es" href="https://www.ai-geminiomni.com/es/prompt-generator/"><link rel="alternate" hreflang="it" href="https://www.ai-geminiomni.com/it/prompt-generator/"><link rel="alternate" hreflang="hi" href="https://www.ai-geminiomni.com/hi/prompt-generator/"><link rel="alternate" hreflang="ar" href="https://www.ai-geminiomni.com/ar/prompt-generator/"><link rel="alternate" hreflang="zh-CN" href="https://www.ai-geminiomni.com/zh/prompt-generator/"><link rel="alternate" hreflang="ja" href="https://www.ai-geminiomni.com/ja/prompt-generator/"><link rel="alternate" hreflang="ko" href="https://www.ai-geminiomni.com/ko/prompt-generator/"><link rel="alternate" hreflang="fr" href="https://www.ai-geminiomni.com/fr/prompt-generator/"><link rel="alternate" hreflang="de" href="https://www.ai-geminiomni.com/de/prompt-generator/"><link rel="alternate" hreflang="nl" href="https://www.ai-geminiomni.com/nl/prompt-generator/"><link rel="alternate" hreflang="pl" href="https://www.ai-geminiomni.com/pl/prompt-generator/"><link rel="alternate" hreflang="pt-BR" href="https://www.ai-geminiomni.com/pt-BR/prompt-generator/"><link rel="alternate" hreflang="ru" href="https://www.ai-geminiomni.com/ru/prompt-generator/"><link rel="alternate" hreflang="tr" href="https://www.ai-geminiomni.com/tr/prompt-generator/"><link rel="alternate" hreflang="id" href="https://www.ai-geminiomni.com/id/prompt-generator/"><link rel="alternate" hreflang="vi" href="https://www.ai-geminiomni.com/vi/prompt-generator/"><link rel="alternate" hreflang="th" href="https://www.ai-geminiomni.com/th/prompt-generator/"><link rel="alternate" hreflang="ms" href="https://www.ai-geminiomni.com/ms/prompt-generator/"><link rel="alternate" hreflang="tl" href="https://www.ai-geminiomni.com/tl/prompt-generator/"><link rel="alternate" hreflang="bn" href="https://www.ai-geminiomni.com/bn/prompt-generator/"><link rel="alternate" hreflang="ta" href="https://www.ai-geminiomni.com/ta/prompt-generator/"><link rel="alternate" hreflang="te" href="https://www.ai-geminiomni.com/te/prompt-generator/"><link rel="alternate" hreflang="mr" href="https://www.ai-geminiomni.com/mr/prompt-generator/"><link rel="alternate" hreflang="he" href="https://www.ai-geminiomni.com/he/prompt-generator/"><link rel="alternate" hreflang="fa" href="https://www.ai-geminiomni.com/fa/prompt-generator/"><link rel="alternate" hreflang="ur" href="https://www.ai-geminiomni.com/ur/prompt-generator/"><link rel="alternate" hreflang="x-default" href="https://www.ai-geminiomni.com/prompt-generator/"><meta property="og:type" content="website"><meta property="og:site_name" content="Gemini Omni Info Hub"><meta property="og:title" content="Gemini Omni video prompt generator · turn a brief into a shot-by-shot script"><meta property="og:description" content="A free prompt generator tuned for the Gemini Omni video model. Drop in a one-line brief and get a structured prompt with camera, pacing, lighting and audio cues. 8 ready-to-use video script templates, 1000-character input, 27 languages, sign in to generate."><meta property="og:url" content="https://www.ai-geminiomni.com/prompt-generator/"><meta property="og:image" content="https://www.ai-geminiomni.com/og.svg"><meta property="og:locale" content="en"><meta property="og:locale:alternate" content="es"><meta property="og:locale:alternate" content="it"><meta property="og:locale:alternate" content="hi"><meta property="og:locale:alternate" content="ar"><meta property="og:locale:alternate" content="zh-CN"><meta property="og:locale:alternate" content="ja"><meta property="og:locale:alternate" content="ko"><meta property="og:locale:alternate" content="fr"><meta property="og:locale:alternate" content="de"><meta property="og:locale:alternate" content="nl"><meta property="og:locale:alternate" content="pl"><meta property="og:locale:alternate" content="pt-BR"><meta property="og:locale:alternate" content="ru"><meta property="og:locale:alternate" content="tr"><meta property="og:locale:alternate" content="id"><meta property="og:locale:alternate" content="vi"><meta property="og:locale:alternate" content="th"><meta property="og:locale:alternate" content="ms"><meta property="og:locale:alternate" content="tl"><meta property="og:locale:alternate" content="bn"><meta property="og:locale:alternate" content="ta"><meta property="og:locale:alternate" content="te"><meta property="og:locale:alternate" content="mr"><meta property="og:locale:alternate" content="he"><meta property="og:locale:alternate" content="fa"><meta property="og:locale:alternate" content="ur"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Gemini Omni video prompt generator · turn a brief into a shot-by-shot script"><meta name="twitter:description" content="A free prompt generator tuned for the Gemini Omni video model. Drop in a one-line brief and get a structured prompt with camera, pacing, lighting and audio cues. 8 ready-to-use video script templates, 1000-character input, 27 languages, sign in to generate."><meta name="twitter:image" content="https://www.ai-geminiomni.com/og.svg">
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebApplication","name":"Gemini Omni video prompt generator","description":"A free prompt generator tuned for the Gemini Omni video model. Drop in a one-line brief and get a structured prompt with camera, pacing, lighting and audio cues. 8 ready-to-use video script templates, 1000-character input, 27 languages, sign in to generate.","url":"https://www.ai-geminiomni.com/prompt-generator/","inLanguage":"en","applicationCategory":"MultimediaApplication","applicationSubCategory":"Video prompt generator","operatingSystem":"Web","browserRequirements":"Requires JavaScript and a modern browser","isAccessibleForFree":true,"offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"featureList":["Brief-to-prompt rewriting tuned for Gemini Omni","Multi-shot script with camera, pacing, lighting and audio cues","Multilingual interface across 27 languages","Copy-ready prompts you can paste into the Gemini app","8 production-ready video script templates (product ad, brand hero, unboxing, tutorial, testimonial, seasonal promo, fashion try-on, food review)","1000-character structured input with live counter for stable Omni output"],"audience":{"@type":"Audience","audienceType":"Video creators, marketers, prompt engineers"},"publisher":{"@type":"Organization","name":"Gemini Omni Info Hub","url":"https://www.ai-geminiomni.com/"}}</script>
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://www.ai-geminiomni.com/"},{"@type":"ListItem","position":2,"name":"Prompt builder","item":"https://www.ai-geminiomni.com/prompt-generator/"}]}</script>
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","inLanguage":"en","mainEntity":[{"@type":"Question","name":"Why write a dedicated prompt for Gemini Omni?","acceptedAnswer":{"@type":"Answer","text":"Omni renders picture and sound in the same forward pass, so a good prompt has to declare camera moves, pacing, lighting and audio together â that is what keeps the output stable and publishable."}},{"@type":"Question","name":"Where does my brief get sent?","acceptedAnswer":{"@type":"Answer","text":"Your text is sent to our Agent endpoint, which rewrites it into a structured Omni prompt. You need to sign in; each generation uses a small amount of your account quota."}},{"@type":"Question","name":"Can I paste the result straight into Gemini Omni?","acceptedAnswer":{"@type":"Answer","text":"Yes. The output is a multi-shot script you can paste into the Gemini app video panel and continue to refine through chat-style editing inside Omni."}}]}</script>
vendor: 63 bytes, line 1
1<script async src="https://www.googletagmanager.com/gtag/js?id=
1G-R7WH0BH713
vendor: 11 bytes, line 1
1"></script>
1<script>(function(){const gaId = "G-R7WH0BH713"; 2 3 window.dataLayer = window.dataLayer || []; 4 function gtag(){ dataLayer.push(arguments); } 5 gtag('js', new Date()); 6 gtag('config', gaId, { anonymize_ip: true }); 7 })();</script>
7<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1916766675410622" crossorigin="anonymous"></script>
7<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="preconnect" href="https://accounts.google.com"><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500&family=Noto+Sans+Arabic:wght@400;500;600;700&family=Noto+Sans+Hebrew:wght@400;500;600;700&family=Noto+Sans+Thai:wght@400;500;600;700&display=swap"><link rel="stylesheet" href="/_astro/_slug_.CcK_mi-L.css"></head> <body class="relative overflow-x-hidden font-sans antialiased"> <aside id="locale-banner" class="locale-banner" role="region" aria-label="Language recommendation banner" data-current-lang="en" data-default-lang="en" data-lang-labels="{"zh":"䏿","en":"English","ja":"æ¥æ¬èª","ko":"íêµì´","es":"Español","fr":"Français","de":"Deutsch","it":"Italiano","nl":"Nederlands","pl":"Polski","pt-BR":"Português","ru":"Ð ÑÑÑкий","tr":"Türkçe","id":"Bahasa Indonesia","vi":"Tiếng Viá»t","th":"à¹à¸à¸¢","ms":"Bahasa Melayu","tl":"Filipino","hi":"हिनà¥à¤¦à¥","bn":"বাà¦à¦²à¦¾","ta":"தமிழà¯","te":"à°¤à±à°²à±à°à±","mr":"मराठà¥","ar":"Ø§ÙØ¹Ø±Ø¨ÙØ©","he":"×¢×ר×ת","fa":"ÙØ§Ø±Ø³Û","ur":"اردÙ"}" data-lang-urls="{"en":"/prompt-generator/","es":"/es/prompt-generator/","it":"/it/prompt-generator/","hi":"/hi/prompt-generator/","ar":"/ar/prompt-generator/","zh":"/zh/prompt-generator/","ja":"/ja/prompt-generator/","ko":"/ko/prompt-generator/","fr":"/fr/prompt-generator/","de":"/de/prompt-generator/","nl":"/nl/prompt-generator/","pl":"/pl/prompt-generator/","pt-BR":"/pt-BR/prompt-generator/","ru":"/ru/prompt-generator/","tr":"/tr/prompt-generator/","id":"/id/prompt-generator/","vi":"/vi/prompt-generator/","th":"/th/prompt-generator/","ms":"/ms/prompt-generator/","tl":"/tl/prompt-generator/","bn":"/bn/prompt-generator/","ta":"/ta/prompt-generator/","te":"/te/prompt-generator/","mr":"/mr/prompt-generator/","he":"/he/prompt-generator/","fa":"/fa/prompt-generator/","ur":"/ur/prompt-generator/"}" data-banner-copy="{"en":{"prompt":"Choose another language to browse content adapted for your browser language preference.","continue":"Continue","close":"Close suggestion banner","selectLabel":"Select preferred language","regionLabel":"Language recommendation banner"},"zh":{"prompt":"éæ©å¦ä¸è¯è¨ä»¥æµè§éç¨äºä½ æµè§å¨è¯è¨å好çå
容ã","continue":"ç»§ç»","close":"å
³éè¯è¨å»ºè®®æ¨ªå¹
","selectLabel":"éæ©é¦éè¯è¨","regionLabel":"è¯è¨æ¨è横å¹
"},"ja":{"prompt":"å¥ã®è¨èªãé¸ã¶ã¨ããã©ã¦ã¶ã®è¨èªè¨å®ã«åãããã³ã³ãã³ãã表示ã§ãã¾ãã","continue":"ç¶ãã","close":"è¨èªææ¡ããã¼ãéãã","selectLabel":"叿ã®è¨èªã鏿","regionLabel":"è¨èªããããããã¼"},"ko":{"prompt":"ë¤ë¥¸ ì¸ì´ë¥¼ ì ííë©´ ë¸ë¼ì°ì ì¸ì´ ì¤ì ì ë§ë ì½í
ì¸ ë¥¼ ë³¼ ì ììµëë¤.","continue":"ê³ì","close":"ì¸ì´ ì ì ë°°ë ë«ê¸°","selectLabel":"ìíë ì¸ì´ ì í","regionLabel":"ì¸ì´ ì¶ì² ë°°ë"},"es":{"prompt":"Elija otro idioma para ver contenido adaptado a la preferencia de idioma de su navegador.","continue":"Continuar","close":"Cerrar banner de sugerencia de idioma","selectLabel":"Seleccionar idioma preferido","regionLabel":"Banner de recomendación de idioma"},"fr":{"prompt":"Choisissez une autre langue pour afficher le contenu adapté aux préférences linguistiques de votre navigateur.","continue":"Continuer","close":"Fermer la bannière de suggestion de langue","selectLabel":"Sélectionner la langue préférée","regionLabel":"Bannière de recommandation de langue"},"de":{"prompt":"Wählen Sie eine andere Sprache, um Inhalte entsprechend Ihrer Browser-Spracheinstellung anzuzeigen.","continue":"Weiter","close":"Sprachvorschlagsbanner schlieÃen","selectLabel":"Bevorzugte Sprache auswählen","regionLabel":"Sprachempfehlungsbanner"},"it":{"prompt":"Scegli un'altra lingua per visualizzare contenuti adattati alle preferenze linguistiche del browser.","continue":"Continua","close":"Chiudi banner suggerimento lingua","selectLabel":"Seleziona lingua preferita","regionLabel":"Banner raccomandazione lingua"},"nl":{"prompt":"Kies een andere taal om content te bekijken die is afgestemd op de taalvoorkeur van je browser.","continue":"Doorgaan","close":"Sluit taalsuggestiebanner","selectLabel":"Selecteer voorkeurstaal","regionLabel":"Taalaanbevelingsbanner"},"pl":{"prompt":"Wybierz inny jÄzyk, aby przeglÄ
daÄ treÅci dopasowane do preferencji jÄzykowych przeglÄ
darki.","continue":"Kontynuuj","close":"Zamknij baner sugestii jÄzyka","selectLabel":"Wybierz preferowany jÄzyk","regionLabel":"Baner rekomendacji jÄzyka"},"pt-BR":{"prompt":"Escolha outro idioma para ver conteúdo adaptado à preferência de idioma do seu navegador.","continue":"Continuar","close":"Fechar banner de sugestão de idioma","selectLabel":"Selecionar idioma preferido","regionLabel":"Banner de recomendação de idioma"},"ru":{"prompt":"ÐÑбеÑиÑе дÑÑгой ÑзÑк, ÑÑÐ¾Ð±Ñ Ð¿ÑоÑмаÑÑиваÑÑ ÐºÐ¾Ð½ÑенÑ, адапÑиÑованнÑй к ÑзÑковÑм наÑÑÑойкам ваÑего бÑаÑзеÑа.","continue":"ÐÑодолжиÑÑ","close":"ÐакÑÑÑÑ Ð±Ð°Ð½Ð½ÐµÑ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑзÑка","selectLabel":"ÐÑбеÑиÑе пÑедпоÑиÑаемÑй ÑзÑк","regionLabel":"ÐÐ°Ð½Ð½ÐµÑ ÑекомендаÑии ÑзÑка"},"tr":{"prompt":"Tarayıcı dil tercihinize uygun içeriÄi görmek için baÅka bir dil seçin.","continue":"Devam","close":"Dil önerisi baÅlıÄını kapat","selectLabel":"Tercih edilen dili seçin","regionLabel":"Dil önerisi baÅlıÄı"},"id":{"prompt":"Pilih bahasa lain untuk melihat konten yang disesuaikan dengan preferensi bahasa browser Anda.","continue":"Lanjutkan","close":"Tutup banner saran bahasa","selectLabel":"Pilih bahasa pilihan","regionLabel":"Banner rekomendasi bahasa"},"vi":{"prompt":"Chá»n ngôn ngữ khác Äá» xem ná»i dung phù hợp vá»i tùy chá»n ngôn ngữ trình duyá»t cá»§a bạn.","continue":"Tiếp tục","close":"Äóng banner gợi ý ngôn ngữ","selectLabel":"Chá»n ngôn ngữ ưa thÃch","regionLabel":"Banner Äá» xuất ngôn ngữ"},"th":{"prompt":"à¹à¸¥à¸·à¸à¸à¸ าษาà¸à¸·à¹à¸à¹à¸à¸·à¹à¸à¸à¸¹à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸µà¹à¸à¸£à¸±à¸à¹à¸«à¹à¹à¸à¹à¸²à¸à¸±à¸à¸à¸²à¸£à¸à¸±à¹à¸à¸à¹à¸²à¸ าษาà¸à¸à¸à¹à¸à¸£à¸²à¸§à¹à¹à¸à¸à¸£à¹à¸à¸à¸à¸à¸¸à¸","continue":"à¸à¸³à¹à¸à¸´à¸à¸à¸²à¸£à¸à¹à¸","close":"à¸à¸´à¸à¹à¸à¸à¹à¸à¸à¸£à¹à¹à¸à¸°à¸à¸³à¸ าษา","selectLabel":"à¹à¸¥à¸·à¸à¸à¸ าษาà¸à¸µà¹à¸à¹à¸à¸à¸à¸²à¸£","regionLabel":"à¹à¸à¸à¹à¸à¸à¸£à¹à¹à¸à¸°à¸à¸³à¸ าษา"},"ms":{"prompt":"Pilih bahasa lain untuk melihat kandungan yang disesuaikan dengan pilihan bahasa pelayar anda.","continue":"Teruskan","close":"Tutup banner cadangan bahasa","selectLabel":"Pilih bahasa pilihan","regionLabel":"Banner cadangan bahasa"},"tl":{"prompt":"Pumili ng ibang wika upang makita ang content na naaayon sa preference ng wika ng browser mo.","continue":"Magpatuloy","close":"Isara ang banner ng mungkahi sa wika","selectLabel":"Piliin ang gustong wika","regionLabel":"Banner ng rekomendasyon sa wika"},"bn":{"prompt":"à¦à¦ªà¦¨à¦¾à¦° বà§à¦°à¦¾à¦à¦à¦¾à¦°à§à¦° à¦à¦¾à¦·à¦¾à¦° পà¦à¦¨à§à¦¦ à¦
নà§à¦¯à¦¾à¦¯à¦¼à§ à¦à¦¨à¦à§à¦¨à§à¦ দà§à¦à¦¤à§ à¦
নà§à¦¯ à¦à¦¾à¦·à¦¾ বà§à¦à§ নিন।","continue":"à¦à¦¾à¦²à¦¿à¦¯à¦¼à§ যান","close":"à¦à¦¾à¦·à¦¾ পরামরà§à¦¶ বà§à¦¯à¦¾à¦¨à¦¾à¦° বনà§à¦§ à¦à¦°à§à¦¨","selectLabel":"পà¦à¦¨à§à¦¦à§à¦° à¦à¦¾à¦·à¦¾ নিরà§à¦¬à¦¾à¦à¦¨ à¦à¦°à§à¦¨","regionLabel":"à¦à¦¾à¦·à¦¾ সà§à¦ªà¦¾à¦°à¦¿à¦¶ বà§à¦¯à¦¾à¦¨à¦¾à¦°"},"ta":{"prompt":"à®à®à¯à®à®³à¯ à®à®²à®¾à®µà®¿ à®®à¯à®´à®¿ விரà¯à®ªà¯à®ª
7தà¯à®¤à®¿à®±à¯à®à¯ à®à®±à¯à®ª à®à®³à¯à®³à®à®à¯à®à®¤à¯à®¤à¯à®ªà¯ பாரà¯à®à¯à® வà¯à®±à¯ à®®à¯à®´à®¿à®¯à¯à®¤à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à®µà¯à®®à¯.","continue":"தà¯à®à®°à®µà¯à®®à¯","close":"à®®à¯à®´à®¿ பரிநà¯à®¤à¯à®°à¯ பà¯à®©à®°à¯ à®®à¯à®à®µà¯à®®à¯","selectLabel":"விரà¯à®ªà¯à®ª à®®à¯à®´à®¿à®¯à¯à®¤à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à®µà¯à®®à¯","regionLabel":"à®®à¯à®´à®¿ பரிநà¯à®¤à¯à®°à¯ பà¯à®©à®°à¯"},"te":{"prompt":"మౠబà±à°°à±à°à°°à± à°à°¾à°·à°¾ à°ªà±à°°à°¾à°§à°¾à°¨à±à°¯à°¤à°à± à°
à°¨à±à°à±à°£à°à°à°¾ à°à°à°à±à°à°à±âనౠà°à±à°¡à°à°¾à°¨à°¿à°à°¿ మరà±à° à°à°¾à°·à°¨à± à°à°à°à±à°à±à°à°¡à°¿.","continue":"à°à±à°¨à°¸à°¾à°à°¿à°à°à±","close":"à°à°¾à°· à°¸à±à°à°¨ à°¬à±à°¯à°¾à°¨à°°à±âనౠమà±à°¸à°¿à°µà±à°¯à°¿","selectLabel":"à°à°·à±à°à°®à±à°¨ à°à°¾à°·à°¨à± à°à°à°à±à°à±à°à°¡à°¿","regionLabel":"à°à°¾à°· సిఫారà±à°¸à± à°¬à±à°¯à°¾à°¨à°°à±"},"mr":{"prompt":"तà¥à¤®à¤à¥à¤¯à¤¾ बà¥à¤°à¤¾à¤à¤à¤°à¤à¥à¤¯à¤¾ à¤à¤¾à¤·à¤¾ पà¥à¤°à¤¾à¤§à¤¾à¤¨à¥à¤¯à¤¾à¤¨à¥à¤¸à¤¾à¤° सामà¤à¥à¤°à¥ पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ ॠदà¥à¤¸à¤°à¥ à¤à¤¾à¤·à¤¾ निवडा.","continue":"पà¥à¤¢à¥ à¤à¤¾","close":"à¤à¤¾à¤·à¤¾ सà¥à¤à¤¨à¤¾ बà¥
नर बà¤à¤¦ à¤à¤°à¤¾","selectLabel":"पसà¤à¤¤à¥à¤à¥ à¤à¤¾à¤·à¤¾ निवडा","regionLabel":"à¤à¤¾à¤·à¤¾ शिफारस बà¥
नर"},"ar":{"prompt":"اختر ÙØºØ© Ø£Ø®Ø±Ù ÙØ¹Ø±Ø¶ Ù
ØØªÙÙ ÙØªÙÙÙ Ù
ع ØªÙØ¶ÙÙØ§Øª ÙØºØ© Ù
ØªØµÙØÙ.","continue":"Ù
تابعة","close":"Ø¥ØºÙØ§Ù Ø´Ø±ÙØ· Ø§ÙØªØ±Ø§Ø اÙÙØºØ©","selectLabel":"اختر اÙÙØºØ© اÙÙ
ÙØ¶ÙØ©","regionLabel":"Ø´Ø±ÙØ· ØªÙØµÙØ© اÙÙØºØ©"},"he":{"prompt":"××ר ×©×¤× ××רת ××× ×צפ×ת ×ת××× ×××ת×× ×××¢×פת ××©×¤× ×©× ××פ××¤× ×©××.","continue":"××ש×","close":"ס××ר ×ת ××× ×¨ ×צעת ×שפ×","selectLabel":"××ר ×©×¤× ×××¢×פת","regionLabel":"××× ×¨ ×××צת שפ×"},"fa":{"prompt":"زبا٠دÛÚ¯Ø±Û Ø±Ø§ Ø§ÙØªØ®Ø§Ø¨ Ú©ÙÛØ¯ تا Ù
ØØªÙاÛÛ Ù
ØªÙØ§Ø³Ø¨ با ØªØ±Ø¬ÛØ زبا٠Ù
Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ ببÛÙÛØ¯.","continue":"اداÙ
Ù","close":"Ø¨Ø³ØªÙ Ø¨ÙØ± Ù¾ÛØ´ÙÙØ§Ø¯ زباÙ","selectLabel":"Ø§ÙØªØ®Ø§Ø¨ Ø²Ø¨Ø§Ù ØªØ±Ø¬ÛØÛ","regionLabel":"Ø¨ÙØ± Ù¾ÛØ´ÙÙØ§Ø¯ زباÙ"},"hi":{"prompt":"à¤
पनॠबà¥à¤°à¤¾à¤à¤à¤¼à¤° à¤à¤¾à¤·à¤¾ पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤à¤¤à¤¾ à¤à¥ à¤
नà¥à¤¸à¤¾à¤° सामà¤à¥à¤°à¥ दà¥à¤à¤¨à¥ à¤à¥ लिठदà¥à¤¸à¤°à¥ à¤à¤¾à¤·à¤¾ à¤à¥à¤¨à¥à¤à¥¤","continue":"à¤à¤¾à¤°à¥ रà¤à¥à¤","close":"à¤à¤¾à¤·à¤¾ सà¥à¤à¤¾à¤µ बà¥à¤¨à¤° बà¤à¤¦ à¤à¤°à¥à¤","selectLabel":"पसà¤à¤¦à¥à¤¦à¤¾ à¤à¤¾à¤·à¤¾ à¤à¥à¤¨à¥à¤","regionLabel":"à¤à¤¾à¤·à¤¾ à¤
नà¥à¤¶à¤à¤¸à¤¾ बà¥à¤¨à¤°"},"ur":{"prompt":"اپÙÛ Ø¨Ø±Ø§Ø¤Ø²Ø± Ø²Ø¨Ø§Ù Ú©Û ØªØ±Ø¬ÛØ Ú©Û Ù
طاب٠Ù
ÙØ§Ø¯ دÛÚ©Ú¾ÙÛ Ú©Û ÙÛÛ Ø¯ÙØ³Ø±Û زبا٠Ù
ÙØªØ®Ø¨ کرÛÚºÛ","continue":"Ø¬Ø§Ø±Û Ø±Ú©Ú¾ÛÚº","close":"Ø²Ø¨Ø§Ù Ú©Û ØªØ¬ÙÛØ² بÛÙØ± Ø¨ÙØ¯ کرÛÚº","selectLabel":"Ù¾Ø³ÙØ¯ÛØ¯Û Ø²Ø¨Ø§Ù Ù
ÙØªØ®Ø¨ کرÛÚº","regionLabel":"Ø²Ø¨Ø§Ù Ú©Û Ø³ÙØ§Ø±Ø´ بÛÙØ±"}}" style="display: none;" data-astro-cid-xujs2ijk> <div class="locale-banner-inner" data-astro-cid-xujs2ijk> <div class="locale-banner-text" data-astro-cid-xujs2ijk> <span id="locale-banner-message" data-astro-cid-xujs2ijk>Choose another language to browse content adapted for your browser language preference.</span> </div>
7 <div class="locale-banner-controls" data-astro-cid-xujs2ijk> <div class="locale-banner-actions" data-astro-cid-xujs2ijk> <div class="locale-banner-select-wrapper" data-astro-cid-xujs2ijk> <svg class="locale-banner-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true" data-astro-cid-xujs2ijk> <polyline points="20 6 9 17 4 12" data-astro-cid-xujs2ijk></polyline> </svg> <select id="locale-banner-select" class="locale-banner-select" aria-label="Select preferred language" data-astro-cid-xujs2ijk> <option value="en" data-astro-cid-xujs2ijk>English</option><option value="es" selected data-astro-cid-xujs2ijk>Español</option><option value="it" selected data-astro-cid-xujs2ijk>Italiano</option><option value="hi" selected data-astro-cid-xujs2ijk>हिनà¥à¤¦à¥</option><option value="ar" selected data-astro-cid-xujs2ijk>Ø§ÙØ¹Ø±Ø¨ÙØ©</option><option value="zh" selected data-astro-cid-xujs2ijk>䏿</option><option value="ja" selected data-astro-cid-xujs2ijk>æ¥æ¬èª</option><option value="ko" selected data-astro-cid-xujs2ijk>íêµì´</option><option value="fr" selected data-astro-cid-xujs2ijk>Français</option><option value="de" selected data-astro-cid-xujs2ijk>Deutsch</option><option value="nl" selected data-astro-cid-xujs2ijk>Nederlands</option><option value="pl" selected data-astro-cid-xujs2ijk>Polski</option><option value="pt-BR" selected data-astro-cid-xujs2ijk>Português</option><option value="ru" selected data-astro-cid-xujs2ijk>Ð ÑÑÑкий</option><option value="tr" selected data-astro-cid-xujs2ijk>Türkçe</option><option value="id" selected data-astro-cid-xujs2ijk>Bahasa Indonesia</option><option value="vi" selected data-astro-cid-xujs2ijk>Tiếng Viá»t</option><option value="th" selected data-astro-cid-xujs2ijk>à¹à¸à¸¢</option><option value="ms" selected data-astro-cid-xujs2ijk>Bahasa Melayu</option><option value="tl" selected data-astro-cid-xujs2ijk>Filipino</option><option value="bn" selected data-astro-cid-xujs2ijk>বাà¦à¦²à¦¾</option><option value="ta" selected data-astro-cid-xujs2ijk>தமிழà¯</option><option value="te" selected data-astro-cid-xujs2ijk>à°¤à±à°²à±à°à±</option><option value="mr" selected data-astro-cid-xujs2ijk>मराठà¥</option><option value="he" selected data-astro-cid-xujs2ijk>×¢×ר×ת</option><option value="fa" selected data-astro-cid-xujs2ijk>ÙØ§Ø±Ø³Û</option><option value="ur" selected data-astro-cid-xujs2ijk>اردÙ</option> </select> <svg class="locale-banner-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" data-astro-cid-xujs2ijk> <polyline points="6 9 12 15 18 9" data-astro-cid-xujs2ijk></polyline> </svg> </div> <a id="locale-banner-continue" href="#" class="locale-banner-button" data-astro-cid-xujs2ijk> Continue </a> </div> <button id="locale-banner-close" class="locale-banner-close" aria-label="Close suggestion banner" type="button" data-astro-cid-xujs2ijk> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" data-astro-cid-xujs2ijk> <line x1="18" y1="6" x2="6" y2="18" data-astro-cid-xujs2ijk></line> <line x1="6" y1="6" x2="18" y2="18" data-astro-cid-xujs2ijk></line> </svg> </button> </div> </div> </aside>
7<script> 8 (() => { 9 try { 10 const banner = document.getElementById('locale-banner'); 11 if (!banner) return; 12 13 const DISMISSED_KEY = 'apple_style_lang_banner_dismissed'; 14 if (sessionStorage.getItem(DISMISSED_KEY) === '1') return; 15 16 const currentLang = banner.getAttribute('data-current-lang') || 'en'; 17 const langUrls = JSON.parse(banner.getAttribute('data-lang-urls') || '{}'); 18 const bannerCopy = JSON.parse(banner.getAttribute('data-banner-copy') || '{}'); 19 const supportedLangs = Object.keys(langUrls); 20 21 const alias = { pt: 'pt-BR', zh: 'zh', iw: 'he', in: 'id', fil: 'tl', tl: 'tl' }; 22 23 function match(raw) { 24 raw = (raw || '').toLowerCase(); 25 if (!raw) return ''; 26 for (let i = 0; i < supportedLangs.length; i++) { 27 if (supportedLangs[i].toLowerCase() === raw) return supportedLangs[i]; 28 } 29 const base = raw.split('-')[0]; 30 if (alias[base]) return alias[base]; 31 for (let j = 0; j < supportedLangs.length; j++) { 32 const s = supportedLangs[j].toLowerCase(); 33 if (s === base || s.split('-')[0] === base) return supportedLangs[j]; 34 } 35 return ''; 36 } 37 38 const prefs = 39 navigator.languages && navigator.languages.length 40 ? navigator.languages 41 : [navigator.language || 'en']; 42 43 let detectedLang = ''; 44 for (let k = 0; k < prefs.length && !detectedLang; k++) { 45 detectedLang = match(prefs[k]); 46 } 47 if (!detectedLang) detectedLang = 'en'; 48 49 if (detectedLang === currentLang) return; 50 51 const select = document.getElementById('locale-banner-select'); 52 const continueBtn = document.getElementById('locale-banner-continue'); 53 const closeBtn = document.getElementById('locale-banner-close'); 54 const msg = document.getElementById('locale-banner-message'); 55 56 function applyBannerCopy(lang) { 57 const copy = bannerCopy[lang] || bannerCopy.en || {}; 58 if (msg) msg.textContent = copy.prompt || ''; 59 if (continueBtn) continueBtn.textContent = copy.continue || ''; 60 if (select) select.setAttribute('aria-label', copy.selectLabel || ''); 61 if (closeBtn) closeBtn.setAttribute('aria-label', copy.close || ''); 62 banner.setAttribute('aria-label', copy.regionLabel || ''); 63 } 64 65 if (select) select.value = detectedLang; 66 applyBannerCopy(detectedLang); 67 68 function updateContinueTarget() { 69 if (!select || !continueBtn) return; 70 const target = select.value; 71 continueBtn.setAttribute('href', langUrls[target] || '/'); 72 applyBannerCopy(target); 73 } 74 75 if (select) select.addEventListener('change', updateContinueTarget); 76 77 if (closeBtn) { 78 closeBtn.addEventListener('click', () => { 79 banner.style.display = 'none'; 80 sessionStorage.setItem(DISMISSED_KEY, '1'); 81 }); 82 } 83 84 updateContinueTarget(); 85 banner.style.display = 'block'; 86 } catch (e) {} 87 })(); 88</script>
88 <div aria-hidden="true" class="pointer-events-none fixed inset-0 -z-10 mask-fade-b"> <div class="absolute -top-40 left-1/2 h-[600px] w-[1200px] -translate-x-1/2 rounded-full bg-violet-500/20 blur-3xl"></div> <div class="absolute right-[-200px] top-40 h-[500px] w-[500px] rounded-full bg-cyan-400/10 blur-3xl"></div> <div class="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/15 to-transparent"></div> </div> <header class="sticky top-0 z-40 border-b border-white/5 bg-ink-950/70 backdrop-blur-md"> <div class="container-x flex h-16 items-center justify-between gap-4"> <a href="/" class="flex shrink-0 items-center gap-2.5 font-display text-base font-semibold tracking-tight text-white"> <span class="grid h-7 w-7 shrink-0 place-items-center rounded-lg bg-brand-gradient text-ink-950 shadow-glow"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="currentColor" d="M12 2l1.7 7.3L21 11l-7.3 1.7L12 20l-1.7-7.3L3 11l7.3-1.7L12 2z"></path> </svg> </span> <span class="whitespace-nowrap">Gemini Omni</span> </a> <nav aria-label="Primary" class="hidden lg:block"> <ul class="flex items-center gap-1 text-sm text-zinc-300"> <li> <a href="/" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Home </a> </li><li> <a href="/#showcase" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Demos </a> </li><li> <a href="/#features" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Features </a> </li><li> <a href="/#free" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Free vs paid </a> </li><li> <a href="/prompt-generator/" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Prompt builder </a> </li><li> <a href="/video-studio/" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Video Studio </a> </li><li> <a href="/pricing/" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Pricing </a> </li><li> <a href="/blog/" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> Articles </a> </li><li> <a href="/#faq" class="whitespace-nowrap rounded-full px-3 py-1.5 transition-colors hover:bg-white/[0.06] hover:text-white"> FAQ </a> </li> </ul> </nav> <div class="flex shrink-0 items-center gap-2"> <div data-auth class="relative flex items-center gap-2"> <button type="button" data-open-login data-auth-signed-out class="chip cursor-pointer hover:border-violet-400/40 hover:text-white"> Sign in </button> <a href="/pricing/" data-auth-points hidden aria-label="Available credits" title="Credits" class="hidden items-center gap-1.5 rounded-full border border-violet-400/30 bg-violet-500/10 px-3 py-1 text-xs font-semibold text-violet-100 transition-colors hover:border-violet-400/60 hover:bg-violet-500/15 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="currentColor" d="M13 2L3 14h7l-1 8 10-12h-7l1-8z"></path> </svg> <span data-auth-points-value class="tabular-nums">0</span> </a> <button type="button" data-auth-signed-in hidden aria-haspopup="menu" aria-expanded="false" class="flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] py-1 pl-1 pr-3 text-sm transition-colors hover:border-violet-400/40"> <span data-auth-avatar class="grid h-7 w-7 place-items-center overflow-hidden rounded-full bg-brand-gradient text-xs font-semibold uppercase text-ink-950"></span> <span data-auth-name class="hidden max-w-[8rem] truncate text-zinc-200 sm:inline"></span> <svg viewBox="0 0 24 24" class="hidden h-3 w-3 opacity-60 sm:inline" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"></path> </svg> </button> <div data-auth-menu hidden role="menu" class="absolute right-0 top-full z-50 mt-2 w-64 max-w-[calc(100vw-1rem)] origin-top-right rounded-2xl border border-white/10 bg-ink-900/95 p-3 shadow-xl backdrop-blur"> <div class="flex items-center gap-3 border-b border-white/5 px-2 pb-3"> <span data-auth-avatar-lg class="grid h-10 w-10 shrink-0 place-items-center overflow-hidden rounded-full bg-brand-gradient text-sm font-semibold uppercase text-ink-950"></span> <div class="min-w-0"> <p data-auth-name-full class="truncate text-sm font-semibold text-white"></p> <p data-auth-email class="truncate text-xs text-zinc-400"></p> </div> </div> <button type="button" data-auth-logout class="mt-3 flex w-full items-center justify-center gap-2 rounded-xl border border-rose-400/30 bg-rose-500/10 px-3 py-2 text-sm font-semibold text-rose-200 transition-colors hover:bg-rose-500/15"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 12H4m0 0l4-4m-4 4l4 4M9 4h7a2 2 0 012 2v12a2 2 0 01-2 2H9"></path> </svg> Log out </button> </div> </div>
88<script>(function(){const API_BASE = "https://www.gushanai.com/api"; 89const APP_KEY = "gemini_omni_4561"; 90const HTML_LANG = "en"; 91 92 (() => { 93 if (typeof window === 'undefined') return; 94 95 const AUTH_TOKEN_KEY = 'auth_token'; 96 const USER_INFO_KEY = 'user_info'; 97 const AUTH_CHANGED_EVENT = 'gemini-omni:auth-changed'; 98 const REFRESH_USER_EVENT = 'gemini-omni:refresh-user'; 99 const SESSION_REFRESHED_KEY = 'gemini-omni:auth-refreshed'; 100 101 const root = document.querySelector('[data-auth]'); 102 if (!root) return; 103 104 const signedOutEl = root.querySelector('[data-auth-signed-out]'); 105 const signedInEl = root.querySelector('[data-auth-signed-in]'); 106 const menuEl = root.querySelector('[data-auth-menu]'); 107 const avatarEl = root.querySelector('[data-auth-avatar]'); 108 const avatarLgEl = root.querySelector('[data-auth-avatar-lg]'); 109 const nameEl = root.querySelector('[data-auth-name]'); 110 const nameFullEl = root.querySelector('[data-auth-name-full]'); 111 const emailEl = root.querySelector('[data-auth-email]'); 112 const logoutBtn = root.querySelector('[data-auth-logout]'); 113 const pointsEl = root.querySelector('[data-auth-points]'); 114 const pointsValueEl = root.querySelector('[data-auth-points-value]'); 115 116 let pointsFormatter; 117 try { 118 pointsFormatter = new Intl.NumberFormat(HTML_LANG); 119 } catch { 120 pointsFormatter = new Intl.NumberFormat('en'); 121 } 122 123 const getToken = () => window.localStorage.getItem(AUTH_TOKEN_KEY); 124 const getUser = () => { 125 const raw = window.localStorage.getItem(USER_INFO_KEY); 126 if (!raw) return null; 127 try { 128 return JSON.parse(raw); 129 } catch { 130 return null; 131 } 132 }; 133 134 const initials = (user) => { 135 const src = (user?.nickName || user?.email || '').trim(); 136 if (!src) return '?'; 137 const ch = src.codePointAt(0); 138 return ch ? String.fromCodePoint(ch).toUpperCase() : '?'; 139 }; 140 141 const renderAvatar = (el, user) => { 142 if (!el) return; 143 el.innerHTML = ''; 144 if (user?.avatarUrl) { 145 const img = document.createElement('img'); 146 img.src = user.avatarUrl; 147 img.alt = user.nickName || user.email || ''; 148 img.referrerPolicy = 'no-referrer'; 149 img.className = 'h-full w-full object-cover'; 150 el.appendChild(img); 151 } else { 152 el.textContent = initials(user); 153 } 154 }; 155 156 const closeMenu = () => { 157 menuEl?.setAttribute('hidden', ''); 158 signedInEl?.setAttribute('aria-expanded', 'false'); 159 if (menuEl) menuEl.style.right = ''; 160 }; 161 162 const adjustMenuPosition = () => { 163 if (!menuEl) return; 164 menuEl.style.right = ''; 165 const rect = menuEl.getBoundingClientRect(); 166 const minMargin = 8; 167 if (rect.left < minMargin) { 168 const shift = minMargin - rect.left; 169 menuEl.style.right = `-${shift}px`; 170 } else if (rect.right > window.innerWidth - minMargin) { 171 const overflow = rect.right - (window.innerWidth - minMargin); 172 menuEl.style.right = `${overflow}px`; 173 } 174 }; 175 176 const openMenu = () => { 177 menuEl?.removeAttribute('hidden'); 178 signedInEl?.setAttribute('aria-expanded', 'true'); 179 adjustMenuPosition(); 180 }; 181 182 const renderPoints = (user) => { 183 if (!pointsEl) return; 184 const total = Number(user?.wallet?.points?.totalBalance); 185 if (Number.isFinite(total) && total >= 0) { 186 if (pointsValueEl) pointsValueEl.textContent = pointsFormatter.format(total); 187 pointsEl.removeAttribute('hidden'); 188 pointsEl.classList.remove('hidden'); 189 pointsEl.classList.add('inline-flex'); 190 } else { 191 pointsEl.setAttribute('hidden', ''); 192 pointsEl.classList.add('hidden'); 193 pointsEl.classList.remove('inline-flex'); 194 } 195 }; 196 197 const render = () => { 198 const token = getToken(); 199 const user = getUser(); 200 if (token && user) { 201 signedOutEl?.setAttribute('hidden', ''); 202 signedInEl?.removeAttribute('hidden'); 203 renderAvatar(avatarEl, user); 204 renderAvatar(avatarLgEl, user); 205 const display = user.nickName || user.email || ''; 206 if (nameEl) nameEl.textContent = display; 207 if (nameFullEl) nameFullEl.textContent = user.nickName || user.email || ''; 208 if (emailEl) emailEl.textContent = user.email || ''; 209 renderPoints(user); 210 } else { 211 signedInEl?.setAttribute('hidden', ''); 212 signedOutEl?.removeAttribute('hidden'); 213 renderPoints(null); 214 closeMenu(); 215 } 216 }; 217 218 const apiRequest = async (path, body) => { 219 const headers = { 'Content-Type': 'application/json', 'x-app-key': APP_KEY }; 220 const token = getToken(); 221 if (token) headers.Authorization = token; 222 const res = await fetch(`${API_BASE}${path}`, { 223 method: 'POST', 224 headers, 225 body: JSON.stringify(body || {}), 226 }); 227 let env;
228 try { 229 env = await res.json(); 230 } catch { 231 env = { code: res.status, message: `HTTP ${res.status}` }; 232 } 233 if (!env || (env.code !== 200 && env.code !== 0)) { 234 const err = new Error(env?.message || `HTTP ${res.status}`); 235 err.code = env?.code ?? res.status; 236 err.status = res.status; 237 throw err; 238 } 239 return env.data; 240 }; 241 242 const clearAuth = () => { 243 window.localStorage.removeItem(AUTH_TOKEN_KEY); 244 window.localStorage.removeItem(USER_INFO_KEY); 245 try { 246 window.sessionStorage.removeItem(SESSION_REFRESHED_KEY); 247 } catch {} 248 window.dispatchEvent(new CustomEvent(AUTH_CHANGED_EVENT, { detail: { token: null, user: null } })); 249 }; 250 251 const refreshIfNeeded = async () => { 252 const token = getToken(); 253 if (!token) return; 254 let alreadyRefreshed = false; 255 try { 256 alreadyRefreshed = window.sessionStorage.getItem(SESSION_REFRESHED_KEY) === '1'; 257 } catch {} 258 if (alreadyRefreshed) return; 259 try { 260 const refreshData = await apiRequest('/auth/refresh', {}); 261 if (refreshData?.token) { 262 window.localStorage.setItem(AUTH_TOKEN_KEY, refreshData.token); 263 } 264 const user = await apiRequest('/mine/info', {}); 265 if (user) { 266 window.localStorage.setItem(USER_INFO_KEY, JSON.stringify(user)); 267 } 268 try { 269 window.sessionStorage.setItem(SESSION_REFRESHED_KEY, '1'); 270 } catch {} 271 window.dispatchEvent( 272 new CustomEvent(AUTH_CHANGED_EVENT, { detail: { token: getToken(), user } }) 273 ); 274 } catch (err) { 275 const status = err && (err.status || err.code); 276 if (status === 401 || status === 403) { 277 clearAuth(); 278 } 279 } 280 }; 281 282 signedInEl?.addEventListener('click', (e) => { 283 e.stopPropagation(); 284 if (menuEl?.hasAttribute('hidden')) openMenu(); 285 else closeMenu(); 286 }); 287 288 logoutBtn?.addEventListener('click', (e) => { 289 e.stopPropagation(); 290 clearAuth(); 291 closeMenu(); 292 }); 293 294 document.addEventListener('click', (e) => { 295 if (!root.contains(e.target)) closeMenu(); 296 }); 297 298 document.addEventListener('keydown', (e) => { 299 if (e.key === 'Escape') closeMenu(); 300 }); 301 302 window.addEventListener(AUTH_CHANGED_EVENT, render); 303 304 window.addEventListener(REFRESH_USER_EVENT, async () => { 305 if (!getToken()) return; 306 try { 307 const user = await apiRequest('/mine/info', {}); 308 if (user) { 309 window.localStorage.setItem(USER_INFO_KEY, JSON.stringify(user)); 310 window.dispatchEvent( 311 new CustomEvent(AUTH_CHANGED_EVENT, { detail: { token: getToken(), user } }) 312 ); 313 } 314 } catch (err) { 315 const status = err && (err.status || err.code); 316 if (status === 401 || status === 403) { 317 clearAuth(); 318 } 319 } 320 }); 321 322 render(); 323 refreshIfNeeded(); 324 })(); 325})();</script>
325 <div class="relative" data-lang-switcher> <button type="button" class="chip hover:border-violet-400/40 hover:text-white" aria-label="Switch language" aria-haspopup="listbox" aria-expanded="false" data-lang-toggle> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" d="M12 3v18M3 12h18M5.5 7.5c4 3 9 3 13 0M5.5 16.5c4-3 9-3 13 0"></path> </svg> <span class="hidden sm:inline">English</span> <svg viewBox="0 0 24 24" class="h-3 w-3 opacity-60" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"></path> </svg> </button> <div class="absolute end-0 z-50 mt-2 hidden max-h-[min(60vh,420px)] w-48 origin-top-right overflow-y-auto overscroll-contain rtl:origin-top-left rounded-2xl border border-white/10 bg-ink-900/95 p-1.5 shadow-xl backdrop-blur" role="listbox" data-lang-menu> <a href="/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors bg-white/[0.06] text-white" role="option" aria-selected="true" hreflang="en"> <span>English</span> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5 text-violet-300" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M5 12l5 5 9-11"></path> </svg> </a><a href="/es/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="es"> <span>Español</span> </a><a href="/it/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="it"> <span>Italiano</span> </a><a href="/hi/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="hi"> <span>हिनà¥à¤¦à¥</span> </a><a href="/ar/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ar"> <span>Ø§ÙØ¹Ø±Ø¨ÙØ©</span> </a><a href="/zh/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="zh"> <span>䏿</span> </a><a href="/ja/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ja"> <span>æ¥æ¬èª</span> </a><a href="/ko/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ko"> <span>íêµì´</span> </a><a href="/fr/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="fr"> <span>Français</span> </a><a href="/de/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="de"> <span>Deutsch</span> </a><a href="/nl/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="nl"> <span>Nederlands</span> </a><a href="/pl/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="pl"> <span>Polski</span> </a><a href="/pt-BR/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="pt-BR"> <span>Português</span> </a><a href="/ru/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ru"> <span>Ð ÑÑÑкий</span> </a><a href="/tr/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="tr"> <span>Türkçe</span> </a><a href="/id/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="id"> <span>Bahasa Indonesia</span> </a><a href="/vi/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="vi"> <span>Tiếng Viá»t</span> </a><a href="/th/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="th"> <span>à¹à¸à¸¢</span> </a>
325<a href="/ms/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ms"> <span>Bahasa Melayu</span> </a><a href="/tl/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="tl"> <span>Filipino</span> </a><a href="/bn/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="bn"> <span>বাà¦à¦²à¦¾</span> </a><a href="/ta/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ta"> <span>தமிழà¯</span> </a><a href="/te/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="te"> <span>à°¤à±à°²à±à°à±</span> </a><a href="/mr/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="mr"> <span>मराठà¥</span> </a><a href="/he/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="he"> <span>×¢×ר×ת</span> </a><a href="/fa/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="fa"> <span>ÙØ§Ø±Ø³Û</span> </a><a href="/ur/prompt-generator/" class="flex items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors text-zinc-300 hover:bg-white/[0.04] hover:text-white" role="option" aria-selected="false" hreflang="ur"> <span>اردÙ</span> </a> </div> </div> <button type="button" class="grid h-9 w-9 place-items-center rounded-full border border-white/10 bg-white/[0.04] text-zinc-200 transition-colors hover:border-violet-400/40 hover:text-white lg:hidden" aria-label="Menu" aria-expanded="false" aria-controls="mobile-menu" data-mobile-toggle> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" d="M4 7h16M4 12h16M4 17h16"></path> </svg> </button> </div> </div> <div id="mobile-menu" class="lg:hidden hidden border-t border-white/5 bg-ink-950/95 backdrop-blur"> <ul class="container-x flex flex-col gap-1 py-3 text-sm text-zinc-300"> <li> <a href="/" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Home </a> </li><li> <a href="/#showcase" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Demos </a> </li><li> <a href="/#features" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Features </a> </li><li> <a href="/#specs" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Specs </a> </li><li> <a href="/#comparison" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Compare </a> </li><li> <a href="/#free" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Free vs paid </a> </li><li> <a href="/prompt-generator/" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Prompt builder </a> </li><li> <a href="/video-studio/" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Video Studio </a> </li><li> <a href="/pricing/" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Pricing </a> </li><li> <a href="/blog/" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> Articles </a> </li><li> <a href="/#faq" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link> FAQ </a> </li><li> <a href="/#sources" class="block rounded-lg px-3 py-2 transition-colors hover:bg-white/[0.06] hover:text-white" data-mobile-link>
325 Sources </a> </li> </ul> </div> </header>
325<script> 326 (() => { 327 const toggle = document.querySelector('[data-mobile-toggle]'); 328 const menu = document.getElementById('mobile-menu'); 329 if (toggle && menu) { 330 const close = () => { menu.classList.add('hidden'); toggle.setAttribute('aria-expanded', 'false'); }; 331 const open = () => { menu.classList.remove('hidden'); toggle.setAttribute('aria-expanded', 'true'); }; 332 toggle.addEventListener('click', () => menu.classList.contains('hidden') ? open() : close()); 333 menu.querySelectorAll('[data-mobile-link]').forEach((el) => el.addEventListener('click', close)); 334 } 335 336 const switcher = document.querySelector('[data-lang-switcher]'); 337 if (switcher) { 338 const langToggle = switcher.querySelector('[data-lang-toggle]'); 339 const langMenu = switcher.querySelector('[data-lang-menu]'); 340 const closeLang = () => { langMenu.classList.add('hidden'); langToggle.setAttribute('aria-expanded', 'false'); }; 341 const openLang = () => { langMenu.classList.remove('hidden'); langToggle.setAttribute('aria-expanded', 'true'); }; 342 langToggle.addEventListener('click', (e) => { 343 e.stopPropagation(); 344 langMenu.classList.contains('hidden') ? openLang() : closeLang(); 345 }); 346 document.addEventListener('click', (e) => { 347 if (!switcher.contains(e.target)) closeLang(); 348 }); 349 document.addEventListener('keydown', (e) => { 350 if (e.key === 'Escape') closeLang(); 351 }); 352 } 353 })(); 354</script>
354 <main> <div data-pg-root data-pg-signed-in="false" class="group/pgroot flex flex-col"> <section data-pg-hero class="relative order-1 overflow-hidden pt-12 pb-10 sm:pt-20 sm:pb-14 group-data-[pg-signed-in=true]/pgroot:order-2 group-data-[pg-signed-in=true]/pgroot:pt-2 group-data-[pg-signed-in=true]/pgroot:pb-10 group-data-[pg-signed-in=true]/pgroot:sm:pt-4 group-data-[pg-signed-in=true]/pgroot:sm:pb-14"> <div class="container-x"> <nav aria-label="Breadcrumb" class="mb-5 flex flex-wrap items-center gap-2 text-xs text-zinc-500 group-data-[pg-signed-in=true]/pgroot:hidden"> <a class="hover:text-zinc-200" href="/">Home</a> <span aria-hidden="true">/</span> <span class="text-zinc-300">Prompt builder</span> </nav> <div class="grid items-start gap-8 sm:gap-10 lg:grid-cols-[1.05fr_0.95fr]"> <div class="reveal"> <span class="chip mb-4 border-violet-400/30 text-violet-200"> Tool · prompt engineering </span> <h1 class="font-display text-[2rem] font-semibold leading-[1.1] tracking-tight text-white sm:text-5xl group-data-[pg-signed-in=true]/pgroot:text-2xl group-data-[pg-signed-in=true]/pgroot:sm:text-3xl"> <span class="text-gradient">Gemini Omni video prompt generator</span> </h1> <p class="mt-4 max-w-xl text-sm leading-relaxed text-zinc-400 sm:mt-5 sm:text-lg group-data-[pg-signed-in=true]/pgroot:text-sm group-data-[pg-signed-in=true]/pgroot:sm:text-base"> Turn a one-line creative brief into a copy-ready, multi-shot Omni prompt â complete with camera, lighting, beat and audio direction. </p> <div data-pg-hero-ctas class="mt-5 flex flex-wrap items-center gap-3 group-data-[pg-signed-in=true]/pgroot:hidden"> <a href="/#features" class="btn-ghost">See the capabilities</a> <a href="https://gemini.google.com/" class="btn-ghost" target="_blank" rel="noopener noreferrer"> Open the Gemini app <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M7 17L17 7M9 7h8v8"></path> </svg> </a> </div> </div> <aside class="reveal"> <div class="card"> <h2 class="font-display text-base font-semibold text-white"> Try one of these briefs </h2> <ul class="mt-4 space-y-3"> <li> <button type="button" data-pg-example data-pg-example-brief="8-second product ad for a gardenia-scented bar of soap. Clean premium visuals, ending with a tight product close-up." class="group flex w-full flex-col items-start gap-1.5 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-start transition-colors hover:border-violet-400/40 hover:bg-white/[0.07]"> <span class="text-sm font-semibold text-zinc-100">Product ad</span> <span class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> 8-second product ad for a gardenia-scented bar of soap. Clean premium visuals, ending with a tight product close-up. </span> </button> </li><li> <button type="button" data-pg-example data-pg-example-brief="A Xiaohongshu-style clip: a young woman using the soap in a bright bathroom, natural light, soft pacing, soothing vibe." class="group flex w-full flex-col items-start gap-1.5 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-start transition-colors hover:border-violet-400/40 hover:bg-white/[0.07]"> <span class="text-sm font-semibold text-zinc-100">Xiaohongshu / lifestyle</span> <span class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> A Xiaohongshu-style clip: a young woman using the soap in a bright bathroom, natural light, soft pacing, soothing vibe. </span> </button> </li><li> <button type="button" data-pg-example data-pg-example-brief="9:16 Reels following hands from unboxing to use, with an upbeat electronic beat and a closing logo shot." class="group flex w-full flex-col items-start gap-1.5 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-start transition-colors hover:border-violet-400/40 hover:bg-white/[0.07]"> <span class="text-sm font-semibold text-zinc-100">Vertical Reels</span> <span class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> 9:16 Reels following hands from unboxing to use, with an upbeat electronic beat and a closing logo shot. </span> </button> </li> </ul> </div> </aside> </div> </div> </section> <section id="builder" data-pg-builder class="order-2 pb-14 sm:pb-16 group-data-[pg-signed-in=true]/pgroot:order-1 group-data-[pg-signed-in=true]/pgroot:pt-10 group-data-[pg-signed-in=true]/pgroot:sm:pt-16"> <div class="container-x"> <nav aria-label="Breadcrumb" class="mb-4 hidden flex-wrap items-center gap-2 text-xs text-zinc-500 group-data-[pg-signed-in=true]/pgroot:flex"> <a class="hover:text-zinc-200" href="/">Home</a> <span aria-hidden="true">/</span> <span class="text-zinc-300">Prompt builder</span> </nav> <form data-pg-form class="grid gap-6 rounded-3xl border border-white/10 bg-white/[0.03] p-4 backdrop-blur-sm sm:p-6 md:p-8 lg:grid-cols-2" data-error-empty="Please write your creative brief first." data-error-generic="Could not generate a prompt. Please try again." data-login-required="Sign in to generate prompts." data-copy-success="Copied" data-copy-failed="Could not copy. Please select the text manually." data-copy-idle="Copy"> <div class="flex min-w-0 flex-col gap-3"> <label for="pg-input" class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400"> Your creative brief </label> <textarea id="pg-input" data-pg-input rows="9" maxlength="1000" placeholder="e.g. From the uploaded soap product image, generate a Xiaohongshu-style video that highlights a gardenia scent â clean, premium look, optimised for shoppable content." class="min-h-[10rem] w-full resize-y rounded-2xl border border-white/10 bg-ink-950/60 px-4 py-3 text-sm leading-relaxed text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20 sm:min-h-[12rem]"></textarea> <div class="flex flex-wrap items-start justify-between gap-x-3 gap-y-1"> <p class="text-xs text-zinc-500">Include the product, talent, camera, mood and length for the most stable result. Limit 1000 characters.</p> <span data-pg-counter class="shrink-0 font-mono text-[11px] tabular-nums text-zinc-500">0 / 1000</span> </div> <div class="flex flex-col gap-2 pt-1 sm:flex-row sm:flex-wrap sm:items-center sm:gap-3"> <button type="submit" data-pg-submit class="btn-primary w-full justify-center sm:w-auto"> <span data-pg-label-idle class="flex flex-wrap items-center justify-center gap-1.5 sm:gap-2"> <span>Generate prompt</span> <svg viewBox="0 0 24 24" class="hidden h-4 w-4 sm:inline" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M12 3v3M12 18v3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M3 12h3M18 12h3M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"></path> </svg> <span data-pg-cost data-pg-cost-template="Costs {cost} credits" class="inline-flex items-center gap-1 rounded-full bg-black/25 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-white/95 ring-1 ring-white/15"> <svg viewBox="0 0 24 24" class="h-3 w-3" aria-hidden="true"> <path fill="currentColor" d="M13 2L3 14h7l-1 8 10-12h-7l1-8z"></path> </svg> <span data-pg-cost-text>Costs 1 credits</span> </span> </span> <span data-pg-label-loading hidden class="flex items-center justify-center gap-2"> <span class="inline-block h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/70 border-t-transparent"></span> Generating⦠</span> </button> <button type="button" data-pg-open-templates class="inline-flex w-full items-center justify-center gap-2 rounded-full border border-violet-400/30 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-violet-200 transition-colors hover:border-violet-400/60 hover:bg-violet-500/10 hover:text-white sm:w-auto"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h10M4 18h16"></path> </svg> <span>Try templates</span> <span class="hidden text-[11px] font-normal text-violet-300/80 sm:inline"> No inspiration? Fill the form </span> </button> <p data-pg-error hidden class="w-full rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-2 text-xs text-rose-200 sm:w-auto"></p> </div> </div> <div class="flex min-w-0 flex-col gap-3"> <div class="flex items-center justify-between gap-2"> <h2 class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400"> Generated prompt </h2> <button type="button" data-pg-copy disabled class="inline-flex shrink-0 items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-white/10 disabled:hover:text-zinc-300"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M9 9h9v11H9zM6 6h9v3M6 6v11h3"></path> </svg> <span data-pg-copy-label>Copy</span> </button> </div> <div data-pg-output-wrap class="relative min-h-[16rem] rounded-2xl border border-white/10 bg-ink-950/60"> <pre data-pg-output data-empty="1" class="m-0 max-h-[28rem] overflow-y-auto whitespace-pre-wrap break-words px-4 py-3 font-mono text-xs leading-relaxed text-zinc-500 sm:text-sm">The structured Omni prompt will appear here â ready to copy into the Gemini app.</pre> <div data-pg-skeleton hidden class="pointer-events-none absolute inset-0 flex flex-col gap-2 px-4 py-3"> <span class="h-3 w-5/6 animate-pulse rounded-full bg-white/[0.06]"></span> <span class="h-3 w-2/3 animate-pulse rounded-full bg-white/[0.05]"></span> <span class="h-3 w-3/4 animate-pulse rounded-full bg-white/[0.06]"></span> <span class="h-3 w-1/2 animate-pulse rounded-full bg-white/[0.04]"></span> <span class="h-3 w-4/5 animate-pulse rounded-full bg-white/[0.06]"></span> </div> </div> </div> </form> <p class="mt-6 text-xs leading-relaxed text-zinc-500"> A community helper tool, not affiliated with Google. Gemini, Omni and related marks belong to Google. <a class="ml-1 text-violet-300 hover:text-violet-200" href="/#sources">Sources</a> </p> </div> </section> </div> <dialog id="pg-templates-modal" data-pg-tpl-modal data-lang="en" class="hidden w-[min(720px,calc(100vw-24px))] rounded-3xl border border-white/10 bg-ink-900/95 p-0 text-zinc-100 shadow-glow backdrop:bg-ink-950/70 backdrop:backdrop-blur-md open:flex open:flex-col" aria-labelledby="pg-templates-title"> <div class="relative max-h-[min(720px,90vh)] overflow-y-auto px-6 pb-6 pt-7 sm:px-8 sm:pb-8 sm:pt-9"> <button type="button" data-tpl-close aria-label="Close" class="absolute right-3 top-3 grid h-9 w-9 place-items-center rounded-full border border-white/10 bg-white/[0.04] text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" d="M6 6l12 12M18 6L6 18"></path> </svg> </button> <section data-step="picker" class="flex flex-col gap-5"> <header class="text-start"> <h2 id="pg-templates-title" class="font-display text-xl font-semibold tracking-tight text-white sm:text-2xl"> Pick a template and fill the form </h2> <p class="mt-1.5 text-sm leading-relaxed text-zinc-400"> 14 production-ready video script templates â fill out the form to drop a clean brief into the input, ready for Gemini Omni. </p> </header> <div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3"> <button type="button" data-pick-template="product-ad" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M5 7h14l-1 13H6L5 7zm3-2a3 3 0 016 0v2H8V5z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Product ad </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Shoppable short-form: highlight selling points, platform tone and CTA. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 9 fields </span> </button><button type="button" data-pick-template="brand-hero" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22 12 18.56 5.82 22 7 14.14l-5-4.87 6.91-1.01L12 2z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Brand hero </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Brand positioning hero film: mood, scene and pacing in one piece. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 9 fields </span> </button><button type="button" data-pick-template="unboxing" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M3 7l9-4 9 4-9 4-9-4zm0 5l9 4 9-4M3 17l9 4 9-4"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Unboxing </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> First-impression unbox driven by packaging detail and sound. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 7 fields </span> </button><button type="button" data-pick-template="tutorial" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M4 4h16v12H4zM2 20h20M10 10l3 2-3 2v-4z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Tutorial </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Step-by-step how-to with presenter and clear cadence. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 8 fields </span> </button><button type="button" data-pick-template="testimonial" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M21 11.5a8.38 8.38 0 01-9 8.5 8.5 8.5 0 01-7.6-4.7L3 21l1.7-1.4A8.38 8.38 0 013 11.5 8.5 8.5 0 0111.5 3a8.38 8.38 0 019.5 8.5z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Testimonial </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Customer story focused on real problem and measurable outcome. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 8 fields </span> </button><button type="button" data-pick-template="seasonal-promo" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M12 2v6m0 8v6M4.93 4.93l4.24 4.24m5.66 5.66l4.24 4.24M2 12h6m8 0h6M4.93 19.07l4.24-4.24m5.66-5.66l4.24-4.24"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Seasonal promo </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Holiday / seasonal campaign: offer + audience + mood. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 8 fields </span> </button><button type="button" data-pick-template="fashion-tryon" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M16 2l5 4-3 3v13H6V9L3 6l5-4 2 2h4l2-2zM10 4l2 2 2-2"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> OOTD / try-on </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Fashion try-on: outfit, style, scene and season. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 7 fields </span> </button><button type="button" data-pick-template="food-review" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M3 11h18v6a4 4 0 01-4 4H7a4 4 0 01-4-4v-6zm3-6h12a3 3 0 013 3v1H3V8a3 3 0 013-3z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Food review </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Short food review or restaurant visit: vibe, narrator, pace. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 7 fields </span> </button><button type="button" data-pick-template="daily-vlog" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 7h8a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2V9a2 2 0 012-2z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Daily vlog </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Lifestyle day-in-the-life share: key moments, on-camera persona and pacing. Great for TikTok / YouTube / Reels. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 9 fields </span> </button><button type="button" data-pick-template="talking-head" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M12 15a4 4 0 004-4V6a4 4 0 00-8 0v5a4 4 0 004 4zM6 11a6 6 0 0012 0M12 19v3"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Talking head </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Opinion / value piece to camera: hook, key points and a closing CTA. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 9 fields </span> </button><button type="button" data-pick-template="trend-challenge" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-cente
354r rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M3 17l6-6 4 4 8-8M15 7h6v6"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Trend & challenge </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Ride a trending sound or challenge format with your own unique twist. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 8 fields </span> </button><button type="button" data-pick-template="listicle" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Listicle (Top N) </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Top N / countdown video: each item becomes a shot, high info density. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 8 fields </span> </button><button type="button" data-pick-template="live-shopping" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M4.93 4.93a10 10 0 000 14.14M19.07 4.93a10 10 0 010 14.14M7.76 7.76a6 6 0 000 8.49M16.24 7.76a6 6 0 010 8.49M12 11.5a.5.5 0 100 1 .5.5 0 000-1z"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Live shopping </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Live-commerce clip: offer mechanics, host script and urgency hooks. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 9 fields </span> </button><button type="button" data-pick-template="product-launch" class="group flex h-full flex-col items-start gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-start transition-colors hover:border-violet-400/50 hover:bg-white/[0.07]"> <span class="grid h-9 w-9 place-items-center rounded-xl bg-violet-500/15 text-violet-200 ring-1 ring-violet-400/30"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M3 11v2a1 1 0 001 1h2l4 4V6L6 10H4a1 1 0 00-1 1zM15 7a6 6 0 010 10"></path> </svg> </span> <h3 class="text-sm font-semibold text-white"> Product launch </h3> <p class="text-xs leading-relaxed text-zinc-400 group-hover:text-zinc-300"> Launch / marketing film: launch claim, key features and a strong CTA. </p> <span class="mt-auto rounded-full border border-white/10 bg-white/[0.04] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> 10 fields </span> </button> </div> </section> <section data-step="form" data-template-id="product-ad" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Product ad </h3> <p class="truncate text-xs text-zinc-400">Shoppable short-form: highlight selling points, platform tone and CTA.</p> </div> </header> <form data-tpl-form data-template-id="product-ad" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Product name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="productName" maxlength="60" placeholder="e.g. Gardenia bar soap" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key selling points <span class="ml-1 text-rose-400">*</span> </label> <textarea name="sellingPoints" rows="3" maxlength="240" placeholder="Comma-separated; 2â3 strongest" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Target audience </label> <input type="text" name="audience" maxlength="80" placeholder="e.g. women 25â35 valuing premium lifestyle" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Aspect ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Visual style </label> <div class="flex flex-wrap gap-2"> <label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="clean" class="sr-only"> <span>Clean & minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="vibrant" class="sr-only"> <span>Vibrant</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="warm" class="sr-only"> <span>Warm</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cinematic" class="sr-only"> <span>Cinematic</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cool" class="sr-only"> <span>Cool</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="playful" class="sr-only"> <span>Playful</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="minimal" class="sr-only"> <span>Minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="luxury" class="sr-only"> <span>Luxury</span> </label> </div> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Voice-over language </label> <select name="language" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focu
354s:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="en"> English </option><option value="zh"> Chinese </option><option value="es"> Spanish </option><option value="ja"> Japanese </option><option value="ko"> Korean </option><option value="hi"> Hindi </option><option value="id"> Indonesian </option><option value="ar"> Arabic </option><option value="pt_br"> Portuguese (BR) </option><option value="fr"> French </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Closing CTA </label> <input type="text" name="cta" maxlength="80" placeholder="e.g. Shop now, 10% off this week" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="brand-hero" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Brand hero </h3> <p class="truncate text-xs text-zinc-400">Brand positioning hero film: mood, scene and pacing in one piece.</p> </div> </header> <form data-tpl-form data-template-id="brand-hero" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Brand name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="brandName" maxlength="60" placeholder="e.g. Bloom" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Featured product (optional) </label> <input type="text" name="productName" maxlength="60" placeholder="Only if focused on one SKU" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Brand positioning <span class="ml-1 text-rose-400">*</span> </label> <textarea name="positioning" rows="3" maxlength="200" placeholder="One sentence: who you are, who you serve" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key message </label> <input type="text" name="keyMessage" maxlength="120" placeholder="One line you want viewers to remember" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Scene setting </label> <input type="text" name="scene" maxlength="100" placeholder="e.g. modern kitchen, minimal Scandinavian living room" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Aspect ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Mood </label> <select name="mood" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="calm"> Calm </option><option value="energetic"> Energetic </option><option value="professional"> Professional </option><option value="playful"> Playful </option><option value="dramatic"> Dramatic </option><option value="soothing"> Soothing </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="unboxing" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Unboxing </h3> <p class="truncate text-xs text-zinc-400">First-impression unbox driven by packaging detail and sound.</p> </div> </header> <form data-tpl-form data-template-id="unboxing" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Product name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="productName" maxlength="60" placeholder="e.g. wireless earbuds" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Packaging detail </label> <textarea name="packagingNotes" rows="3" maxlength="200" placeholder="Material, colorway, what is inside" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Narrator persona </label> <input type="text" name="narratorPersona" maxlength="80" placeholder="e.g. tech reviewer, lifestyle creator" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="tutorial" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Tutorial </h3> <p class="truncate text-xs text-zinc-400">Step-by-step how-to with presenter and clear cadence.</p> </div> </header> <form data-tpl-form data-template-id="tutorial" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Tutorial topic <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="topic" maxlength="80" placeholder="e.g. 3-step quick makeup" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key steps <span class="ml-1 text-rose-400">*</span> </label> <textarea name="steps" rows="3" maxlength="260" placeholder="Numbered steps; AI will translate to shots" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Audience </label> <input type="text" name="audience" maxlength="80" placeholder="e.g. makeup beginners" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Presenter persona </label> <input type="text" name="presenterPersona" maxlength="80" placeholder="e.g. gentle, patient beauty teacher" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Tone </label> <select name="tone" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="casual"> Casual </option><option value="professional"> Professional </option><option value="expert"> Expert </option><option value="friendly"> Friendly </option><option value="authoritative"> Authoritative </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="testimonial" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Testimonial </h3> <p class="truncate text-xs text-zinc-400">Customer story focused on real problem and measurable outcome.</p> </div> </header> <form data-tpl-form data-template-id="testimonial" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Related product <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="productName" maxlength="60" placeholder="e.g. smart vacuum robot" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Featured persona <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="persona" maxlength="80" placeholder="e.g. working mom of two, 30" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Original problem </label> <textarea name="problem" rows="3" maxlength="160" placeholder="Concrete pain before using" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Outcome </label> <textarea name="outcome" rows="3" maxlength="160" placeholder="Quantifiable improvement" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Scene </label> <input type="text" name="scene" maxlength="100" placeholder="e.g. their own living room" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Language </label> <select name="language" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="en"> English </option><option value="zh"> Chinese </option><option value="es"> Spanish </option><option value="ja"> Japanese </option><option value="ko"> Korean </option><option value="hi"> Hindi </option><option value="id"> Indonesian </option><option value="ar"> Arabic </option><option value="pt_br"> Portuguese (BR) </option><option value="fr"> French </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="seasonal-promo" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Seasonal promo </h3> <p class="truncate text-xs text-zinc-400">Holiday / seasonal campaign: offer + audience + mood.</p> </div> </header> <form data-tpl-form data-template-id="seasonal-promo" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Holiday / moment <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="holiday" maxlength="60" placeholder="e.g. Black Friday, Lunar New Year, Christmas" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Brand name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="brandName" maxlength="60" placeholder="e.g. Bloom" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Featured offer <span class="ml-1 text-rose-400">*</span> </label> <textarea name="offer" rows="3" maxlength="200" placeholder="Specific discount / gift / drop" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Audience </label> <input type="text" name="audience" maxlength="80" placeholder="e.g. young couples" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Mood </label> <select name="mood" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="calm"> Calm </option><option value="energetic"> Energetic </option><option value="professional"> Professional </option><option value="playful"> Playful </option><option value="dramatic"> Dramatic </option><option value="soothing"> Soothing </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="fashion-tryon" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> OOTD / try-on </h3> <p class="truncate text-xs text-zinc-400">Fashion try-on: outfit, style, scene and season.</p> </div> </header> <form data-tpl-form data-template-id="fashion-tryon" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Outfit pieces <span class="ml-1 text-rose-400">*</span> </label> <textarea name="itemList" rows="3" maxlength="200" placeholder="List each piece of the outfit" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Season </label> <select name="season" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="spring"> Spring </option><option value="summer"> Summer </option><option value="autumn"> Autumn </option><option value="winter"> Winter </option> </select> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Style </label> <div class="flex flex-wrap gap-2"> <label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="clean" class="sr-only"> <span>Clean & minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="vibrant" class="sr-only"> <span>Vibrant</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="warm" class="sr-only"> <span>Warm</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cinematic" class="sr-only"> <span>Cinematic</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cool" class="sr-only"> <span>Cool</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="playful" class="sr-only"> <span>Playful</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="minimal" class="sr-only"> <span>Minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="luxury" class="sr-only"> <span>Luxury</span> </label> </div> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Scene </label> <input type="text" name="scene" maxlength="100" placeholder="e.g. urban street style, cafe" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Model persona </label> <input type="text" name="modelPersona" maxlength="80" placeholder="e.g. tall, cool aesthetic" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="food-review" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Food review </h3> <p class="truncate text-xs text-zinc-400">Short food review or restaurant visit: vibe, narrator, pace.</p> </div> </header> <form data-tpl-form data-template-id="food-review" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Dish <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="dish" maxlength="60" placeholder="e.g. handmade black truffle pasta" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Venue (optional) </label> <input type="text" name="venueName" maxlength="80" placeholder="Fill if reviewing a restaurant" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Vibe </label> <input type="text" name="vibe" maxlength="100" placeholder="e.g. Japanese izakaya warm lights" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Narrator persona </label> <input type="text" name="narratorPersona" maxlength="80" placeholder="e.g. food blogger" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="daily-vlog" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Daily vlog </h3> <p class="truncate text-xs text-zinc-400">Lifestyle day-in-the-life share: key moments, on-camera persona and pacing. Great for TikTok / YouTube / Reels.</p> </div> </header> <form data-tpl-form data-template-id="daily-vlog" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Theme <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="theme" maxlength="80" placeholder="e.g. a cozy work-from-home day, weekend city walk" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key moments <span class="ml-1 text-rose-400">*</span> </label> <textarea name="moments" rows="3" maxlength="260" placeholder="List 3â5 moments to capture; AI splits into shots" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Location </label> <input type="text" name="location" maxlength="100" placeholder="e.g. home, cafe, city streets" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> On-camera persona </label> <input type="text" name="narratorPersona" maxlength="80" placeholder="e.g. warm, cozy lifestyle creator" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Mood </label> <select name="mood" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="calm"> Calm </option><option value="energetic"> Energetic </option><option value="professional"> Professional </option><option value="playful"> Playful </option><option value="dramatic"> Dramatic </option><option value="soothing"> Soothing </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focu
354s:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="talking-head" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Talking head </h3> <p class="truncate text-xs text-zinc-400">Opinion / value piece to camera: hook, key points and a closing CTA.</p> </div> </header> <form data-tpl-form data-template-id="talking-head" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Topic <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="topic" maxlength="80" placeholder="e.g. why I quit my 9â5, 3 habits that changed my life" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key points <span class="ml-1 text-rose-400">*</span> </label> <textarea name="keyPoints" rows="3" maxlength="240" placeholder="2â3 main points or punchy takeaways" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Opening hook </label> <input type="text" name="hook" maxlength="120" placeholder="A first line that stops the scroll" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Presenter persona </label> <input type="text" name="presenterPersona" maxlength="80" placeholder="e.g. sharp yet friendly career creator" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote">
354 Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Tone </label> <select name="tone" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="casual"> Casual </option><option value="professional"> Professional </option><option value="expert"> Expert </option><option value="friendly"> Friendly </option><option value="authoritative"> Authoritative </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Closing CTA </label> <input type="text" name="cta" maxlength="80" placeholder="e.g. follow for more" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="trend-challenge" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Trend & challenge </h3> <p class="truncate text-xs text-zinc-400">Ride a trending sound or challenge format with your own unique twist.</p> </div> </header> <form data-tpl-form data-template-id="trend-challenge" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Trend / sound <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="trendName" maxlength="80" placeholder="Trending song, meme or challenge format" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Your twist <span class="ml-1 text-rose-400">*</span> </label> <textarea name="twist" rows="3" maxlength="220" placeholder="Your unique take or punchline" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Tie-in topic / product </label> <input type="text" name="productOrTopic" maxlength="100" placeholder="What you tie the trend to" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Visual style </label> <div class="flex flex-wrap gap-2"> <label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="clean" class="sr-only"> <span>Clean & minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="vibrant" class="sr-only"> <span>Vibrant</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="warm" class="sr-only"> <span>Warm</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cinematic" class="sr-only"> <span>Cinematic</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="cool" class="sr-only"> <span>Cool</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="playful" class="sr-only"> <span>Playful</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="minimal" class="sr-only"> <span>Minimal</span> </label><label class="inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs text-zinc-300 transition-colors hover:border-violet-400/40 has-[:checked]:border-violet-400/60 has-[:checked]:bg-violet-500/15 has-[:checked]:text-white"> <input type="checkbox" name="style" value="luxury" class="sr-only"> <span>Luxury</span> </label> </div> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focu
354s:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="listicle" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Listicle (Top N) </h3> <p class="truncate text-xs text-zinc-400">Top N / countdown video: each item becomes a shot, high info density.</p> </div> </header> <form data-tpl-form data-template-id="listicle" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> List topic <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="topic" maxlength="80" placeholder="e.g. 5 budget travel hacks" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> List items <span class="ml-1 text-rose-400">*</span> </label> <textarea name="items" rows="3" maxlength="280" placeholder="List each item; AI splits into shots" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Audience </label> <input type="text" name="audience" maxlength="80" placeholder="e.g. students on a tight budget" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Narrator persona </label> <input type="text" name="narratorPersona" maxlength="80" placeholder="e.g. value-packed knowledge creator" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote">
354 Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Tone </label> <select name="tone" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="casual"> Casual </option><option value="professional"> Professional </option><option value="expert"> Expert </option><option value="friendly"> Friendly </option><option value="authoritative"> Authoritative </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="live-shopping" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Live shopping </h3> <p class="truncate text-xs text-zinc-400">Live-commerce clip: offer mechanics, host script and urgency hooks.</p> </div> </header> <form data-tpl-form data-template-id="live-shopping" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Product name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="productName" maxlength="60" placeholder="e.g. collagen serum" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Offer mechanics <span class="ml-1 text-rose-400">*</span> </label> <textarea name="offer" rows="3" maxlength="200" placeholder="Price, bundle, limited-time deal" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Host persona </label> <input type="text" name="hostPersona" maxlength="80" placeholder="e.g. high-energy beauty host" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Urgency hook </label> <input type="text" name="urgency" maxlength="100" placeholder="e.g. only 100 left, ends tonight" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Pacing </label> <select name="pace" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="slow"> Slow </option><option value="medium"> Medium </option><option value="fast"> Fast </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Spoken language </label> <select name="language" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="en"> English </option><option value="zh"> Chinese </option><option value="es"> Spanish </option><option value="ja"> Japanese </option><option value="ko"> Korean </option><option value="hi"> Hindi </option><option value="id"> Indonesian </option><option value="ar"> Arabic </option><option value="pt_br"> Portuguese (BR) </option><option value="fr"> French </option> </select> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section><section data-step="form" data-template-id="product-launch" hidden class="flex flex-col gap-5"> <header class="flex items-center justify-between gap-3"> <button type="button" data-tpl-back class="inline-flex items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-3.5 w-3.5" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"></path> </svg> Back </button> <div class="min-w-0 text-end"> <h3 class="truncate font-display text-lg font-semibold text-white"> Product launch </h3> <p class="truncate text-xs text-zinc-400">Launch / marketing film: launch claim, key features and a strong CTA.</p> </div> </header> <form data-tpl-form data-template-id="product-launch" class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Product name <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="productName" maxlength="60" placeholder="e.g. gen-2 noise-cancelling earbuds" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focu
354s:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Brand name (optional) </label> <input type="text" name="brandName" maxlength="60" placeholder="e.g. Bloom" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Launch claim <span class="ml-1 text-rose-400">*</span> </label> <input type="text" name="headline" maxlength="120" placeholder="One line on the biggest new highlight" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 sm:col-span-2"> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Key features <span class="ml-1 text-rose-400">*</span> </label> <textarea name="features" rows="3" maxlength="240" placeholder="Top 2â3 features worth showing" class="min-h-[5rem] w-full resize-y rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"></textarea> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Audience </label> <input type="text" name="audience" maxlength="80" placeholder="e.g. commuters who care about sound" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Platform </label> <select name="platform" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="tiktok"> TikTok </option><option value="reels"> Instagram Reels </option><option value="shorts"> YouTube Shorts </option><option value="facebook"> Facebook </option><option value="snapchat"> Snapchat </option><option value="pinterest"> Pinterest </option><option value="x"> X </option><option value="rednote"> Xiaohongshu </option><option value="youtube_long"> YouTube long-form </option><option value="pdp"> E-commerce PDP </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Ratio </label> <select name="ratio" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="9_16"> 9:16 portrait </option><option value="1_1"> 1:1 square </option><option value="16_9"> 16:9 landscape </option><option value="4_5"> 4:5 feed </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Duration </label> <select name="duration" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focus:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="5s"> 5 seconds </option><option value="8s"> 8 seconds </option><option value="10s"> 10 seconds </option><option value="15s"> 15 seconds </option><option value="30s"> 30 seconds </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Mood </label> <select name="mood" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all focus:border-violet-400/40 focu
354s:ring-violet-400/20"> <option value="">Optional â chooseâ¦</option> <option value="calm"> Calm </option><option value="energetic"> Energetic </option><option value="professional"> Professional </option><option value="playful"> Playful </option><option value="dramatic"> Dramatic </option><option value="soothing"> Soothing </option> </select> </div><div class="flex flex-col gap-1.5 "> <label class="text-[11px] font-semibold uppercase tracking-[0.18em] text-zinc-400"> Call to action </label> <input type="text" name="cta" maxlength="80" placeholder="e.g. pre-order the launch now" class="w-full rounded-xl border border-white/10 bg-ink-950/60 px-3 py-2 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> </div> <footer class="flex flex-wrap items-center justify-end gap-2 sm:col-span-2"> <p data-tpl-error hidden class="me-auto rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-200"></p> <button type="reset" data-tpl-reset class="rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> Reset </button> <button type="submit" class="btn-primary"> Insert into brief </button> </footer> </form> </section> </div> </dialog>
354<script type="application/json" data-pg-tpl-i18n>{"pg.opt.platform.tiktok":"TikTok","pg.opt.platform.reels":"Instagram Reels","pg.opt.platform.shorts":"YouTube Shorts","pg.opt.platform.facebook":"Facebook","pg.opt.platform.snapchat":"Snapchat","pg.opt.platform.pinterest":"Pinterest","pg.opt.platform.x":"X","pg.opt.platform.rednote":"Xiaohongshu","pg.opt.platform.youtube_long":"YouTube long-form","pg.opt.platform.pdp":"E-commerce PDP","pg.opt.ratio.9_16":"9:16 portrait","pg.opt.ratio.1_1":"1:1 square","pg.opt.ratio.16_9":"16:9 landscape","pg.opt.ratio.4_5":"4:5 feed","pg.opt.duration.5s":"5 seconds","pg.opt.duration.8s":"8 seconds","pg.opt.duration.10s":"10 seconds","pg.opt.duration.15s":"15 seconds","pg.opt.duration.30s":"30 seconds","pg.opt.language.en":"English","pg.opt.language.zh":"Chinese","pg.opt.language.es":"Spanish","pg.opt.language.ja":"Japanese","pg.opt.language.ko":"Korean","pg.opt.language.hi":"Hindi","pg.opt.language.id":"Indonesian","pg.opt.language.ar":"Arabic","pg.opt.language.pt_br":"Portuguese (BR)","pg.opt.language.fr":"French","pg.opt.style.clean":"Clean & minimal","pg.opt.style.vibrant":"Vibrant","pg.opt.style.warm":"Warm","pg.opt.style.cinematic":"Cinematic","pg.opt.style.cool":"Cool","pg.opt.style.playful":"Playful","pg.opt.style.minimal":"Minimal","pg.opt.style.luxury":"Luxury","pg.opt.pace.slow":"Slow","pg.opt.pace.medium":"Medium","pg.opt.pace.fast":"Fast","pg.opt.mood.calm":"Calm","pg.opt.mood.energetic":"Energetic","pg.opt.mood.professional":"Professional","pg.opt.mood.playful":"Playful","pg.opt.mood.dramatic":"Dramatic","pg.opt.mood.soothing":"Soothing","pg.opt.tone.casual":"Casual","pg.opt.tone.professional":"Professional","pg.opt.tone.expert":"Expert","pg.opt.tone.friendly":"Friendly","pg.opt.tone.authoritative":"Authoritative","pg.opt.season.spring":"Spring","pg.opt.season.summer":"Summer","pg.opt.season.autumn":"Autumn","pg.opt.season.winter":"Winter"}</script>
354
354<script type="module" src="/_astro/PromptTemplatesModal.astro_astro_type_script_index_0_lang.C8Vn1fa3.js"></script>
354 <section class="pb-24" aria-labelledby="pg-faq-title"> <div class="container-x"> <div class="reveal mx-auto max-w-3xl"> <h2 id="pg-faq-title" class="section-title">About this prompt generator</h2> <div class="mt-8 space-y-4"> <details class="group rounded-2xl border border-white/10 bg-white/[0.03] p-5 transition-colors hover:border-violet-400/40"> <summary class="flex cursor-pointer list-none items-center justify-between gap-4 text-base font-semibold text-zinc-100"> <span>Why write a dedicated prompt for Gemini Omni?</span> <svg viewBox="0 0 24 24" class="h-4 w-4 shrink-0 text-zinc-400 transition-transform group-open:rotate-180" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"></path> </svg> </summary> <p class="mt-3 text-sm leading-relaxed text-zinc-400">Omni renders picture and sound in the same forward pass, so a good prompt has to declare camera moves, pacing, lighting and audio together â that is what keeps the output stable and publishable.</p> </details><details class="group rounded-2xl border border-white/10 bg-white/[0.03] p-5 transition-colors hover:border-violet-400/40"> <summary class="flex cursor-pointer list-none items-center justify-between gap-4 text-base font-semibold text-zinc-100"> <span>Where does my brief get sent?</span> <svg viewBox="0 0 24 24" class="h-4 w-4 shrink-0 text-zinc-400 transition-transform group-open:rotate-180" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"></path> </svg> </summary> <p class="mt-3 text-sm leading-relaxed text-zinc-400">Your text is sent to our Agent endpoint, which rewrites it into a structured Omni prompt. You need to sign in; each generation uses a small amount of your account quota.</p> </details><details class="group rounded-2xl border border-white/10 bg-white/[0.03] p-5 transition-colors hover:border-violet-400/40"> <summary class="flex cursor-pointer list-none items-center justify-between gap-4 text-base font-semibold text-zinc-100"> <span>Can I paste the result straight into Gemini Omni?</span> <svg viewBox="0 0 24 24" class="h-4 w-4 shrink-0 text-zinc-400 transition-transform group-open:rotate-180" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"></path> </svg> </summary> <p class="mt-3 text-sm leading-relaxed text-zinc-400">Yes. The output is a multi-shot script you can paste into the Gemini app video panel and continue to refine through chat-style editing inside Omni.</p> </details> </div> </div> </div> </section>
354<script>(function(){const API_BASE = "https://www.gushanai.com/api"; 355const APP_KEY = "gemini_omni_4561"; 356const LANG = "en"; 357 358 (() => { 359 if (typeof window === 'undefined') return; 360 const form = document.querySelector('[data-pg-form]'); 361 if (!form) return; 362 363 const AUTH_TOKEN_KEY = 'auth_token'; 364 const AUTH_CHANGED_EVENT = 'gemini-omni:auth-changed'; 365 366 const root = document.querySelector('[data-pg-root]'); 367 const input = form.querySelector('[data-pg-input]'); 368 const submitBtn = form.querySelector('[data-pg-submit]'); 369 const idleLabel = form.querySelector('[data-pg-label-idle]'); 370 const loadingLabel = form.querySelector('[data-pg-label-loading]'); 371 const errorEl = form.querySelector('[data-pg-error]'); 372 const output = form.querySelector('[data-pg-output]'); 373 const skeleton = form.querySelector('[data-pg-skeleton]'); 374 const copyBtn = form.querySelector('[data-pg-copy]'); 375 const copyLabel = form.querySelector('[data-pg-copy-label]'); 376 const counterEl = form.querySelector('[data-pg-counter]'); 377 const openTemplatesBtn = form.querySelector('[data-pg-open-templates]'); 378 const exampleBtns = document.querySelectorAll('[data-pg-example]'); 379 const costBadge = form.querySelector('[data-pg-cost]'); 380 const costTextEl = form.querySelector('[data-pg-cost-text]'); 381 const costTemplate = costBadge?.getAttribute('data-pg-cost-template') || ''; 382 const MODEL_CODE = 'PROMPT_VIDEO_BEST'; 383 384 const MAX_LEN = 1000; 385 const WARN_LEN = 900; 386 387 const emptyText = output?.textContent ?? ''; 388 const errorEmpty = form.dataset.errorEmpty || 'Please write your creative brief first.'; 389 const errorGeneric = form.dataset.errorGeneric || 'Could not generate a prompt. Please try again.'; 390 const loginRequiredText = form.dataset.loginRequired || 'Sign in to generate prompts.'; 391 const copyIdle = form.dataset.copyIdle || 'Copy'; 392 const copySuccess = form.dataset.copySuccess || 'Copied'; 393 const copyFailed = form.dataset.copyFailed || 'Copy failed'; 394 395 let pendingAfterLogin = false; 396 let copyResetTimer = null; 397 398 const setError = (msg) => { 399 if (!errorEl) return; 400 if (!msg) { 401 errorEl.setAttribute('hidden', ''); 402 errorEl.textContent = ''; 403 return; 404 } 405 errorEl.textContent = msg; 406 errorEl.removeAttribute('hidden'); 407 }; 408 409 const updateCounter = () => { 410 if (!counterEl || !input) return; 411 const used = (input.value || '').length; 412 counterEl.textContent = `${used} / ${MAX_LEN}`; 413 counterEl.classList.remove('text-zinc-500', 'text-amber-400', 'text-rose-400'); 414 if (used >= MAX_LEN) { 415 counterEl.classList.add('text-rose-400'); 416 } else if (used >= WARN_LEN) { 417 counterEl.classList.add('text-amber-400'); 418 } else { 419 counterEl.classList.add('text-zinc-500'); 420 } 421 }; 422 423 const setLoading = (loading) => { 424 if (!submitBtn) return; 425 submitBtn.toggleAttribute('disabled', loading); 426 idleLabel?.toggleAttribute('hidden', loading); 427 loadingLabel?.toggleAttribute('hidden', !loading); 428 skeleton?.toggleAttribute('hidden', !loading); 429 if (loading && output) { 430 output.dataset.empty = '1'; 431 output.textContent = ''; 432 output.classList.remove('text-zinc-100'); 433 output.classList.add('text-zinc-500'); 434 } 435 }; 436 437 const setOutput = (text) => { 438 if (!output) return; 439 output.textContent = text; 440 output.dataset.empty = text ? '0' : '1'; 441 if (text) { 442 output.classList.remove('text-zinc-500'); 443 output.classList.add('text-zinc-100'); 444 } else { 445 output.classList.add('text-zinc-500'); 446 output.classList.remove('text-zinc-100'); 447 output.textContent = emptyText; 448 } 449 if (copyBtn) { 450 copyBtn.toggleAttribute('disabled', !text); 451 } 452 }; 453 454 const getToken = () => { 455 try { 456 return window.localStorage.getItem(AUTH_TOKEN_KEY); 457 } catch { 458 return null; 459 } 460 }; 461 462 const syncAuthState = () => { 463 if (!root) return; 464 root.setAttribute('data-pg-signed-in', getToken() ? 'true' : 'false'); 465 }; 466 467 const openLogin = () => { 468 window.dispatchEvent(new CustomEvent('open-login')); 469 }; 470 471 const updateCostBadge = (cost) => { 472 if (!costTextEl || !costTemplate) return; 473 const value = typeof cost === 'number' && Number.isFinite(cost) ? cost : 1; 474 costTextEl.textContent = costTemplate.replace('{cost}', String(value)); 475 }; 476 477 const fetchCostConfig = async () => {
478 try { 479 const token = getToken(); 480 const headers = { 'Content-Type': 'application/json', 'x-app-key': APP_KEY, 'x-model-code': MODEL_CODE }; 481 if (token) headers.Authorization = token; 482 const res = await fetch(`${API_BASE}/config/aicost`, { 483 method: 'GET', 484 headers: headers, 485 }); 486 if (!res.ok) return; 487 const env = await res.json(); 488 if (!env || (env.code !== 200 && env.code !== 0)) return; 489 const items = Array.isArray(env.data) ? env.data : []; 490 const match = items.find((x) => x && x.code === MODEL_CODE); 491 if (match && typeof match.aiModelCost === 'number') { 492 updateCostBadge(match.aiModelCost); 493 } 494 } catch {} 495 }; 496 497 const callAgent = async (prompt) => { 498 const token = getToken(); 499 const headers = { 'Content-Type': 'application/json', 'x-app-key': APP_KEY, 'x-model-code': MODEL_CODE }; 500 if (token) headers.Authorization = token; 501 const res = await fetch(`${API_BASE}/agent/ai`, { 502 method: 'POST', 503 headers, 504 body: JSON.stringify({ prompt, lang: LANG }), 505 }); 506 let env; 507 try { 508 env = await res.json(); 509 } catch { 510 env = { code: res.status, msg: `HTTP ${res.status}` }; 511 } 512 const ok = env && (env.code === 200 || env.code === 0); 513 if (!ok) { 514 const err = new Error(env?.msg || env?.message || `HTTP ${res.status}`); 515 err.code = env?.code ?? res.status; 516 err.status = res.status; 517 throw err; 518 } 519 return env.data; 520 }; 521 522 const generate = async () => { 523 const text = (input?.value || '').trim(); 524 setError(''); 525 if (!text) { 526 setError(errorEmpty); 527 input?.focus(); 528 return; 529 } 530 if (!getToken()) { 531 pendingAfterLogin = true; 532 setError(loginRequiredText); 533 openLogin(); 534 return; 535 } 536 setLoading(true);
537 try { 538 const data = await callAgent(text); 539 const value = typeof data === 'string' ? data : JSON.stringify(data, null, 2); 540 setOutput(value); 541 setError(''); 542 try { 543 window.dispatchEvent(new CustomEvent('gemini-omni:refresh-user')); 544 } catch {} 545 } catch (err) { 546 const status = err && (err.status || err.code); 547 if (status === 401 || status === 403) { 548 try { 549 window.localStorage.removeItem(AUTH_TOKEN_KEY); 550 window.localStorage.removeItem('user_info'); 551 } catch {} 552 window.dispatchEvent(new CustomEvent(AUTH_CHANGED_EVENT, { detail: { token: null, user: null } })); 553 pendingAfterLogin = true; 554 setError(loginRequiredText); 555 openLogin(); 556 } else if (status === 789) { 557 try { 558 window.dispatchEvent(new CustomEvent('gemini-omni:refresh-user')); 559 } catch {} 560 window.dispatchEvent(new CustomEvent('gemini-omni:open-recharge')); 561 setError(err?.message || ''); 562 setOutput(''); 563 } else { 564 setError(err?.message || errorGeneric); 565 setOutput(''); 566 } 567 } finally { 568 setLoading(false); 569 } 570 }; 571 572 form.addEventListener('submit', (e) => { 573 e.preventDefault(); 574 generate(); 575 }); 576 577 input?.addEventListener('input', updateCounter); 578 579 openTemplatesBtn?.addEventListener('click', () => { 580 window.dispatchEvent(new CustomEvent('pg-templates-open')); 581 }); 582 583 window.addEventListener('pg-templates-insert', (ev) => { 584 const detail = ev && ev.detail; 585 const brief = (detail && detail.brief) || ''; 586 if (!input) return; 587 input.value = brief.slice(0, MAX_LEN); 588 input.focus(); 589 try { 590 input.setSelectionRange(input.value.length, input.value.length); 591 } catch {} 592 updateCounter(); 593 setError(''); 594 }); 595 596 exampleBtns.forEach((btn) => { 597 btn.addEventListener('click', () => { 598 const brief = btn.getAttribute('data-pg-example-brief') || ''; 599 if (input) { 600 input.value = brief.slice(0, MAX_LEN); 601 input.focus(); 602 input.setSelectionRange(input.value.length, input.value.length); 603 updateCounter(); 604 } 605 setError(''); 606 }); 607 }); 608 609 updateCounter(); 610 611 copyBtn?.addEventListener('click', async () => { 612 const text = output?.dataset.empty === '0' ? output.textContent || '' : ''; 613 if (!text) return; 614 if (copyResetTimer) { 615 clearTimeout(copyResetTimer); 616 copyResetTimer = null; 617 } 618 const resetLabel = () => { 619 if (copyLabel) copyLabel.textContent = copyIdle; 620 }; 621 try { 622 if (navigator.clipboard && navigator.clipboard.writeText) { 623 await navigator.clipboard.writeText(text); 624 } else { 625 const tmp = document.createElement('textarea'); 626 tmp.value = text; 627 tmp.setAttribute('readonly', ''); 628 tmp.style.position = 'absolute'; 629 tmp.style.left = '-9999px'; 630 document.body.appendChild(tmp); 631 tmp.select(); 632 document.execCommand('copy'); 633 document.body.removeChild(tmp); 634 } 635 if (copyLabel) copyLabel.textContent = copySuccess; 636 copyResetTimer = window.setTimeout(resetLabel, 1800); 637 } catch { 638 if (copyLabel) copyLabel.textContent = copyFailed; 639 copyResetTimer = window.setTimeout(resetLabel, 2400); 640 } 641 }); 642 643 window.addEventListener(AUTH_CHANGED_EVENT, (ev) => { 644 const detail = ev && ev.detail; 645 const token = detail && detail.token; 646 syncAuthState(); 647 if (token && pendingAfterLogin) { 648 pendingAfterLogin = false; 649 setError(''); 650 if ((input?.value || '').trim()) { 651 generate(); 652 } 653 } 654 }); 655 656 syncAuthState(); 657 fetchCostConfig(); 658 })(); 659})();</script>
659 </main> <footer class="mt-32 border-t border-white/5"> <div class="container-x grid gap-10 py-12 lg:grid-cols-[1.6fr_1fr_1fr]"> <div> <a href="/" class="inline-flex items-center gap-2.5 font-display text-base font-semibold text-white"> <span class="grid h-7 w-7 place-items-center rounded-lg bg-brand-gradient text-ink-950 shadow-glow"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="currentColor" d="M12 2l1.7 7.3L21 11l-7.3 1.7L12 20l-1.7-7.3L3 11l7.3-1.7L12 2z"></path> </svg> </span> <span>Gemini Omni</span> </a> <p class="mt-4 max-w-md text-sm leading-relaxed text-zinc-500">Unofficial info hub. Content is aggregated from public reporting and community leaks. Gemini, Omni and related marks belong to Google.</p> <p class="mt-4 text-sm text-zinc-400"> <span class="text-zinc-500">Contact:</span> <a class="ml-1 text-white hover:underline" href="mailto:[email protected]">[email protected]</a> </p> </div> <div> <h2 class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400">Quick links</h2> <ul class="mt-4 grid grid-cols-2 gap-y-2 text-sm text-zinc-400"> <li><a class="hover:text-white" href="/#showcase">Demos</a></li> <li><a class="hover:text-white" href="/#features">Features</a></li> <li><a class="hover:text-white" href="/#specs">Specs</a></li> <li><a class="hover:text-white" href="/#architecture">Architecture</a></li> <li><a class="hover:text-white" href="/#cases">Use cases</a></li> <li><a class="hover:text-white" href="/#comparison">Compare</a></li> <li><a class="hover:text-white" href="/#free">Free vs paid</a></li> <li><a class="hover:text-white" href="/#timeline">Timeline</a></li> <li><a class="hover:text-white" href="/prompt-generator/">Prompt builder</a></li> <li><a class="hover:text-white" href="/video-studio/">Video Studio</a></li> <li><a class="hover:text-white" href="/pricing/">Pricing</a></li> <li><a class="hover:text-white" href="/blog/">Articles</a></li> <li><a class="hover:text-white" href="/#faq">FAQ</a></li> <li><a class="hover:text-white" href="/#sources">Sources</a></li> </ul> </div> <div> <h2 class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400">Language</h2> <ul class="mt-4 grid max-h-72 grid-cols-2 gap-y-2 overflow-y-auto overscroll-contain pr-2 text-sm text-zinc-400 sm:grid-cols-3 sm:max-h-64"> <li> <a class="hover:text-white text-white font-medium" href="/prompt-generator" hreflang="en"> English </a> </li><li> <a class="hover:text-white " href="/es/prompt-generator" hreflang="es"> Español </a> </li><li> <a class="hover:text-white " href="/it/prompt-generator" hreflang="it"> Italiano </a> </li><li> <a class="hover:text-white " href="/hi/prompt-generator" hreflang="hi"> हिनà¥à¤¦à¥ </a> </li><li> <a class="hover:text-white " href="/ar/prompt-generator" hreflang="ar"> Ø§ÙØ¹Ø±Ø¨ÙØ© </a> </li><li> <a class="hover:text-white " href="/zh/prompt-generator" hreflang="zh"> 䏿 </a> </li><li> <a class="hover:text-white " href="/ja/prompt-generator" hreflang="ja"> æ¥æ¬èª </a> </li><li> <a class="hover:text-white " href="/ko/prompt-generator" hreflang="ko"> íêµì´ </a> </li><li> <a class="hover:text-white " href="/fr/prompt-generator" hreflang="fr"> Français </a> </li><li> <a class="hover:text-white " href="/de/prompt-generator" hreflang="de"> Deutsch </a> </li><li> <a class="hover:text-white " href="/nl/prompt-generator" hreflang="nl"> Nederlands </a> </li><li> <a class="hover:text-white " href="/pl/prompt-generator" hreflang="pl"> Polski </a> </li><li> <a class="hover:text-white " href="/pt-BR/prompt-generator" hreflang="pt-BR"> Português </a> </li><li> <a class="hover:text-white " href="/ru/prompt-generator" hreflang="ru"> Ð ÑÑÑкий </a> </li><li> <a class="hover:text-white " href="/tr/prompt-generator" hreflang="tr"> Türkçe </a> </li><li> <a class="hover:text-white " href="/id/prompt-generator" hreflang="id"> Bahasa Indonesia </a> </li><li> <a class="hover:text-white " href="/vi/prompt-generator" hreflang="vi"> Tiếng Viá»t </a> </li><li> <a class="hover:text-white " href="/th/prompt-generator" hreflang="th">
659 à¹à¸à¸¢ </a> </li><li> <a class="hover:text-white " href="/ms/prompt-generator" hreflang="ms"> Bahasa Melayu </a> </li><li> <a class="hover:text-white " href="/tl/prompt-generator" hreflang="tl"> Filipino </a> </li><li> <a class="hover:text-white " href="/bn/prompt-generator" hreflang="bn"> বাà¦à¦²à¦¾ </a> </li><li> <a class="hover:text-white " href="/ta/prompt-generator" hreflang="ta"> தமிழ௠</a> </li><li> <a class="hover:text-white " href="/te/prompt-generator" hreflang="te"> à°¤à±à°²à±à°à± </a> </li><li> <a class="hover:text-white " href="/mr/prompt-generator" hreflang="mr"> मराठॠ</a> </li><li> <a class="hover:text-white " href="/he/prompt-generator" hreflang="he"> ×¢×ר×ת </a> </li><li> <a class="hover:text-white " href="/fa/prompt-generator" hreflang="fa"> ÙØ§Ø±Ø³Û </a> </li><li> <a class="hover:text-white " href="/ur/prompt-generator" hreflang="ur"> ارد٠</a> </li> </ul> </div> </div> <div class="border-t border-white/5"> <div class="container-x flex flex-col gap-3 py-5 text-xs text-zinc-500 sm:flex-row sm:items-center sm:justify-between"> <div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4"> <p>© 2026 Gemini Omni Info Hub</p> <nav class="flex flex-wrap gap-x-4 gap-y-1" aria-label="Legal"> <a class="hover:text-white" href="/terms/">Terms of Service</a> <a class="hover:text-white" href="/privacy/">Privacy Policy</a> </nav> </div> <p>Built with Astro · Tailwind</p> </div> </div> </footer> <dialog id="login-modal" class="hidden w-[min(440px,calc(100vw-24px))] rounded-3xl border border-white/10 bg-ink-900/95 p-0 text-zinc-100 shadow-glow backdrop:bg-ink-950/70 backdrop:backdrop-blur-md open:flex open:flex-col" aria-labelledby="login-modal-title"> <div class="relative max-h-[min(720px,90vh)] overflow-y-auto px-7 pb-8 pt-9 sm:px-9"> <button type="button" data-close aria-label="Close" class="absolute right-3 top-3 grid h-9 w-9 place-items-center rounded-full border border-white/10 bg-white/[0.04] text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" d="M6 6l12 12M18 6L6 18"></path> </svg> </button> <div data-state="form" class="flex flex-col gap-6"> <header class="flex flex-col items-center text-center"> <span class="mb-4 grid h-14 w-14 place-items-center rounded-2xl bg-brand-gradient shadow-glow"> <img src="/favicon.svg" alt="Gemini Omni" class="h-9 w-9" width="36" height="36"> </span> <h2 id="login-modal-title" class="font-display text-2xl font-semibold tracking-tight text-white"> Be first when Gemini Omni opens up </h2> <p class="mt-2 max-w-xs text-sm leading-relaxed text-zinc-400"> Sign in to unlock the prompt builder and credits. Omni 1.1 Flash is production-ready for developers (gemini-omni-1.1-flash). </p> </header> <div class="flex flex-col gap-3"> <div id="gsi-button-container" data-locale="en" data-google-failed="Google sign-in failed. Please try again." class="flex min-h-[44px] items-center justify-center"></div> </div> <div class="relative"> <div class="absolute inset-0 flex items-center" aria-hidden="true"> <div class="w-full border-t border-white/10"></div> </div> <div class="relative flex justify-center"> <span class="bg-ink-900/95 px-3 text-xs uppercase tracking-[0.25em] text-zinc-500"> or </span> </div> </div> <div data-step="email" class="flex flex-col gap-3"> <label class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400" for="login-email"> Email </label> <input id="login-email" type="email" autocomplete="email" inputmode="email" placeholder="[email protected]" class="w-full rounded-xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-500 focus:border-violet-400/40 focus:ring-violet-400/20"> <button type="button" data-action="send-code" data-invalid-email="Please enter a valid email address." data-send-failed="Failed to send code. Please try again." class="btn-primary w-full justify-center"> <span data-label-idle>
659Send code</span> <span data-label-loading hidden class="flex items-center gap-2"> <span class="inline-block h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/70 border-t-transparent"></span> Sending⦠</span> </button> </div> <div data-step="code" hidden class="flex flex-col gap-3"> <div class="flex items-center justify-between"> <label class="text-xs font-semibold uppercase tracking-[0.18em] text-zinc-400" for="login-code"> Verification code </label> <button type="button" data-action="change-email" class="text-xs font-semibold text-violet-300 transition-colors hover:text-violet-200"> Change email </button> </div> <p class="rounded-xl border border-white/5 bg-white/[0.03] px-3 py-2 text-xs text-zinc-400"> <span>We sent a 6-digit code to</span> <span data-code-email class="ml-1 font-semibold text-zinc-100"></span> </p> <input id="login-code" type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="6" placeholder="000000" class="w-full rounded-xl border border-white/10 bg-white/[0.04] px-4 py-4 text-center text-2xl font-semibold tracking-[0.6em] text-white outline-none ring-2 ring-transparent transition-all placeholder:text-zinc-600 focus:border-violet-400/40 focus:ring-violet-400/20"> <button type="button" data-action="verify" data-verify-failed="Invalid or expired code." class="btn-primary w-full justify-center"> <span data-label-idle>Verify & sign in</span> <span data-label-loading hidden class="flex items-center gap-2"> <span class="inline-block h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/70 border-t-transparent"></span> Verifying⦠</span> </button> <div class="text-center text-xs text-zinc-400"> <button type="button" data-action="resend" data-template="Resend in {n}s" class="font-semibold text-violet-300 transition-colors hover:text-violet-200 disabled:cursor-not-allowed disabled:text-zinc-500 disabled:hover:text-zinc-500"> <span data-resend-idle>Resend code</span> <span data-resend-countdown hidden></span> </button> </div> </div> <p data-error hidden class="rounded-xl border border-rose-500/30 bg-rose-500/10 px-3 py-2 text-sm text-rose-200"></p> <p class="text-center text-xs leading-relaxed text-zinc-500"> By signing in, you agree to our <a href="/terms/" class="text-zinc-300 underline decoration-zinc-600 underline-offset-2 hover:text-white">Terms of Service</a> and <a href="/privacy/" class="text-zinc-300 underline decoration-zinc-600 underline-offset-2 hover:text-white">Privacy Policy</a> </p> </div> <div data-state="success" hidden class="flex flex-col items-center gap-5 py-4 text-center"> <span class="grid h-16 w-16 place-items-center rounded-full bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-400/40"> <svg viewBox="0 0 24 24" class="h-8 w-8" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" d="M5 12l4.5 4.5L19 7"></path> </svg> </span> <h2 class="font-display text-2xl font-semibold tracking-tight text-white"> You're signed in </h2> <p class="max-w-xs text-sm leading-relaxed text-zinc-400"> You can close this and keep exploring. Try the prompt builder when you are ready. </p> <p data-success-user class="text-sm font-semibold text-zinc-200"></p> <div class="flex w-full flex-col items-stretch gap-2 sm:flex-row sm:justify-center sm:gap-3"> <a href="/prompt-generator/" class="btn-primary justify-center"> Open the prompt builder <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M13 6l6 6-6 6"></path> </svg> </a> <button type="button" data-close class="btn-ghost justify-center"> Close </button> </div> </div> </div> </dialog>
659<script>(function(){const API_BASE = "https://www.gushanai.com/api"; 660const APP_KEY = "gemini_omni_4561"; 661const GOOGLE_CLIENT_ID = "463343176094-ptfq906flrtlronsfq8c4omvui6dtck2.apps.googleusercontent.com"; 662const HTML_LANG = "en"; 663 664 (() => { 665 if (typeof window === 'undefined') return; 666 const dialog = document.getElementById('login-modal'); 667 if (!(dialog instanceof HTMLDialogElement)) return; 668 669 const AUTH_TOKEN_KEY = 'auth_token'; 670 const USER_INFO_KEY = 'user_info'; 671 const AUTH_CHANGED_EVENT = 'gemini-omni:auth-changed'; 672 673 const formRoot = dialog.querySelector('[data-state="form"]'); 674 const successRoot = dialog.querySelector('[data-state="success"]'); 675 const errorEl = dialog.querySelector('[data-error]'); 676 const stepEmail = dialog.querySelector('[data-step="email"]'); 677 const stepCode = dialog.querySelector('[data-step="code"]'); 678 const emailInput = dialog.querySelector('#login-email'); 679 const codeInput = dialog.querySelector('#login-code'); 680 const codeEmailLabel = dialog.querySelector('[data-code-email]'); 681 const successUserEl = dialog.querySelector('[data-success-user]'); 682 const gsiContainer = dialog.querySelector('#gsi-button-container'); 683 684 const sendBtn = dialog.querySelector('[data-action="send-code"]'); 685 const verifyBtn = dialog.querySelector('[data-action="verify"]'); 686 const resendBtn = dialog.querySelector('[data-action="resend"]'); 687 const changeEmailBtn = dialog.querySelector('[data-action="change-email"]'); 688 689 let currentEmail = ''; 690 let countdown = 0; 691 let countdownTimer = null; 692 let gsiLoaded = false; 693 let gsiInitialized = false; 694 695 const isAuthed = () => !!window.localStorage.getItem(AUTH_TOKEN_KEY); 696 697 const showError = (msg) => { 698 if (!errorEl) return; 699 if (!msg) { 700 errorEl.textContent = ''; 701 errorEl.setAttribute('hidden', ''); 702 return; 703 } 704 errorEl.textContent = msg; 705 errorEl.removeAttribute('hidden'); 706 }; 707 708 const setBtnLoading = (btn, loading) => { 709 if (!btn) return; 710 btn.toggleAttribute('disabled', loading); 711 const idle = btn.querySelector('[data-label-idle]'); 712 const busy = btn.querySelector('[data-label-loading]'); 713 if (idle) idle.toggleAttribute('hidden', loading); 714 if (busy) busy.toggleAttribute('hidden', !loading); 715 }; 716 717 const switchStep = (step) => { 718 if (step === 'code') { 719 stepEmail?.setAttribute('hidden', ''); 720 stepCode?.removeAttribute('hidden'); 721 setTimeout(() => codeInput?.focus(), 30); 722 } else { 723 stepCode?.setAttribute('hidden', ''); 724 stepEmail?.removeAttribute('hidden'); 725 setTimeout(() => emailInput?.focus(), 30); 726 } 727 }; 728 729 const stopCountdown = () => { 730 if (countdownTimer) { 731 clearInterval(countdownTimer); 732 countdownTimer = null; 733 } 734 }; 735 736 const updateResendUI = () => { 737 if (!resendBtn) return; 738 const idle = resendBtn.querySelector('[data-resend-idle]'); 739 const cd = resendBtn.querySelector('[data-resend-countdown]'); 740 if (countdown > 0) { 741 resendBtn.setAttribute('disabled', ''); 742 idle?.setAttribute('hidden', ''); 743 if (cd) { 744 cd.removeAttribute('hidden'); 745 cd.textContent = (resendBtn.dataset.template || '{n}s').replace('{n}', String(countdown)); 746 } 747 } else { 748 resendBtn.removeAttribute('disabled'); 749 idle?.removeAttribute('hidden'); 750 cd?.setAttribute('hidden', ''); 751 } 752 }; 753 754 const startCountdown = (seconds) => { 755 stopCountdown(); 756 countdown = seconds; 757 updateResendUI(); 758 countdownTimer = window.setInterval(() => { 759 countdown -= 1; 760 if (countdown <= 0) { 761 countdown = 0; 762 stopCountdown(); 763 } 764 updateResendUI(); 765 }, 1000); 766 }; 767 768 const showSuccess = (user) => { 769 formRoot?.setAttribute('hidden', ''); 770 successRoot?.removeAttribute('hidden'); 771 if (successUserEl) { 772 const name = user?.nickName || user?.email || ''; 773 successUserEl.textContent = name; 774 successUserEl.toggleAttribute('hidden', !name); 775 } 776 }; 777 778 const resetForm = () => { 779 currentEmail = ''; 780 stopCountdown(); 781 countdown = 0; 782 updateResendUI(); 783 if (emailInput) emailInput.value = ''; 784 if (codeInput) codeInput.value = ''; 785 showError(''); 786 switchStep('email'); 787 formRoot?.removeAttribute('hidden'); 788 successRoot?.setAttribute('hidden', ''); 789 }; 790 791 const openDialog = () => { 792 showError(''); 793 if (isAuthed()) { 794 const raw = window.localStorage.getItem(USER_INFO_KEY); 795 let user = null; 796 try { user = raw ? JSON.parse(raw) : null; } catch {} 797 formRoot?.setAttribute('hidden', ''); 798 successRoot?.removeAttribute('hidden'); 799 if (successUserEl) { 800 const name = user?.nickName || user?.email || ''; 801 successUserEl.textContent = name; 802 successUserEl.toggleAttribute('hidden', !name); 803 } 804 } else { 805 resetForm(); 806 } 807 if (!dialog.open) { 808 try { dialog.showModal(); } catch { dialog.setAttribute('open', ''); } 809 } 810 ensureGoogleButton(); 811 }; 812 813 const closeDialog = () => { 814 if (dialog.open) { 815 try { dialog.close(); } catch { dialog.removeAttribute('open'); } 816 } 817 }; 818 819 const apiRequest = async (path, body) => { 820 const headers = { 'Content-Type': 'application/json', 'x-app-key': APP_KEY }; 821 const token = window.localStorage.getItem(AUTH_TOKEN_KEY); 822 if (token) headers.Authorization = token; 823 const res = await fetch(`${API_BASE}${path}`, { 824 method: 'POST', 825 headers, 826 body: JSON.stringify(body || {}), 827 }); 828 let env;
829 try { env = await res.json(); } catch { env = { code: res.status, message: `HTTP ${res.status}` }; } 830 if (!env || (env.code !== 200 && env.code !== 0)) { 831 const err = new Error(env?.message || `HTTP ${res.status}`); 832 err.code = env?.code ?? res.status; 833 throw err; 834 } 835 return env.data; 836 }; 837 838 const finishLogin = (token, user) => { 839 window.localStorage.setItem(AUTH_TOKEN_KEY, token); 840 if (user) window.localStorage.setItem(USER_INFO_KEY, JSON.stringify(user)); 841 window.dispatchEvent(new CustomEvent(AUTH_CHANGED_EVENT, { detail: { token, user } })); 842 showSuccess(user); 843 }; 844 845 const handleGoogleCredential = async (response) => { 846 const idToken = response?.credential; 847 if (!idToken) return; 848 showError(''); 849 try { 850 const data = await apiRequest('/auth/google/web', { idToken }); 851 finishLogin(data.token, data.user || null); 852 try { 853 const fresh = await apiRequest('/mine/info', {}); 854 window.localStorage.setItem(USER_INFO_KEY, JSON.stringify(fresh)); 855 if (successUserEl) { 856 const name = fresh?.nickName || fresh?.email || ''; 857 successUserEl.textContent = name; 858 successUserEl.toggleAttribute('hidden', !name); 859 } 860 } catch {} 861 } catch (err) { 862 showError(err?.message || gsiContainer?.dataset.googleFailed || 'Google sign-in failed'); 863 } 864 }; 865 866 const initGoogle = () => { 867 if (gsiInitialized || !gsiContainer) return; 868 const g = window.google; 869 if (!g?.accounts?.id) return; 870 g.accounts.id.initialize({ 871 client_id: GOOGLE_CLIENT_ID, 872 callback: handleGoogleCredential, 873 ux_mode: 'popup', 874 auto_select: false, 875 }); 876 gsiContainer.innerHTML = ''; 877 g.accounts.id.renderButton(gsiContainer, { 878 theme: 'filled_black', 879 size: 'large', 880 shape: 'pill', 881 text: 'signin_with', 882 logo_alignment: 'left', 883 width: gsiContainer.clientWidth || 320, 884 locale: HTML_LANG, 885 }); 886 gsiInitialized = true; 887 }; 888 889 const ensureGoogleButton = () => { 890 if (!gsiContainer || gsiInitialized) return; 891 if (gsiLoaded) { 892 initGoogle(); 893 return; 894 } 895 const existing = document.querySelector('script[data-gsi-loader]'); 896 if (existing) { 897 existing.addEventListener('load', initGoogle, { once: true }); 898 gsiLoaded = true; 899 return; 900 } 901 const s = document.createElement('script'); 902 s.src = 'https://accounts.google.com/gsi/client'; 903 s.async = true; 904 s.defer = true; 905 s.dataset.gsiLoader = '1'; 906 s.onload = () => { gsiLoaded = true; initGoogle(); }; 907 document.head.appendChild(s); 908 }; 909 910 const isValidEmail = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v); 911 912 sendBtn?.addEventListener('click', async () => { 913 const email = (emailInput?.value || '').trim(); 914 showError(''); 915 if (!email || !isValidEmail(email)) { 916 showError(sendBtn.dataset.invalidEmail || 'Invalid email'); 917 return; 918 } 919 setBtnLoading(sendBtn, true);
920 try { 921 await apiRequest('/auth/email/send-code', { email }); 922 currentEmail = email; 923 if (codeEmailLabel) codeEmailLabel.textContent = email; 924 switchStep('code'); 925 startCountdown(60); 926 } catch (err) { 927 showError(err?.message || sendBtn.dataset.sendFailed || 'Failed to send code'); 928 } finally { 929 setBtnLoading(sendBtn, false); 930 } 931 }); 932 933 verifyBtn?.addEventListener('click', async () => { 934 const code = (codeInput?.value || '').replace(/\D/g, ''); 935 showError(''); 936 if (code.length !== 6) { 937 showError(verifyBtn.dataset.verifyFailed || 'Invalid code'); 938 return; 939 } 940 setBtnLoading(verifyBtn, true); 941 try { 942 const data = await apiRequest('/auth/email/verify', { email: currentEmail, code }); 943 finishLogin(data.token, data.user || null); 944 try { 945 const fresh = await apiRequest('/mine/info', {}); 946 window.localStorage.setItem(USER_INFO_KEY, JSON.stringify(fresh)); 947 if (successUserEl) { 948 const name = fresh?.nickName || fresh?.email || ''; 949 successUserEl.textContent = name; 950 successUserEl.toggleAttribute('hidden', !name); 951 } 952 } catch {} 953 } catch (err) { 954 showError(err?.message || verifyBtn.dataset.verifyFailed || 'Verification failed'); 955 } finally { 956 setBtnLoading(verifyBtn, false); 957 } 958 }); 959 960 resendBtn?.addEventListener('click', async () => { 961 if (countdown > 0 || !currentEmail) return; 962 showError(''); 963 try { 964 await apiRequest('/auth/email/send-code', { email: currentEmail }); 965 startCountdown(60); 966 } catch (err) { 967 showError(err?.message || sendBtn?.dataset.sendFailed || 'Failed to send code'); 968 } 969 }); 970 971 changeEmailBtn?.addEventListener('click', () => { 972 showError(''); 973 stopCountdown(); 974 countdown = 0; 975 updateResendUI(); 976 if (codeInput) codeInput.value = ''; 977 switchStep('email'); 978 }); 979 980 codeInput?.addEventListener('input', (e) => { 981 const target = e.target; 982 if (target instanceof HTMLInputElement) { 983 target.value = target.value.replace(/\D/g, '').slice(0, 6); 984 } 985 }); 986 987 emailInput?.addEventListener('keydown', (e) => { 988 if (e.key === 'Enter') { 989 e.preventDefault(); 990 sendBtn?.click(); 991 } 992 }); 993 994 codeInput?.addEventListener('keydown', (e) => { 995 if (e.key === 'Enter') { 996 e.preventDefault(); 997 verifyBtn?.click(); 998 } 999 }); 1000 1001 dialog.addEventListener('click', (e) => { 1002 const target = e.target; 1003 if (target instanceof Element && target.closest('[data-close]')) { 1004 e.preventDefault(); 1005 closeDialog(); 1006 return; 1007 } 1008 if (target === dialog) { 1009 closeDialog(); 1010 } 1011 }); 1012 1013 dialog.addEventListener('cancel', (e) => { 1014 e.preventDefault(); 1015 closeDialog(); 1016 }); 1017 1018 window.addEventListener('open-login', openDialog); 1019 1020 document.addEventListener('click', (e) => { 1021 const target = e.target; 1022 if (!(target instanceof Element)) return; 1023 const trigger = target.closest('[data-open-login]'); 1024 if (trigger) { 1025 e.preventDefault(); 1026 openDialog(); 1027 } 1028 }); 1029 })(); 1030})();</script>
1030 <dialog id="recharge-modal" class="hidden w-[min(440px,calc(100vw-24px))] rounded-3xl border border-white/10 bg-ink-900/95 p-0 text-zinc-100 shadow-glow backdrop:bg-ink-950/70 backdrop:backdrop-blur-md open:flex open:flex-col" aria-labelledby="recharge-modal-title"> <div class="relative px-7 pb-8 pt-9 sm:px-9"> <button type="button" data-close aria-label="Not now" class="absolute right-3 top-3 grid h-9 w-9 place-items-center rounded-full border border-white/10 bg-white/[0.04] text-zinc-300 transition-colors hover:border-violet-400/40 hover:text-white"> <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" d="M6 6l12 12M18 6L6 18"></path> </svg> </button> <header class="flex flex-col items-center text-center"> <span class="mb-4 grid h-14 w-14 place-items-center rounded-2xl bg-gradient-to-br from-amber-400/30 via-rose-400/20 to-violet-500/30 ring-1 ring-amber-400/40"> <svg viewBox="0 0 24 24" class="h-7 w-7 text-amber-300" aria-hidden="true"> <path fill="currentColor" d="M13 2L3 14h7l-1 8 10-12h-7l1-8z"></path> </svg> </span> <h2 id="recharge-modal-title" class="font-display text-2xl font-semibold tracking-tight text-white"> You are out of credits </h2> <p class="mt-2 max-w-xs text-sm leading-relaxed text-zinc-400"> Top up your Gemini Omni balance to keep generating prompts and adaptations. </p> </header> <div class="mt-6 flex flex-col gap-3 sm:flex-row"> <button type="button" data-close class="btn-ghost w-full justify-center"> Not now </button> <a href="/pricing/" class="btn-primary w-full justify-center" data-recharge-cta> Go to pricing <svg viewBox="0 0 24 24" class="h-4 w-4" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M13 6l6 6-6 6"></path> </svg> </a> </div> </div> </dialog>
1030<script> 1031 (() => { 1032 if (typeof window === 'undefined') return; 1033 const dialog = document.getElementById('recharge-modal'); 1034 if (!(dialog instanceof HTMLDialogElement)) return; 1035 1036 const openDialog = () => { 1037 if (!dialog.open) { 1038 try { 1039 dialog.showModal(); 1040 } catch { 1041 dialog.setAttribute('open', ''); 1042 } 1043 } 1044 }; 1045 1046 const closeDialog = () => { 1047 if (dialog.open) { 1048 try { 1049 dialog.close(); 1050 } catch { 1051 dialog.removeAttribute('open'); 1052 } 1053 } 1054 }; 1055 1056 dialog.addEventListener('click', (e) => { 1057 const target = e.target; 1058 if (target instanceof Element && target.closest('[data-close]')) { 1059 e.preventDefault(); 1060 closeDialog(); 1061 return; 1062 } 1063 if (target === dialog) closeDialog(); 1064 }); 1065 1066 dialog.addEventListener('cancel', (e) => { 1067 e.preventDefault(); 1068 closeDialog(); 1069 }); 1070 1071 window.addEventListener('gemini-omni:open-recharge', openDialog); 1072 })(); 1073</script>
1073
1073<script> 1074 (() => { 1075 if (typeof window === 'undefined') return; 1076 const observer = new IntersectionObserver( 1077 (entries) => { 1078 for (const entry of entries) { 1079 if (entry.isIntersecting) { 1080 entry.target.classList.add('is-visible'); 1081 observer.unobserve(entry.target); 1082 } 1083 } 1084 }, 1085 { threshold: 0.12, rootMargin: '0px 0px -40px 0px' } 1086 ); 1087 const onReady = () => { 1088 document.querySelectorAll('.reveal').forEach((el) => observer.observe(el)); 1089 }; 1090 if (document.readyState === 'loading') { 1091 document.addEventListener('DOMContentLoaded', onReady); 1092 } else { 1093 onReady(); 1094 } 1095 })(); 1096 </script>
1096 </body> </html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.