Comfy Apps: 12-workflow image-gen web GUI + payment frontend

- Flask frontend + serialized GPU worker + BTCPay invoice/webhook
- 12 example images rendered from the real ComfyUI workflows
- fix: ipadapter workflow uses modern IPAdapter node (was broken IPAdapterApply)
- helper scripts: generate/optimize examples
- README with deploy recipe
This commit is contained in:
drjones
2026-08-27 20:37:11 -07:00
commit 55bea5757c
23 changed files with 800 additions and 0 deletions

BIN
static/examples/article.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
static/examples/banner.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
static/examples/hero.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
static/examples/inpaint.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
static/examples/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
static/examples/upscale.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

68
static/style.css Normal file
View File

@@ -0,0 +1,68 @@
:root{
--bg:#0a0a0f; --bg2:#12121a; --card:#16161f; --card2:#1d1d28;
--text:#e8e8f0; --muted:#8a8a9a; --accent:#7c5cff; --accent2:#00e5c7;
--gold:#ffb347; --danger:#ff5470; --ok:#3ddc84;
--r:16px; --glow:0 0 24px rgba(124,92,255,.35);
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
min-height:100vh;background-image:radial-gradient(1200px 600px at 80% -10%,rgba(124,92,255,.15),transparent),
radial-gradient(900px 500px at -10% 110%,rgba(0,229,199,.10),transparent)}
a{color:var(--accent);text-decoration:none}
.wrap{max-width:1200px;margin:0 auto;padding:0 24px}
header{padding:28px 0;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px}
.logo{font-size:26px;font-weight:800;letter-spacing:-.5px}
.logo span{background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent}
.nav a{margin-left:20px;color:var(--muted);font-weight:600}
.nav a:hover{color:var(--text)}
.hero{padding:50px 0 30px}
.hero h1{font-size:46px;font-weight:800;letter-spacing:-1.5px;line-height:1.05}
.hero h1 b{background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p{color:var(--muted);font-size:18px;margin-top:14px;max-width:620px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:20px;padding:20px 0 60px}
.card{background:var(--card);border:1px solid #ffffff0d;border-radius:var(--r);padding:22px;transition:.2s;position:relative;overflow:hidden}
.card:hover{transform:translateY(-4px);border-color:var(--accent);box-shadow:var(--glow)}
.card .emoji{font-size:34px;margin-bottom:12px;width:100%;height:150px;align-items:center;justify-content:center}
.card .thumb{width:100%;height:150px;border-radius:12px;overflow:hidden;margin-bottom:14px;background:var(--bg2);border:1px solid #ffffff0d}
.card .thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:.25s}
.card:hover .thumb img{transform:scale(1.05)}
.example{max-width:680px;margin:0 0 22px}
.example img{width:100%;border-radius:var(--r);border:1px solid #ffffff14;display:block}
.example-caption{color:var(--muted);font-size:12.5px;margin-top:8px;text-align:center}
.card h3{font-size:19px;margin-bottom:6px}
.card .desc{color:var(--muted);font-size:13.5px;line-height:1.5;min-height:40px}
.card .price{margin-top:16px;font-weight:700;font-size:15px;color:var(--gold)}
.card .models{margin-top:6px;color:var(--muted);font-size:11.5px}
.card .go{display:inline-block;margin-top:16px;padding:9px 16px;border-radius:10px;
background:linear-gradient(90deg,var(--accent),var(--accent2));color:#000;font-weight:700;font-size:13.5px}
form.panel{background:var(--card);border:1px solid #ffffff0d;border-radius:var(--r);padding:28px;max-width:680px;margin:10px 0 60px}
form.panel label{display:block;font-size:13px;color:var(--muted);margin:16px 0 6px;font-weight:600}
form.panel textarea,input[type=text],input[type=number],select{width:100%;background:var(--bg2);border:1px solid #ffffff14;
border-radius:10px;padding:12px 14px;color:var(--text);font-size:15px;font-family:inherit}
form.panel textarea{min-height:110px;resize:vertical}
form.panel .btn{display:inline-block;margin-top:22px;padding:13px 26px;border-radius:12px;border:none;cursor:pointer;
background:linear-gradient(90deg,var(--accent),var(--accent2));color:#000;font-weight:800;font-size:15px}
.status{display:inline-block;padding:5px 12px;border-radius:20px;font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px}
.status.done{background:var(--ok);color:#000}.status.running{background:var(--accent);color:#fff}
.status.queued{background:var(--gold);color:#000}.status.failed{background:var(--danger);color:#fff}
.status.awaiting_payment{background:#555;color:#fff}
.result img{max-width:100%;border-radius:var(--r);border:1px solid #ffffff14}
.badge{display:inline-block;background:#ffffff10;border-radius:6px;padding:2px 8px;font-size:11px;color:var(--muted);margin:2px 3px 0 0}
.muted{color:var(--muted)}
.stats{display:flex;gap:28px;margin-top:30px;flex-wrap:wrap}
.stat{display:flex;flex-direction:column;align-items:flex-start}
.stat b{font-size:28px;font-weight:800;background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent}
.stat span{color:var(--muted);font-size:12.5px;margin-top:2px}
.how{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;padding:24px 0 10px}
.step{background:var(--card);border:1px solid #ffffff0d;border-radius:var(--r);padding:22px}
.step .n{width:34px;height:34px;border-radius:50%;background:linear-gradient(90deg,var(--accent),var(--accent2));color:#000;font-weight:800;display:flex;align-items:center;justify-content:center;margin-bottom:12px;font-size:16px}
.step h3{font-size:16px;margin-bottom:6px}
.step p{color:var(--muted);font-size:13px;line-height:1.5}
footer{border-top:1px solid #ffffff0d;padding:28px 0 40px;margin-top:20px;color:var(--muted);font-size:13px}
.field{margin-bottom:2px}
.row{display:flex;gap:14px;flex-wrap:wrap}
.row .field{flex:1;min-width:130px}
.row .field label{margin-top:8px}
form.panel input[type=file]{width:100%;background:var(--bg2);border:1px solid #ffffff14;border-radius:10px;padding:11px 14px;color:var(--muted);font-size:14px;font-family:inherit}
form.panel input[type=file]::file-selector-button{margin-right:12px;padding:6px 14px;border-radius:8px;border:none;background:var(--card2);color:var(--text);font-weight:600;cursor:pointer}
form.panel input[type=file]:hover::file-selector-button{background:var(--accent);color:#000}