Comics — Webtoon Platform Landing
A bright, mobile-first webtoon platform landing built with vanilla HTML, CSS and JavaScript. It pairs a flat-design hero and a phone mockup running a looping vertical-scroll comic with app-store download buttons, a draggable auto-cruising trending scroller of rated cover cards, interactive genre chips, a creator feature trio and a footer. Friendly green and coral accents, rounded ink borders and subtle halftone textures give it a playful, app-store feel.
MCP
Код
:root {
/* Palette override — Webtoon platform: bright flat on white */
--accent: #00d564;
--accent-2: #ff5e6c;
--accent-3: #2e6bff;
--accent-soft: #e6fbef;
--ink: #14151a;
--ink-2: #3a3c46;
--paper: #ffffff;
--panel: #ffffff;
--muted: #6b6e7b;
--line: rgba(20, 21, 26, 0.10);
--line-2: rgba(20, 21, 26, 0.18);
--halftone: radial-gradient(circle, rgba(20, 21, 26, 0.10) 1px, transparent 1.6px);
--r-sm: 10px;
--r-md: 18px;
--r-lg: 28px;
--r-pill: 999px;
--shadow: 0 18px 40px -18px rgba(20, 21, 26, 0.28);
--shadow-sm: 0 8px 20px -10px rgba(20, 21, 26, 0.25);
--display: "Baloo 2", "Inter", system-ui, sans-serif;
--body: "Inter", system-ui, -apple-system, sans-serif;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: var(--body);
color: var(--ink);
background: var(--paper);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 {
font-family: var(--display);
margin: 0;
line-height: 1.1;
letter-spacing: -0.01em;
}
a {
color: inherit;
text-decoration: none;
}
.skip {
position: absolute;
left: -999px;
top: 0;
background: var(--ink);
color: #fff;
padding: 10px 16px;
border-radius: 0 0 var(--r-sm) 0;
z-index: 100;
}
.skip:focus {
left: 0;
}
/* ---------- Buttons ---------- */
.btn {
font-family: var(--body);
font-weight: 700;
font-size: 0.95rem;
border: 2px solid var(--ink);
border-radius: var(--r-pill);
padding: 0.6rem 1.2rem;
cursor: pointer;
transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.btn:focus-visible {
outline: 3px solid var(--accent-3);
outline-offset: 2px;
}
.btn--solid {
background: var(--accent);
color: var(--ink);
box-shadow: 0 4px 0 var(--ink);
}
.btn--solid:hover {
transform: translateY(-2px);
box-shadow: 0 6px 0 var(--ink);
}
.btn--solid:active {
transform: translateY(2px);
box-shadow: 0 1px 0 var(--ink);
}
.btn--ghost {
background: transparent;
color: var(--ink);
border-color: transparent;
}
.btn--ghost:hover {
background: var(--accent-soft);
}
.btn--lg {
font-size: 1.1rem;
padding: 0.85rem 1.8rem;
}
/* ---------- Nav ---------- */
.nav {
position: sticky;
top: 0;
z-index: 50;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(10px);
border-bottom: 2px solid var(--ink);
}
.nav__inner {
max-width: 1140px;
margin: 0 auto;
padding: 0.8rem 1.25rem;
display: flex;
align-items: center;
gap: 1.25rem;
}
.brand {
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-family: var(--display);
font-weight: 800;
font-size: 1.3rem;
}
.brand__mark {
display: grid;
place-items: center;
width: 30px;
height: 30px;
border-radius: 9px;
background: var(--accent);
color: var(--ink);
border: 2px solid var(--ink);
font-size: 1rem;
transform: rotate(-8deg);
}
.nav__links {
display: flex;
gap: 1.4rem;
margin-left: auto;
font-weight: 600;
color: var(--ink-2);
}
.nav__links a {
position: relative;
padding: 0.2rem 0;
}
.nav__links a:hover {
color: var(--ink);
}
.nav__links a::after {
content: "";
position: absolute;
left: 0;
bottom: -2px;
width: 0;
height: 3px;
background: var(--accent);
border-radius: 3px;
transition: width 0.18s ease;
}
.nav__links a:hover::after {
width: 100%;
}
.nav__cta {
display: flex;
gap: 0.5rem;
}
/* ---------- Hero ---------- */
.hero {
max-width: 1140px;
margin: 0 auto;
padding: clamp(2.5rem, 6vw, 5rem) 1.25rem;
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: clamp(1.5rem, 5vw, 4rem);
align-items: center;
}
.pill {
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-weight: 700;
font-size: 0.82rem;
color: var(--ink);
background: var(--accent-soft);
border: 2px solid var(--ink);
border-radius: var(--r-pill);
padding: 0.35rem 0.9rem;
}
.hero__title {
font-size: clamp(2.4rem, 6vw, 4rem);
margin: 1rem 0 0.75rem;
}
.hl {
color: var(--accent);
background: linear-gradient(transparent 62%, rgba(0, 213, 100, 0.22) 0);
}
.hero__sub {
font-size: 1.1rem;
color: var(--ink-2);
max-width: 34ch;
margin: 0 0 1.6rem;
}
.store {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
}
.store__btn {
display: inline-flex;
align-items: center;
gap: 0.6rem;
background: var(--ink);
color: #fff;
border-radius: var(--r-md);
padding: 0.6rem 1.1rem;
border: 2px solid var(--ink);
transition: transform 0.12s ease;
}
.store__btn:hover {
transform: translateY(-2px);
}
.store__icn {
width: 24px;
height: 24px;
border-radius: 6px;
background: var(--accent);
flex: none;
-webkit-mask: radial-gradient(circle at 50% 38%, transparent 0, transparent 4px, #000 4px) ;
mask: none;
}
.store__icn--play {
background: var(--accent-2);
clip-path: polygon(20% 8%, 86% 50%, 20% 92%);
}
.store__txt {
display: flex;
flex-direction: column;
line-height: 1.1;
}
.store__txt small {
font-size: 0.65rem;
opacity: 0.75;
}
.store__txt strong {
font-size: 1.05rem;
font-weight: 700;
}
.trust {
display: flex;
gap: 1.5rem;
list-style: none;
padding: 0;
margin: 1.8rem 0 0;
color: var(--muted);
font-size: 0.9rem;
flex-wrap: wrap;
}
.trust strong {
display: block;
font-family: var(--display);
font-size: 1.4rem;
color: var(--ink);
}
/* ---------- Phone device ---------- */
.hero__device {
position: relative;
display: grid;
place-items: center;
}
.phone {
position: relative;
width: 280px;
height: 560px;
background: var(--ink);
border-radius: 44px;
padding: 12px;
box-shadow: var(--shadow);
z-index: 2;
}
.phone__notch {
position: absolute;
top: 12px;
left: 50%;
transform: translateX(-50%);
width: 120px;
height: 24px;
background: var(--ink);
border-radius: 0 0 16px 16px;
z-index: 3;
}
.phone__screen {
width: 100%;
height: 100%;
border-radius: 34px;
overflow: hidden;
background: var(--paper);
position: relative;
}
.reader {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
}
.reader__bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.7rem 0.9rem;
font-size: 0.78rem;
font-weight: 700;
background: #fff;
border-bottom: 2px solid var(--ink);
z-index: 4;
}
.reader__heart {
color: var(--accent-2);
}
.reader__track {
flex: 1;
overflow: hidden;
position: relative;
}
.reader__track {
will-change: transform;
}
.panel {
height: 240px;
margin: 8px;
border-radius: var(--r-sm);
border: 3px solid var(--ink);
display: grid;
place-items: center;
position: relative;
overflow: hidden;
background-image: var(--halftone);
background-size: 6px 6px;
}
.panel--a { background-color: #ffe1e5; }
.panel--b { background-color: #e1f3ff; }
.panel--c { background-color: #e6fbef; }
.panel--d { background-color: #fff3d6; }
.panel--e { background-color: var(--ink); }
.sfx {
font-family: var(--display);
font-weight: 800;
font-size: 1.9rem;
color: var(--accent-2);
-webkit-text-stroke: 2px var(--ink);
paint-order: stroke fill;
transform: rotate(-6deg);
text-transform: uppercase;
}
.sfx--blue { color: var(--accent-3); }
.panel--e .sfx {
font-size: 1rem;
color: var(--accent);
-webkit-text-stroke: 0;
}
.bubble {
position: relative;
background: #fff;
border: 3px solid var(--ink);
border-radius: 18px;
padding: 0.7rem 0.9rem;
font-weight: 600;
font-size: 0.82rem;
max-width: 80%;
box-shadow: 3px 3px 0 var(--ink);
}
.bubble::after {
content: "";
position: absolute;
bottom: -14px;
left: 24px;
border: 8px solid transparent;
border-top-color: var(--ink);
}
.bubble--right::after {
left: auto;
right: 24px;
}
.blob {
position: absolute;
border-radius: 50%;
filter: blur(2px);
z-index: 1;
}
.blob--1 {
width: 200px;
height: 200px;
background: var(--accent);
opacity: 0.25;
top: -20px;
right: 10px;
}
.blob--2 {
width: 160px;
height: 160px;
background: var(--accent-2);
opacity: 0.22;
bottom: 10px;
left: 0;
}
/* ---------- Section heads ---------- */
.section__head {
max-width: 1140px;
margin: 0 auto;
padding: 0 1.25rem;
text-align: center;
}
.section__head h2 {
font-size: clamp(1.8rem, 4vw, 2.6rem);
}
.section__head p {
color: var(--muted);
margin: 0.4rem 0 0;
}
/* ---------- Trending scroller ---------- */
.trending {
padding: clamp(2.5rem, 6vw, 4rem) 0;
background: linear-gradient(180deg, #fff, var(--accent-soft));
border-top: 2px solid var(--ink);
border-bottom: 2px solid var(--ink);
}
.scroller {
margin: 1.8rem auto 0;
max-width: 1240px;
overflow-x: auto;
overflow-y: hidden;
padding: 0.5rem 1.25rem 1rem;
cursor: grab;
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
}
.scroller::-webkit-scrollbar { display: none; }
.scroller.is-drag {
cursor: grabbing;
scroll-behavior: auto;
}
.scroller:focus-visible {
outline: 3px solid var(--accent-3);
outline-offset: 4px;
border-radius: var(--r-md);
}
.scroller__track {
display: flex;
gap: 1rem;
width: max-content;
}
.card {
width: 190px;
flex: none;
background: var(--panel);
border: 3px solid var(--ink);
border-radius: var(--r-md);
box-shadow: var(--shadow-sm);
overflow: hidden;
transition: transform 0.14s ease, box-shadow 0.14s ease;
user-select: none;
}
.card:hover {
transform: translateY(-6px) rotate(-1deg);
box-shadow: 0 16px 30px -14px rgba(20, 21, 26, 0.4);
}
.card__cover {
height: 220px;
position: relative;
display: grid;
place-items: center;
background-image: var(--halftone);
background-size: 6px 6px;
}
.card__rank {
position: absolute;
top: 8px;
left: 8px;
font-family: var(--display);
font-weight: 800;
font-size: 1.4rem;
color: #fff;
-webkit-text-stroke: 2px var(--ink);
paint-order: stroke fill;
}
.card__badge {
position: absolute;
top: 8px;
right: 8px;
font-size: 0.66rem;
font-weight: 800;
text-transform: uppercase;
padding: 0.2rem 0.5rem;
border-radius: var(--r-pill);
border: 2px solid var(--ink);
background: var(--accent-2);
color: #fff;
}
.card__emoji {
font-size: 3rem;
filter: drop-shadow(2px 2px 0 var(--ink));
}
.card__body {
padding: 0.7rem 0.85rem 0.95rem;
border-top: 3px solid var(--ink);
}
.card__title {
font-family: var(--display);
font-weight: 700;
font-size: 1.05rem;
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card__genre {
color: var(--muted);
font-size: 0.8rem;
margin: 0.1rem 0 0.5rem;
}
.card__meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.82rem;
font-weight: 700;
}
.card__rating {
color: var(--ink);
}
.card__rating .star { color: var(--accent-2); }
.card__reads {
color: var(--accent);
}
.scroller__hint {
text-align: center;
color: var(--muted);
font-size: 0.8rem;
margin-top: 0.6rem;
letter-spacing: 0.06em;
}
/* ---------- Genres ---------- */
.genres {
padding: clamp(2.5rem, 6vw, 4rem) 0;
}
.chips {
max-width: 860px;
margin: 1.8rem auto 0;
padding: 0 1.25rem;
display: flex;
flex-wrap: wrap;
gap: 0.7rem;
justify-content: center;
}
.chip {
font-family: var(--body);
font-weight: 700;
font-size: 0.95rem;
border: 2px solid var(--ink);
border-radius: var(--r-pill);
padding: 0.55rem 1.1rem;
background: #fff;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 0.4rem;
transition: transform 0.12s ease, background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
.chip:hover {
transform: translateY(-3px) scale(1.03);
box-shadow: 0 5px 0 var(--ink);
}
.chip .emoji { font-size: 1.05rem; }
.chip.is-active {
background: var(--ink);
color: #fff;
}
.chip.is-active .count { color: var(--accent); }
.chip .count {
font-size: 0.78rem;
color: var(--muted);
}
.chip:focus-visible {
outline: 3px solid var(--accent-3);
outline-offset: 2px;
}
/* ---------- Creators ---------- */
.creators {
padding: clamp(2.5rem, 6vw, 4rem) 0;
background: linear-gradient(180deg, var(--accent-soft), #fff);
border-top: 2px solid var(--ink);
}
.feature-trio {
max-width: 1080px;
margin: 2rem auto 0;
padding: 0 1.25rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.2rem;
}
.feature {
background: #fff;
border: 3px solid var(--ink);
border-radius: var(--r-lg);
padding: 1.6rem 1.4rem;
box-shadow: var(--shadow-sm);
transition: transform 0.14s ease;
}
.feature:hover {
transform: translateY(-5px);
}
.feature__icn {
display: grid;
place-items: center;
width: 52px;
height: 52px;
border-radius: 14px;
border: 3px solid var(--ink);
background: var(--accent);
font-family: var(--display);
font-weight: 800;
font-size: 1.4rem;
margin-bottom: 0.9rem;
}
.feature:nth-child(2) .feature__icn { background: var(--accent-2); color: #fff; }
.feature:nth-child(3) .feature__icn { background: var(--accent-3); color: #fff; }
.feature h3 {
font-size: 1.3rem;
margin-bottom: 0.4rem;
}
.feature p {
color: var(--ink-2);
margin: 0;
font-size: 0.95rem;
}
.creators__cta {
text-align: center;
margin-top: 2.2rem;
}
/* ---------- Footer ---------- */
.foot {
background: var(--ink);
color: #d9dbe4;
border-top: 3px solid var(--accent);
}
.foot__inner {
max-width: 1140px;
margin: 0 auto;
padding: 3rem 1.25rem 2rem;
display: grid;
grid-template-columns: 1.1fr 2fr;
gap: 2rem;
}
.foot__brand {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.foot__brand strong {
font-family: var(--display);
font-size: 1.4rem;
color: #fff;
}
.foot__brand .brand__mark { width: 34px; height: 34px; }
.foot__brand p {
margin: 0;
color: #9a9db0;
font-size: 0.9rem;
}
.foot__cols {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.foot__cols h4 {
color: #fff;
font-size: 0.95rem;
margin-bottom: 0.7rem;
}
.foot__cols a {
display: block;
padding: 0.25rem 0;
color: #b8bac8;
font-size: 0.9rem;
}
.foot__cols a:hover { color: var(--accent); }
.foot__bar {
border-top: 1px solid rgba(255, 255, 255, 0.12);
padding: 1.1rem 1.25rem;
text-align: center;
font-size: 0.82rem;
color: #8d90a3;
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 24px;
transform: translate(-50%, 140%);
background: var(--ink);
color: #fff;
font-weight: 600;
font-size: 0.9rem;
padding: 0.75rem 1.2rem;
border-radius: var(--r-pill);
border: 2px solid var(--accent);
box-shadow: var(--shadow);
z-index: 200;
transition: transform 0.3s cubic-bezier(0.18, 0.9, 0.3, 1.2);
pointer-events: none;
max-width: 90vw;
}
.toast.is-show {
transform: translate(-50%, 0);
}
/* ---------- Responsive ---------- */
@media (max-width: 880px) {
.hero {
grid-template-columns: 1fr;
text-align: center;
}
.hero__sub { margin-left: auto; margin-right: auto; }
.store, .trust { justify-content: center; }
.feature-trio { grid-template-columns: 1fr; }
.foot__inner { grid-template-columns: 1fr; }
}
@media (max-width: 520px) {
.nav__links { display: none; }
.nav__cta .btn--ghost { display: none; }
.nav__inner { gap: 0.6rem; }
.hero { padding-top: 2rem; }
.hero__title { font-size: clamp(2rem, 9vw, 2.6rem); }
.phone { width: 240px; height: 480px; }
.panel { height: 200px; }
.trust { gap: 1.1rem; }
.foot__cols { grid-template-columns: 1fr 1fr; }
.card { width: 160px; }
.card__cover { height: 190px; }
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.reader__track { transition: none !important; }
}(function () {
"use strict";
var reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("is-show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-show");
}, 2400);
}
document.querySelectorAll("[data-toast]").forEach(function (el) {
el.addEventListener("click", function (e) {
if (el.tagName === "A") e.preventDefault();
toast(el.getAttribute("data-toast"));
});
});
/* ---------- Phone screen scroll loop ---------- */
var track = document.getElementById("readerTrack");
if (track && !reduceMotion) {
var offset = 0;
var maxScroll = 0;
function measure() {
var viewport = track.parentElement ? track.parentElement.clientHeight : 0;
maxScroll = Math.max(0, track.scrollHeight - viewport + 40);
}
measure();
window.addEventListener("resize", measure);
var dir = 1;
var paused = false;
var speed = 0.45; // px per frame
function loop() {
if (!paused && maxScroll > 0) {
offset += dir * speed;
if (offset >= maxScroll) {
offset = maxScroll;
dir = -1;
} else if (offset <= 0) {
offset = 0;
dir = 1;
}
track.style.transform = "translateY(" + -offset + "px)";
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
var phone = track.closest(".phone");
if (phone) {
phone.addEventListener("mouseenter", function () { paused = true; });
phone.addEventListener("mouseleave", function () { paused = false; });
}
}
/* ---------- Trending scroller (build + drag + auto) ---------- */
var TITLES = [
{ t: "Neon Ronin", g: "Action · Sci-fi", emoji: "⚔️", rating: "4.9", reads: "8.2M", badge: "HOT", c: "#ffe1e5" },
{ t: "Iron Vanguard", g: "Mecha · Drama", emoji: "🤖", rating: "4.8", reads: "5.1M", badge: "", c: "#e1f3ff" },
{ t: "Petal & Thorn", g: "Romance", emoji: "🌸", rating: "4.9", reads: "6.7M", badge: "NEW", c: "#ffe6f0" },
{ t: "Hollow Crown", g: "Fantasy", emoji: "👑", rating: "4.7", reads: "3.9M", badge: "", c: "#fff3d6" },
{ t: "Static Heart", g: "Slice of life", emoji: "💚", rating: "4.8", reads: "4.4M", badge: "", c: "#e6fbef" },
{ t: "Graveyard Shift", g: "Horror", emoji: "👻", rating: "4.6", reads: "2.8M", badge: "", c: "#e7e8f5" },
{ t: "Sugar Riot", g: "Comedy", emoji: "🍭", rating: "4.9", reads: "7.0M", badge: "HOT", c: "#fff0e1" },
{ t: "Tidecaller", g: "Adventure", emoji: "🌊", rating: "4.7", reads: "3.1M", badge: "", c: "#dff5ff" }
];
var trackEl = document.getElementById("scrollerTrack");
if (trackEl) {
TITLES.forEach(function (item, i) {
var card = document.createElement("article");
card.className = "card";
card.innerHTML =
'<div class="card__cover" style="background-color:' + item.c + '">' +
'<span class="card__rank">#' + (i + 1) + "</span>" +
(item.badge ? '<span class="card__badge">' + item.badge + "</span>" : "") +
'<span class="card__emoji">' + item.emoji + "</span>" +
"</div>" +
'<div class="card__body">' +
'<h3 class="card__title">' + item.t + "</h3>" +
'<p class="card__genre">' + item.g + "</p>" +
'<div class="card__meta">' +
'<span class="card__rating"><span class="star">★</span> ' + item.rating + "</span>" +
'<span class="card__reads">' + item.reads + " reads</span>" +
"</div>" +
"</div>";
card.addEventListener("click", function () {
if (dragged) return;
toast("Opening “" + item.t + "” — demo only.");
});
trackEl.appendChild(card);
});
}
var scroller = document.getElementById("scroller");
var dragged = false;
if (scroller) {
var isDown = false;
var startX = 0;
var startScroll = 0;
scroller.addEventListener("pointerdown", function (e) {
isDown = true;
dragged = false;
startX = e.clientX;
startScroll = scroller.scrollLeft;
scroller.classList.add("is-drag");
scroller.setPointerCapture(e.pointerId);
autoPaused = true;
});
scroller.addEventListener("pointermove", function (e) {
if (!isDown) return;
var dx = e.clientX - startX;
if (Math.abs(dx) > 4) dragged = true;
scroller.scrollLeft = startScroll - dx;
});
function endDrag(e) {
if (!isDown) return;
isDown = false;
scroller.classList.remove("is-drag");
try { scroller.releasePointerCapture(e.pointerId); } catch (err) {}
setTimeout(function () { dragged = false; }, 50);
// resume auto-scroll after a pause
clearTimeout(resumeTimer);
resumeTimer = setTimeout(function () { autoPaused = false; }, 2500);
}
scroller.addEventListener("pointerup", endDrag);
scroller.addEventListener("pointercancel", endDrag);
// Pause auto on hover / wheel interaction
scroller.addEventListener("mouseenter", function () { autoPaused = true; });
scroller.addEventListener("mouseleave", function () {
clearTimeout(resumeTimer);
resumeTimer = setTimeout(function () { autoPaused = false; }, 1200);
});
scroller.addEventListener("wheel", function () {
autoPaused = true;
clearTimeout(resumeTimer);
resumeTimer = setTimeout(function () { autoPaused = false; }, 1800);
}, { passive: true });
// Keyboard
scroller.addEventListener("keydown", function (e) {
if (e.key === "ArrowRight") { scroller.scrollLeft += 210; e.preventDefault(); }
if (e.key === "ArrowLeft") { scroller.scrollLeft -= 210; e.preventDefault(); }
});
// Auto-cruise
var autoPaused = false;
var resumeTimer = null;
var autoDir = 1;
if (!reduceMotion) {
setInterval(function () {
if (autoPaused) return;
var max = scroller.scrollWidth - scroller.clientWidth;
if (max <= 0) return;
scroller.scrollLeft += autoDir * 0.6;
if (scroller.scrollLeft >= max - 1) autoDir = -1;
else if (scroller.scrollLeft <= 0) autoDir = 1;
}, 16);
}
}
/* ---------- Genre chips ---------- */
var GENRES = [
{ name: "Romance", emoji: "💕", count: "2.1k" },
{ name: "Action", emoji: "⚔️", count: "1.8k" },
{ name: "Fantasy", emoji: "🐉", count: "1.5k" },
{ name: "Comedy", emoji: "😂", count: "980" },
{ name: "Horror", emoji: "👻", count: "640" },
{ name: "Sci-fi", emoji: "🚀", count: "720" },
{ name: "Drama", emoji: "🎭", count: "1.1k" },
{ name: "Slice of life", emoji: "☕", count: "830" },
{ name: "Thriller", emoji: "🔪", count: "510" }
];
var chips = document.getElementById("chips");
if (chips) {
GENRES.forEach(function (g, i) {
var btn = document.createElement("button");
btn.type = "button";
btn.className = "chip" + (i === 0 ? " is-active" : "");
btn.setAttribute("aria-pressed", i === 0 ? "true" : "false");
btn.innerHTML =
'<span class="emoji" aria-hidden="true">' + g.emoji + "</span>" +
"<span>" + g.name + "</span>" +
'<span class="count">' + g.count + "</span>";
btn.addEventListener("click", function () {
chips.querySelectorAll(".chip").forEach(function (c) {
c.classList.remove("is-active");
c.setAttribute("aria-pressed", "false");
});
btn.classList.add("is-active");
btn.setAttribute("aria-pressed", "true");
toast(g.name + " — " + g.count + " series. (demo)");
});
chips.appendChild(btn);
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Toonburst — Read webtoons anywhere</title>
<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=Baloo+2:wght@500;600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="nav">
<div class="nav__inner">
<a class="brand" href="#" aria-label="Toonburst home">
<span class="brand__mark" aria-hidden="true">◗</span>
<span class="brand__name">Toonburst</span>
</a>
<nav class="nav__links" aria-label="Primary">
<a href="#trending">Trending</a>
<a href="#genres">Genres</a>
<a href="#creators">Creators</a>
</nav>
<div class="nav__cta">
<button class="btn btn--ghost" type="button" data-toast="Welcome back! Sign-in is a demo.">Log in</button>
<button class="btn btn--solid" type="button" data-toast="Account flow is illustrative only.">Sign up free</button>
</div>
</div>
</header>
<main id="main">
<!-- HERO -->
<section class="hero">
<div class="hero__copy">
<span class="pill">★ Over 40 million reads this week</span>
<h1 class="hero__title">Vertical comics that<br /><span class="hl">hook you instantly.</span></h1>
<p class="hero__sub">
Thousands of original webtoons in your pocket. Scroll, binge and follow your favorite
creators — first three episodes always free.
</p>
<div class="store">
<a class="store__btn" href="#" data-toast="App Store link is a demo.">
<span class="store__icn"></span>
<span class="store__txt"><small>Download on the</small><strong>App Store</strong></span>
</a>
<a class="store__btn" href="#" data-toast="Google Play link is a demo.">
<span class="store__icn store__icn--play"></span>
<span class="store__txt"><small>Get it on</small><strong>Google Play</strong></span>
</a>
</div>
<ul class="trust">
<li><strong>4.9★</strong> avg rating</li>
<li><strong>12k+</strong> series</li>
<li><strong>Free</strong> daily passes</li>
</ul>
</div>
<div class="hero__device">
<div class="phone" role="img" aria-label="Phone showing a vertical-scrolling webtoon called Neon Ronin">
<div class="phone__notch" aria-hidden="true"></div>
<div class="phone__screen">
<div class="reader" id="reader" aria-hidden="true">
<div class="reader__bar">
<span class="reader__title">Neon Ronin · Ep 14</span>
<span class="reader__heart">♥ 8.2k</span>
</div>
<div class="reader__track" id="readerTrack">
<div class="panel panel--a"><span class="sfx">KRA-KOOM</span></div>
<div class="panel panel--b">
<div class="bubble">The city never sleeps... and neither do I.</div>
</div>
<div class="panel panel--c"><span class="sfx sfx--blue">WHOOSH</span></div>
<div class="panel panel--d">
<div class="bubble bubble--right">Last chance to run, rookie.</div>
</div>
<div class="panel panel--e"><span class="sfx">TO BE CONTINUED →</span></div>
</div>
</div>
</div>
</div>
<span class="blob blob--1" aria-hidden="true"></span>
<span class="blob blob--2" aria-hidden="true"></span>
</div>
</section>
<!-- TRENDING -->
<section class="trending" id="trending">
<div class="section__head">
<h2>Trending now</h2>
<p>Drag to browse, or let it cruise on its own.</p>
</div>
<div class="scroller" id="scroller" tabindex="0" aria-label="Trending titles, scroll horizontally">
<div class="scroller__track" id="scrollerTrack"></div>
</div>
<div class="scroller__hint">← drag · scroll →</div>
</section>
<!-- GENRES -->
<section class="genres" id="genres">
<div class="section__head">
<h2>Pick your vibe</h2>
<p>Tap a genre to start a binge.</p>
</div>
<div class="chips" id="chips" aria-label="Genres"></div>
</section>
<!-- CREATORS -->
<section class="creators" id="creators">
<div class="section__head">
<h2>Why creators love us</h2>
<p>Tools and reach built for storytellers.</p>
</div>
<div class="feature-trio">
<article class="feature">
<span class="feature__icn" aria-hidden="true">$</span>
<h3>Get paid to draw</h3>
<p>Earn from ad revenue, fan tips and unlock passes from episode one — paid out monthly.</p>
</article>
<article class="feature">
<span class="feature__icn" aria-hidden="true">↗</span>
<h3>Built-in audience</h3>
<p>Smart discovery pushes your series to readers who finish what they start. No ad spend.</p>
</article>
<article class="feature">
<span class="feature__icn" aria-hidden="true">✎</span>
<h3>Studio that just works</h3>
<p>Drag-and-drop the vertical canvas, schedule episodes, and track reads in real time.</p>
</article>
</div>
<div class="creators__cta">
<button class="btn btn--solid btn--lg" type="button" data-toast="Creator onboarding is a demo.">Start publishing</button>
</div>
</section>
</main>
<footer class="foot">
<div class="foot__inner">
<div class="foot__brand">
<span class="brand__mark" aria-hidden="true">◗</span>
<strong>Toonburst</strong>
<p>Vertical comics, made to binge.</p>
</div>
<nav class="foot__cols" aria-label="Footer">
<div><h4>Read</h4><a href="#trending">Trending</a><a href="#genres">Genres</a><a href="#">New & hot</a></div>
<div><h4>Create</h4><a href="#creators">Become a creator</a><a href="#">Studio</a><a href="#">Payouts</a></div>
<div><h4>Company</h4><a href="#">About</a><a href="#">Careers</a><a href="#">Press</a></div>
</nav>
</div>
<div class="foot__bar">
<span>© 2026 Toonburst — illustrative demo. Fictional series & data.</span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Webtoon Platform Landing
A modern, mobile-first marketing page for a fictional vertical-comics app called Toonburst. The hero leads with a bold flat headline, app-store and Google Play download buttons, and trust stats, beside a phone mockup whose screen runs a looping vertical-scroll reader — complete with ink panel borders, halftone dots, comic SFX lettering and tailed speech balloons. Hovering the phone pauses the scroll loop.
Below the fold, a trending-titles row renders rated cover cards you can drag with the pointer, nudge with the arrow keys, or simply watch auto-cruise back and forth; interacting pauses the cruise and it resumes after a beat. A “pick your vibe” section offers single-select genre chips with hover lift and active states, followed by a “why creators love us” feature trio and a dark footer. Every CTA fires a small accessible toast, and the layout reflows cleanly down to roughly 360px.
The whole thing is self-contained vanilla HTML, CSS and JavaScript — no frameworks, no build step. The palette uses a lime-green primary with a coral secondary on white, rounded sans typography, hard ink borders and offset drop-shadows for a friendly, playful flat-comic look.
Illustrative UI only — fictional series, characters, and data.