- Like/Plus/Nachmachen/Generieren als Liquid-Metal: WebGL-Shader (esm.sh @paper-design/shaders, liquidMetalFragmentShader) ueber Metall-Gradient- Fallback, schwarzer Kern, graues Icon mit Schattenwurf - Nav-Glas: bl-glass-refract (feImage-Displacement-Map mit RGB-Split, aus Nav-Groesse dynamisch generiert) + blur(3px) saturate(1.15), Weiss .12, Ring .4/.3; Layer als echte divs statt Pseudo-Elemente - Create komplett neu (aus BrandLoop.dc.html): Vorschau-Stack mit Ketten- Faecher + Dots + Video-Badge, Optionen-Accordion (Typ/Format/Kette), Prompt-Box mit Border-Beam (border-beam.css), Liquid-Metal-Generate, Fake-iOS-Tastatur mit @Modell-Tokens (inputmode=none gegen echte Tastatur), interner Scroll + body.noscroll auch fuer Create Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1452 lines
90 KiB
HTML
1452 lines
90 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||
<meta name="theme-color" content="#0a0a0a">
|
||
<title>BrandLoop – Prototyp</title>
|
||
<link rel="stylesheet" href="border-beam.css">
|
||
<script type="module">import('https://esm.sh/@paper-design/shaders').then(function(m){window.__paperShaders=m;var u={u_repetition:4,u_softness:.5,u_shiftRed:.3,u_shiftBlue:.3,u_distortion:0,u_contour:0,u_angle:45,u_scale:8,u_shape:1,u_offsetX:.1,u_offsetY:-.1};setInterval(function(){document.querySelectorAll('.lm-shader:not([data-lm])').forEach(function(el){el.dataset.lm='1';try{new m.ShaderMount(el,m.liquidMetalFragmentShader,u,undefined,0.6)}catch(e){}})},500)}).catch(function(){})</script>
|
||
<style>
|
||
/* Liquid-Metal-Buttons (aus BrandLoop.dc.html): Shader-Canvas ueber
|
||
Metall-Gradient (Fallback ohne WebGL/offline), schwarzer Kern, graues Icon */
|
||
.lm-shader canvas{width:100%!important;height:100%!important;display:block!important;position:absolute!important;top:0!important;left:0!important;border-radius:100px!important;}
|
||
.lm-bg{position:absolute; inset:0; border-radius:100px; overflow:hidden;
|
||
background:linear-gradient(135deg,#e8e8e8,#6f6f6f 35%,#f2f2f2 50%,#5c5c5c 68%,#cfcfcf);}
|
||
.lm-bg.deg120{background:linear-gradient(120deg,#e8e8e8,#6f6f6f 35%,#f2f2f2 50%,#5c5c5c 68%,#cfcfcf);}
|
||
.lm-core{position:absolute; inset:2px; border-radius:100px; background:linear-gradient(180deg,#202020,#000);}
|
||
.lm-ic{position:absolute; inset:0; display:grid; place-items:center;}
|
||
.lm-btn{position:relative; height:52px; border-radius:100px; cursor:pointer;
|
||
box-shadow:0 2px 5px rgba(0,0,0,.35), 0 9px 9px rgba(0,0,0,.12);}
|
||
.lm-label{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:8px;
|
||
font-size:14.5px; font-weight:700; color:#9a9a9a; text-shadow:0 1px 2px rgba(0,0,0,.5);}
|
||
</style>
|
||
<style>
|
||
:root{
|
||
--bg:#0a0a0a;
|
||
--surface:rgba(255,255,255,.05);
|
||
--surface2:rgba(255,255,255,.1);
|
||
--sheet:#131316;
|
||
--card:#161616;
|
||
--border:rgba(255,255,255,.09);
|
||
--border-strong:rgba(255,255,255,.18);
|
||
--txt:#fff;
|
||
--mut:rgba(255,255,255,.6);
|
||
--faint:rgba(255,255,255,.4);
|
||
--accent:#ff5c39;
|
||
--ok:#34d399;
|
||
--gold:#fbbf24;
|
||
}
|
||
*{box-sizing:border-box; margin:0; padding:0;}
|
||
html{-webkit-text-size-adjust:100%;}
|
||
html, body{overscroll-behavior-y:none;}
|
||
/* Explore ist ein fixer Vollbild-Screen: Seite darf nicht scrollen/wippen */
|
||
body.noscroll{overflow:hidden; height:100dvh;}
|
||
body.noscroll .app{padding-bottom:0;}
|
||
body{
|
||
background:var(--bg); color:var(--txt);
|
||
font-family:-apple-system,BlinkMacSystemFont,"Helvetica Neue","Inter",Roboto,system-ui,sans-serif;
|
||
font-size:15px; line-height:1.5;
|
||
-webkit-font-smoothing:antialiased;
|
||
-webkit-tap-highlight-color:transparent;
|
||
}
|
||
svg.ic{fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;}
|
||
.mono{font-family:ui-monospace,Menlo,SFMono-Regular,Consolas,monospace;}
|
||
|
||
.app{position:relative; max-width:430px; margin:0 auto; min-height:100dvh; overflow-x:hidden;}
|
||
@media(min-width:480px){.app{border-inline:1px solid var(--border);}}
|
||
|
||
.screen{display:none; animation:fade .28s ease; position:relative; z-index:1;
|
||
padding:0 18px calc(112px + env(safe-area-inset-bottom));}
|
||
.screen.active{display:block;}
|
||
@keyframes fade{from{opacity:0; transform:translateY(8px);} to{opacity:1; transform:none;}}
|
||
|
||
/* ---- Topbar ---- */
|
||
.topbar{position:sticky; top:0; z-index:20; display:flex; align-items:center; gap:12px;
|
||
margin:0 -18px 14px; padding:calc(12px + env(safe-area-inset-top)) 18px 12px;
|
||
background:rgba(10,10,10,.85); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);}
|
||
.topbar h1{font-size:16px; font-weight:700; letter-spacing:-.01em;}
|
||
.backpill{display:flex; align-items:center; gap:7px; padding:9px 16px 9px 12px; border-radius:100px;
|
||
background:var(--surface2); border:none; color:var(--txt); font-size:13px; font-weight:600; font-family:inherit;
|
||
cursor:pointer; flex-shrink:0; transition:transform .12s;}
|
||
.backpill:active{transform:scale(.94);}
|
||
.backpill .ar{font-size:14px; opacity:.8;}
|
||
.iconbtn{display:grid; place-items:center; width:36px; height:36px; border-radius:100px;
|
||
background:var(--surface); border:1px solid var(--border); color:var(--mut); cursor:pointer; flex-shrink:0; transition:transform .12s, color .15s;}
|
||
.iconbtn:active{transform:scale(.92);}
|
||
.iconbtn svg{width:18px; height:18px;}
|
||
|
||
/* ---- Typo ---- */
|
||
h3{font-size:12px; font-weight:700; color:var(--faint); text-transform:uppercase; letter-spacing:.1em; margin:22px 0 10px;}
|
||
.sub{color:var(--mut); font-size:13.5px; line-height:1.55; margin-top:4px;}
|
||
.note{font-size:12px; color:var(--faint); line-height:1.55; margin-top:10px;}
|
||
.hl{color:var(--txt); font-weight:600;}
|
||
|
||
/* ---- Cards ---- */
|
||
.card{background:var(--card); border:1px solid rgba(255,255,255,.07); border-radius:16px; padding:15px 16px; margin-bottom:12px; position:relative;}
|
||
.card h4{font-size:15px; font-weight:700; margin-bottom:3px;}
|
||
.card h4.t-sm{font-size:13.5px;}
|
||
.card p{font-size:13px; color:var(--mut); line-height:1.55;}
|
||
.card.click{cursor:pointer; transition:border-color .15s, transform .1s, background .15s;}
|
||
.card.click:hover{border-color:var(--border-strong);}
|
||
.card.click:active{transform:scale(.98);}
|
||
.cardrow{display:flex; align-items:center; gap:13px;}
|
||
.cardrow .body{flex:1; min-width:0;}
|
||
.ico{width:42px; height:42px; border-radius:14px; display:grid; place-items:center; flex-shrink:0;}
|
||
.ico svg{width:20px; height:20px;}
|
||
.ico.rose{background:rgba(255,92,57,.14); color:var(--accent);}
|
||
.ico.orange{background:rgba(249,115,22,.12); color:#fb923c;}
|
||
.ico.amber{background:rgba(251,191,36,.12); color:var(--gold);}
|
||
.ico.emerald{background:rgba(52,211,153,.12); color:var(--ok);}
|
||
.ico.zinc{background:var(--surface2); color:var(--mut);}
|
||
.chev{width:16px; height:16px; color:var(--faint); flex-shrink:0;}
|
||
|
||
/* ---- Media-Platzhalter ---- */
|
||
.ph{display:flex; gap:10px; align-items:flex-start; border:1.5px dashed rgba(255,255,255,.18); border-radius:14px;
|
||
padding:13px 14px; font-size:12.5px; color:var(--mut); font-style:italic; line-height:1.55;
|
||
background:rgba(255,255,255,.02); margin:10px 0;}
|
||
.ph svg{width:16px; height:16px; flex-shrink:0; margin-top:2px; color:var(--faint);}
|
||
|
||
/* ---- Buttons ---- */
|
||
.btn{display:flex; align-items:center; justify-content:center; gap:8px; width:100%;
|
||
border:none; border-radius:100px; padding:15px; font-size:14.5px; font-weight:800; font-family:inherit; cursor:pointer; margin-top:14px;
|
||
background:var(--accent); color:#0a0a0a;
|
||
box-shadow:0 0 22px rgba(255,92,57,.27);
|
||
transition:transform .12s, filter .15s;}
|
||
.btn:hover{filter:brightness(1.06);}
|
||
.btn:active{transform:scale(.98);}
|
||
.btn.sec{background:var(--surface2); color:var(--txt); border:1px solid var(--border); box-shadow:none; font-weight:600;}
|
||
.btn svg{width:17px; height:17px;}
|
||
|
||
/* ---- Formulare ---- */
|
||
input[type=text], textarea{width:100%; background:var(--card); border:1px solid rgba(255,255,255,.1); border-radius:16px;
|
||
color:var(--txt); padding:13px 15px; font-size:13.5px; font-family:inherit; margin:6px 0 14px; line-height:1.55;
|
||
transition:border-color .15s, box-shadow .15s; -webkit-appearance:none;}
|
||
::placeholder{color:var(--faint);}
|
||
input:focus, textarea:focus{outline:none; border-color:rgba(255,92,57,.6); box-shadow:0 0 0 3px rgba(255,92,57,.14);}
|
||
textarea{min-height:96px; resize:vertical;}
|
||
label{font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--faint); display:block;}
|
||
.req{color:var(--accent); text-transform:none;}
|
||
|
||
/* ---- Tags, Scores, Badges ---- */
|
||
.tag{display:inline-flex; align-items:center; gap:5px; background:var(--surface2); border:none;
|
||
color:var(--txt); border-radius:100px; padding:7px 13px; font-size:12px; font-weight:600; margin:3px 5px 0 0;}
|
||
.score{color:var(--gold); font-weight:700; font-size:.95em;}
|
||
.badge{display:inline-block; font-size:10px; border-radius:999px; padding:3px 9px; font-weight:700; letter-spacing:.03em; vertical-align:2px;}
|
||
.b-ok{background:rgba(52,211,153,.14); color:var(--ok);}
|
||
.b-arch{background:rgba(161,161,170,.14); color:var(--mut);}
|
||
.b-new{background:rgba(255,92,57,.16); color:var(--accent);}
|
||
|
||
/* ---- Favorit ---- */
|
||
.fav{border-color:rgba(251,191,36,.45); box-shadow:0 0 0 1px rgba(251,191,36,.25), 0 8px 28px rgba(251,191,36,.07);}
|
||
.favlabel{position:absolute; top:-10px; right:14px; background:linear-gradient(135deg,#fbbf24,#f59e0b);
|
||
color:#1c1400; font-size:10px; font-weight:700; letter-spacing:.04em; border-radius:999px; padding:3px 10px;}
|
||
|
||
/* ---- Chips / Pills ---- */
|
||
.pill-row{display:flex; gap:7px; margin:10px 0 4px;}
|
||
.pill{flex:1; text-align:center; background:var(--surface); border:1px solid var(--border); border-radius:100px;
|
||
padding:11px 6px; font-size:12.5px; color:rgba(255,255,255,.8); font-weight:600; cursor:pointer;
|
||
transition:color .15s, background .15s, transform .1s, border-color .15s;}
|
||
.pill:active{transform:scale(.96);}
|
||
.pill.on{border-color:transparent; color:#000; background:#fff;}
|
||
.chiprow{display:flex; gap:8px; overflow-x:auto; margin:0 -18px; padding:2px 18px 4px; scrollbar-width:none;}
|
||
.chiprow::-webkit-scrollbar{display:none;}
|
||
.chip{flex:none; display:flex; align-items:center; gap:8px; padding:10px 15px; border-radius:100px;
|
||
font-size:12.5px; font-weight:600; cursor:pointer; background:var(--surface); color:rgba(255,255,255,.8);
|
||
transition:background .15s, color .15s;}
|
||
.chip.on{background:#fff; color:#000;}
|
||
.chip .dot{width:9px; height:9px; border-radius:100px; flex:none; background:rgba(255,255,255,.3);}
|
||
.chip.on .dot{background:var(--accent);}
|
||
|
||
/* ---- Steps ---- */
|
||
.steps{display:flex; gap:6px; margin-bottom:18px;}
|
||
.steps div{flex:1; height:4px; border-radius:4px; background:var(--surface2);}
|
||
.steps div.on{background:var(--accent);}
|
||
|
||
/* ---- Metriken ---- */
|
||
.row{display:flex; gap:10px;}
|
||
.row .card{flex:1;}
|
||
.metric{text-align:center; padding:14px 8px;}
|
||
.metric p{font-size:10.5px; color:var(--faint); margin-bottom:4px; text-transform:uppercase; letter-spacing:.06em; font-weight:700;}
|
||
.metric h4{font-size:19px; font-weight:800; margin:0;}
|
||
.metric h4.g{color:var(--ok);}
|
||
|
||
/* ---- Listen in Cards ---- */
|
||
.rule{display:flex; gap:10px; align-items:center; padding:9px 0; border-bottom:1px solid var(--border); font-size:13.5px; color:var(--txt);}
|
||
.rule:last-child{border-bottom:none; padding-bottom:2px;}
|
||
.rule:first-child{padding-top:2px;}
|
||
.rule svg{width:16px; height:16px; color:var(--ok); flex-shrink:0;}
|
||
.asset{display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--border); font-size:13.5px;}
|
||
.asset:last-child{border-bottom:none; padding-bottom:2px;}
|
||
.asset:first-child{padding-top:2px;}
|
||
.asset svg{width:16px; height:16px; color:var(--mut); flex-shrink:0;}
|
||
.asset .score{margin-left:auto;}
|
||
|
||
/* ---- Log & Code ---- */
|
||
.log{font-size:12.5px; color:var(--mut); border-left:2px solid var(--border-strong); padding:5px 0 5px 12px; margin:8px 0; line-height:1.5;}
|
||
.code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:11px; line-height:1.7; color:var(--mut);
|
||
background:#0c0c0f; border:1px solid var(--border); border-radius:14px; padding:14px; overflow-x:auto; margin:10px 0;}
|
||
.code b{color:var(--accent); font-weight:600;}
|
||
|
||
/* ---- Tutorial ---- */
|
||
.tut{display:flex; flex-direction:column; justify-content:center; min-height:calc(100dvh - 160px); text-align:center; padding:20px 6px;}
|
||
.tut .emoji{font-size:52px; margin-bottom:18px;}
|
||
.tut h1{font-size:26px; font-weight:800; letter-spacing:-.02em; margin-bottom:12px;}
|
||
.tut .sub{font-size:14.5px;}
|
||
|
||
/* ================= EXPLORE (Feed) ================= */
|
||
#explore{padding:0; --xs:max(env(safe-area-inset-top, 0px), 64px);}
|
||
#explore.active{display:flex; flex-direction:column; height:100dvh; overflow:hidden;}
|
||
.x-blur{position:absolute; inset:-50px; pointer-events:none; z-index:0;
|
||
filter:blur(36px) brightness(.78) saturate(1.15); transform:scale(1.08);
|
||
transition:background .7s ease, opacity .25s ease;}
|
||
.x-hood{position:absolute; inset:0; pointer-events:none; z-index:2;}
|
||
.x-hood svg{position:absolute; top:calc(var(--xs) - 14px); left:0; display:block; width:100%; height:120px;}
|
||
.x-hood .solid{position:absolute; top:calc(var(--xs) + 105px); left:0; right:0; bottom:0; background:var(--bg);}
|
||
.x-hood .glowred, .glowred-screen{background:radial-gradient(125% 125% at 50% 150%, rgba(241,99,99,.21) 40%, transparent 100%);}
|
||
.x-hood .glowred{position:absolute; inset:0;}
|
||
.x-tabs{position:absolute; top:calc(var(--xs) + 12px); left:0; right:0; height:24px; z-index:6;
|
||
display:flex; justify-content:center; align-items:center; gap:96px;}
|
||
.x-tab{position:relative; white-space:nowrap; padding:4px 6px;
|
||
font-size:14.5px; font-weight:600; cursor:pointer; color:rgba(255,255,255,.42); transition:color .25s;}
|
||
.x-tab::before{content:''; position:absolute; inset:-18px -30px;}
|
||
.x-tab.on{color:#fff; text-shadow:0 1px 10px rgba(0,0,0,.45);}
|
||
.x-deck{flex:1; position:relative; margin:calc(var(--xs) + 144px) 22px 10px; min-height:0; z-index:3;}
|
||
.x-card{position:absolute; inset:0; border-radius:26px; overflow:hidden; background:#141414;
|
||
touch-action:none; box-shadow:0 18px 44px rgba(0,0,0,.45);}
|
||
.x-card .img{position:absolute; inset:0; pointer-events:none;}
|
||
.x-card .imglabel{position:absolute; inset:0; display:grid; place-items:center; pointer-events:none;}
|
||
.x-card .imglabel span{font-family:ui-monospace,Menlo,monospace; font-size:12px; color:rgba(255,255,255,.85);
|
||
background:rgba(0,0,0,.35); padding:6px 12px; border-radius:8px;}
|
||
.x-card .playwrap{position:absolute; inset:0; display:grid; place-items:center; pointer-events:none;}
|
||
.x-card .play{width:64px; height:64px; border-radius:100px; background:rgba(10,10,10,.55);
|
||
backdrop-filter:blur(10px); display:grid; place-items:center; margin-top:90px;}
|
||
.x-segs{position:absolute; top:12px; left:14px; right:14px; display:flex; gap:5px; pointer-events:none;}
|
||
.x-segs div{flex:1; height:3px; border-radius:100px;}
|
||
.x-chips{position:absolute; top:24px; left:14px; display:flex; gap:6px; pointer-events:none;}
|
||
.x-chips div{padding:7px 13px; border-radius:100px; background:rgba(10,10,10,.55); backdrop-filter:blur(12px); font-size:12px; font-weight:600;}
|
||
.x-meta{position:absolute; left:0; right:0; bottom:0; padding:56px 18px 18px;
|
||
background:linear-gradient(transparent,rgba(0,0,0,.78)); pointer-events:none; display:flex; align-items:center; gap:10px;}
|
||
.x-meta .av{width:38px; height:38px; border-radius:100px; flex:none; display:grid; place-items:center; font-size:14px; font-weight:700;}
|
||
.x-meta .nm{font-size:15px; font-weight:700;}
|
||
.x-meta .md{font-size:12px; color:rgba(255,255,255,.6); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||
.x-badge{position:absolute; top:48px; padding:8px 16px; border-radius:12px; font-size:22px; font-weight:800;
|
||
letter-spacing:.08em; pointer-events:none; opacity:0;}
|
||
.x-badge.like{left:20px; border:3px solid var(--accent); color:var(--accent); transform:rotate(-14deg);}
|
||
.x-badge.skip{right:20px; border:3px solid #ff5c5c; color:#ff5c5c; transform:rotate(14deg);}
|
||
.x-empty{position:absolute; inset:0; border-radius:26px; background:#141414; border:1px dashed rgba(255,255,255,.15);
|
||
display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;}
|
||
.x-actions{position:relative; z-index:3; display:flex; justify-content:center; align-items:center; gap:22px;
|
||
padding:6px 0 84px;}
|
||
.x-act{width:56px; height:56px; border-radius:100px; background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.12);
|
||
display:grid; place-items:center; cursor:pointer; font-size:20px; color:rgba(255,255,255,.8); transition:transform .12s;}
|
||
.x-act:active{transform:scale(.92);}
|
||
.x-act.sm{width:44px; height:44px;}
|
||
.x-act.like{position:relative; background:none; border:none;
|
||
box-shadow:0 2px 5px rgba(0,0,0,.4), 0 9px 9px rgba(0,0,0,.15);}
|
||
|
||
/* ================= DETAIL & CREATE ================= */
|
||
#detail.active, #create.active{min-height:100dvh;
|
||
background:radial-gradient(125% 125% at 50% 150%, rgba(241,99,99,.21) 40%, transparent 100%);}
|
||
/* Create = fixer Vollbild-Screen mit internem Scroll + Fake-Tastatur */
|
||
#create.active{display:flex; flex-direction:column; height:100dvh; overflow:hidden; position:relative;}
|
||
.c-scroll{flex:1; overflow-y:auto; min-height:0; margin:0 -20px; padding:8px 18px 110px; scrollbar-width:none;
|
||
transition:padding-bottom .3s ease;}
|
||
.c-scroll::-webkit-scrollbar{display:none;}
|
||
.c-scroll.kb-open{padding-bottom:380px;}
|
||
.c-optlabel{font-size:11px; font-weight:700; letter-spacing:.12em; color:rgba(255,255,255,.4); margin-bottom:9px;}
|
||
.c-behind{position:absolute; top:0; left:50%; border-radius:22px; background:#1b1b1b;
|
||
border:1px solid rgba(255,255,255,.09); transform-origin:top center; z-index:0;}
|
||
.c-preview{position:relative; border-radius:22px; overflow:hidden; z-index:1;
|
||
box-shadow:0 18px 44px rgba(0,0,0,.5); transition:width .25s ease, height .25s ease;}
|
||
.kb{position:fixed; left:0; right:0; bottom:0; z-index:45; max-width:430px; margin:0 auto;
|
||
transform:translateY(112%); transition:transform .34s cubic-bezier(.22,1,.36,1);}
|
||
.kb.open{transform:none;}
|
||
.kb-row{display:flex; gap:5px; margin-bottom:8px;}
|
||
.kb-key{flex:1; height:38px; border-radius:6px; background:rgba(255,255,255,.16); display:grid; place-items:center;
|
||
font-size:16px; font-weight:500; color:#fff; cursor:pointer; user-select:none; -webkit-user-select:none; min-width:0;}
|
||
.kb-key.mod{background:rgba(255,255,255,.28); font-size:15px;}
|
||
.kb-chip{flex:none; display:flex; align-items:center; gap:7px; padding:8px 13px; border-radius:100px;
|
||
background:rgba(255,255,255,.12); font-size:12.5px; font-weight:600; cursor:pointer; white-space:nowrap; color:#fff;}
|
||
.kb-chip .dot{width:8px; height:8px; border-radius:100px; flex:none;}
|
||
.d-strip{display:flex; gap:10px; overflow-x:auto; margin:0 -18px; padding:0 18px; scrollbar-width:none; scroll-snap-type:x mandatory;}
|
||
.d-strip::-webkit-scrollbar{display:none;}
|
||
.d-img{flex:none; width:272px; height:330px; border-radius:20px; position:relative; display:grid; place-items:center; scroll-snap-align:center;}
|
||
.d-img .lbl{font-family:ui-monospace,Menlo,monospace; font-size:11.5px; color:rgba(255,255,255,.85);
|
||
background:rgba(0,0,0,.35); padding:5px 10px; border-radius:8px;}
|
||
.d-img .num{position:absolute; top:10px; right:12px; font-size:11px; font-weight:700; background:rgba(10,10,10,.55); padding:5px 9px; border-radius:100px;}
|
||
.d-title{font-size:26px; font-weight:800; letter-spacing:-.5px; margin:18px 0 4px;}
|
||
.d-sub{font-size:13px; color:rgba(255,255,255,.5); margin-bottom:16px;}
|
||
.promptbox{border-radius:16px; background:var(--card); border:1px solid rgba(255,255,255,.07); padding:14px 16px; margin-bottom:14px;}
|
||
.promptbox .k{font-size:11px; font-weight:700; letter-spacing:.12em; color:var(--faint); margin-bottom:8px;}
|
||
.promptbox .v{font-family:ui-monospace,Menlo,monospace; font-size:12.5px; line-height:1.6; color:rgba(255,255,255,.85);}
|
||
.frames{display:flex; gap:8px; overflow-x:auto; margin:0 -18px; padding:0 18px; scrollbar-width:none;}
|
||
.frames::-webkit-scrollbar{display:none;}
|
||
.frame{flex:none; border-radius:14px; border:1px dashed rgba(255,255,255,.2);
|
||
background:repeating-linear-gradient(135deg,transparent 0 12px,rgba(255,255,255,.04) 12px 24px); display:grid; place-items:center;}
|
||
.frame span{font-family:ui-monospace,Menlo,monospace; font-size:11px; color:rgba(255,255,255,.5);}
|
||
|
||
/* ================= PROFIL (Menschlein) ================= */
|
||
.p-hero{text-align:center; padding:calc(30px + env(safe-area-inset-top)) 0 6px;}
|
||
.p-hero .av{width:76px; height:76px; border-radius:100px; margin:0 auto 12px; display:grid; place-items:center;
|
||
font-size:28px; font-weight:800; background:linear-gradient(140deg,oklch(.72 .13 40),oklch(.5 .13 40));}
|
||
.p-hero h2{font-size:22px; font-weight:800; letter-spacing:-.02em;}
|
||
.p-hero p{color:var(--mut); font-size:13px; margin-top:3px;}
|
||
|
||
/* ================= Bottom-Navigation ================= */
|
||
/* Liquid-Glass-Nav (aus BrandLoop.dc.html): echte Refraktion via dynamischer
|
||
Displacement-Map (bl-glass-refract, RGB-Split) + Blur/Saturate-Backdrop +
|
||
Weiss-Layer + Kanten-Ring. bottom:14px = exakt die Hoehe aus dem Design. */
|
||
.nav{position:fixed; bottom:14px; left:50%; transform:translateX(-50%); z-index:30;
|
||
display:flex; align-items:center; gap:6px; padding:8px 10px; border-radius:100px;
|
||
box-shadow:0 6px 6px rgba(0,0,0,.2), 0 0 20px rgba(0,0,0,.1);
|
||
transition:all .7s cubic-bezier(.175,.885,.32,2.2);}
|
||
.nav-glass{position:absolute; inset:0; border-radius:100px;}
|
||
.nav-glass.blur{overflow:hidden; -webkit-backdrop-filter:blur(3px) saturate(1.15); backdrop-filter:blur(3px) saturate(1.15);}
|
||
.nav-glass.refract{overflow:hidden; -webkit-backdrop-filter:url(#bl-glass-refract); backdrop-filter:url(#bl-glass-refract);}
|
||
.nav-glass.white{background:rgba(255,255,255,.12); z-index:1;}
|
||
.nav-glass.ring{z-index:2; pointer-events:none;
|
||
box-shadow:inset 2px 2px 1px 0 rgba(255,255,255,.4), inset -1px -1px 1px 1px rgba(255,255,255,.3);}
|
||
.nav button{position:relative; z-index:3; display:flex; align-items:center; gap:8px; background:none; border:none; font-family:inherit;
|
||
width:40px; height:40px; justify-content:center; border-radius:100px; color:rgba(255,255,255,.6);
|
||
font-size:13.5px; font-weight:600; cursor:pointer; transition:background .2s, color .2s, width .2s;}
|
||
.nav button svg{width:20px; height:20px; flex:none;}
|
||
.nav button span{display:none;}
|
||
.nav button.on{width:auto; padding:9px 16px 9px 12px; background:rgba(255,255,255,.14); color:#fff;}
|
||
.nav button.on span{display:inline;}
|
||
/* Plus-Button = Liquid-Metal (Shader + schwarzer Kern) */
|
||
.nav button.plus{background:none; box-shadow:0 2px 5px rgba(0,0,0,.35);}
|
||
.nav button.plus.on{width:40px; padding:0;}
|
||
.nav button.plus.on span{display:none;}
|
||
|
||
/* ---- Info-Sheet ---- */
|
||
.backdrop{position:fixed; inset:0; background:rgba(0,0,0,.6); opacity:0; pointer-events:none; transition:opacity .25s; z-index:40;}
|
||
.backdrop.open{opacity:1; pointer-events:auto;}
|
||
.sheet{position:fixed; bottom:0; left:0; right:0; margin:0 auto; max-width:430px; background:var(--sheet);
|
||
border:1px solid var(--border); border-bottom:none; border-radius:24px 24px 0 0;
|
||
padding:14px 20px calc(28px + env(safe-area-inset-bottom));
|
||
transform:translateY(105%); transition:transform .32s cubic-bezier(.32,.72,0,1); z-index:50; max-height:80dvh; overflow-y:auto;}
|
||
.sheet.open{transform:none;}
|
||
.sheet .grab{width:36px; height:4px; border-radius:4px; background:var(--surface2); margin:0 auto 18px;}
|
||
.sheet h2{font-size:17px; font-weight:700; margin-bottom:10px;}
|
||
.sheet p{color:var(--mut); font-size:13.5px; line-height:1.6; margin-bottom:12px;}
|
||
.sheet ul{list-style:none; margin-bottom:12px;}
|
||
.sheet li{color:var(--mut); font-size:13.5px; line-height:1.6; padding-left:14px; position:relative; margin-bottom:4px;}
|
||
.sheet li::before{content:"·"; position:absolute; left:2px; color:var(--accent); font-weight:700;}
|
||
</style>
|
||
</head>
|
||
<body class="noscroll">
|
||
|
||
<!-- Lucide-Icon-Sprite + Liquid-Glass-Filter -->
|
||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||
<defs>
|
||
<filter id="bl-glass-refract" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%" height="100%">
|
||
<feImage id="glassMapImage" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" href="" result="map"/>
|
||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-180" xChannelSelector="R" yChannelSelector="G" result="dispRed"/>
|
||
<feColorMatrix in="dispRed" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red"/>
|
||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-170" xChannelSelector="R" yChannelSelector="G" result="dispGreen"/>
|
||
<feColorMatrix in="dispGreen" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green"/>
|
||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-160" xChannelSelector="R" yChannelSelector="G" result="dispBlue"/>
|
||
<feColorMatrix in="dispBlue" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue"/>
|
||
<feBlend in="red" in2="green" mode="screen" result="rg"/>
|
||
<feBlend in="rg" in2="blue" mode="screen" result="out"/>
|
||
<feGaussianBlur in="out" stdDeviation="0.7"/>
|
||
</filter>
|
||
<symbol id="i-back" viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></symbol>
|
||
<symbol id="i-chev" viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></symbol>
|
||
<symbol id="i-home" viewBox="0 0 24 24"><path d="M4 11 L12 4 L20 11 V20 H14 V15 H10 V20 H4 Z"/></symbol>
|
||
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5 V19 M5 12 H19"/></symbol>
|
||
<symbol id="i-spark" viewBox="0 0 24 24"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></symbol>
|
||
<symbol id="i-db" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></symbol>
|
||
<symbol id="i-gear" viewBox="0 0 24 24"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></symbol>
|
||
<symbol id="i-film" viewBox="0 0 24 24"><path d="M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z"/><path d="m6.2 5.3 3.1 3.9"/><path d="m12.4 3.4 3.1 4"/><path d="M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/></symbol>
|
||
<symbol id="i-user" viewBox="0 0 24 24"><circle cx="12" cy="8.5" r="3.5"/><path d="M5 20 c1.2-3.6 4-5 7-5 s5.8 1.4 7 5"/></symbol>
|
||
<symbol id="i-box" viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.29 7 12 12 20.71 7"/><line x1="12" x2="12" y1="22" y2="12"/></symbol>
|
||
<symbol id="i-pin" viewBox="0 0 24 24"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></symbol>
|
||
<symbol id="i-bulb" viewBox="0 0 24 24"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></symbol>
|
||
<symbol id="i-mic" viewBox="0 0 24 24"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></symbol>
|
||
<symbol id="i-up" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></symbol>
|
||
<symbol id="i-play" viewBox="0 0 24 24"><polygon points="6 3 20 12 6 21 6 3"/></symbol>
|
||
<symbol id="i-img" viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></symbol>
|
||
<symbol id="i-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></symbol>
|
||
<symbol id="i-check" viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5"/></symbol>
|
||
<symbol id="i-refresh" viewBox="0 0 24 24"><path d="M4 12 a8 8 0 1 1 2.3 5.7"/><path d="M4 18 v-5 h5"/></symbol>
|
||
<symbol id="i-lock" viewBox="0 0 24 24"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
|
||
</defs>
|
||
</svg>
|
||
|
||
<div class="app">
|
||
|
||
<!-- ============ EXPLORE / FEED (neu, aus BrandLoop.dc.html) ============ -->
|
||
<div class="screen active" id="explore">
|
||
<div class="x-blur" id="xBlur"></div>
|
||
<div class="x-hood">
|
||
<svg viewBox="0 0 430 120" preserveAspectRatio="none"><path id="xHoodPath" d="" fill="#0a0a0a"></path></svg>
|
||
<div class="solid"></div>
|
||
<div class="glowred"></div>
|
||
</div>
|
||
<button class="iconbtn" style="position:absolute; top:calc(var(--xs) - 54px); right:14px; z-index:8;" onclick="toggleInfo(true)" aria-label="Info zum Prototyp"><svg class="ic"><use href="#i-info"/></svg></button>
|
||
<div class="x-tabs">
|
||
<div class="x-tab" data-tab="videos">Videos</div>
|
||
<div class="x-tab" data-tab="folge">Folge ich</div>
|
||
<div class="x-tab on" data-tab="posts">Posts</div>
|
||
</div>
|
||
<div class="x-deck" id="xDeck"></div>
|
||
<div class="x-actions">
|
||
<div class="x-act" id="btnSkip" role="button" aria-label="Skip">✕</div>
|
||
<div class="x-act sm" id="btnDetail" role="button" aria-label="Details / Nachmachen"><svg class="ic" style="width:18px;height:18px;color:rgba(255,255,255,.8)"><use href="#i-refresh"/></svg></div>
|
||
<div class="x-act like" id="btnLike" role="button" aria-label="Like">
|
||
<div class="lm-shader lm-bg"></div>
|
||
<div class="lm-core"></div>
|
||
<div class="lm-ic"><svg width="24" height="24" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 21 C5 15.5 2.5 12 2.5 8.5 A4.7 4.7 0 0 1 12 6.2 A4.7 4.7 0 0 1 21.5 8.5 C21.5 12 19 15.5 12 21 Z"/></svg></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ POST-DETAIL (neu) ============ -->
|
||
<div class="screen" id="detail">
|
||
<div class="topbar">
|
||
<button class="backpill" onclick="go('explore')"><span class="ar">‹</span> Zurück</button>
|
||
<div style="margin-left:auto; display:flex; align-items:center; gap:10px;">
|
||
<div id="dAvatar" style="width:34px; height:34px; border-radius:100px; background:linear-gradient(140deg,oklch(.72 .13 40),oklch(.55 .13 40)); display:grid; place-items:center; font-size:13px; font-weight:700;">M</div>
|
||
<div><div style="font-size:13.5px; font-weight:700;">Mara S.</div><div style="font-size:11px; color:rgba(255,255,255,.5);">1.2k Remakes</div></div>
|
||
</div>
|
||
</div>
|
||
<div class="d-strip" id="dStrip"></div>
|
||
<div class="d-title">Skincare Routine – 3er Kette</div>
|
||
<div class="d-sub">Bild-Kette · Produkt-Modell · Format 4:5</div>
|
||
<div class="promptbox">
|
||
<div class="k">PROMPT</div>
|
||
<div class="v" id="detailPrompt">Roter Toner im rosa Bogenfenster, weiches Gegenlicht, Editorial-Look — Kette: Fenster-Szene → Dropper auf Glaskante → Poster-Ad in Orange</div>
|
||
</div>
|
||
<div style="margin-bottom:22px;">
|
||
<span class="tag">Modell · Glow Serum v3</span><span class="tag">4:5</span><span class="tag">Editorial</span><span class="tag">3 Bilder</span>
|
||
</div>
|
||
<div style="font-size:15px; font-weight:800; margin-bottom:10px;">Mit deinem Modell nachmachen</div>
|
||
<div class="chiprow" id="detailModels"></div>
|
||
<div class="lm-btn" id="remakeBtn" role="button" style="margin-top:16px;">
|
||
<div class="lm-shader lm-bg deg120"></div>
|
||
<div class="lm-core"></div>
|
||
<div class="lm-label"><svg width="15" height="15" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 2 L14.4 9.6 L22 12 L14.4 14.4 L12 22 L9.6 14.4 L2 12 L9.6 9.6 Z"/></svg><span id="remakeLabel"></span></div>
|
||
</div>
|
||
<div style="text-align:center; font-size:11.5px; color:rgba(255,255,255,.4); margin-top:10px;">Prompt + Einstellungen werden übernommen, dein Modell wird eingesetzt</div>
|
||
</div>
|
||
|
||
<!-- ============ POST ERSTELLEN (neu, aus BrandLoop.dc.html v4) ============ -->
|
||
<div class="screen" id="create">
|
||
<div class="topbar">
|
||
<button class="backpill" onclick="go('explore')"><span class="ar">‹</span> Zurück</button>
|
||
<h1 style="flex:1; text-align:center; margin-right:80px;">Neuer KI-Post</h1>
|
||
</div>
|
||
<div class="c-scroll" id="cScroll">
|
||
<div style="display:flex; flex-direction:column; align-items:center; padding:10px 0 4px;">
|
||
<div id="cStack" onclick="toggleOpts()" style="position:relative; cursor:pointer;"></div>
|
||
<div onclick="toggleOpts()" style="display:flex; align-items:center; gap:8px; margin-top:14px; padding:9px 10px 9px 16px; border-radius:100px; background:rgba(255,255,255,.08); cursor:pointer;">
|
||
<span style="font-size:13px; font-weight:600;" id="cSelLabel"></span>
|
||
<svg id="cChevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,.6)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="transition:transform .2s;"><path d="M6 9 l6 6 l6 -6"/></svg>
|
||
</div>
|
||
<div id="cOpts" style="display:none; width:100%; margin-top:14px; border-radius:20px; background:#161616; border:1px solid rgba(255,255,255,.09); padding:16px; box-sizing:border-box;">
|
||
<div class="c-optlabel">TYP</div>
|
||
<div class="pill-row" style="margin:0 0 16px;" id="typeRow"></div>
|
||
<div class="c-optlabel">FORMAT</div>
|
||
<div class="pill-row" style="margin:0 0 16px;" id="formatRow"></div>
|
||
<div class="c-optlabel">KETTE</div>
|
||
<div class="pill-row" style="margin:0;" id="countRow"></div>
|
||
</div>
|
||
</div>
|
||
<label style="margin:22px 0 8px;">Dein Modell</label>
|
||
<div class="chiprow" id="createModels"></div>
|
||
<label style="margin:20px 0 8px;">Prompt</label>
|
||
<div data-beam="bb" data-active="true" style="border-radius:24px;">
|
||
<div style="border-radius:24px; background:#171717; border:1px solid rgba(255,255,255,.05); box-shadow:0 12px 34px rgba(0,0,0,.4);">
|
||
<textarea id="createPrompt" inputmode="none" placeholder="Beschreibe deinen Post … z.B. Sneaker auf Betonboden, goldenes Abendlicht" style="display:block; width:100%; box-sizing:border-box; height:104px; resize:none; border:none; border-radius:23px; background:transparent; color:#fff; font-size:13.5px; line-height:1.55; padding:16px 18px; outline:none;"></textarea>
|
||
</div>
|
||
<div data-beam-bloom="true"></div>
|
||
</div>
|
||
<div class="lm-btn" id="generateBtn" role="button" style="margin-top:22px;">
|
||
<div class="lm-shader lm-bg deg120"></div>
|
||
<div class="lm-core"></div>
|
||
<div class="lm-label"><svg width="15" height="15" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 2 L14.4 9.6 L22 12 L14.4 14.4 L12 22 L9.6 14.4 L2 12 L9.6 9.6 Z"/></svg><span id="generateLabel">Post generieren</span></div>
|
||
</div>
|
||
|
||
<h3 style="margin-top:28px;">Mehr erstellen</h3>
|
||
<div class="card click" onclick="go('tut1')">
|
||
<div class="cardrow">
|
||
<div class="ico rose"><svg class="ic"><use href="#i-film"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Szene (Video)</h4><p>Video aus Prompt mit Script-Bestätigung – mehrere KI-Modelle parallel.</p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
<div class="card click" onclick="go('model-create')">
|
||
<div class="cardrow">
|
||
<div class="ico orange"><svg class="ic"><use href="#i-user"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Modell</h4><p>Person oder Produkt als festes Brand-Asset – bleibt in jedem Video 1:1 gleich.</p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
</div><!-- /c-scroll -->
|
||
|
||
<!-- Fake-Tastatur (Prototyp): erscheint beim Fokus aufs Prompt-Feld -->
|
||
<div class="kb" id="kbOverlay">
|
||
<div style="display:flex; align-items:center; gap:8px; padding:10px 12px; background:rgba(24,24,24,.96); border-top:1px solid rgba(255,255,255,.08);">
|
||
<div style="display:flex; gap:8px; overflow-x:auto; flex:1; scrollbar-width:none;" id="kbModels"></div>
|
||
<div id="kbDone" style="flex:none; padding:8px 14px; border-radius:100px; background:rgba(255,255,255,.14); font-size:12px; font-weight:700; cursor:pointer;">Fertig</div>
|
||
</div>
|
||
<div style="padding:8px 4px 24px; background:rgba(30,30,32,.98); backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);" id="kbKeys"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ PROFIL / MENSCHLEIN (neu, enthält Knowledge Base) ============ -->
|
||
<div class="screen" id="profile">
|
||
<div class="p-hero">
|
||
<div class="av">V</div>
|
||
<h2>Velvet Rouge</h2>
|
||
<p>Brand-Profil · seit 2021 · mutig, clean, luxuriös</p>
|
||
</div>
|
||
<div class="row" style="margin-top:14px;">
|
||
<div class="card metric"><p>Videos</p><h4>31</h4></div>
|
||
<div class="card metric"><p>Vote-Match</p><h4 class="g">78 %</h4></div>
|
||
<div class="card metric"><p>Follower</p><h4 class="g">+218</h4></div>
|
||
</div>
|
||
|
||
<div class="card click" onclick="go('improve-select')">
|
||
<div class="cardrow">
|
||
<div class="ico amber"><svg class="ic"><use href="#i-spark"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Asset verbessern</h4><p>Gesicht, Produkt oder Szene weiterentwickeln – jederzeit.</p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
<div class="card click" onclick="go('scene-results')">
|
||
<div class="cardrow">
|
||
<div class="ico zinc"><svg class="ic"><use href="#i-film"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Zuletzt: „Roter Lippenstift – Close-up"</h4><p>3 Videos generiert · Vote offen</p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>Knowledge Base · Feste Regeln <span style="text-transform:none; letter-spacing:0; color:var(--faint); font-weight:500;">(kein Score, gelten immer)</span></h3>
|
||
<div class="card">
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Cleaner Hintergrund</p></div>
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Nur zeigen, was verlangt ist</p></div>
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Logo nie verzerren</p></div>
|
||
</div>
|
||
|
||
<h3>Assets (freigegebene Versionen)</h3>
|
||
<div class="card">
|
||
<div class="asset"><svg class="ic"><use href="#i-user"/></svg><span>Mara <span class="badge b-ok">v4</span></span><span class="score">6120</span></div>
|
||
<div class="asset"><svg class="ic"><use href="#i-box"/></svg><span>Rouge No. 5 <span class="badge b-ok">v2</span></span><span class="score">6480</span></div>
|
||
</div>
|
||
|
||
<h3>Attribute (Elo 0–10.000)</h3>
|
||
<div class="card click" onclick="go('kb-detail')">
|
||
<div class="cardrow">
|
||
<div class="ico rose"><svg class="ic"><use href="#i-pin"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Location: Kaiserslautern <span class="score">5240 ▲</span></h4><p>12 Videos · 8 Siege · Unter-Attribut: Stadion <span class="score">5560</span></p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="cardrow">
|
||
<div class="ico zinc"><svg class="ic"><use href="#i-pin"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Location: Köln <span class="score" style="color:var(--faint);">4980 ▼</span> <span class="badge b-arch">ARCHIVIERT</span></h4><p>Historie bleibt erhalten – ein schlechter Score ist auch Wissen.</p></div>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="asset"><svg class="ic"><use href="#i-bulb"/></svg><span>Licht: warmes Abendlicht</span><span class="score">6350 ▲</span></div>
|
||
<div class="asset"><svg class="ic"><use href="#i-mic"/></svg><span>Voice: warm-weiblich</span><span class="score">5890</span></div>
|
||
</div>
|
||
|
||
<h3>Log (letzte Einträge)</h3>
|
||
<div class="log">19.07. · Vote „Verbessern Mara v4": warmes Abendlicht +14 (K hoch), Studio-Look −14</div>
|
||
<div class="log">18.07. · Ad-Performance Video #31: Kaiserslautern +22, Close-up +22 <b style="color:#fb923c;">(Performance zählt 2×)</b></div>
|
||
<div class="log">17.07. · Gezielte Frage: „Kaiserslautern besser als Köln" → K'lautern +10, Köln −10</div>
|
||
<div class="log">17.07. · LLM-Vergleich K'lautern vs. Köln: „Stadion war der Unterschied" → neues Unter-Attribut Stadion (Start: Ø 5480)</div>
|
||
</div>
|
||
|
||
<!-- ============ KB DETAIL ============ -->
|
||
<div class="screen" id="kb-detail">
|
||
<div class="topbar"><button class="backpill" onclick="go('profile')"><span class="ar">‹</span> Zurück</button><h1>Kaiserslautern</h1></div>
|
||
<div class="card">
|
||
<h4>Score: <span class="score">5240</span> · 12 Videos · 8 Siege</h4>
|
||
<p style="margin-top:10px;"><span class="hl">Was diese Location ausmacht:</span><br>Urban, aber nahbar; Stadion als Wiedererkennungspunkt. Warmes Abendlicht funktioniert besser als Tageslicht.</p>
|
||
<p style="margin-top:10px;"><span class="hl">Gelernt aus Vergleichen:</span><br>vs. Köln (12.07.): Stadion-Hintergrund war der Unterschied → Stadion als eigenes Unter-Attribut angelegt.</p>
|
||
</div>
|
||
<h3>Score-Verlauf</h3>
|
||
<div class="log">Start 5000 → 5090 (Votes) → 5180 (Ad-Performance) → 5240 (heute)</div>
|
||
<div class="note">Vollständige Historie pro Attribut: jeder Vote mit Datum, Vergleichspartner, Punktänderung und Grund. Ablesbar, was besser und was schlechter geworden ist.</div>
|
||
</div>
|
||
|
||
<!-- ============ TUTORIAL 1 (Fullscreen) ============ -->
|
||
<div class="screen" id="tut1">
|
||
<div class="tut">
|
||
<div class="emoji">👋</div>
|
||
<h1>Bevor's losgeht</h1>
|
||
<p class="sub">Damit deine Videos nach <span class="hl">deiner Brand</span> aussehen, stellen wir dir einmalig 5 kurze Fragen.<br><br>Danach nie wieder – ab dann lernt die App von selbst, mit jedem Video.</p>
|
||
<button class="btn" onclick="go('onboarding1')">Los geht's</button>
|
||
<button class="btn sec" onclick="go('create')">Zurück</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ ONBOARDING 1 ============ -->
|
||
<div class="screen" id="onboarding1">
|
||
<div class="topbar"><button class="backpill" onclick="go('tut1')"><span class="ar">‹</span> Zurück</button><h1>Dein Unternehmen</h1></div>
|
||
<div class="steps"><div class="on"></div><div></div></div>
|
||
<label>Labelname <span class="req">*</span></label>
|
||
<input type="text" placeholder="z. B. VELVET ROUGE Cosmetics">
|
||
<label>Was verkaufst du? <span class="req">*</span></label>
|
||
<input type="text" placeholder="z. B. vegane Lippenstifte & Lipgloss">
|
||
<label>Wen willst du erreichen? <span class="req">*</span></label>
|
||
<input type="text" placeholder="z. B. Frauen 18–35, TikTok & Instagram">
|
||
<label>3 Worte, die deine Brand beschreiben <span class="req">*</span></label>
|
||
<input type="text" placeholder="z. B. mutig, clean, luxuriös">
|
||
<label>Wie lange seid ihr schon auf dem Markt? <span class="req">*</span></label>
|
||
<input type="text" placeholder="z. B. seit 2021">
|
||
<button class="btn" onclick="go('tut2')">Weiter</button>
|
||
</div>
|
||
|
||
<!-- ============ TUTORIAL 2 (Fullscreen) ============ -->
|
||
<div class="screen" id="tut2">
|
||
<div class="tut">
|
||
<div class="emoji">📸</div>
|
||
<h1>Zeig uns deine Brand</h1>
|
||
<p class="sub">Logo, Produktbilder, deine besten bisherigen Ads – alles optional.<br><br>Aber: Je mehr du hochlädst, desto besser sieht schon dein <span class="hl">allererstes Video</span> aus.</p>
|
||
<button class="btn" onclick="go('onboarding2')">Weiter</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ ONBOARDING 2 ============ -->
|
||
<div class="screen" id="onboarding2">
|
||
<div class="topbar"><button class="backpill" onclick="go('tut2')"><span class="ar">‹</span> Zurück</button><h1>Uploads</h1></div>
|
||
<div class="steps"><div class="on"></div><div class="on"></div></div>
|
||
<p class="sub" style="margin-bottom:12px;">Optional, aber empfohlen – füttert deine Knowledge Base von Tag 1.</p>
|
||
<div class="ph"><svg class="ic"><use href="#i-up"/></svg><span>[Upload: Logo]</span></div>
|
||
<div class="ph"><svg class="ic"><use href="#i-up"/></svg><span>[Upload: Produktbilder – z. B. Lippenstift „Rouge No. 5" aus 3 Winkeln]</span></div>
|
||
<div class="ph"><svg class="ic"><use href="#i-up"/></svg><span>[Upload: Deine bisher besten Ads (Video/Bild) – das System lernt daraus deine Startattribute]</span></div>
|
||
<button class="btn" onclick="go('scene-create')">Profil speichern → Erste Szene</button>
|
||
<button class="btn sec" onclick="go('scene-create')">Überspringen</button>
|
||
</div>
|
||
|
||
<!-- ============ SZENE ERSTELLEN ============ -->
|
||
<div class="screen" id="scene-create">
|
||
<div class="topbar"><button class="backpill" onclick="go('create')"><span class="ar">‹</span> Zurück</button><h1>Szene erstellen</h1></div>
|
||
<label>Dein Prompt</label>
|
||
<textarea>Eine Frau hält einen roten Lippenstift in die Kamera.</textarea>
|
||
<h3>Anzahl Videos</h3>
|
||
<div class="pill-row">
|
||
<div class="pill" onclick="pick(this)">3</div>
|
||
<div class="pill on" onclick="pick(this)">4</div>
|
||
<div class="pill" onclick="pick(this)">5</div>
|
||
<div class="pill" onclick="pick(this)">6</div>
|
||
</div>
|
||
<div class="note">Jedes Video von einem anderen Top-KI-Modell. Mehr Videos = mehr Vergleichssignal, Preis pro Video.</div>
|
||
<h3>Automatisch eingebaut (Brand Knowledge)</h3>
|
||
<div class="card">
|
||
<span class="tag">Regel: cleaner Hintergrund</span>
|
||
<span class="tag">Gesicht: „Mara" v3 <span class="score">6120</span></span>
|
||
<span class="tag">Produkt: Rouge No. 5 v2 <span class="score">6480</span></span>
|
||
<span class="tag">Location: Kaiserslautern <span class="score">5240</span></span>
|
||
<span class="tag">Voice: warm-weiblich <span class="score">5890</span></span>
|
||
<p style="margin-top:10px;">Dein Prompt wird automatisch überarbeitet und mit den Top-Attributen & freigegebenen Assets angereichert.</p>
|
||
</div>
|
||
<button class="btn" onclick="go('script-confirm')">Weiter → Script</button>
|
||
</div>
|
||
|
||
<!-- ============ SCRIPT BESTÄTIGEN ============ -->
|
||
<div class="screen" id="script-confirm">
|
||
<div class="topbar"><button class="backpill" onclick="go('scene-create')"><span class="ar">‹</span> Zurück</button><h1>Dein Script</h1></div>
|
||
<p class="sub" style="margin-bottom:10px;">Aus deinem Prompt + Brand Knowledge erstellt. Lies es, ändere was du willst – generiert wird erst nach deiner Bestätigung.</p>
|
||
<textarea style="min-height:250px; font-size:13px; line-height:1.6;">SZENE: „Roter Lippenstift – Close-up"
|
||
|
||
SETTING: Kaiserslautern, Abendlicht (golden hour), cleaner unscharfer Hintergrund
|
||
|
||
PERSON: Mara (v3, freigegeben) – dunkle schulterlange Haare, nahbar-edel
|
||
|
||
ABLAUF:
|
||
1. Close-up: Maras Hand hebt Rouge No. 5 (v2) frontal in die Kamera
|
||
2. Schnitt auf Gesicht: natürliches Lächeln, Blick in die Linse
|
||
3. Produkt dreht sich langsam, Logo sichtbar (nie verzerrt)
|
||
|
||
VOICE (warm-weiblich): „Dein Rot. Dein Statement."
|
||
|
||
TEXT-OVERLAY: keins (Brand-Stil: clean)</textarea>
|
||
<div class="note">Erst nach Bestätigung werden die Videos generiert – Kosten entstehen erst dann. Änderungen am Script fließen als Signal in die Knowledge Base.</div>
|
||
<button class="btn" onclick="go('scene-results')"><svg class="ic"><use href="#i-check"/></svg>Bestätigen & 4 Videos generieren</button>
|
||
<button class="btn sec" onclick="go('script-confirm')"><svg class="ic"><use href="#i-refresh"/></svg>Script neu schreiben lassen</button>
|
||
</div>
|
||
|
||
<!-- ============ SZENE ERGEBNISSE ============ -->
|
||
<div class="screen" id="scene-results">
|
||
<div class="topbar"><button class="backpill" onclick="go('scene-create')"><span class="ar">‹</span> Zurück</button><h1>Wähle das Beste</h1></div>
|
||
<p class="sub" style="margin-bottom:16px;">Tippe auf dein Favoriten-Video. Die goldene Umrandung ist die System-Vorhersage.</p>
|
||
|
||
<div class="card click fav" onclick="go('scene-vote')">
|
||
<span class="favlabel">SYSTEM-FAVORIT</span>
|
||
<h4 class="t-sm">Video 1 · Modell A</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-play"/></svg><span>[VIDEO: Mara (Gesicht v3) hält Rouge No. 5 frontal in die Kamera, Close-up, warmes Abendlicht, Kaiserslautern-Kulisse unscharf im Hintergrund, warme weibliche Stimme: „Dein Rot. Dein Statement."]</span></div>
|
||
<span class="tag">warm-rot</span><span class="tag">Close-up</span><span class="tag">Kaiserslautern</span>
|
||
</div>
|
||
|
||
<div class="card click" onclick="go('scene-vote')">
|
||
<h4 class="t-sm">Video 2 · Modell B</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-play"/></svg><span>[VIDEO: Gleiche Szene, aber kühles Studiolicht, langsamer Schwenk von der Hand zum Gesicht, Text-Overlay statt Stimme]</span></div>
|
||
<span class="tag">Studio</span><span class="tag">Schwenk</span><span class="tag">Text-Overlay</span>
|
||
</div>
|
||
|
||
<div class="card click" onclick="go('scene-vote')">
|
||
<h4 class="t-sm">Video 3 · Modell C</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-play"/></svg><span>[VIDEO: Outdoor Köln, Mara läuft auf Kamera zu, hält Lippenstift hoch, Upbeat-Musik, schnelle Schnitte]</span></div>
|
||
<span class="tag">Köln</span><span class="tag">Bewegung</span><span class="tag">Upbeat</span>
|
||
</div>
|
||
|
||
<div class="card click" onclick="go('scene-vote')">
|
||
<h4 class="t-sm">Video 4 · Modell D</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-play"/></svg><span>[VIDEO: Extreme Makro-Aufnahme nur vom Lippenstift, der sich dreht, ASMR-Sound beim Öffnen]</span></div>
|
||
<span class="tag">Makro</span><span class="tag">ASMR</span><span class="tag">ohne Gesicht</span>
|
||
</div>
|
||
|
||
<div class="note">Bestätigst du den markierten Favoriten → wenig Elo-Punkte. Weichst du ab → volle Punkte (stärkeres Signal).</div>
|
||
</div>
|
||
|
||
<!-- ============ VOTE + GEZIELTE FRAGE ============ -->
|
||
<div class="screen" id="scene-vote">
|
||
<div class="topbar"><button class="backpill" onclick="go('scene-results')"><span class="ar">‹</span> Zurück</button><h1>Danke!</h1></div>
|
||
<div class="card" style="border-color:rgba(52,211,153,.4);">
|
||
<h4><span class="badge b-ok">GESPEICHERT</span></h4>
|
||
<p style="margin-top:8px;">Dein Vote fließt in die Knowledge Base. Übereinstimmung mit System-Vorhersage: <span class="hl">78 %</span> (letzte 30 Votes).</p>
|
||
</div>
|
||
<h3>Kurze Frage (optional)</h3>
|
||
<div class="card">
|
||
<p style="color:var(--txt); font-size:14px; margin-bottom:8px;">Welche Location war besser?</p>
|
||
<div class="pill-row">
|
||
<div class="pill" onclick="pick(this)">Kaiserslautern</div>
|
||
<div class="pill" onclick="pick(this)">Köln</div>
|
||
<div class="pill" onclick="pick(this)">Egal</div>
|
||
</div>
|
||
<div class="note">Gezielte Fragen wirken nur auf dieses eine Attribut – das schnellste Signal gegen das Zuordnungsproblem.</div>
|
||
</div>
|
||
<h3>Video verwenden</h3>
|
||
<button class="btn" onclick="go('publish')"><svg class="ic"><use href="#i-up"/></svg>Hochladen / Ad schalten</button>
|
||
<button class="btn sec" onclick="go('improve-select')"><svg class="ic"><use href="#i-spark"/></svg>Erst noch verbessern</button>
|
||
</div>
|
||
|
||
<!-- ============ PUBLISH / PERFORMANCE ============ -->
|
||
<div class="screen" id="publish">
|
||
<div class="topbar"><button class="backpill" onclick="go('scene-vote')"><span class="ar">‹</span> Zurück</button><h1>Ad läuft</h1></div>
|
||
<div class="card">
|
||
<h4 class="t-sm">„Roter Lippenstift – Close-up" · Video 1</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-play"/></svg><span>[Gewähltes Video – veröffentlicht auf TikTok & Instagram via Ads-API]</span></div>
|
||
</div>
|
||
<h3>Live-Performance (Meta / TikTok API)</h3>
|
||
<div class="row">
|
||
<div class="card metric"><p>CTR</p><h4 class="g">2,4 %</h4></div>
|
||
<div class="card metric"><p>Thumbstop</p><h4 class="g">41 %</h4></div>
|
||
<div class="card metric"><p>ROAS</p><h4 class="g">3,1×</h4></div>
|
||
</div>
|
||
<div class="card">
|
||
<p><span class="hl">+218</span> neue Follower seit Schaltung</p>
|
||
</div>
|
||
<div class="note">Performance-Daten fließen automatisch und höher gewichtet als Votes in die Scores – der Markt entscheidet, keine Bestätigung nötig. Jedes Video loggt, welche Asset-Versionen es nutzte.</div>
|
||
<button class="btn sec" onclick="go('profile')">→ Was hat das System gelernt?</button>
|
||
</div>
|
||
|
||
<!-- ============ MODELL ERSTELLEN ============ -->
|
||
<div class="screen" id="model-create">
|
||
<div class="topbar"><button class="backpill" onclick="go('create')"><span class="ar">‹</span> Zurück</button><h1>Modell erstellen</h1></div>
|
||
<div class="pill-row">
|
||
<div class="pill on" onclick="pick(this)">Person</div>
|
||
<div class="pill" onclick="pick(this)">Produkt</div>
|
||
</div>
|
||
<label style="margin-top:14px;">Beschreibe deine Person</label>
|
||
<textarea>Frau, Ende 20, dunkle schulterlange Haare, natürliches Lächeln, nahbar aber edel – passt zu „mutig, clean, luxuriös".</textarea>
|
||
<label>Referenzbilder</label>
|
||
<div class="ph"><svg class="ic"><use href="#i-up"/></svg><span>[Upload: 3–10 Referenzbilder der gewünschten Person / des Looks]</span></div>
|
||
<div class="note">Rechte-Regel: Gesichter echter Personen nur mit dokumentierter Einwilligung. Rein KI-generierte Gesichter sind der sichere Standard.</div>
|
||
<button class="btn" onclick="go('model-result')">Modell generieren</button>
|
||
</div>
|
||
|
||
<!-- ============ MODELL ERGEBNIS ============ -->
|
||
<div class="screen" id="model-result">
|
||
<div class="topbar"><button class="backpill" onclick="go('model-create')"><span class="ar">‹</span> Zurück</button><h1>Dein Modell</h1></div>
|
||
<div class="card">
|
||
<h4>„Mara" <span class="badge b-new">v1 · ENTWURF</span></h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-img"/></svg><span>[BILD: Generierte Frau, Ende 20, dunkle schulterlange Haare, natürliches Lächeln, cleaner Studiohintergrund – aus 4 Blickwinkeln]</span></div>
|
||
<span class="tag">Ende 20</span><span class="tag">dunkle Haare</span><span class="tag">nahbar-edel</span>
|
||
</div>
|
||
<button class="btn" onclick="go('profile')"><svg class="ic"><use href="#i-check"/></svg>Freigeben (Release v1)</button>
|
||
<button class="btn sec" onclick="go('improve-input')"><svg class="ic"><use href="#i-spark"/></svg>Verbessern – sieht noch nicht gut aus</button>
|
||
<div class="note">Nur <span class="hl">freigegebene</span> Versionen werden in Videos verwendet. Verbessern erzeugt neue Versionen (v2, v3 …) – ein neues Gesicht ist ein bewusster Release, kein schleichender Drift.</div>
|
||
</div>
|
||
|
||
<!-- ============ VERBESSERN: ASSET WÄHLEN ============ -->
|
||
<div class="screen" id="improve-select">
|
||
<div class="topbar"><button class="backpill" onclick="go('profile')"><span class="ar">‹</span> Zurück</button><h1>Verbessern</h1></div>
|
||
<p class="sub" style="margin-bottom:16px;">Wähle das Asset, das du weiterentwickeln willst.</p>
|
||
<div class="card click" onclick="go('improve-input')">
|
||
<div class="cardrow">
|
||
<div class="ico rose"><svg class="ic"><use href="#i-user"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Gesicht „Mara" <span class="badge b-ok">v3 · FREIGEGEBEN</span></h4><p>Verwendet in 12 Videos · Score <span class="score">6120</span></p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
<div class="card click" onclick="go('improve-input')">
|
||
<div class="cardrow">
|
||
<div class="ico orange"><svg class="ic"><use href="#i-box"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Produkt „Rouge No. 5" <span class="badge b-ok">v2 · FREIGEGEBEN</span></h4><p>Verwendet in 18 Videos · Score <span class="score">6480</span></p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
<div class="card click" onclick="go('improve-input')">
|
||
<div class="cardrow">
|
||
<div class="ico zinc"><svg class="ic"><use href="#i-film"/></svg></div>
|
||
<div class="body"><h4 class="t-sm">Szene „Lippenstift Close-up"</h4><p>Video-Iteration: Licht, Schnitt, Tempo anpassen</p></div>
|
||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ VERBESSERN: EINGABE ============ -->
|
||
<div class="screen" id="improve-input">
|
||
<div class="topbar"><button class="backpill" onclick="go('improve-select')"><span class="ar">‹</span> Zurück</button><h1>„Mara" verbessern</h1></div>
|
||
<div class="pill-row">
|
||
<div class="pill on" onclick="pick(this)">Text-Feedback</div>
|
||
<div class="pill" onclick="pick(this)">Referenz hochladen</div>
|
||
</div>
|
||
<label style="margin-top:14px;">Was soll besser werden?</label>
|
||
<textarea>Haare etwas dunkler, Ausstrahlung natürlicher, weniger Studio-Look.</textarea>
|
||
<div class="card" style="border-style:dashed;">
|
||
<p style="margin-bottom:8px;"><span class="hl">Bei Referenz-Upload:</span></p>
|
||
<div class="ph"><svg class="ic"><use href="#i-up"/></svg><span>[Upload: Referenzbild]</span></div>
|
||
<label>Was übernehmen? <span class="req">* Pflichtfeld</span></label>
|
||
<input type="text" placeholder="z. B. nur die Frisur und der Hautton – nicht das Gesicht" style="margin-bottom:0;">
|
||
<div class="note">Ohne Beschreibung rät das System, was gemeint ist, und kopiert das Falsche. Aus fremden Referenzen wird gelernt, nie 1:1 kopiert.</div>
|
||
</div>
|
||
<button class="btn" onclick="go('improve-results')">Neue Versionen generieren</button>
|
||
</div>
|
||
|
||
<!-- ============ VERBESSERN: VORHER/NACHHER ============ -->
|
||
<div class="screen" id="improve-results">
|
||
<div class="topbar"><button class="backpill" onclick="go('improve-input')"><span class="ar">‹</span> Zurück</button><h1>Vorher / Nachher</h1></div>
|
||
<h3>Vorher (v3 – aktuell freigegeben)</h3>
|
||
<div class="ph"><svg class="ic"><use href="#i-img"/></svg><span>[BILD: Mara v3 – schulterlange dunkle Haare, Studio-Look]</span></div>
|
||
<h3>Wähle die neue Version</h3>
|
||
<p class="sub" style="margin-bottom:12px;">Jede Version zieht andere Vorlieben aus deiner Knowledge Base.</p>
|
||
|
||
<div class="card click" onclick="go('improve-vote')">
|
||
<h4 class="t-sm">Version A</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-img"/></svg><span>[BILD: Haare fast schwarz, Tageslicht statt Studio, dezentes Lächeln]</span></div>
|
||
<span class="tag">Tageslicht <span class="score">5210</span></span><span class="tag">dezent</span>
|
||
</div>
|
||
<div class="card click" onclick="go('improve-vote')">
|
||
<h4 class="t-sm">Version B</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-img"/></svg><span>[BILD: Dunkelbraune Haare, warmes Abendlicht (Top-Attribut!), offenes Lachen]</span></div>
|
||
<span class="tag">warmes Abendlicht <span class="score">6350</span></span><span class="tag">offen</span>
|
||
</div>
|
||
<div class="card click" onclick="go('improve-vote')">
|
||
<h4 class="t-sm">Version C</h4>
|
||
<div class="ph"><svg class="ic"><use href="#i-img"/></svg><span>[BILD: Wie v3, aber Outdoor-Hintergrund unscharf, natürlichere Haut-Textur]</span></div>
|
||
<span class="tag">Outdoor <span class="score">5580</span></span><span class="tag">natürliche Haut <span class="badge b-new">NEU · Start 5720 (Ø Kategorie)</span></span>
|
||
</div>
|
||
<div class="note">Gewinner-Merkmale steigen in der Elo gegenüber der ersetzten Version – aber nur Merkmale, in denen sich die Versionen <span class="hl">unterscheiden</span>. Neue Merkmale starten beim Kategorie-Durchschnitt (nicht bei 5000) mit hohem K-Faktor.</div>
|
||
</div>
|
||
|
||
<!-- ============ VERBESSERN: VOTE ============ -->
|
||
<div class="screen" id="improve-vote">
|
||
<div class="topbar"><button class="backpill" onclick="go('improve-results')"><span class="ar">‹</span> Zurück</button><h1>Version gewählt</h1></div>
|
||
<div class="card" style="border-color:rgba(52,211,153,.4);">
|
||
<h4><span class="badge b-ok">MARA v4 ERSTELLT</span></h4>
|
||
<p style="margin-top:8px;">Versionskette geloggt: v3 → v4 · Grund: „Haare dunkler, natürlicher" · Gewinner: Version B</p>
|
||
<p style="margin-top:6px;">Elo-Update: <b style="color:var(--gold);">warmes Abendlicht +14</b> · Studio-Look −14</p>
|
||
</div>
|
||
<button class="btn" onclick="go('profile')"><svg class="ic"><use href="#i-check"/></svg>v4 freigeben (ab jetzt in Videos)</button>
|
||
<button class="btn sec" onclick="go('improve-input')"><svg class="ic"><use href="#i-spark"/></svg>Weiter verbessern (v5)</button>
|
||
<div class="note">Bis zur Freigabe nutzen alle Videos weiterhin v3 – Wiedererkennung bleibt erhalten, und es bleibt messbar, welche Version performt.</div>
|
||
</div>
|
||
|
||
<!-- ============ DEVELOPER-MODUS ============ -->
|
||
<div class="screen" id="devmode">
|
||
<div class="topbar"><button class="backpill" onclick="go('explore')"><span class="ar">‹</span> Zurück</button><h1>Developer-Modus</h1></div>
|
||
<div class="card" style="border-color:rgba(255,92,57,.4);">
|
||
<div class="cardrow">
|
||
<div class="ico orange"><svg class="ic"><use href="#i-lock"/></svg></div>
|
||
<div class="body"><p><b style="color:var(--accent);">Nur intern.</b> Dieser Bereich ist für Nutzer unsichtbar – hier liegt das Feintuning, das die App ausmacht. Im Prototyp zur Präsentation sichtbar geschaltet.</p></div>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>Feste Regeln (Prompt-Injection, jede Generierung)</h3>
|
||
<div class="card">
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Cleaner, neutraler Hintergrund</p></div>
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Nur zeigen, was verlangt ist – nicht mehr, nicht weniger</p></div>
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Logo nie verzerren oder umfärben</p></div>
|
||
<div class="rule"><svg class="ic"><use href="#i-check"/></svg><p style="color:var(--txt);">Aus fremden Referenzen lernen, nie 1:1 kopieren</p></div>
|
||
</div>
|
||
<input type="text" placeholder="+ Regel hinzufügen …">
|
||
<div class="note" style="margin-top:0;">Regeln nehmen nicht am Scoring teil und können nicht absteigen. Der Nutzer sieht und verwaltet sie nicht – sie sind Teil des Produkts.</div>
|
||
|
||
<h3>Prompt-Einblick (letzte Generierung)</h3>
|
||
<div class="code">[SYSTEM] Regeln: cleaner Hintergrund; nur Verlangtes zeigen; Logo unverändert …<br>[ASSETS] Gesicht: Mara v3 (ref_0231) · Produkt: Rouge No. 5 v2 (ref_0198)<br>[ATTRIBUTE] Location: Kaiserslautern (5240) · Licht: warmes Abendlicht (6350) · Voice: warm-weiblich (5890)<br>[SCRIPT] Close-up: Hand hebt Lippenstift frontal … Voice: „Dein Rot. Dein Statement."<br><b>[USER-PROMPT]</b> Eine Frau hält einen roten Lippenstift in die Kamera.</div>
|
||
|
||
<h3>Elo-Parameter</h3>
|
||
<div class="row">
|
||
<div class="card metric"><p>K-Faktor neu</p><h4>32</h4></div>
|
||
<div class="card metric"><p>K-Faktor etabliert</p><h4>8</h4></div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="card metric"><p>Performance : Vote</p><h4>2 : 1</h4></div>
|
||
<div class="card metric"><p>Favorit bestätigt</p><h4>× 0,3</h4></div>
|
||
</div>
|
||
<div class="card"><p>Startwert neuer Einträge: <span class="hl">Kategorie-Durchschnitt</span> (Fallback 5000, wenn Kategorie leer)</p></div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- ============ NAVIGATION (neu: Feed · Profil · Plus · Dev) ============ -->
|
||
<nav class="nav" id="navBar">
|
||
<div class="nav-glass blur"></div>
|
||
<div class="nav-glass refract"></div>
|
||
<div class="nav-glass white"></div>
|
||
<div class="nav-glass ring"></div>
|
||
<button id="n-feed" class="on" onclick="go('explore')"><svg class="ic"><use href="#i-home"/></svg><span>Feed</span></button>
|
||
<button id="n-profile" onclick="go('profile')"><svg class="ic"><use href="#i-user"/></svg><span>Profil</span></button>
|
||
<button id="n-create" class="plus" onclick="go('create')" aria-label="Neuer KI-Post">
|
||
<div class="lm-shader lm-bg"></div>
|
||
<div class="lm-core"></div>
|
||
<div class="lm-ic"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#9a9a9a" stroke-width="2.4" stroke-linecap="round" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 5 V19 M5 12 H19"/></svg></div>
|
||
</button>
|
||
<button id="n-dev" onclick="go('devmode')" style="opacity:.55;" title="Nur intern sichtbar"><svg class="ic"><use href="#i-gear"/></svg><span>Dev</span></button>
|
||
</nav>
|
||
|
||
<!-- ============ INFO-SHEET (Präsentationsnotizen) ============ -->
|
||
<div class="backdrop" id="backdrop" onclick="toggleInfo(false)"></div>
|
||
<div class="sheet" id="infoSheet">
|
||
<div class="grab"></div>
|
||
<h2>BrandLoop – Prototyp</h2>
|
||
<p><b>Textversion:</b> Alle Bilder & Videos sind durch Beschreibungen / Dummy-Verläufe ersetzt. Alles ist klickbar, Karten sind swipebar.</p>
|
||
<p style="margin-bottom:6px;"><b>Neu (Explore-Konzept):</b></p>
|
||
<ul>
|
||
<li>Feed: swipen wie Tinder – rechts = Like, links = Skip, Tippen blättert die Bild-Kette</li>
|
||
<li>Detail (↺-Button): Prompt übernehmen, eigenes Modell einsetzen → landet vorausgefüllt im Editor</li>
|
||
<li>Plus: neuer KI-Post mit Bild-Kette & Format – Szene- und Modell-Flow von dort erreichbar</li>
|
||
<li>Menschlein (Profil): Brand-Profil inkl. kompletter Knowledge Base & Verbessern</li>
|
||
<li>Navbar verschlankt: Home → Profil, „Erstellen"/„Verbessern" raus, Knowledge im Profil</li>
|
||
</ul>
|
||
<p style="margin-bottom:0;"><b>Klickpfad zum Präsentieren:</b><br>Feed (swipen) → ↺ Detail → Nachmachen → Editor → Profil (Knowledge) → Verbessern → Dev-Modus</p>
|
||
</div>
|
||
|
||
<script>
|
||
/* ---------- Navigation ---------- */
|
||
function go(id){
|
||
document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active'));
|
||
document.getElementById(id).classList.add('active');
|
||
var navMap={
|
||
explore:'n-feed',
|
||
profile:'n-profile','kb-detail':'n-profile','improve-select':'n-profile','improve-input':'n-profile','improve-results':'n-profile','improve-vote':'n-profile',
|
||
create:'n-create',detail:'n-create',tut1:'n-create',tut2:'n-create',onboarding1:'n-create',onboarding2:'n-create',
|
||
'scene-create':'n-create','script-confirm':'n-create','scene-results':'n-create','scene-vote':'n-create',publish:'n-create',
|
||
'model-create':'n-create','model-result':'n-create',
|
||
devmode:'n-dev'
|
||
};
|
||
document.querySelectorAll('.nav button').forEach(b=>b.classList.remove('on'));
|
||
if(navMap[id]) document.getElementById(navMap[id]).classList.add('on');
|
||
document.body.classList.toggle('noscroll', id==='explore'||id==='create');
|
||
window.scrollTo(0,0);
|
||
}
|
||
function pick(el){
|
||
el.parentElement.querySelectorAll('.pill').forEach(p=>p.classList.remove('on'));
|
||
el.classList.add('on');
|
||
}
|
||
function toggleInfo(open){
|
||
document.getElementById('backdrop').classList.toggle('open',open);
|
||
document.getElementById('infoSheet').classList.toggle('open',open);
|
||
}
|
||
|
||
/* ---------- Explore-Feed (Swipe-Deck, portiert aus BrandLoop.dc.html) ---------- */
|
||
var ACCENT='#ff5c39';
|
||
var HUES={Produkt:40, Mensch:260, Szene:170};
|
||
var POSTS=[
|
||
{id:1, creator:'Lena M.', cat:'Produkt', model:'Sneaker Studio v2', video:true, h:250, imgs:['[ki-video: sneaker spot]'],
|
||
pics:['uploads/pasted-1784663207742-0.jpg']},
|
||
{id:2, creator:'Mara S.', cat:'Produkt', model:'Glow Serum v3', video:false, h:150, imgs:['Toner im Bogenfenster','Age Decoder Essence','Poster-Ad'],
|
||
pics:['uploads/pasted-1784643149542-0.jpg','uploads/pasted-1784643165286-0.jpg','uploads/pasted-1784643111353-0.jpg'],
|
||
avatar:'uploads/pasted-1784663200459-0.jpg'},
|
||
{id:3, creator:'Jonas K.', cat:'Mensch', model:'Coach Avatar', video:true, h:40, imgs:['[ki-video: gym coaching ad]'],
|
||
pics:['uploads/pasted-1784663200459-0.jpg']},
|
||
{id:4, creator:'Tom B.', cat:'Mensch', model:'Barber Ich v1', video:false, h:90, imgs:['[ki-bild 1/4: portrait]','[ki-bild 2/4: fade cut]','[ki-bild 3/4: shop szene]','[ki-bild 4/4: logo karte]'],
|
||
pics:['uploads/pasted-1784663261701-0.jpg','uploads/pasted-1784663207742-0.jpg','uploads/pasted-1784663200459-0.jpg','uploads/pasted-1784663233931-0.jpg']},
|
||
{id:5, creator:'Feld & Co',cat:'Szene', model:'Café Interieur', video:false, h:190, imgs:['[ki-bild 1/3: tresen]','[ki-bild 2/3: latte art]','[ki-bild 3/3: fassade]'],
|
||
pics:['uploads/pasted-1784663233931-0.jpg','uploads/pasted-1784663383522-0.jpg','uploads/pasted-1784663261701-0.jpg']},
|
||
{id:6, creator:'Nina R.', cat:'Produkt', model:'Schmuck Makro', video:false, h:310, imgs:['[ki-bild: ring makro]'],
|
||
pics:['uploads/pasted-1784663383522-0.jpg']},
|
||
{id:7, creator:'Kai W.', cat:'Szene', model:'Immo Walkthrough', video:true, h:210, imgs:['[ki-video: wohnungs-tour]'],
|
||
pics:['uploads/pasted-1784663233931-0.jpg']}
|
||
];
|
||
var X={tab:'posts', idx:0, dx:0, imgIdx:0, liked:[], anim:false, hoodCx:null, hoodHalf:null, hoodRaf:null, centers:null, halves:null};
|
||
var TAB_CENTERS={videos:40, folge:205, posts:366};
|
||
var TAB_HALVES={videos:40, folge:46, posts:35};
|
||
|
||
/* Bilder vorladen: nur geladene Dateien werden benutzt, sonst Dummy-Verlauf */
|
||
var PICS_OK={};
|
||
function pic(p,i){ var u=p.pics&&p.pics[i]; return (u&&PICS_OK[u])?u:null; }
|
||
function preloadPics(){
|
||
var all={};
|
||
POSTS.forEach(function(p){ (p.pics||[]).forEach(function(u){ all[u]=1; }); if(p.avatar) all[p.avatar]=1; });
|
||
Object.keys(all).forEach(function(u){
|
||
var im=new Image();
|
||
im.onload=function(){ PICS_OK[u]=true; renderDeck(); renderDetailStrip(); renderCreateStack(); };
|
||
im.src=u;
|
||
});
|
||
}
|
||
|
||
function dummy(h){
|
||
return 'linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),'+
|
||
'repeating-linear-gradient(135deg,transparent 0 14px,rgba(255,255,255,.05) 14px 28px),'+
|
||
'linear-gradient(160deg,oklch(.62 .09 '+h+'),oklch(.34 .09 '+(h+40)+'))';
|
||
}
|
||
function deck(){
|
||
if(X.tab==='videos') return POSTS.filter(function(p){return p.video;});
|
||
if(X.tab==='folge') return POSTS.filter(function(p){return ['Mara S.','Kai W.','Lena M.'].indexOf(p.creator)>=0;});
|
||
return POSTS.filter(function(p){return !p.video;});
|
||
}
|
||
|
||
/* Hood-Kurve unter dem aktiven Tab (Geometrie 1:1 aus BrandLoop.dc.html):
|
||
pro Tab eigene Breite (nh = halbe Plateau-Breite), am Bildschirmrand
|
||
verschmilzt die Hood mit der Kante statt eine Schulter zu zeichnen */
|
||
function hoodPath(cx, nh){
|
||
var W=430, top=8, floor=76, r=40, sw=80, bt=.6, tt=.6, H=120;
|
||
var xl=cx-nh, xr=cx+nh, lStart=xl-sw, rEnd=xr+sw;
|
||
var rl=Math.max(8,Math.min(r,lStart-2)), rr=Math.max(8,Math.min(r,W-rEnd-2));
|
||
var d;
|
||
if(lStart<=24){
|
||
d='M0 '+H+' L0 '+Math.min(floor+r,H-4)+' Q0 '+floor+' '+Math.min(Math.max(xl,r),xr-10)+' '+floor+' ';
|
||
}else{
|
||
d='M0 '+H+' L0 '+(top+rl)+' Q0 '+top+' '+rl+' '+top+' ';
|
||
d+='L'+lStart+' '+top+' C'+(lStart+sw*tt)+' '+top+' '+(xl-sw*bt)+' '+floor+' '+xl+' '+floor+' ';
|
||
}
|
||
d+='L'+xr+' '+floor+' ';
|
||
if(rEnd>=W-24){
|
||
d+='L'+Math.max(Math.min(xr,W-r),xl+10)+' '+floor+' Q'+W+' '+floor+' '+W+' '+Math.min(floor+r,H-4)+' L'+W+' '+H+' Z';
|
||
}else{
|
||
d+='C'+(xr+sw*bt)+' '+floor+' '+(rEnd-sw*tt)+' '+top+' '+rEnd+' '+top+' ';
|
||
d+='L'+(W-rr)+' '+top+' Q'+W+' '+top+' '+W+' '+(top+rr)+' L'+W+' '+H+' Z';
|
||
}
|
||
return d;
|
||
}
|
||
function centerOf(k){ return (X.centers&&X.centers[k]!=null)?X.centers[k]:TAB_CENTERS[k]; }
|
||
function halfOf(k){ return (X.halves&&X.halves[k]!=null)?X.halves[k]:TAB_HALVES[k]; }
|
||
/* Tab-Positionen aus dem DOM messen (in 430er-viewBox-Koordinaten) */
|
||
function measureTabs(){
|
||
var cont=document.querySelector('.x-tabs');
|
||
if(!cont||!cont.offsetWidth) return;
|
||
var scale=430/cont.offsetWidth;
|
||
var els={};
|
||
['videos','folge','posts'].forEach(function(k){ els[k]=cont.querySelector('.x-tab[data-tab="'+k+'"]'); });
|
||
if(!els.videos||!els.folge||!els.posts) return;
|
||
function m(el){ return {L:el.offsetLeft*scale, R:(el.offsetLeft+el.offsetWidth)*scale}; }
|
||
var v=m(els.videos), f=m(els.folge), p=m(els.posts);
|
||
var sw=80, m1=(v.R+f.L)/2, m2=(f.R+p.L)/2;
|
||
var x={videos:[v.L-12, m1-sw/2], folge:[m1+sw/2, m2-sw/2], posts:[m2+sw/2, p.R+12]};
|
||
var c={}, h={};
|
||
for(var k in x){ c[k]=(x[k][0]+x[k][1])/2; h[k]=(x[k][1]-x[k][0])/2; }
|
||
X.centers=c; X.halves=h;
|
||
}
|
||
function setHood(cx,nh){
|
||
X.hoodCx=cx; X.hoodHalf=nh;
|
||
document.getElementById('xHoodPath').setAttribute('d',hoodPath(cx,nh));
|
||
}
|
||
function animateHood(target,targetHalf){
|
||
if(X.hoodRaf) cancelAnimationFrame(X.hoodRaf);
|
||
var from=(X.hoodCx==null)?centerOf(X.tab):X.hoodCx;
|
||
var fromH=(X.hoodHalf==null)?halfOf(X.tab):X.hoodHalf;
|
||
var t0=performance.now(), dur=460, c1=1.3;
|
||
function step(now){
|
||
var t=Math.min((now-t0)/dur,1);
|
||
var e=1+(c1+1)*Math.pow(t-1,3)+c1*Math.pow(t-1,2);
|
||
setHood(from+(target-from)*e, fromH+(targetHalf-fromH)*e);
|
||
if(t<1) X.hoodRaf=requestAnimationFrame(step);
|
||
}
|
||
X.hoodRaf=requestAnimationFrame(step);
|
||
}
|
||
|
||
function renderTabs(){
|
||
document.querySelectorAll('.x-tab').forEach(function(el){
|
||
el.classList.toggle('on', el.dataset.tab===X.tab);
|
||
});
|
||
}
|
||
function renderBlur(){
|
||
var d=deck(), top=d[X.idx];
|
||
var el=document.getElementById('xBlur');
|
||
if(!top){ el.style.background='var(--bg)'; return; }
|
||
var imgI=Math.min(X.imgIdx, top.imgs.length-1), u=pic(top,imgI);
|
||
el.style.background = u ? '#0a0a0a url("'+u+'") center / cover no-repeat' : dummy(top.h+imgI*25);
|
||
}
|
||
function esc(s){ return s.replace(/&/g,'&').replace(/</g,'<'); }
|
||
|
||
function cardTransform(depth){
|
||
return depth===0 ? 'translateX(0px) rotate(0deg)' : 'scale('+(1-depth*.06)+') translateY('+(-depth*34)+'px)';
|
||
}
|
||
/* settle=true: Karten starten eine Position tiefer und gleiten nach vorn
|
||
(Nachrueck-Animation aus dem Design nach Fling/Tab-Wechsel) */
|
||
function renderDeck(settle){
|
||
var host=document.getElementById('xDeck');
|
||
var d=deck();
|
||
renderBlur();
|
||
if(X.idx>=d.length){
|
||
host.innerHTML=
|
||
'<div class="x-empty">'+
|
||
'<div style="font-size:17px; font-weight:700;">Alles gesehen ✦</div>'+
|
||
'<div style="font-size:13px; color:rgba(255,255,255,.5);">Du hast '+X.liked.length+' Posts gemerkt</div>'+
|
||
'<div id="xReset" style="padding:11px 22px; border-radius:100px; background:#fff; color:#000; font-size:13px; font-weight:700; cursor:pointer;">Nochmal ansehen</div>'+
|
||
'</div>';
|
||
document.getElementById('xReset').onclick=function(){ X.idx=0; X.dx=0; X.imgIdx=0; renderDeck(); };
|
||
return;
|
||
}
|
||
var html='';
|
||
var slice=d.slice(X.idx, X.idx+4);
|
||
for(var i=slice.length-1; i>=0; i--){
|
||
var p=slice[i], top=(i===0);
|
||
var imgI=top?Math.min(X.imgIdx,p.imgs.length-1):0;
|
||
var u=pic(p,imgI);
|
||
var hue=p.h+imgI*25;
|
||
var depth=settle?i+1:i;
|
||
var tf=(top&&!settle)
|
||
? 'translateX('+X.dx+'px) rotate('+(X.dx/22)+'deg)'
|
||
: cardTransform(depth);
|
||
html+='<div class="x-card'+(top?' top':'')+'" data-i="'+i+'" style="z-index:'+(5-i)+'; transform:'+tf+'; transition:'+(settle?'none':'transform .45s cubic-bezier(.22,1,.36,1)')+'; cursor:'+(top?'grab':'default')+';">';
|
||
var bg=u ? '#141414 url("'+u+'") center / cover no-repeat' : dummy(hue);
|
||
html+='<div class="img" style="background:'+bg+';'+(top?'':' filter:brightness(.85);')+'"></div>';
|
||
if(top){
|
||
if(!u) html+='<div class="imglabel"><span>'+esc(p.imgs[imgI])+'</span></div>';
|
||
if(p.video){
|
||
html+='<div class="playwrap"><div class="play"><svg width="22" height="22" viewBox="0 0 24 24" fill="#fff"><path d="M8 5 L19 12 L8 19 Z"/></svg></div></div>';
|
||
}
|
||
html+='<div class="x-segs">';
|
||
for(var j=0;j<p.imgs.length;j++){
|
||
html+='<div style="background:'+(j<=imgI?'rgba(255,255,255,.9)':'rgba(255,255,255,.28)')+';"></div>';
|
||
}
|
||
html+='</div>';
|
||
html+='<div class="x-chips"><div>'+esc(p.cat)+'</div>'+(p.imgs.length>1?'<div>⧉ '+p.imgs.length+' Bilder</div>':'')+'</div>';
|
||
var avOk=p.avatar&&PICS_OK[p.avatar];
|
||
var avBg=avOk ? '#141414 url("'+p.avatar+'") 50% 16% / 300% no-repeat'
|
||
: 'linear-gradient(140deg,oklch(.72 .13 '+HUES[p.cat]+'),oklch(.5 .13 '+HUES[p.cat]+'))';
|
||
html+='<div class="x-meta">'+
|
||
'<div class="av" style="background:'+avBg+';">'+(avOk?'':esc(p.creator[0]))+'</div>'+
|
||
'<div style="min-width:0;"><div class="nm">'+esc(p.creator)+'</div><div class="md">Modell · '+esc(p.model)+'</div></div>'+
|
||
'</div>';
|
||
html+='<div class="x-badge like" id="xLikeBadge">LIKE</div><div class="x-badge skip" id="xSkipBadge">SKIP</div>';
|
||
}
|
||
html+='</div>';
|
||
}
|
||
host.innerHTML=html;
|
||
var topEl=host.querySelector('.x-card.top');
|
||
if(topEl) topEl.addEventListener('pointerdown', onDown);
|
||
if(settle){
|
||
requestAnimationFrame(function(){ requestAnimationFrame(function(){
|
||
host.querySelectorAll('.x-card').forEach(function(el){
|
||
el.style.transition='transform .45s cubic-bezier(.22,1,.36,1)';
|
||
el.style.transform=cardTransform(+el.dataset.i);
|
||
});
|
||
});});
|
||
}
|
||
}
|
||
|
||
function fling(dir){
|
||
if(X.anim) return;
|
||
var d=deck(), post=d[X.idx];
|
||
X.anim=true;
|
||
var topEl=document.querySelector('#xDeck .x-card.top');
|
||
if(topEl){
|
||
topEl.style.transition='transform .3s cubic-bezier(.4,0,.7,1), opacity .3s ease';
|
||
topEl.style.transform='translateX('+(dir*640)+'px) rotate('+(dir*640/22)+'deg)';
|
||
topEl.style.opacity='0';
|
||
}
|
||
setTimeout(function(){
|
||
if(dir>0 && post) X.liked.push(post.id);
|
||
X.idx++; X.dx=0; X.imgIdx=0; X.anim=false;
|
||
renderDeck(true);
|
||
},300);
|
||
}
|
||
|
||
function onDown(e){
|
||
if(X.anim) return;
|
||
e.preventDefault();
|
||
var sx=e.clientX, moved=false;
|
||
var topEl=e.currentTarget;
|
||
var likeB=document.getElementById('xLikeBadge'), skipB=document.getElementById('xSkipBadge');
|
||
function mv(ev){
|
||
var d=ev.clientX-sx;
|
||
if(Math.abs(d)>5) moved=true;
|
||
X.dx=d;
|
||
topEl.style.transition='none';
|
||
topEl.style.transform='translateX('+d+'px) rotate('+(d/22)+'deg)';
|
||
if(likeB) likeB.style.opacity=Math.min(Math.max(d,0)/90,1);
|
||
if(skipB) skipB.style.opacity=Math.min(Math.max(-d,0)/90,1);
|
||
}
|
||
function up(ev){
|
||
window.removeEventListener('pointermove',mv);
|
||
window.removeEventListener('pointerup',up);
|
||
var d=ev.clientX-sx;
|
||
if(Math.abs(d)>110){ fling(d>0?1:-1); return; }
|
||
X.dx=0;
|
||
topEl.style.transition='transform .45s cubic-bezier(.22,1,.36,1)';
|
||
topEl.style.transform='translateX(0) rotate(0)';
|
||
if(likeB) likeB.style.opacity=0;
|
||
if(skipB) skipB.style.opacity=0;
|
||
if(!moved){
|
||
var post=deck()[X.idx];
|
||
if(post && post.imgs.length>1){ X.imgIdx=(X.imgIdx+1)%post.imgs.length; renderDeck(); }
|
||
}
|
||
}
|
||
window.addEventListener('pointermove',mv);
|
||
window.addEventListener('pointerup',up);
|
||
}
|
||
|
||
document.querySelectorAll('.x-tab').forEach(function(el){
|
||
el.addEventListener('click',function(){
|
||
if(X.tab===el.dataset.tab) return;
|
||
var k=el.dataset.tab;
|
||
var deckEl=document.getElementById('xDeck'), blurEl=document.getElementById('xBlur');
|
||
animateHood(centerOf(k), halfOf(k));
|
||
deckEl.style.transition='opacity .18s ease';
|
||
deckEl.style.opacity='0'; blurEl.style.opacity='0';
|
||
setTimeout(function(){
|
||
X.tab=k; X.idx=0; X.dx=0; X.imgIdx=0;
|
||
renderTabs(); renderDeck(true);
|
||
deckEl.style.opacity='1'; blurEl.style.opacity='1';
|
||
},180);
|
||
});
|
||
});
|
||
window.addEventListener('resize',function(){
|
||
measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab)); updateGlassMap();
|
||
});
|
||
document.getElementById('btnSkip').onclick=function(){ fling(-1); };
|
||
document.getElementById('btnLike').onclick=function(){ fling(1); };
|
||
document.getElementById('btnDetail').onclick=function(){ go('detail'); };
|
||
|
||
/* ---------- Detail: Bild-Strip (Maras Kette, echte Bilder mit Fallback) ---------- */
|
||
function renderDetailStrip(){
|
||
var host=document.getElementById('dStrip');
|
||
if(!host) return;
|
||
var p=POSTS[1];
|
||
var av=document.getElementById('dAvatar');
|
||
if(av && p.avatar && PICS_OK[p.avatar]){
|
||
av.style.background='#141414 url("'+p.avatar+'") 50% 16% / 300% no-repeat';
|
||
av.textContent='';
|
||
}
|
||
host.innerHTML=p.imgs.map(function(label,i){
|
||
var u=pic(p,i);
|
||
var bg=u ? '#141414 url("'+u+'") center / cover no-repeat' : dummy(150+i*25);
|
||
return '<div class="d-img" style="background:'+bg+';">'+
|
||
(u?'':'<span class="lbl">'+esc(label)+'</span>')+
|
||
'<span class="num">'+(i+1)+'/'+p.imgs.length+'</span></div>';
|
||
}).join('');
|
||
}
|
||
|
||
/* ---------- Detail: Modell wählen + Nachmachen ---------- */
|
||
var MODELS=['Mensch – Ich (Avatar)','Produkt – Kerze Studio','Szene – Showroom'];
|
||
var D={model:1, remade:false};
|
||
function renderDetailModels(){
|
||
var host=document.getElementById('detailModels');
|
||
host.innerHTML=MODELS.map(function(m,i){
|
||
return '<div class="chip'+(i===D.model?' on':'')+'" data-i="'+i+'"><div class="dot"></div>'+m+'</div>';
|
||
}).join('');
|
||
host.querySelectorAll('.chip').forEach(function(c){
|
||
c.onclick=function(){ D.model=+c.dataset.i; D.remade=false; renderDetailModels(); };
|
||
});
|
||
document.getElementById('remakeLabel').textContent=
|
||
D.remade ? '✓ Übernommen — im Editor geöffnet' : 'Nachmachen mit „'+MODELS[D.model].split(' – ')[1]+'“';
|
||
}
|
||
document.getElementById('remakeBtn').onclick=function(){
|
||
if(D.remade) return;
|
||
D.remade=true; renderDetailModels();
|
||
setTimeout(function(){
|
||
document.getElementById('createPrompt').value=document.getElementById('detailPrompt').textContent.trim();
|
||
C.model=D.model; renderCreateModels();
|
||
go('create');
|
||
D.remade=false; renderDetailModels();
|
||
},900);
|
||
};
|
||
|
||
/* ---------- Create: Vorschau-Stack / Optionen / Prompt-Beam / Fake-Tastatur ---------- */
|
||
var C={model:0, count:1, format:'4:5', mediaType:'image', optOpen:false, kbOpen:false, generating:0};
|
||
var C_MODELS=[
|
||
{name:'Ich (Avatar)', token:'@Ich', hue:260},
|
||
{name:'Kerze Studio', token:'@Kerze', hue:40},
|
||
{name:'Showroom', token:'@Showroom', hue:170}
|
||
];
|
||
function renderCreateStack(){
|
||
var host=document.getElementById('cStack');
|
||
if(!host) return;
|
||
var isVideo=C.mediaType==='video';
|
||
var isChain=!isVideo&&C.count>1;
|
||
var pr={'1:1':1,'4:5':.8,'9:16':.5625}[C.format];
|
||
var ph=258, pw=Math.round(ph*pr);
|
||
var cp=POSTS[1], u=pic(cp,0);
|
||
var bg=u?'#141414 url("'+u+'") center / cover no-repeat':dummy(150);
|
||
var html='';
|
||
var nBehind=isChain?Math.min(C.count-1,2):0;
|
||
for(var k=nBehind;k>=1;k--){
|
||
html+='<div class="c-behind" style="width:'+pw+'px; height:'+ph+'px; transform:translateX(-50%) rotate('+(k===1?-6:6)+'deg) translateY('+(4*k)+'px) scale('+(1-.04*k)+');"></div>';
|
||
}
|
||
html+='<div class="c-preview" style="width:'+pw+'px; height:'+ph+'px; background:'+bg+';">';
|
||
if(isVideo){
|
||
html+='<div style="position:absolute; inset:0; display:grid; place-items:center; pointer-events:none;"><div style="width:62px; height:62px; border-radius:100px; background:rgba(10,10,10,.5); backdrop-filter:blur(8px); display:grid; place-items:center;"><svg width="20" height="20" viewBox="0 0 24 24" fill="#fff"><path d="M8 5 L19 12 L8 19 Z"/></svg></div></div>';
|
||
html+='<div style="position:absolute; top:12px; left:12px; padding:5px 10px; border-radius:100px; background:rgba(10,10,10,.55); font-size:11px; font-weight:700; letter-spacing:.06em;">VIDEO · 0:08</div>';
|
||
}
|
||
if(isChain){
|
||
html+='<div style="position:absolute; top:12px; right:12px; padding:5px 10px; border-radius:100px; background:rgba(10,10,10,.55); font-size:11px; font-weight:700;">1/'+C.count+'</div>';
|
||
html+='<div style="position:absolute; left:0; right:0; bottom:14px; display:flex; justify-content:center; align-items:center; gap:5px;">';
|
||
for(var i=0;i<C.count;i++){
|
||
html+='<div style="width:'+(i===0?16:6)+'px; height:6px; border-radius:100px; background:'+(i===0?'#fff':'rgba(255,255,255,.45)')+'; transition:width .2s;"></div>';
|
||
}
|
||
html+='</div>';
|
||
}
|
||
html+='</div>';
|
||
host.innerHTML=html;
|
||
document.getElementById('cSelLabel').textContent = isVideo ? ('Video · '+C.format) : ((C.count===1?'Bild':C.count+'er-Kette')+' · '+C.format);
|
||
document.getElementById('cChevron').style.transform=C.optOpen?'rotate(180deg)':'none';
|
||
document.getElementById('cOpts').style.display=C.optOpen?'block':'none';
|
||
}
|
||
function pills(hostId, items, activeVal, onPick){
|
||
var host=document.getElementById(hostId);
|
||
host.innerHTML=items.map(function(it){
|
||
return '<div class="pill'+(it.v===activeVal?' on':'')+'" data-v="'+it.v+'">'+it.label+'</div>';
|
||
}).join('');
|
||
host.querySelectorAll('.pill').forEach(function(p){
|
||
p.onclick=function(){ onPick(p.dataset.v); };
|
||
});
|
||
}
|
||
function renderCreateOpts(){
|
||
pills('typeRow',[{v:'image',label:'Bild'},{v:'video',label:'Video'}],C.mediaType,function(v){C.mediaType=v; renderCreateOpts(); renderCreateStack();});
|
||
pills('formatRow',[{v:'1:1',label:'1:1'},{v:'4:5',label:'4:5'},{v:'9:16',label:'9:16'}],C.format,function(v){C.format=v; renderCreateOpts(); renderCreateStack();});
|
||
pills('countRow',[{v:'1',label:'1 Bild'},{v:'3',label:'3er'},{v:'5',label:'5er'}],String(C.count),function(v){C.count=+v; renderCreateOpts(); renderCreateStack();});
|
||
}
|
||
function toggleOpts(){ C.optOpen=!C.optOpen; renderCreateStack(); }
|
||
function renderCreateModels(){
|
||
var host=document.getElementById('createModels');
|
||
host.innerHTML=C_MODELS.map(function(m,i){
|
||
return '<div class="chip'+(i===C.model?' on':'')+'" data-i="'+i+'"><div class="dot"></div>'+m.name+'</div>';
|
||
}).join('');
|
||
host.querySelectorAll('.chip').forEach(function(c){
|
||
c.onclick=function(){ C.model=+c.dataset.i; renderCreateModels(); };
|
||
});
|
||
}
|
||
/* Prompt-Editing über die Fake-Tastatur (Caret-genau wie im Design) */
|
||
function editPrompt(mutate){
|
||
var ta=document.getElementById('createPrompt');
|
||
var p=ta.value, s=ta.selectionStart, e=ta.selectionEnd;
|
||
var r=mutate(p,s,e);
|
||
ta.value=r.val;
|
||
ta.focus(); ta.setSelectionRange(r.caret,r.caret);
|
||
}
|
||
function applyKey(code){
|
||
editPrompt(function(p,s,e){
|
||
if(code==='del'){
|
||
if(s!==e) return {val:p.slice(0,s)+p.slice(e), caret:s};
|
||
return {val:p.slice(0,Math.max(0,s-1))+p.slice(e), caret:Math.max(0,s-1)};
|
||
}
|
||
var ins=code==='space'?' ':code==='ret'?'\n':code;
|
||
return {val:p.slice(0,s)+ins+p.slice(e), caret:s+ins.length};
|
||
});
|
||
}
|
||
function insertToken(tok){
|
||
editPrompt(function(p,s,e){
|
||
var before=p.slice(0,s);
|
||
var lead=before&&!/\s$/.test(before)?' ':'';
|
||
var ins=lead+tok+' ';
|
||
return {val:before+ins+p.slice(e), caret:s+ins.length};
|
||
});
|
||
}
|
||
function setKb(open){
|
||
C.kbOpen=open;
|
||
document.getElementById('kbOverlay').classList.toggle('open',open);
|
||
document.getElementById('cScroll').classList.toggle('kb-open',open);
|
||
if(open){
|
||
C.optOpen=false; renderCreateStack();
|
||
requestAnimationFrame(function(){requestAnimationFrame(function(){
|
||
var el=document.getElementById('cScroll'); el.scrollTop=el.scrollHeight;
|
||
});});
|
||
}
|
||
}
|
||
function renderKb(){
|
||
var mh=document.getElementById('kbModels');
|
||
mh.innerHTML=C_MODELS.map(function(m,i){
|
||
return '<div class="kb-chip" data-i="'+i+'"><div class="dot" style="background:oklch(.7 .13 '+m.hue+');"></div>'+m.name+'</div>';
|
||
}).join('');
|
||
mh.querySelectorAll('.kb-chip').forEach(function(c){
|
||
function ins(e){ e.preventDefault(); insertToken(C_MODELS[+c.dataset.i].token); }
|
||
c.addEventListener('mousedown',ins);
|
||
c.addEventListener('touchstart',ins,{passive:false});
|
||
});
|
||
var rows=[
|
||
{pad:0, keys:'qwertyuiop'.split('').map(function(l){return {label:l, code:l};})},
|
||
{pad:16, keys:'asdfghjkl'.split('').map(function(l){return {label:l, code:l};})},
|
||
{pad:0, keys:[{label:'⇧', code:null, cls:'mod', flex:1.5}].concat('zxcvbnm'.split('').map(function(l){return {label:l, code:l};})).concat([{label:'⌫', code:'del', cls:'mod', flex:1.5}])},
|
||
{pad:0, keys:[{label:'123', code:null, cls:'mod', flex:1.6, fs:13},{label:'', code:'space', flex:5},{label:'return', code:'ret', flex:1.9, fs:13, bg:'rgba(122,162,255,.9)'}]}
|
||
];
|
||
var kh=document.getElementById('kbKeys'); var html='';
|
||
rows.forEach(function(row,ri){
|
||
html+='<div class="kb-row" style="padding:0 '+row.pad+'px;">';
|
||
row.keys.forEach(function(k,ki){
|
||
var st='';
|
||
if(k.flex) st+='flex:'+k.flex+';';
|
||
if(k.fs) st+='font-size:'+k.fs+'px;';
|
||
if(k.bg) st+='background:'+k.bg+';';
|
||
html+='<div class="kb-key'+(k.cls?' '+k.cls:'')+'" data-r="'+ri+'" data-k="'+ki+'" style="'+st+'">'+k.label+'</div>';
|
||
});
|
||
html+='</div>';
|
||
});
|
||
kh.innerHTML=html;
|
||
kh.querySelectorAll('.kb-key').forEach(function(el){
|
||
var k=rows[+el.dataset.r].keys[+el.dataset.k];
|
||
function press(e){ e.preventDefault(); if(k.code) applyKey(k.code); }
|
||
el.addEventListener('mousedown',press);
|
||
el.addEventListener('touchstart',press,{passive:false});
|
||
});
|
||
function done(e){ e.preventDefault(); document.getElementById('createPrompt').blur(); setKb(false); }
|
||
document.getElementById('kbDone').addEventListener('mousedown',done);
|
||
document.getElementById('kbDone').addEventListener('touchstart',done,{passive:false});
|
||
}
|
||
(function(){
|
||
var ta=document.getElementById('createPrompt');
|
||
ta.addEventListener('focus',function(){ setKb(true); });
|
||
ta.addEventListener('blur',function(){ setKb(false); });
|
||
})();
|
||
document.getElementById('generateBtn').onclick=function(){
|
||
if(C.generating) return;
|
||
var lbl=document.getElementById('generateLabel');
|
||
C.generating=1; lbl.textContent='Generiere '+C.count+' Bilder …';
|
||
setTimeout(function(){ C.generating=2; lbl.textContent='✓ In der Warteschlange'; },1400);
|
||
setTimeout(function(){ C.generating=0; lbl.textContent='Post generieren'; },3200);
|
||
};
|
||
|
||
/* ---------- Nav-Glas: dynamische Displacement-Map (aus dem Design) ---------- */
|
||
function updateGlassMap(){
|
||
var nav=document.getElementById('navBar'), img=document.getElementById('glassMapImage');
|
||
if(!nav||!img) return;
|
||
var w=nav.offsetWidth||286, h=nav.offsetHeight||56;
|
||
var r=Math.min(100,h/2), e=Math.min(w,h)*0.035;
|
||
var svg='<svg viewBox="0 0 '+w+' '+h+'" xmlns="http://www.w3.org/2000/svg">'+
|
||
'<defs><linearGradient id="rg" x1="100%" y1="0%" x2="0%" y2="0%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="red"/></linearGradient>'+
|
||
'<linearGradient id="bg" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="blue"/></linearGradient></defs>'+
|
||
'<rect width="'+w+'" height="'+h+'" fill="black"/>'+
|
||
'<rect width="'+w+'" height="'+h+'" rx="'+r+'" fill="url(#rg)"/>'+
|
||
'<rect width="'+w+'" height="'+h+'" rx="'+r+'" fill="url(#bg)" style="mix-blend-mode:difference"/>'+
|
||
'<rect x="'+e+'" y="'+e+'" width="'+(w-e*2)+'" height="'+(h-e*2)+'" rx="'+r+'" fill="hsl(0 0% 50% / 0.93)" style="filter:blur(11px)"/></svg>';
|
||
img.setAttribute('href','data:image/svg+xml,'+encodeURIComponent(svg));
|
||
}
|
||
|
||
/* ---------- Init ---------- */
|
||
setHood(centerOf(X.tab), halfOf(X.tab));
|
||
requestAnimationFrame(function(){ measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab)); updateGlassMap(); });
|
||
renderTabs();
|
||
renderDeck();
|
||
renderDetailStrip();
|
||
preloadPics();
|
||
renderDetailModels();
|
||
renderCreateModels();
|
||
renderCreateOpts();
|
||
renderCreateStack();
|
||
renderKb();
|
||
</script>
|
||
</body>
|
||
</html>
|