AI Product — Image Generation Landing
A full one-page marketing landing for a fictional AI image generator, Prismeo, built in vanilla HTML, CSS, and JavaScript. It pairs a black, gallery-like canvas with iridescent magenta-to-teal-to-gold accents, a floating masonry hero gallery, and a live prompt bar. Interactive pieces include a style-picker that swaps the gallery, a before-to-after comparison slider, a monthly-annual pricing toggle, scroll reveals, a typewriter prompt, and a mobile nav with toast feedback.
MCP
Code
/* ============================================================
Prismeo — AI Image Generation Landing
Black + iridescent/holographic (magenta→teal→gold) palette
============================================================ */
:root {
/* core */
--bg: #070608;
--bg-2: #0e0c12;
--surface: #131019;
--surface-2: #1a1622;
--line: rgba(255, 255, 255, 0.09);
--line-strong: rgba(255, 255, 255, 0.16);
--ink: #f4f1f7;
--muted: #a39db3;
--faint: #6f6982;
/* iridescent accents */
--magenta: #ff3bd4;
--teal: #2ff3d6;
--gold: #ffd166;
--violet: #8b5cff;
--grad-holo: linear-gradient(110deg, #ff3bd4 0%, #8b5cff 30%, #2ff3d6 65%, #ffd166 100%);
--grad-soft: linear-gradient(135deg, rgba(255,59,212,0.18), rgba(47,243,214,0.16), rgba(255,209,102,0.14));
--radius: 16px;
--radius-lg: 26px;
--shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.8);
--glow: 0 0 0 1px rgba(255,255,255,0.06), 0 18px 50px -18px rgba(139, 92, 255, 0.45);
--maxw: 1180px;
--font-display: "Space Grotesk", system-ui, sans-serif;
--font-body: "Inter", system-ui, -apple-system, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: var(--font-body);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
/* ambient holographic glow */
body::before {
content: "";
position: fixed;
inset: -20% -10% auto -10%;
height: 70vh;
background:
radial-gradient(40% 60% at 18% 20%, rgba(255,59,212,0.16), transparent 70%),
radial-gradient(45% 55% at 82% 12%, rgba(47,243,214,0.14), transparent 70%),
radial-gradient(40% 50% at 55% 0%, rgba(255,209,102,0.10), transparent 70%);
filter: blur(20px);
z-index: 0;
pointer-events: none;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; line-height: 1.08; letter-spacing: -0.02em; margin: 0; }
.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; position: relative; z-index: 1; }
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
position: absolute; left: 12px; top: -60px; z-index: 100;
background: var(--ink); color: #000; padding: 10px 16px; border-radius: 10px;
transition: top .2s;
}
.skip-link:focus { top: 12px; }
.grad-text {
background: var(--grad-holo);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; color: transparent;
}
/* ---------- buttons ---------- */
.btn {
--pad: 12px 20px;
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
padding: var(--pad); border-radius: 999px; font-family: var(--font-display);
font-weight: 600; font-size: 0.95rem; cursor: pointer; border: 1px solid transparent;
transition: transform .18s ease, box-shadow .25s ease, background .25s ease, border-color .25s;
white-space: nowrap;
}
.btn:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.btn--primary {
color: #0a0710; background: var(--grad-holo); background-size: 200% 200%;
box-shadow: 0 10px 30px -10px rgba(255, 59, 212, 0.5);
}
.btn--primary:hover { transform: translateY(-2px); background-position: 100% 50%; box-shadow: 0 16px 40px -10px rgba(47, 243, 214, 0.55); }
.btn--ghost {
color: var(--ink); background: rgba(255,255,255,0.04); border-color: var(--line-strong);
}
.btn--ghost:hover { transform: translateY(-2px); border-color: var(--teal); background: rgba(47,243,214,0.08); }
.btn.full { width: 100%; }
.pill {
display: inline-flex; align-items: center; gap: 8px;
padding: 7px 14px; border-radius: 999px; font-size: 0.8rem; font-weight: 500;
background: rgba(255,255,255,0.04); border: 1px solid var(--line-strong); color: var(--muted);
}
.pill__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 10px var(--teal); animation: pulse 2s infinite; }
@keyframes pulse { 0%,100%{ opacity:1 } 50%{ opacity:.4 } }
.eyebrow {
font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--teal);
}
/* ---------- nav ---------- */
.nav {
position: sticky; top: 0; z-index: 50;
backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
background: rgba(7,6,8,0.55); border-bottom: 1px solid transparent;
transition: background .3s, border-color .3s;
}
.nav.is-stuck { background: rgba(7,6,8,0.85); border-bottom-color: var(--line); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; height: 72px; gap: 20px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; }
.brand__mark { width: 22px; height: 22px; border-radius: 7px; background: var(--grad-holo); box-shadow: 0 0 16px rgba(255,59,212,0.5); }
.nav__links { display: flex; gap: 28px; }
.nav__links a { color: var(--muted); font-size: 0.92rem; font-weight: 500; transition: color .2s; }
.nav__links a:hover { color: var(--ink); }
.nav__cta { display: flex; gap: 10px; align-items: center; }
.nav__toggle { display: none; background: none; border: 0; cursor: pointer; flex-direction: column; gap: 5px; padding: 8px; }
.nav__toggle span { width: 24px; height: 2px; background: var(--ink); border-radius: 2px; transition: transform .25s, opacity .2s; }
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
/* ---------- hero ---------- */
.hero { padding: 64px 0 88px; }
.hero__inner { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center; }
.hero__title { font-size: clamp(2.6rem, 6vw, 4.6rem); margin: 22px 0 18px; }
.hero__sub { font-size: 1.16rem; color: var(--muted); max-width: 30ch; }
.prompt-bar {
display: flex; align-items: center; gap: 8px; margin: 26px 0 12px;
background: var(--surface); border: 1px solid var(--line-strong);
border-radius: 999px; padding: 7px 7px 7px 18px; box-shadow: var(--shadow);
transition: border-color .25s, box-shadow .25s;
}
.prompt-bar:focus-within { border-color: var(--magenta); box-shadow: 0 0 0 4px rgba(255,59,212,0.15); }
.prompt-bar__icon { color: var(--gold); font-size: 1.1rem; }
.prompt-bar__input { flex: 1; background: none; border: 0; color: var(--ink); font-family: var(--font-body); font-size: 1rem; outline: none; min-width: 0; }
.prompt-bar__input::placeholder { color: var(--faint); }
.prompt-bar__btn { padding: 11px 22px; }
.prompt-bar__hint { font-size: 0.85rem; color: var(--faint); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chip { background: rgba(255,255,255,0.05); border: 1px solid var(--line); color: var(--muted); border-radius: 999px; padding: 5px 12px; font-size: 0.82rem; cursor: pointer; font-family: var(--font-mono); transition: all .2s; }
.chip:hover { color: var(--ink); border-color: var(--teal); background: rgba(47,243,214,0.08); }
.hero__proof { display: flex; align-items: center; gap: 14px; margin-top: 30px; }
.hero__proof p { color: var(--muted); font-size: 0.92rem; }
.avatars { display: flex; }
.avatars span { width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--bg); margin-left: -10px; }
.avatars span:first-child { margin-left: 0; }
.avatars span:nth-child(1){ background: linear-gradient(135deg,#ff3bd4,#8b5cff); }
.avatars span:nth-child(2){ background: linear-gradient(135deg,#2ff3d6,#3b82f6); }
.avatars span:nth-child(3){ background: linear-gradient(135deg,#ffd166,#ff7b54); }
.avatars span:nth-child(4){ background: linear-gradient(135deg,#8b5cff,#2ff3d6); }
/* hero masonry art */
.hero__art { position: relative; }
.masonry {
display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 92px; gap: 14px;
}
.tile { border-radius: 18px; box-shadow: var(--shadow); position: relative; overflow: hidden; animation: floaty 7s ease-in-out infinite; }
.tile::after { content:""; position:absolute; inset:0; background: linear-gradient(160deg, rgba(255,255,255,0.18), transparent 55%); mix-blend-mode: overlay; }
.t1 { grid-row: span 2; background: linear-gradient(150deg,#ff3bd4,#8b5cff 70%); }
.t2 { background: linear-gradient(150deg,#2ff3d6,#1ea7c4); }
.t3 { grid-row: span 2; background: linear-gradient(150deg,#ffd166,#ff7b54); }
.t4 { background: linear-gradient(150deg,#8b5cff,#2ff3d6); }
.t5 { grid-row: span 2; background: conic-gradient(from 120deg,#ff3bd4,#ffd166,#2ff3d6,#8b5cff,#ff3bd4); }
.t6 { background: linear-gradient(150deg,#3b82f6,#8b5cff); }
.tile:nth-child(2){ animation-delay:-1.2s } .tile:nth-child(3){ animation-delay:-2.4s }
.tile:nth-child(4){ animation-delay:-3.1s } .tile:nth-child(5){ animation-delay:-1.8s } .tile:nth-child(6){ animation-delay:-0.6s }
@keyframes floaty { 0%,100%{ transform: translateY(0) } 50%{ transform: translateY(-8px) } }
.hero__badge {
position: absolute; bottom: -14px; left: 50%; transform: translateX(-50%);
background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink);
font-family: var(--font-mono); font-size: 0.78rem; padding: 8px 16px; border-radius: 999px; box-shadow: var(--shadow);
}
/* ---------- logos ---------- */
.logos { padding: 28px 0 8px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.logos__label { text-align: center; color: var(--faint); font-size: 0.82rem; font-family: var(--font-mono); letter-spacing: 0.08em; margin: 0 0 18px; }
.logos__row { display: flex; flex-wrap: wrap; gap: 20px 44px; justify-content: center; align-items: center; padding-bottom: 22px; }
.logo { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; color: var(--faint); letter-spacing: 0.02em; opacity: .7; transition: opacity .2s, color .2s; }
.logo:hover { opacity: 1; color: var(--ink); }
/* ---------- section heads ---------- */
section { padding: 92px 0; }
.section-head { max-width: 620px; margin: 0 auto 48px; text-align: center; }
.section-head h2 { font-size: clamp(2rem, 4vw, 2.9rem); margin: 14px 0 12px; }
.section-head p { color: var(--muted); font-size: 1.05rem; }
/* ---------- style picker ---------- */
.tabs { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 34px; }
.tab {
font-family: var(--font-display); font-weight: 600; font-size: 0.92rem; cursor: pointer;
padding: 10px 18px; border-radius: 999px; color: var(--muted);
background: rgba(255,255,255,0.04); border: 1px solid var(--line); transition: all .22s;
}
.tab:hover { color: var(--ink); border-color: var(--line-strong); }
.tab.is-active { color: #0a0710; background: var(--grad-holo); border-color: transparent; box-shadow: 0 8px 24px -10px rgba(255,59,212,0.5); }
.tab:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.style-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.style-card {
aspect-ratio: 1; border-radius: var(--radius); position: relative; overflow: hidden;
box-shadow: var(--shadow); animation: fadeUp .5s ease both;
}
.style-card::after { content:""; position:absolute; inset:0; background: linear-gradient(160deg, rgba(255,255,255,0.16), transparent 50%); mix-blend-mode: overlay; }
.style-card span {
position: absolute; left: 12px; bottom: 12px; z-index: 2;
font-family: var(--font-mono); font-size: 0.72rem; color: #fff;
background: rgba(0,0,0,0.45); padding: 4px 10px; border-radius: 999px; backdrop-filter: blur(4px);
}
@keyframes fadeUp { from { opacity:0; transform: translateY(14px) scale(.98) } to { opacity:1; transform:none } }
/* ---------- features ---------- */
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.feature {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
padding: 30px 26px; transition: transform .25s, border-color .25s, box-shadow .25s; position: relative; overflow: hidden;
}
.feature::before { content:""; position:absolute; inset:0; background: var(--grad-soft); opacity:0; transition: opacity .3s; }
.feature:hover { transform: translateY(-6px); border-color: var(--line-strong); box-shadow: var(--glow); }
.feature:hover::before { opacity: 1; }
.feature > * { position: relative; z-index: 1; }
.feature__icon {
width: 48px; height: 48px; display: grid; place-items: center; border-radius: 14px;
background: rgba(255,255,255,0.05); border: 1px solid var(--line-strong); font-size: 1.3rem; color: var(--teal); margin-bottom: 18px;
}
.feature h3 { font-size: 1.2rem; margin-bottom: 8px; }
.feature p { color: var(--muted); font-size: 0.96rem; }
/* ---------- process ---------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; list-style: none; padding: 0; margin: 0; counter-reset: s; }
.step { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 32px 28px; position: relative; }
.step__num { font-family: var(--font-mono); font-size: 0.9rem; color: var(--gold); }
.step h3 { font-size: 1.35rem; margin: 14px 0 8px; background: var(--grad-holo); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.step p { color: var(--muted); }
/* ---------- before/after ---------- */
.ba {
position: relative; max-width: 880px; margin: 0 auto; aspect-ratio: 16/9;
border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); border: 1px solid var(--line-strong); user-select: none;
}
.ba__after { position: absolute; inset: 0; background: conic-gradient(from 200deg at 60% 40%, #ff3bd4, #8b5cff, #2ff3d6, #ffd166, #ff3bd4); }
.ba__before {
position: absolute; inset: 0; width: 50%; overflow: hidden;
background:
repeating-linear-gradient(45deg, #1a1622 0 14px, #221c2c 14px 28px);
border-right: 2px solid rgba(255,255,255,0.7);
}
.ba__tag { position: absolute; top: 14px; left: 14px; z-index: 3; font-family: var(--font-mono); font-size: 0.72rem; background: rgba(0,0,0,0.5); color:#fff; padding: 5px 11px; border-radius: 999px; }
.ba__tag--after { left: auto; right: 14px; }
.ba__range { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ew-resize; margin: 0; }
.ba__handle {
position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); z-index: 4;
width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
background: #fff; color: #000; font-size: 1.1rem; box-shadow: 0 6px 18px rgba(0,0,0,0.5); pointer-events: none;
}
/* ---------- pricing ---------- */
.pricing .section-head { margin-bottom: 36px; }
.toggle { display: inline-flex; align-items: center; gap: 12px; margin-top: 22px; }
.toggle__label { font-family: var(--font-mono); font-size: 0.85rem; color: var(--faint); transition: color .2s; }
.toggle__label.is-active { color: var(--ink); }
.toggle__label em { font-style: normal; color: var(--teal); }
.toggle__switch { width: 50px; height: 28px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line-strong); cursor: pointer; position: relative; padding: 0; }
.toggle__switch span { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--grad-holo); transition: transform .25s; }
.toggle__switch[aria-checked="true"] span { transform: translateX(22px); }
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
.plan {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
padding: 32px 28px; display: flex; flex-direction: column; transition: transform .25s, border-color .25s;
}
.plan:hover { transform: translateY(-4px); border-color: var(--line-strong); }
.plan--featured {
border-color: transparent; background:
linear-gradient(var(--surface), var(--surface)) padding-box,
var(--grad-holo) border-box;
border: 1.5px solid transparent; box-shadow: var(--glow); position: relative;
}
.plan__badge { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: var(--grad-holo); color: #0a0710; font-family: var(--font-display); font-weight: 700; font-size: 0.72rem; padding: 5px 14px; border-radius: 999px; }
.plan h3 { font-size: 1.4rem; }
.plan__desc { color: var(--muted); font-size: 0.92rem; margin: 6px 0 18px; }
.plan__price { display: flex; align-items: baseline; gap: 4px; margin-bottom: 20px; }
.plan__price .amount { font-family: var(--font-display); font-weight: 700; font-size: 2.6rem; }
.plan__price .per { color: var(--faint); font-size: 0.95rem; }
.plan__list { list-style: none; padding: 0; margin: 0 0 26px; display: grid; gap: 12px; flex: 1; }
.plan__list li { color: var(--muted); font-size: 0.95rem; padding-left: 26px; position: relative; }
.plan__list li::before { content: "✦"; position: absolute; left: 0; color: var(--teal); }
/* ---------- reviews ---------- */
.review-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.review { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 30px 28px; margin: 0; transition: transform .25s, border-color .25s; }
.review:hover { transform: translateY(-4px); border-color: var(--line-strong); }
.review blockquote { margin: 0 0 22px; font-size: 1.05rem; color: var(--ink); line-height: 1.55; }
.review figcaption { display: flex; align-items: center; gap: 12px; }
.review figcaption span:last-child { display: flex; flex-direction: column; }
.review figcaption strong { font-family: var(--font-display); }
.review figcaption em { font-style: normal; color: var(--faint); font-size: 0.85rem; }
.review__avatar { width: 42px; height: 42px; border-radius: 50%; flex: none; }
.review__avatar.a1 { background: linear-gradient(135deg,#ff3bd4,#8b5cff); }
.review__avatar.a2 { background: linear-gradient(135deg,#2ff3d6,#3b82f6); }
.review__avatar.a3 { background: linear-gradient(135deg,#ffd166,#ff7b54); }
/* ---------- cta ---------- */
.cta__inner {
text-align: center; max-width: 720px; margin: 0 auto;
background: var(--grad-soft); border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
padding: 56px 32px; box-shadow: var(--shadow);
}
.cta__inner h2 { font-size: clamp(1.8rem, 4vw, 2.7rem); margin-bottom: 12px; }
.cta__inner > p { color: var(--muted); margin-bottom: 26px; }
.cta__form { display: flex; gap: 10px; max-width: 460px; margin: 0 auto; }
.cta__form input { flex: 1; background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink); border-radius: 999px; padding: 13px 20px; font-family: var(--font-body); font-size: 1rem; outline: none; min-width: 0; }
.cta__form input:focus { border-color: var(--teal); }
.cta__fine { color: var(--faint); font-size: 0.82rem; margin-top: 14px; }
/* ---------- footer ---------- */
.footer { border-top: 1px solid var(--line); padding: 60px 0 30px; }
.footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 30px; padding-bottom: 36px; }
.footer__brand p { color: var(--faint); margin-top: 12px; font-size: 0.9rem; }
.footer h4 { font-family: var(--font-display); font-size: 0.95rem; margin-bottom: 14px; }
.footer nav { display: flex; flex-direction: column; gap: 10px; }
.footer nav a { color: var(--muted); font-size: 0.92rem; transition: color .2s; }
.footer nav a:hover { color: var(--ink); }
.footer__bar { display: flex; justify-content: space-between; align-items: center; padding-top: 24px; border-top: 1px solid var(--line); }
.footer__bar p { color: var(--faint); font-size: 0.85rem; }
.footer__social { display: flex; gap: 12px; }
.footer__social a { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%; background: rgba(255,255,255,0.05); border: 1px solid var(--line); transition: all .2s; }
.footer__social a:hover { border-color: var(--teal); color: var(--teal); }
/* ---------- toast ---------- */
.toast {
position: fixed; bottom: 28px; left: 50%; transform: translate(-50%, 140%);
background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink);
padding: 14px 22px; border-radius: 14px; box-shadow: var(--shadow); z-index: 200;
font-size: 0.95rem; transition: transform .35s cubic-bezier(.2,.9,.3,1.2); max-width: 90vw;
}
.toast.show { transform: translate(-50%, 0); }
/* ---------- scroll reveal ---------- */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in { opacity: 1; transform: none; }
/* ---------- responsive ---------- */
@media (max-width: 980px) {
.hero__inner { grid-template-columns: 1fr; gap: 40px; }
.hero__sub { max-width: none; }
.feature-grid, .style-grid { grid-template-columns: repeat(2, 1fr); }
.footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
.nav__links {
position: fixed; inset: 72px 0 auto 0; flex-direction: column; gap: 0;
background: rgba(10,8,14,0.97); backdrop-filter: blur(14px); padding: 8px 24px 22px;
border-bottom: 1px solid var(--line); transform: translateY(-130%); transition: transform .3s ease; z-index: 49;
}
.nav__links.open { transform: translateY(0); }
.nav__links a { padding: 14px 0; border-bottom: 1px solid var(--line); width: 100%; }
.nav__toggle { display: flex; }
.nav__cta .btn--ghost { display: none; }
section { padding: 64px 0; }
.steps, .plans, .review-grid, .feature-grid { grid-template-columns: 1fr; }
.plan--featured { order: -1; }
}
@media (max-width: 520px) {
.container { padding: 0 18px; }
.hero { padding: 40px 0 64px; }
.style-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
.prompt-bar { flex-wrap: wrap; border-radius: 22px; padding: 12px; }
.prompt-bar__btn { width: 100%; }
.cta__form { flex-direction: column; }
.cta__form .btn { width: 100%; }
.footer__grid { grid-template-columns: 1fr; }
.footer__bar { flex-direction: column; gap: 14px; text-align: center; }
.masonry { grid-auto-rows: 74px; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
.reveal { opacity: 1; transform: none; }
}/* ============================================================
Prismeo — landing page interactions (vanilla JS)
============================================================ */
(function () {
"use strict";
/* ---------- toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2600);
}
/* ---------- sticky nav shadow ---------- */
var nav = document.getElementById("nav");
function onScroll() {
if (window.scrollY > 12) nav.classList.add("is-stuck");
else nav.classList.remove("is-stuck");
}
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
/* ---------- mobile menu ---------- */
var toggle = document.getElementById("navToggle");
var links = document.getElementById("navLinks");
function closeMenu() {
links.classList.remove("open");
toggle.setAttribute("aria-expanded", "false");
}
toggle.addEventListener("click", function () {
var open = links.classList.toggle("open");
toggle.setAttribute("aria-expanded", open ? "true" : "false");
});
links.addEventListener("click", function (e) {
if (e.target.tagName === "A") closeMenu();
});
/* ---------- generic CTA toasts ---------- */
document.querySelectorAll("[data-toast]").forEach(function (el) {
el.addEventListener("click", function () {
toast(el.getAttribute("data-toast"));
});
});
/* ---------- hero prompt bar ---------- */
var promptForm = document.getElementById("hero-prompt");
var promptInput = document.getElementById("promptInput");
if (promptForm) {
promptForm.addEventListener("submit", function (e) {
e.preventDefault();
var v = promptInput.value.trim();
toast(v ? "Rendering: “" + v.slice(0, 40) + "” …" : "Type a prompt to begin ✨");
});
}
document.querySelectorAll("#promptHint .chip").forEach(function (chip) {
chip.addEventListener("click", function () {
promptInput.value = chip.textContent;
promptInput.focus();
toast("Loaded a starter prompt ✨");
});
});
/* ---------- placeholder rotating hero prompt (typewriter) ---------- */
var samples = [
"a holographic koi swimming through neon rain…",
"iridescent cathedral carved from liquid chrome…",
"a desert bloom under aurora light…",
"retro-future transit poster, risograph print…"
];
var si = 0, ci = 0, deleting = false;
function typeLoop() {
if (document.activeElement === promptInput) { setTimeout(typeLoop, 900); return; }
var word = samples[si];
if (!deleting) {
promptInput.placeholder = word.slice(0, ++ci);
if (ci === word.length) { deleting = true; return setTimeout(typeLoop, 1800); }
} else {
promptInput.placeholder = word.slice(0, --ci);
if (ci === 0) { deleting = false; si = (si + 1) % samples.length; }
}
setTimeout(typeLoop, deleting ? 32 : 58);
}
if (promptInput) setTimeout(typeLoop, 1200);
/* ---------- style picker tabs ---------- */
var STYLES = {
holo: {
label: ["aurora portrait", "chrome bloom", "prism city", "liquid sky", "neon koi", "glass orchid", "spectral wave", "iris nebula"],
grads: [
"conic-gradient(from 120deg,#ff3bd4,#8b5cff,#2ff3d6,#ffd166,#ff3bd4)",
"linear-gradient(150deg,#ff3bd4,#8b5cff 70%)",
"linear-gradient(150deg,#2ff3d6,#8b5cff)",
"radial-gradient(120% 120% at 20% 10%,#ffd166,#ff3bd4 60%,#8b5cff)"
]
},
oil: {
label: ["harvest field", "still life", "stormy port", "garden path", "fruit bowl", "river bend", "old town", "haystacks"],
grads: [
"linear-gradient(150deg,#b86b2e,#e0a458 60%,#6b4a2a)",
"linear-gradient(150deg,#3b6b4a,#88a25a)",
"linear-gradient(150deg,#7a4a2a,#c98b4a)",
"radial-gradient(120% 120% at 30% 20%,#e8c071,#9a5b2e 70%)"
]
},
cyber: {
label: ["rain alley", "megacity", "neon market", "drone view", "back street", "skybridge", "arcade", "tunnel run"],
grads: [
"linear-gradient(150deg,#ff2e97,#3b0f6b 70%)",
"linear-gradient(150deg,#00e0ff,#7a00ff)",
"linear-gradient(150deg,#ff006e,#0a0a3c)",
"radial-gradient(120% 120% at 70% 10%,#00ffd5,#ff2e97 60%,#1a0033)"
]
},
blueprint: {
label: ["engine bay", "floor plan", "turbine", "exploded view", "chassis", "circuit", "gearbox", "frame"],
grads: [
"linear-gradient(150deg,#0a2a52,#0e3e7a)",
"repeating-linear-gradient(0deg,#0c3168 0 18px,#0e3a7a 18px 19px)",
"linear-gradient(150deg,#08305f,#1259a8)",
"repeating-linear-gradient(45deg,#0b2e5c 0 14px,#103a72 14px 16px)"
]
},
claymation: {
label: ["round bot", "tiny house", "sleepy cat", "mushroom", "balloon", "snail", "lil ghost", "donut"],
grads: [
"linear-gradient(150deg,#ff9bd2,#ffd1a3)",
"linear-gradient(150deg,#a7e0c8,#ffe5a3)",
"linear-gradient(150deg,#c4b5fd,#fbcfe8)",
"radial-gradient(120% 120% at 30% 25%,#ffe0a3,#ff9bd2 70%)"
]
}
};
var grid = document.getElementById("styleGrid");
var tabs = Array.prototype.slice.call(document.querySelectorAll("#styleTabs .tab"));
function renderStyle(key) {
var set = STYLES[key];
if (!set || !grid) return;
grid.innerHTML = "";
for (var i = 0; i < 8; i++) {
var card = document.createElement("div");
card.className = "style-card";
card.style.animationDelay = (i * 0.04) + "s";
card.style.background = set.grads[i % set.grads.length];
var tag = document.createElement("span");
tag.textContent = set.label[i % set.label.length];
card.appendChild(tag);
grid.appendChild(card);
}
}
tabs.forEach(function (tab) {
tab.addEventListener("click", function () {
tabs.forEach(function (t) {
t.classList.remove("is-active");
t.setAttribute("aria-selected", "false");
});
tab.classList.add("is-active");
tab.setAttribute("aria-selected", "true");
renderStyle(tab.getAttribute("data-style"));
});
});
// keyboard arrow navigation on tabs
document.getElementById("styleTabs").addEventListener("keydown", function (e) {
var idx = tabs.indexOf(document.activeElement);
if (idx < 0) return;
if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
e.preventDefault();
var next = e.key === "ArrowRight" ? (idx + 1) % tabs.length : (idx - 1 + tabs.length) % tabs.length;
tabs[next].focus();
tabs[next].click();
}
});
renderStyle("holo");
/* ---------- before/after slider ---------- */
var range = document.getElementById("baRange");
var before = document.getElementById("baBefore");
var handle = document.getElementById("baHandle");
if (range) {
function syncBA() {
var v = range.value;
before.style.width = v + "%";
handle.style.left = v + "%";
}
range.addEventListener("input", syncBA);
syncBA();
}
/* ---------- pricing billing toggle ---------- */
var billSwitch = document.getElementById("billSwitch");
var billToggle = document.getElementById("billingToggle");
var amounts = document.querySelectorAll(".plan__price .amount");
if (billSwitch) {
billSwitch.addEventListener("click", function () {
var annual = billSwitch.getAttribute("aria-checked") !== "true";
billSwitch.setAttribute("aria-checked", annual ? "true" : "false");
billToggle.querySelectorAll(".toggle__label").forEach(function (l) {
l.classList.toggle("is-active", l.getAttribute("data-bill") === (annual ? "annual" : "monthly"));
});
amounts.forEach(function (a) {
var val = annual ? a.getAttribute("data-annual") : a.getAttribute("data-monthly");
a.textContent = "$" + val;
});
});
}
/* ---------- CTA email form ---------- */
var ctaForm = document.getElementById("ctaForm");
if (ctaForm) {
ctaForm.addEventListener("submit", function (e) {
e.preventDefault();
toast("You're on the list ✨ We'll be in touch.");
ctaForm.reset();
});
}
/* ---------- scroll reveal ---------- */
var reveals = document.querySelectorAll(".reveal");
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add("in");
io.unobserve(entry.target);
}
});
}, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" });
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add("in"); });
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Prismeo — Generate Impossible Images</title>
<meta name="description" content="Prismeo is an AI image generator that turns a single prompt into gallery-grade visuals across any style, resolution, and aspect ratio." />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- ===== NAV ===== -->
<header class="nav" id="nav">
<div class="container nav__inner">
<a class="brand" href="#top" aria-label="Prismeo home">
<span class="brand__mark" aria-hidden="true"></span>
<span class="brand__name">Prismeo</span>
</a>
<nav class="nav__links" id="navLinks" aria-label="Primary">
<a href="#styles">Styles</a>
<a href="#features">Features</a>
<a href="#showcase">Showcase</a>
<a href="#pricing">Pricing</a>
<a href="#reviews">Reviews</a>
</nav>
<div class="nav__cta">
<a href="#pricing" class="btn btn--ghost">Sign in</a>
<a href="#hero-prompt" class="btn btn--primary" data-toast="Spinning up your canvas…">Start creating</a>
</div>
<button class="nav__toggle" id="navToggle" aria-expanded="false" aria-controls="navLinks" aria-label="Toggle menu">
<span></span><span></span><span></span>
</button>
</div>
</header>
<main id="main">
<span id="top"></span>
<!-- ===== HERO ===== -->
<section class="hero" id="hero">
<div class="container hero__inner">
<div class="hero__copy reveal">
<span class="pill"><span class="pill__dot"></span> Diffusion v5 · now in public beta</span>
<h1 class="hero__title">Type a thought.<br /><span class="grad-text">Render the impossible.</span></h1>
<p class="hero__sub">Prismeo turns a single line of text into gallery-grade imagery — any style, any resolution, any aspect ratio — in seconds, not afternoons.</p>
<form class="prompt-bar" id="hero-prompt" autocomplete="off">
<span class="prompt-bar__icon" aria-hidden="true">✦</span>
<label class="sr-only" for="promptInput">Describe an image</label>
<input id="promptInput" class="prompt-bar__input" type="text" placeholder="a holographic koi swimming through neon rain…" />
<button class="btn btn--primary prompt-bar__btn" type="submit">Generate</button>
</form>
<p class="prompt-bar__hint" id="promptHint">Try: <button class="chip" type="button">iridescent desert at dusk</button><button class="chip" type="button">chrome orchid macro</button><button class="chip" type="button">retro-future transit poster</button></p>
<div class="hero__proof">
<div class="avatars" aria-hidden="true"><span></span><span></span><span></span><span></span></div>
<p>Loved by <strong>240,000+</strong> artists & studios</p>
</div>
</div>
<div class="hero__art reveal" aria-hidden="true">
<div class="masonry" id="heroMasonry">
<div class="tile t1"></div>
<div class="tile t2"></div>
<div class="tile t3"></div>
<div class="tile t4"></div>
<div class="tile t5"></div>
<div class="tile t6"></div>
</div>
<div class="hero__badge">4K · instant upscale</div>
</div>
</div>
</section>
<!-- ===== LOGOS ===== -->
<section class="logos" aria-label="Trusted by">
<div class="container">
<p class="logos__label">Powering creative teams at</p>
<div class="logos__row">
<span class="logo">NOVABLOOM</span>
<span class="logo">Aperture&Co</span>
<span class="logo">HÜEM</span>
<span class="logo">Tessellate</span>
<span class="logo">Mirrorwave</span>
<span class="logo">Studio Onyx</span>
</div>
</div>
</section>
<!-- ===== STYLE PICKER (interactive tabs) ===== -->
<section class="styles" id="styles">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">One prompt, infinite looks</span>
<h2>Pick a style. Watch it transform.</h2>
<p>Swap rendering models on the fly — the same idea, re-imagined in a dozen aesthetics.</p>
</header>
<div class="tabs" role="tablist" aria-label="Image styles" id="styleTabs">
<button class="tab is-active" role="tab" aria-selected="true" data-style="holo">Holographic</button>
<button class="tab" role="tab" aria-selected="false" data-style="oil">Oil Paint</button>
<button class="tab" role="tab" aria-selected="false" data-style="cyber">Cyberpunk</button>
<button class="tab" role="tab" aria-selected="false" data-style="blueprint">Blueprint</button>
<button class="tab" role="tab" aria-selected="false" data-style="claymation">Claymation</button>
</div>
<div class="style-grid" id="styleGrid" role="tabpanel" aria-live="polite">
<!-- populated by JS -->
</div>
</div>
</section>
<!-- ===== FEATURES ===== -->
<section class="features" id="features">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">Built for makers</span>
<h2>A studio behind a single text box</h2>
</header>
<div class="feature-grid">
<article class="feature reveal">
<div class="feature__icon">◈</div>
<h3>120+ trained styles</h3>
<p>From wet-plate photography to risograph print, switch the entire visual language without re-prompting.</p>
</article>
<article class="feature reveal">
<div class="feature__icon">⬚</div>
<h3>Up to 8K resolution</h3>
<p>Generate small, upscale lossless. Export billboard-ready files with crisp edges and zero artifacts.</p>
</article>
<article class="feature reveal">
<div class="feature__icon">✦</div>
<h3>Inpaint & edit</h3>
<p>Brush over a region, describe the fix, and Prismeo repaints just that area — lighting and all.</p>
</article>
<article class="feature reveal">
<div class="feature__icon">⤢</div>
<h3>Any aspect ratio</h3>
<p>Square for social, ultrawide for cinema, vertical for stories — composition stays balanced everywhere.</p>
</article>
<article class="feature reveal">
<div class="feature__icon">⟳</div>
<h3>Consistent characters</h3>
<p>Lock a face, a mascot, or a product and keep it identical across an entire campaign.</p>
</article>
<article class="feature reveal">
<div class="feature__icon">⚡</div>
<h3>2-second drafts</h3>
<p>Iterate at the speed of thought with our distilled turbo model, then commit to a full-quality render.</p>
</article>
</div>
</div>
</section>
<!-- ===== HOW IT WORKS ===== -->
<section class="process" id="process">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">How it works</span>
<h2>From blank canvas to final cut in three moves</h2>
</header>
<ol class="steps">
<li class="step reveal">
<span class="step__num">01</span>
<h3>Describe it</h3>
<p>Write a prompt — or drop a reference image — and pick a style preset.</p>
</li>
<li class="step reveal">
<span class="step__num">02</span>
<h3>Steer it</h3>
<p>Nudge color, mood, and composition with live sliders until it clicks.</p>
</li>
<li class="step reveal">
<span class="step__num">03</span>
<h3>Ship it</h3>
<p>Upscale, export, and hand off layered files straight to your design tool.</p>
</li>
</ol>
</div>
</section>
<!-- ===== SHOWCASE / BEFORE-AFTER ===== -->
<section class="showcase" id="showcase">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">Before → After</span>
<h2>Rough sketch in, finished art out</h2>
<p>Drag the handle to compare a doodle with Prismeo's render.</p>
</header>
<div class="ba" id="beforeAfter" aria-label="Before and after comparison">
<div class="ba__after"></div>
<div class="ba__before" id="baBefore">
<span class="ba__tag">sketch</span>
</div>
<span class="ba__tag ba__tag--after">render</span>
<input type="range" class="ba__range" id="baRange" min="0" max="100" value="50" aria-label="Comparison slider" />
<span class="ba__handle" id="baHandle" aria-hidden="true">⇆</span>
</div>
</div>
</section>
<!-- ===== PRICING ===== -->
<section class="pricing" id="pricing">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">Pricing</span>
<h2>Plans that scale with your imagination</h2>
<div class="toggle" id="billingToggle">
<span class="toggle__label is-active" data-bill="monthly">Monthly</span>
<button class="toggle__switch" id="billSwitch" role="switch" aria-checked="false" aria-label="Toggle annual billing"><span></span></button>
<span class="toggle__label" data-bill="annual">Annual <em>−20%</em></span>
</div>
</header>
<div class="plans">
<article class="plan reveal">
<h3>Spark</h3>
<p class="plan__desc">For curious creators dipping in.</p>
<p class="plan__price"><span class="amount" data-monthly="0" data-annual="0">$0</span><span class="per">/mo</span></p>
<ul class="plan__list">
<li>200 renders / month</li>
<li>Up to 2K resolution</li>
<li>30 core styles</li>
<li>Community gallery</li>
</ul>
<a href="#" class="btn btn--ghost full" data-toast="Free plan — no card needed!">Start free</a>
</article>
<article class="plan plan--featured reveal">
<span class="plan__badge">Most popular</span>
<h3>Studio</h3>
<p class="plan__desc">For working artists & freelancers.</p>
<p class="plan__price"><span class="amount" data-monthly="24" data-annual="19">$24</span><span class="per">/mo</span></p>
<ul class="plan__list">
<li>Unlimited renders</li>
<li>Up to 8K + lossless upscale</li>
<li>All 120+ styles</li>
<li>Inpaint, edit & character lock</li>
<li>Commercial license</li>
</ul>
<a href="#" class="btn btn--primary full" data-toast="Welcome to Studio ✦">Choose Studio</a>
</article>
<article class="plan reveal">
<h3>Atelier</h3>
<p class="plan__desc">For teams & studios at scale.</p>
<p class="plan__price"><span class="amount" data-monthly="79" data-annual="63">$79</span><span class="per">/mo</span></p>
<ul class="plan__list">
<li>Everything in Studio</li>
<li>Shared brand styles</li>
<li>API + priority GPU queue</li>
<li>SSO & admin controls</li>
</ul>
<a href="#" class="btn btn--ghost full" data-toast="A specialist will reach out.">Talk to sales</a>
</article>
</div>
</div>
</section>
<!-- ===== TESTIMONIALS ===== -->
<section class="reviews" id="reviews">
<div class="container">
<header class="section-head reveal">
<span class="eyebrow">Loved by creators</span>
<h2>The reviews are in</h2>
</header>
<div class="review-grid">
<figure class="review reviews__card reveal">
<blockquote>"I storyboarded an entire ad campaign in an afternoon. Prismeo's character lock is genuinely magic — the mascot stayed on-model across 40 frames."</blockquote>
<figcaption><span class="review__avatar a1"></span><span><strong>Lena Ortiz</strong><em>Creative Director, NOVABLOOM</em></span></figcaption>
</figure>
<figure class="review reveals__card reveal">
<blockquote>"The holographic style alone replaced two stock subscriptions. Output goes straight into our decks at 4K, no cleanup."</blockquote>
<figcaption><span class="review__avatar a2"></span><span><strong>Marcus Vale</strong><em>Brand Designer, HÜEM</em></span></figcaption>
</figure>
<figure class="review reveal">
<blockquote>"Inpainting saved a client shoot. We repainted a whole background in minutes and nobody could tell."</blockquote>
<figcaption><span class="review__avatar a3"></span><span><strong>Priya Raman</strong><em>Freelance Illustrator</em></span></figcaption>
</figure>
</div>
</div>
</section>
<!-- ===== CTA ===== -->
<section class="cta">
<div class="container cta__inner reveal">
<h2>Your next masterpiece is one sentence away.</h2>
<p>Join 240,000 creators rendering the impossible with Prismeo.</p>
<form class="cta__form" id="ctaForm">
<label class="sr-only" for="ctaEmail">Email address</label>
<input id="ctaEmail" type="email" placeholder="[email protected]" required />
<button class="btn btn--primary" type="submit">Get early access</button>
</form>
<p class="cta__fine">No credit card. Cancel anytime.</p>
</div>
</section>
</main>
<!-- ===== FOOTER ===== -->
<footer class="footer">
<div class="container footer__grid">
<div class="footer__brand">
<a class="brand" href="#top"><span class="brand__mark" aria-hidden="true"></span><span class="brand__name">Prismeo</span></a>
<p>Rendering imagination since 2025.</p>
</div>
<nav aria-label="Product"><h4>Product</h4><a href="#styles">Styles</a><a href="#features">Features</a><a href="#pricing">Pricing</a><a href="#showcase">Showcase</a></nav>
<nav aria-label="Company"><h4>Company</h4><a href="#">About</a><a href="#">Careers</a><a href="#">Press</a><a href="#">Blog</a></nav>
<nav aria-label="Legal"><h4>Legal</h4><a href="#">Terms</a><a href="#">Privacy</a><a href="#">Content policy</a></nav>
</div>
<div class="container footer__bar">
<p>© 2026 Prismeo Labs — fictional brand for demonstration.</p>
<div class="footer__social"><a href="#" aria-label="X">✕</a><a href="#" aria-label="Instagram">◎</a><a href="#" aria-label="Dribbble">◐</a></div>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Image Generation Landing
A complete, self-contained marketing landing page for Prismeo, a fictional AI image generator. The page opens on a sticky, glassy navigation bar and a high-contrast hero: a bold display headline, a working prompt bar with a rotating typewriter placeholder, starter-prompt chips, and a floating masonry gallery of holographic gradient “renders.” From there it flows through a logo proof strip, an interactive style picker, a six-card feature grid, a three-step process, a before-to-after showcase, three pricing tiers, testimonials, an email capture CTA, and a footer.
The visual identity leans gallery-like: a near-black canvas, generous spacing, large headline type in Space Grotesk over an Inter body, a mono accent, and an iridescent magenta-to-violet-to-teal-to-gold sheen used across buttons, borders, and gradient artwork. Everything is themed with CSS variables defined in :root, with ambient radial glows and tasteful hover, float, and scroll-reveal micro-interactions.
The vanilla JavaScript drives a tabbed style picker that re-renders the eight-tile gallery for each aesthetic, a draggable before-to-after comparison slider, a monthly-annual pricing toggle that rewrites prices, a scroll-reveal IntersectionObserver, an animated prompt typewriter, an accessible mobile menu with keyboard support, and a reusable toast() helper for CTA feedback. It is fully responsive down to about 360px and respects prefers-reduced-motion.
Illustrative UI only — fictional brand, not a real product.