// KWEE — Editorial Luxe (responsive: mobile + desktop)
const { useState, useEffect, useRef } = React;
const D = window.KWEE_DATA;
const MOBILE_BREAKPOINT = 900;
// ─── Icons ─────────────────────────────────────────────────────
const Icon = {
menu: ,
search: ,
close: ,
bookmark:,
arrow: ,
arrowSm: ,
home: ,
grid: ,
shop: ,
saved: ,
back: ,
};
// ─── Brutalist splash (shared) ─────────────────────────────────
function Splash({ gone, desktop }) {
return (
★ KWEE
ISSUE №184
EST. 2018
{desktop ? `YGN · MM · ${D.brand.tagline_my}` : 'YGN · MM'}
KWEE
);
}
// ════════════════════════════════════════════════════════════════
// MOBILE
// ════════════════════════════════════════════════════════════════
function MobileTopBar({ scrolled, onMenu, onLogo }) {
return (
);
}
function MobileTicker() {
const items = D.ticker;
const repeated = [...items, ...items];
return (
{repeated.map((t, i) => {t}✦)}
{repeated.map((t, i) => {t}✦)}
);
}
function MobileCover({ onOpen, scrollerRef }) {
const ref = useRef(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const img = el.querySelector('.cover-img');
const sc = scrollerRef.current;
const onScroll = () => {
const rect = el.getBoundingClientRect();
const p = Math.max(-1, Math.min(1, (rect.top + rect.height / 2 - window.innerHeight / 2) / window.innerHeight));
img.style.transform = `scale(1.08) translateY(${p * 18}px)`;
};
onScroll();
const target = sc || window;
target.addEventListener('scroll', onScroll, { passive: true });
return () => target.removeEventListener('scroll', onScroll);
}, []);
const titleWords = D.cover.title_my.split(' ');
return (
KWEE·{D.brand.issue_short}
EST. 2018
{D.cover.date}
{D.cover.read_time}
{D.cover.eyebrow_my}
{titleWords.map((w, i) => (
{w}
))}
{D.cover.subtitle_my}
);
}
function MobileCategoryStrip({ active, onPick }) {
return (
{D.nav.filter(n => !['home', 'shop'].includes(n.id)).map(n => (
))}
);
}
function MobileEditorPick({ article, onOpen }) {
return (
{article.eyebrow_my}
{article.title_my}
{article.excerpt_my}
{article.author}
·
{article.read_time}
);
}
function MobileFeaturedScroll({ onOpen }) {
return (
Featured — ဆောင်းပါးများ
{D.features.map(f => (
onOpen(f)}>
{f.eyebrow_my}
{f.title_my}
{f.excerpt_my}
{f.author}
·
{f.read_time}
))}
);
}
function MobileLatestGrid({ onOpen, items }) {
const items_ = items || D.latest;
const refs = useRef([]);
useEffect(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('revealed'); });
}, { threshold: 0.2 });
refs.current.forEach(el => el && io.observe(el));
return () => io.disconnect();
}, [items_]);
return (
{items_.map((a, i) => (
refs.current[i] = el}
onClick={() => onOpen(a)}>
{a.cat_label} · {a.date}
{a.title_my}
))}
);
}
function MobilePartners() {
const partners = [...D.partners, ...D.partners];
return (
Our Partners
{partners.map((p, i) => (
{p.tag}
{p.name}
))}
);
}
function MobileEvents() {
return (
Parties & Events
{D.events.map((e, i) => (
/ {String(i + 1).padStart(2, '0')}
{e.date}
))}
);
}
function MobileShopTeaser({ onShop }) {
return (
KWEE STORE
Issue 184 — out now.
Limited print collector's edition. ICONS feature, 180 pages.
Shop the issue {Icon.arrowSm}
K
);
}
function MobileNewsletter() {
return (
JOIN THE LIST
The Saturday Edition.
လစဥ်ထွက်ရှိနေတဲ့ ဆောင်းပါးအသစ်တွေ၊ ပါတီပွဲတွေ၊ ဈေးကွက်ထဲက အကြောင်းအရာတွေ။
);
}
function MobileFooter() {
return (
);
}
function MobileTabBar({ page, onChange }) {
const tabs = [
{ id: 'home', my: 'ပင်မ', icon: Icon.home },
{ id: 'browse', my: 'ဆောင်းပါး', icon: Icon.grid },
{ id: 'shop', my: 'ဈေး', icon: Icon.shop },
{ id: 'saved', my: 'သိမ်း', icon: Icon.saved },
];
return (
);
}
function MobileDrawer({ open, onClose, onNav }) {
return (
);
}
function MobileArticlePage({ article, onBack }) {
const a = article;
const body = (a.body_my && a.body_my.length) ? a.body_my : D.articleBody_my;
const quoteText = a.excerpt_my || a.subtitle_my || '';
const pullQuoteAt = body.length > 4 ? 2 : 1;
return (
{a.eyebrow_my || a.cat_label}
{a.title_my}
{a.author || 'KWEE'}
·
{a.date || '2025'}
·
{a.read_time || '5 မိနစ်'}
{body.map((p, i) => (
{i === 0
? {p}
: {p}
}
{i === pullQuoteAt && quoteText && (
"{quoteText}"
)}
))}
{['#fashion', '#90s', '#urban', '#streetwear'].map(t =>
{t}
)}
);
}
function MobileCategoryPage({ catId, onOpen, onBack }) {
const cat = D.nav.find(n => n.id === catId);
if (!cat) return null;
const items = D.latest.filter(l => l.cat === catId).concat(D.latest);
return (
{cat.label}
{cat.my}
{items.length} ဆောင်းပါး · {cat.label}
onOpen(D.features[0])} />
All — ဆောင်းပါး
);
}
const shopFindCategory = (catId) => (D.shop_categories || []).find(c => c.id === catId);
const shopProductsInCategory = (catId) => (D.shop_products || []).filter(p => (p.cat_ids || []).includes(catId));
function MobileShopLanding({ onPick }) {
const cats = D.shop_categories || [];
const totalProducts = (D.shop_products || []).length;
return (
KWEE Store
The Shop
{totalProducts} products in {cats.length} collections · curated by KWEE
);
}
function MobileShopCategory({ catId, onProduct, onBack }) {
const cat = shopFindCategory(catId);
const products = shopProductsInCategory(catId);
const total = products.length;
return (
{cat?.name || 'KWEE Store'}
{cat?.name || 'Shop'}
{total} products
);
}
function MobileShopProduct({ product, onBack }) {
const p = product;
return (
Sold Out
{p.tag}
{p.name}
{p.price}
{p.description &&
{p.description}
}
{p.sub &&
{p.sub}
}
);
}
function MobileHomePage({ onOpen, onCat, onShop, scrollerRef }) {
const [activeCat, setActiveCat] = useState('sports');
return (
onOpen(D.cover)} scrollerRef={scrollerRef} />
{ setActiveCat(c); onCat(c); }} />
Editor's pick
onOpen(D.features[1])} />
Latest — နောက်ဆုံး
);
}
function MobileApp() {
const [page, setPage] = useState({ name: 'home' });
const [drawer, setDrawer] = useState(false);
const [scrolled, setScrolled] = useState(false);
const [splashGone, setSplashGone] = useState(false);
const scrollerRef = useRef(null);
useEffect(() => {
const t = setTimeout(() => setSplashGone(true), 1800);
return () => clearTimeout(t);
}, []);
useEffect(() => {
const el = scrollerRef.current;
if (!el) return;
const onScroll = () => setScrolled(el.scrollTop > 20);
el.addEventListener('scroll', onScroll, { passive: true });
return () => el.removeEventListener('scroll', onScroll);
}, [page]);
const scrollTop = () => requestAnimationFrame(() => scrollerRef.current?.scrollTo({ top: 0 }));
const goCat = (cid) => { setPage({ name: 'category', cat: cid }); scrollTop(); };
const goArticle = (a) => { setPage({ name: 'article', article: a }); scrollTop(); };
const goShop = () => { setPage({ name: 'shop' }); scrollTop(); };
const goShopCat = (catId) => { setPage({ name: 'shop_cat', catId }); scrollTop(); };
const goShopProduct = (product, catId) => { setPage({ name: 'shop_product', product, catId }); scrollTop(); };
const goHome = () => { setPage({ name: 'home' }); scrollTop(); };
const backFromProduct = () => {
if (page.catId != null) goShopCat(page.catId);
else goShop();
};
const onTab = (id) => {
if (id === 'home') goHome();
else if (id === 'shop') goShop();
else if (id === 'browse') setPage({ name: 'category', cat: 'sports' });
else goHome();
};
const onDrawerNav = (id) => {
setDrawer(false);
if (id === 'home') goHome();
else if (id === 'shop') goShop();
else setPage({ name: 'category', cat: id });
scrollTop();
};
const tabKey = page.name === 'home' ? 'home'
: (page.name === 'shop' || page.name === 'shop_cat' || page.name === 'shop_product') ? 'shop'
: 'browse';
return (
setDrawer(true)} onLogo={goHome} />
{page.name === 'home' && }
{page.name === 'category' && }
{page.name === 'article' && }
{page.name === 'shop' && }
{page.name === 'shop_cat' && }
{page.name === 'shop_product' && }
setDrawer(false)} onNav={onDrawerNav} />
);
}
// ════════════════════════════════════════════════════════════════
// DESKTOP
// ════════════════════════════════════════════════════════════════
function useDesktopCursor() {
useEffect(() => {
const cursor = document.getElementById('cursor');
if (!cursor) return;
let mx = 0, my = 0, cx = 0, cy = 0;
const onMove = (e) => { mx = e.clientX; my = e.clientY; };
document.addEventListener('mousemove', onMove);
let raf;
const tick = () => {
cx += (mx - cx) * 0.18;
cy += (my - cy) * 0.18;
cursor.style.transform = `translate(${cx}px, ${cy}px) translate(-50%, -50%)`;
raf = requestAnimationFrame(tick);
};
tick();
const onOver = (e) => {
const t = e.target.closest('[data-magnetic]');
if (t) {
cursor.classList.add(t.dataset.magnetic === 'read' ? 'read' : 'magnetic');
cursor.dataset.label = t.dataset.cursorLabel || 'READ';
} else if (e.target.closest('a, button, .grid-card, .feat-card, .editor-spread, .nav-link')) {
cursor.classList.remove('magnetic', 'read');
cursor.classList.add('dot');
cursor.dataset.label = '';
} else {
cursor.classList.remove('magnetic', 'read', 'dot');
cursor.dataset.label = '';
}
};
document.addEventListener('mouseover', onOver);
return () => {
cancelAnimationFrame(raf);
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseover', onOver);
};
}, []);
}
function DesktopUtilBar() {
return (
●YANGON · 28°C
EST. 2018
{D.brand.tagline_my}
EN / မြန်မာ
SUBSCRIBE
LOGIN
);
}
function DesktopTopBar({ scrolled, page, onMenu, onLogo, onCat, onShop }) {
const left = D.nav.slice(1, 4);
const right = D.nav.slice(4, 7);
return (
);
}
function splitTitle(title, lines = 3) {
const words = (title || '').trim().split(/\s+/).filter(Boolean);
if (words.length <= lines) {
return [...words, ...Array(Math.max(0, lines - words.length)).fill('')].slice(0, lines);
}
const total = words.reduce((n, w) => n + w.length + 1, 0);
const target = total / lines;
const out = [[]];
let cur = 0;
for (const w of words) {
const next = cur + w.length + (out[out.length - 1].length ? 1 : 0);
if (out.length < lines && cur > 0 && next > target * 0.95) {
out.push([]);
cur = 0;
}
out[out.length - 1].push(w);
cur += w.length + 1;
}
while (out.length < lines) out.push([]);
return out.map(a => a.join(' '));
}
function DesktopHero({ onOpen }) {
const coverRef = useRef(null);
useEffect(() => {
const el = coverRef.current;
if (!el) return;
const onScroll = () => {
const y = window.scrollY;
el.style.transform = `scale(1.08) translateY(${y * 0.2}px)`;
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
const titleParts = splitTitle(D.cover.title_my, 3);
return (
COVER STORY · {D.cover.cat_label}
{titleParts[0]}
{titleParts[1]}
{titleParts[2]}
{D.cover.subtitle_my}
Author
Pyae Phyo
Date
{D.cover.date}
Reading
{D.cover.read_time}
onOpen(D.cover)}
data-magnetic data-cursor-label="OPEN">
KWEE · {D.brand.issue_short}
VOL. XII
{D.cover.eyebrow_my}
"{D.cover.title_my}"
);
}
function DesktopTicker() {
const items = D.ticker;
return (
{[...items, ...items].map((t, i) => {t}✦)}
{[...items, ...items].map((t, i) => {t}✦)}
);
}
function DesktopCats({ active, onPick }) {
return (
{D.nav.filter(n => !['home', 'shop'].includes(n.id)).map(n => (
))}
);
}
function DesktopEditorSpread({ article, onOpen }) {
return (
onOpen(article)}>
{article.eyebrow_my}
{article.title_my}
{article.excerpt_my}
{article.author}
·
{article.read_time}
·
{article.date}
Read the story {Icon.arrow}
);
}
function DesktopFeatGrid({ items, onOpen }) {
const refs = useRef([]);
useEffect(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('revealed'); });
}, { threshold: 0.2 });
refs.current.forEach(el => el && io.observe(el));
return () => io.disconnect();
}, []);
return (
{items.map((f, i) => (
refs.current[i] = el}
onClick={() => onOpen(f)}>
{f.eyebrow_my}
{f.title_my}
{f.excerpt_my}
{f.author}
·
{f.read_time}
·
{f.date}
))}
);
}
function DesktopLatestGrid({ items, onOpen }) {
const refs = useRef([]);
useEffect(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('revealed'); });
}, { threshold: 0.2 });
refs.current.forEach(el => el && io.observe(el));
return () => io.disconnect();
}, [items]);
return (
{items.map((a, i) => (
refs.current[i] = el}
onClick={() => onOpen(a)}>
{a.cat_label} · {a.date}
{a.title_my}
))}
);
}
function DesktopPartners() {
const partners = [...D.partners, ...D.partners];
return (
Our Partners & brands
{partners.map((p, i) => (
{p.tag}
{p.name}
))}
);
}
function DesktopEvents() {
return (
№ 03
Parties & Events
{D.events.map((e, i) => (
/ {String(i + 1).padStart(2, '0')}
{e.venue}
{e.date}
))}
);
}
function DesktopShopBanner({ onShop }) {
return (
KWEE STORE · LIMITED EDITION
Issue 184 — out now.
Collector's print, 180 pages, numbered to 500. Featuring Ty Dolla $ign cover story and exclusive editorial.
Shop the issue {Icon.arrow}
12K
MMK · FREE SHIPPING IN YGN
);
}
function DesktopNewsletter() {
return (
THE SATURDAY EDITION
Join the list.
လစဥ်ထွက်ရှိနေတဲ့ ဆောင်းပါးအသစ်တွေ၊ ပါတီပွဲတွေ — တနင်္ဂနွေနေ့တိုင်း mailbox ထဲ။
);
}
function DesktopFooter({ onCat, onShop }) {
return (
);
}
function DesktopDrawer({ open, onClose, onNav }) {
return (
);
}
function DesktopArticlePage({ article, onBack }) {
const a = article;
const body = (a.body_my && a.body_my.length) ? a.body_my : D.articleBody_my;
const quoteText = a.excerpt_my || a.subtitle_my || '';
const pullQuoteAt = body.length > 5 ? 2 : 1;
return (
{a.eyebrow_my || a.cat_label}
{a.title_my}
BY {a.author || 'KWEE'}
·
{a.date || '2025'}
·
{a.read_time || '5 မိနစ်'}
{body.map((p, i) => (
{p}
{i === pullQuoteAt && quoteText && "{quoteText}"
}
))}
{['#fashion', '#90s', '#urban', '#streetwear', '#' + a.cat].map(t =>
{t}
)}
);
}
function DesktopCategoryPage({ catId, onOpen }) {
const cat = D.nav.find(n => n.id === catId);
if (!cat) return null;
const items = D.latest.filter(l => l.cat === catId).concat(D.latest).slice(0, 12);
return (
/ {cat.label.toUpperCase()}
{cat.my}
{items.length} ဆောင်းပါး
curated by KWEE
№ 02
All — ဆောင်းပါးများ
);
}
function DesktopShopLanding({ onPick }) {
const cats = D.shop_categories || [];
const totalProducts = (D.shop_products || []).length;
return (
{totalProducts} products in {cats.length} collections
curated by KWEE
);
}
function DesktopShopCategory({ catId, onProduct, onBack }) {
const cat = shopFindCategory(catId);
const products = shopProductsInCategory(catId);
const total = products.length;
const refs = useRef([]);
useEffect(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('revealed'); });
}, { threshold: 0.2 });
refs.current.forEach(el => el && io.observe(el));
return () => io.disconnect();
}, [catId]);
return (
/ {cat?.name?.toUpperCase() || 'KWEE STORE'}
{cat?.name || 'Shop'}
);
}
function DesktopShopProduct({ product, onBack }) {
const p = product;
return (
{p.tag}
{p.name}
{p.price}
{p.description &&
{p.description}
}
{p.sub &&
{p.sub}
}
);
}
function DesktopHomePage({ onOpen, onCat, onShop }) {
const [activeCat, setActiveCat] = useState(null);
return (
{ setActiveCat(c); onCat(c); }} />
№ 01
Editor's pick
№ 02
Featured — ဆောင်းပါးများ
№ 03
Latest — နောက်ဆုံး
);
}
function DesktopApp() {
const [page, setPage] = useState({ name: 'home' });
const [scrolled, setScrolled] = useState(false);
const [drawer, setDrawer] = useState(false);
const [splashGone, setSplashGone] = useState(false);
useDesktopCursor();
useEffect(() => {
const t = setTimeout(() => setSplashGone(true), 1900);
return () => clearTimeout(t);
}, []);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
const goHome = () => { setPage({ name: 'home' }); window.scrollTo({ top: 0 }); };
const goCat = (cid) => { setPage({ name: 'category', cat: cid }); window.scrollTo({ top: 0 }); };
const goArticle = (a) => { setPage({ name: 'article', article: a }); window.scrollTo({ top: 0 }); };
const goShop = () => { setPage({ name: 'shop' }); window.scrollTo({ top: 0 }); };
const goShopCat = (catId) => { setPage({ name: 'shop_cat', catId }); window.scrollTo({ top: 0 }); };
const goShopProduct = (product, catId) => { setPage({ name: 'shop_product', product, catId }); window.scrollTo({ top: 0 }); };
const backFromProduct = () => {
if (page.catId != null) goShopCat(page.catId);
else goShop();
};
const onDrawerNav = (id) => {
setDrawer(false);
if (id === 'home') goHome();
else if (id === 'shop') goShop();
else goCat(id);
};
return (
setDrawer(true)} onLogo={goHome}
onCat={goCat} onShop={goShop} />
{page.name === 'home' && }
{page.name === 'category' && }
{page.name === 'article' && }
{page.name === 'shop' && }
{page.name === 'shop_cat' && }
{page.name === 'shop_product' && }
setDrawer(false)} onNav={onDrawerNav} />
);
}
// ════════════════════════════════════════════════════════════════
// Root — picks mobile or desktop based on viewport
// ════════════════════════════════════════════════════════════════
function Root() {
const [isMobile, setIsMobile] = useState(window.innerWidth < MOBILE_BREAKPOINT);
useEffect(() => {
const onResize = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, []);
return isMobile ? : ;
}
ReactDOM.createRoot(document.getElementById('app')).render();