The og:image for the EmojiCopy website. The main image is the site default; the page template puts each page's own surfaces up front with the page name as the title.
Search, copy, and build your own lists.
packages/design-system/src/templates/EcBlogHero.tsx + EcSiteWindow.tsx — copy at 96px, window at 614/120 with five grid rows, pills at 548/44 and 604/500ui/store/list.js — the app's line icons are stood in by the nearest JoyPixels emoji.site__nav / .site__body rows · the window is authored at 820px and positioned absolutely so it bleeds off the right edge.site__grid 6-up · 40px emoji, 17px row gap, five rows so the window runs near the bottom edge<div class="hero">
<div class="hero__copy">
<div class="hero__brand"><img src="ec-logo-horizontal.svg" alt="EmojiCopy"></div>
<h2 class="hero__title">Find it.<br>Copy it.</h2>
<p class="hero__sub">Search, copy, and build your own lists.</p>
</div>
<div class="hero__site">
<div class="site__chrome">
<span class="site__dots"><i></i><i></i><i></i></span>
<span class="site__url"><svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M17 10V8a5 5 0 0 0-10 0v2H5v12h14V10h-2zm-8-2a3 3 0 0 1 6 0v2H9V8z"/></svg> emojicopy.com</span>
</div>
<div class="site__nav">
<img src="ec-logo-horizontal.svg" alt="EmojiCopy">
<span class="site__tab site__tab--on">My Emoji</span>
<span class="site__tab">All Emojis</span>
<span class="site__tab">Explore</span>
<span class="site__tab">Apps</span>
<span class="site__icons"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 8h10M18 8h2M4 16h4M12 16h8"/><circle cx="16" cy="8" r="2"/><circle cx="10" cy="16" r="2"/></svg><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="10" r="3"/><path d="M6.5 19a6 6 0 0 1 11 0"/></svg></span>
</div>
<div class="site__body">
<div class="site__side">
<div class="site__search"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.6-3.6"/></svg> Search</div>
<div class="site__label">Smart lists</div>
<div class="site__row site__row--on"><img src=".../64/1f553.png" alt="">Recent Emoji</div>
<div class="site__row"><img src=".../64/1f9ec.png" alt="">Recent Combos</div>
<div class="site__label">My lists</div>
<div class="site__row"><img src=".../64/2764.png" alt="">Favorites</div>
<div class="site__row"><img src=".../64/1f46f.png" alt="">Friends</div>
</div>
<div class="site__main">
<div class="site__head"><img src=".../64/1f553.png" alt="">Recent Emoji<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg><i></i></div>
<div class="site__grid">
<!-- thirty imgs, 6 per row:
1f602 1f607 1f642 1f609 1f60d 1f618
1f92a 1f929 1f917 1f914 1f920 1f916
1f973 1f44f 1f603 1f44d 1f644 1f92f
1f913 1f634 1f47d 1f383 1f91e 1f590
1f60e 1f970 1f92d 1f60f 1f979 1f971 -->
</div>
</div>
</div>
</div>
<div class="hero__pill hero__pill--a"><!-- three imgs: 1f389 1f60d 1f44d --></div>
<div class="hero__pill hero__pill--b"><!-- three imgs: 1f92f 1f929 1f607 --></div>
</div>
<!-- emoji base: https://cdn.jsdelivr.net/joypixels/assets/11.0/png/unicode/64/<codepoint>.png -->
<!-- the site default: served on / and on any route without its own image --> <meta property="og:title" content="EmojiCopy"> <meta property="og:description" content="Search any emoji, copy it in a tap, and build your own lists."> <meta property="og:image" content="https://www.emojicopy.com/og/og-main.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta name="twitter:card" content="summary_large_image">
/* fixed-canvas PNG export: raw px on purpose; colors from tokens.css */
.hero {
width: 1200px; height: 630px;
position: relative; overflow: hidden;
font-family: var(--ff-inter);
background:
radial-gradient(46% 62% at 77% 44%, var(--green-300) 0%, transparent 72%),
radial-gradient(42% 54% at 4% 96%, var(--metal-50) 0%, transparent 70%),
var(--white);
}
.hero__copy { position: absolute; left: 96px; top: 50%; transform: translateY(-50%); z-index: 3; }
.hero__brand { display: flex; align-items: center; margin-bottom: 32px; }
.hero__brand img { height: 34px; display: block; }
.hero__title {
margin: 0 0 28px;
font-family: var(--ff-dm-sans); font-weight: 900;
font-size: 124px; line-height: .94; letter-spacing: -.045em;
color: var(--metal-950);
}
.hero__sub { margin: 0; font-size: 24px; font-weight: 500; color: var(--metal-600); white-space: nowrap; }
/* the site window, authored at 820px, bleeding off the right */
.hero__site {
position: absolute; left: 614px; top: 120px; z-index: 2;
width: 820px;
background: var(--white);
border: 1px solid var(--metal-100); border-radius: 16px; overflow: hidden;
box-shadow: 0 48px 100px -24px rgba(15,16,18,.22), 0 20px 44px -20px rgba(15,16,18,.14), 0 1px 2px rgba(15,16,18,.05);
}
.site__chrome { display: flex; align-items: center; height: 44px; padding: 0 16px; background: var(--metal-50); border-bottom: 1px solid var(--metal-100); }
.site__dots { display: flex; gap: 8px; flex: none; }
.site__dots i { width: 12px; height: 12px; border-radius: 50%; display: block; }
.site__dots i:nth-child(1) { background: #FF5F57; } /* browser-chrome literals */
.site__dots i:nth-child(2) { background: #FEBC2E; }
.site__dots i:nth-child(3) { background: #28C840; }
.site__url {
display: flex; align-items: center; gap: 7px;
margin: 0 auto; transform: translateX(-26px);
padding: 6px 18px;
background: var(--white); border: 1px solid var(--metal-200); border-radius: 999px;
font-size: 13px; color: var(--metal-500);
}
.site__nav { display: flex; align-items: center; gap: 22px; height: 58px; padding: 0 22px; border-bottom: 1px solid var(--metal-100); }
.site__nav img { height: 22px; display: block; }
.site__tab { font-size: 14px; font-weight: 500; color: var(--metal-600); }
.site__tab--on { font-weight: 700; color: var(--green-800); background: var(--green-300); padding: 7px 15px; border-radius: 999px; }
.site__icons { margin-left: auto; display: flex; align-items: center; gap: 14px; color: var(--metal-500); }
.site__body { display: flex; align-items: stretch; }
.site__side { width: 198px; flex: none; border-right: 1px solid var(--metal-100); padding: 14px 12px 20px; }
.site__search { display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 11px; background: var(--metal-50); border-radius: 10px; font-size: 13px; color: var(--metal-400); }
.site__search svg { flex: none; }
.site__label { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--metal-400); padding: 14px 10px 6px; }
.site__row { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 9px; font-size: 13.5px; font-weight: 500; color: var(--metal-700); }
.site__row img { width: 17px; height: 17px; flex: none; display: block; }
.site__row--on { font-weight: 700; color: var(--green-900); background: var(--green-300); }
.site__main { flex: 1; padding: 16px 22px 24px; }
.site__head { display: flex; align-items: center; gap: 8px; padding-bottom: 16px; font-weight: 600; font-size: 13px; color: var(--metal-500); }
.site__head img { width: 16px; height: 16px; opacity: .75; display: block; }
.site__head i { flex: 1; height: 1px; background: var(--metal-100); margin-left: 8px; }
.site__grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 17px 0; justify-items: center; }
.site__grid img { width: 40px; height: 40px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
/* floating emoji pills over the seam */
.hero__pill {
position: absolute; z-index: 4;
display: flex; align-items: center; gap: 10px;
padding: 12px 18px;
background: var(--white); border: 1px solid var(--metal-100); border-radius: 999px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.hero__pill img { width: 34px; height: 34px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.hero__pill--a { left: 548px; top: 44px; transform: rotate(-4deg); }
.hero__pill--b { left: 604px; top: 500px; transform: rotate(3deg); }
Collections to follow.
+ follow button (green check when followed). Titles, icons and emoji are the real ones from ui/utils/data/generated/collections.json<div class="pv">
<div class="pv__copy">
<div class="pv__brand"><img src="ec-logo-horizontal.svg" alt="EmojiCopy"></div>
<h2 class="pv__title">Explore</h2>
<p class="pv__sub">Collections to follow.</p>
</div>
<div class="pv__card pv-cc pv-cc--l">
<div class="pv-cc__grid">
<!-- sixteen imgs, 4 per row: 1f928 1f913 1f60e 1f624 1f633 1fae0 1f974 1f921 1f480 2620 1f90c 1f90f 1faf5 1f444 1f441 1f9e2 -->
</div>
<div class="pv-cc__foot">
<span class="pv-cc__avatar"><img src=".../64/1f5ff.png" alt=""></span>
<span class="pv-cc__about"><span class="pv-cc__title">Meme Classics</span><span class="pv-cc__meta">177.9K followers</span></span>
<span class="pv-cc__add"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></span>
</div>
</div>
<div class="pv__card pv-cc pv-cc--c">
<div class="pv-cc__grid">
<!-- sixteen imgs, 4 per row: 1f643 1f92a 1f928 1f62d 1f624 1fae3 1f92d 1fae2 1fae1 1fae0 1fae5 1f62c 1f974 1f608 1f921 1f480 -->
</div>
<div class="pv-cc__foot">
<span class="pv-cc__avatar"><img src=".../64/1f480.png" alt=""></span>
<span class="pv-cc__about"><span class="pv-cc__title">Gen Z / TikTok Vibes</span><span class="pv-cc__meta">174.1K followers</span></span>
<span class="pv-cc__add"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></span>
</div>
</div>
<div class="pv__card pv-cc pv-cc--r">
<div class="pv-cc__grid">
<!-- sixteen imgs, 4 per row: 1f973 1f64c 1f44f 1f4aa 1f57a 1f451 1f496 1f9c1 1f382 1f37b 1f942 1f37e 2728 1f3c6 1f947 1f387 -->
</div>
<div class="pv-cc__foot">
<span class="pv-cc__avatar"><img src=".../64/1f389.png" alt=""></span>
<span class="pv-cc__about"><span class="pv-cc__title">Celebrate</span><span class="pv-cc__meta"></span></span>
<span class="pv-cc__add"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></span>
</div>
</div>
<div class="pv__pill pv__pill--explore"><!-- three imgs: 1f5ff 1f480 1f389 --></div>
</div>
<!-- emoji base: https://cdn.jsdelivr.net/joypixels/assets/11.0/png/unicode/64/<codepoint>.png -->
<meta property="og:title" content="Explore · EmojiCopy"> <meta property="og:description" content="Emoji collections to follow. Meme Classics, Gen Z / TikTok Vibes, Celebrate and more."> <meta property="og:image" content="https://www.emojicopy.com/og/og-explore.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta name="twitter:card" content="summary_large_image">
/* fixed-canvas PNG export: raw px on purpose; colors from tokens.css */
.pv {
width: 1200px; height: 630px;
position: relative; overflow: hidden;
font-family: var(--ff-inter);
background:
radial-gradient(46% 62% at 77% 44%, var(--green-300) 0%, transparent 72%),
radial-gradient(42% 54% at 4% 96%, var(--metal-50) 0%, transparent 70%),
var(--white);
}
/* the copy: page name as the title, small, top-left; the page's own content owns the rest */
.pv__copy { position: absolute; left: 96px; top: 96px; z-index: 6; }
.pv__brand img { height: 34px; display: block; }
.pv__title {
margin: 24px 0 10px;
font-family: var(--ff-dm-sans); font-weight: 900;
font-size: 56px; line-height: 1; letter-spacing: -.04em;
color: var(--metal-950);
}
.pv__sub { margin: 0; font-size: 22px; font-weight: 500; color: var(--metal-600); white-space: nowrap; }
/* every floating surface shares one lift */
.pv__card {
position: absolute;
background: var(--white);
border: 1px solid var(--metal-100); border-radius: 16px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill {
position: absolute; z-index: 7;
display: flex; align-items: center; gap: 10px;
padding: 12px 18px;
background: var(--white); border: 1px solid var(--metal-100); border-radius: 999px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill img { width: 34px; height: 34px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
/* explore: the real Explore collection card — emoji grid, then a footer with the
collection's own emoji in a circle, its title, follower count and the + follow button */
.pv-cc { width: 292px; padding: 20px 18px 18px; }
.pv-cc__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px 0; justify-items: center; }
.pv-cc__grid img { width: 44px; height: 44px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.pv-cc__foot { display: flex; align-items: center; gap: 12px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--metal-100); }
.pv-cc__avatar { width: 42px; height: 42px; flex: none; display: grid; place-items: center; border-radius: 50%; background: var(--metal-50); }
.pv-cc__avatar img { width: 24px; height: 24px; display: block; }
.pv-cc__about { flex: 1; min-width: 0; }
.pv-cc__title { display: block; font-size: 17px; font-weight: 700; color: var(--metal-950); line-height: 1.25; }
.pv-cc__meta { display: block; margin-top: 2px; font-size: 13px; font-weight: 500; color: var(--metal-500); }
.pv-cc__add { flex: none; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 10px; background: var(--metal-50); color: var(--metal-700); }
.pv-cc--l { left: 408px; top: 232px; z-index: 2; transform: rotate(-6deg); }
.pv-cc--c { left: 692px; top: 148px; z-index: 4; }
.pv-cc--r { left: 972px; top: 372px; z-index: 3; transform: rotate(5deg); }
.pv__pill--explore { left: 596px; top: 104px; transform: rotate(-5deg); }
For Chrome and desktop.
emojicopy-extension-dist popup.html panel-width), opening on Recent Emoji with the shipped "Search" placeholder; the desktop window runs the same client<div class="pv">
<div class="pv__copy">
<div class="pv__brand"><img src="ec-logo-horizontal.svg" alt="EmojiCopy"></div>
<h2 class="pv__title">Apps</h2>
<p class="pv__sub">For Chrome and desktop.</p>
</div>
<div class="pv__card pv-mac">
<div class="pv-mac__bar"><i></i><i></i><i></i></div>
<div class="pv-mac__body">
<div class="pv-mac__side">
<div class="pv-mac__search"><svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.6-3.6"/></svg> Search</div>
<div class="pv-mac__row pv-mac__row--on"><img src=".../64/1f553.png" alt="">Recent Emoji</div>
<div class="pv-mac__row"><img src=".../64/1f9ec.png" alt="">Recent Combos</div>
<div class="pv-mac__row"><img src=".../64/2764.png" alt="">Favorites</div>
<div class="pv-mac__row"><img src=".../64/1f46f.png" alt="">Friends</div>
</div>
<div class="pv-mac__main">
<div class="pv-mac__head"><img src=".../64/1f553.png" alt="">Recent Emoji<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg><i></i></div>
<div class="pv-mac__grid">
<!-- twenty imgs, 4 per row: 1f602 1f60d 1f44d 1f525 2728 1f389 1f973 1f64f 1f440 2705 1f680 1f92f 1f929 1f607 1f60e 1f970 1f92d 1f60f 1f979 1f971 -->
</div>
</div>
</div>
</div>
<div class="pv__card pv-ext">
<div class="pv-ext__search"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.6-3.6"/></svg> Search</div>
<div class="pv-ext__head"><img src=".../64/1f553.png" alt="">Recent Emoji<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg><i></i></div>
<div class="pv-ext__grid">
<!-- twenty-five imgs, 5 per row: 1f602 1f44d 1f525 2728 1f60d 1f389 1f64f 1f440 2705 1f680 1f92f 1f929 1f607 1f60e 1f970 1f923 1f643 1f609 1f60a 1f914 1f44f 1f4aa 1f496 1f382 1f37b -->
</div>
</div>
<div class="pv__pill pv__pill--apps"><!-- three imgs: 1f4bb 1f310 2728 --></div>
</div>
<!-- emoji base: https://cdn.jsdelivr.net/joypixels/assets/11.0/png/unicode/64/<codepoint>.png -->
<meta property="og:title" content="Apps · EmojiCopy"> <meta property="og:description" content="EmojiCopy in your browser and on your desktop. The Chrome extension and the desktop app."> <meta property="og:image" content="https://www.emojicopy.com/og/og-apps.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta name="twitter:card" content="summary_large_image">
/* fixed-canvas PNG export: raw px on purpose; colors from tokens.css */
.pv {
width: 1200px; height: 630px;
position: relative; overflow: hidden;
font-family: var(--ff-inter);
background:
radial-gradient(46% 62% at 77% 44%, var(--green-300) 0%, transparent 72%),
radial-gradient(42% 54% at 4% 96%, var(--metal-50) 0%, transparent 70%),
var(--white);
}
/* the copy: page name as the title, small, top-left; the page's own content owns the rest */
.pv__copy { position: absolute; left: 96px; top: 96px; z-index: 6; }
.pv__brand img { height: 34px; display: block; }
.pv__title {
margin: 24px 0 10px;
font-family: var(--ff-dm-sans); font-weight: 900;
font-size: 56px; line-height: 1; letter-spacing: -.04em;
color: var(--metal-950);
}
.pv__sub { margin: 0; font-size: 22px; font-weight: 500; color: var(--metal-600); white-space: nowrap; }
/* every floating surface shares one lift */
.pv__card {
position: absolute;
background: var(--white);
border: 1px solid var(--metal-100); border-radius: 16px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill {
position: absolute; z-index: 7;
display: flex; align-items: center; gap: 10px;
padding: 12px 18px;
background: var(--white); border: 1px solid var(--metal-100); border-radius: 999px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill img { width: 34px; height: 34px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
/* apps: the two apps themselves, fanned — the desktop app window and the Chrome
extension panel (385 wide with no chrome of its own, as it ships) */
.pv-mac { left: 466px; top: 158px; z-index: 2; width: 440px; overflow: hidden; transform: rotate(-4deg); }
.pv-mac__bar { display: flex; align-items: center; height: 38px; padding: 0 14px; background: var(--metal-50); border-bottom: 1px solid var(--metal-100); }
.pv-mac__bar i { width: 10px; height: 10px; border-radius: 50%; display: block; margin-right: 7px; }
.pv-mac__bar i:nth-child(1) { background: #FF5F57; } /* window-chrome literals */
.pv-mac__bar i:nth-child(2) { background: #FEBC2E; }
.pv-mac__bar i:nth-child(3) { background: #28C840; }
.pv-mac__body { display: flex; align-items: stretch; }
.pv-mac__side { width: 152px; flex: none; border-right: 1px solid var(--metal-100); padding: 12px 10px 18px; }
.pv-mac__search { display: flex; align-items: center; gap: 7px; height: 30px; padding: 0 9px; margin-bottom: 8px; background: var(--metal-50); border-radius: 9px; font-size: 11.5px; color: var(--metal-400); }
.pv-mac__search svg { flex: none; }
.pv-mac__row { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 8px; font-size: 12.5px; font-weight: 500; color: var(--metal-700); white-space: nowrap; }
.pv-mac__row img { width: 15px; height: 15px; flex: none; display: block; }
.pv-mac__row--on { font-weight: 700; color: var(--green-900); background: var(--green-300); }
.pv-mac__main { flex: 1; padding: 14px 16px 20px; }
.pv-mac__head { display: flex; align-items: center; gap: 7px; padding-bottom: 12px; font-size: 12px; font-weight: 600; color: var(--metal-500); }
.pv-mac__head img { width: 14px; height: 14px; opacity: .75; display: block; }
.pv-mac__head i { flex: 1; height: 1px; background: var(--metal-100); margin-left: 6px; }
.pv-mac__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px 0; justify-items: center; }
.pv-mac__grid img { width: 40px; height: 40px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.pv-ext { left: 888px; top: 258px; z-index: 4; width: 385px; padding: 16px 18px 22px; transform: rotate(4deg); }
.pv-ext__search { display: flex; align-items: center; gap: 10px; height: 42px; padding: 0 14px; background: var(--metal-50); border-radius: 12px; font-size: 15px; color: var(--metal-400); }
.pv-ext__search svg { flex: none; }
.pv-ext__head { display: flex; align-items: center; gap: 8px; margin: 16px 0 12px; font-size: 13px; font-weight: 600; color: var(--metal-500); }
.pv-ext__head img { width: 16px; height: 16px; opacity: .75; display: block; }
.pv-ext__head i { flex: 1; height: 1px; background: var(--metal-100); margin-left: 8px; }
.pv-ext__grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px 0; justify-items: center; }
.pv-ext__grid img { width: 44px; height: 44px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.pv__pill--apps { left: 130px; top: 486px; transform: rotate(6deg); }
Browse by category.
ui/pages/AllEmoji.vue renders a Category per category: the sidebar rail of categories beside the main column of stacked group headings, each followed by its grid. Category titles and icons from components/AllEmoji/Category.vue, the grid in utils/data/categories/people.json file order<div class="pv">
<div class="pv__copy">
<div class="pv__brand"><img src="ec-logo-horizontal.svg" alt="EmojiCopy"></div>
<h2 class="pv__title">All Emojis</h2>
<p class="pv__sub">Browse by category.</p>
</div>
<div class="pv__card pv-ae">
<div class="pv-ae__body">
<div class="pv-ae__side">
<div class="pv-ae__row pv-ae__row--on"><img src=".../64/1f600.png" alt="">Smileys & People</div>
<div class="pv-ae__row"><img src=".../64/1f436.png" alt="">Animals & Nature</div>
<div class="pv-ae__row"><img src=".../64/1f354.png" alt="">Food & Drink</div>
<div class="pv-ae__row"><img src=".../64/26bd.png" alt="">Activity</div>
<div class="pv-ae__row"><img src=".../64/1f3d9.png" alt="">Travel & Places</div>
<div class="pv-ae__row"><img src=".../64/1f4a1.png" alt="">Objects</div>
<div class="pv-ae__row"><img src=".../64/2764.png" alt="">Symbols</div>
<div class="pv-ae__row"><img src=".../64/1f3c1.png" alt="">Flags</div>
</div>
<div class="pv-ae__main">
<div class="pv-ae__head"><img src=".../64/1f600.png" alt="">Smileys & People<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg><i></i></div>
<div class="pv-ae__grid">
<!-- forty imgs, 8 per row: 1f600 1f603 1f604 1f601 1f606 1f979 1f605 1f602 1f923 1f972 263a 1f60a 1f607 1f642 1f643 1f609 1f60c 1f60d 1f970 1f618 1f617 1f619 1f61a 1f60b 1f61b 1f61d 1f61c 1f92a 1f928 1f9d0 1f913 1f60e 1f978 1f929 1f973 1f60f 1f612 1f61e 1f614 1f61f -->
</div>
<div class="pv-ae__head pv-ae__head--next"><img src=".../64/1f436.png" alt="">Animals & Nature<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg><i></i></div>
<div class="pv-ae__grid">
<!-- fourteen imgs, 8 per row: 1f436 1f431 1f42d 1f439 1f430 1f98a 1f43b 1f43c 1f428 1f42f 1f981 1f42e 1f437 1f438 -->
</div>
</div>
</div>
</div>
<div class="pv__pill pv__pill--all"><!-- three imgs: 1f436 1f354 26bd --></div>
</div>
<!-- emoji base: https://cdn.jsdelivr.net/joypixels/assets/11.0/png/unicode/64/<codepoint>.png -->
<meta property="og:title" content="All Emojis · EmojiCopy"> <meta property="og:description" content="Browse every category. Find the emoji, copy it."> <meta property="og:image" content="https://www.emojicopy.com/og/og-emoji.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta name="twitter:card" content="summary_large_image">
/* fixed-canvas PNG export: raw px on purpose; colors from tokens.css */
.pv {
width: 1200px; height: 630px;
position: relative; overflow: hidden;
font-family: var(--ff-inter);
background:
radial-gradient(46% 62% at 77% 44%, var(--green-300) 0%, transparent 72%),
radial-gradient(42% 54% at 4% 96%, var(--metal-50) 0%, transparent 70%),
var(--white);
}
/* the copy: page name as the title, small, top-left; the page's own content owns the rest */
.pv__copy { position: absolute; left: 96px; top: 96px; z-index: 6; }
.pv__brand img { height: 34px; display: block; }
.pv__title {
margin: 24px 0 10px;
font-family: var(--ff-dm-sans); font-weight: 900;
font-size: 56px; line-height: 1; letter-spacing: -.04em;
color: var(--metal-950);
}
.pv__sub { margin: 0; font-size: 22px; font-weight: 500; color: var(--metal-600); white-space: nowrap; }
/* every floating surface shares one lift */
.pv__card {
position: absolute;
background: var(--white);
border: 1px solid var(--metal-100); border-radius: 16px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill {
position: absolute; z-index: 7;
display: flex; align-items: center; gap: 10px;
padding: 12px 18px;
background: var(--white); border: 1px solid var(--metal-100); border-radius: 999px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill img { width: 34px; height: 34px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
/* all emojis: the page itself — the category sidebar beside the stacked category
sections, bleeding off the right and bottom so the page reads as it scrolls */
.pv-ae { left: 400px; top: 140px; z-index: 2; width: 830px; overflow: hidden; }
.pv-ae__body { display: flex; align-items: stretch; }
.pv-ae__side { width: 210px; flex: none; border-right: 1px solid var(--metal-100); padding: 18px 12px 24px; }
.pv-ae__row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 9px; font-size: 14px; font-weight: 500; color: var(--metal-700); }
.pv-ae__row img { width: 18px; height: 18px; flex: none; display: block; }
.pv-ae__row--on { font-weight: 700; color: var(--green-900); background: var(--green-300); }
.pv-ae__main { flex: 1; padding: 18px 24px 0; }
.pv-ae__head { display: flex; align-items: center; gap: 9px; padding: 0 0 14px; font-size: 15px; font-weight: 700; color: var(--metal-950); }
.pv-ae__head img { width: 20px; height: 20px; display: block; }
.pv-ae__head i { flex: 1; height: 1px; background: var(--metal-100); margin-left: 8px; }
.pv-ae__head--next { padding-top: 24px; }
.pv-ae__grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 20px 0; justify-items: center; }
.pv-ae__grid img { width: 48px; height: 48px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.pv__pill--all { left: 1000px; top: 96px; transform: rotate(7deg); }
Favorites and your lists.
ui/blocks/SubNavSidebar.vue, lists.my[0]; the ❤️ divider from favorites-empty); "Work" is an illustrative custom list<div class="pv">
<div class="pv__copy">
<div class="pv__brand"><img src="ec-logo-horizontal.svg" alt="EmojiCopy"></div>
<h2 class="pv__title">My Emoji</h2>
<p class="pv__sub">Favorites and your lists.</p>
</div>
<div class="pv__card pv-list pv-list--fav">
<div class="pv-list__head"><img src=".../64/2764.png" alt=""><span class="pv-list__title">Favorites</span><i></i></div>
<div class="pv-list__grid">
<!-- fifteen imgs, 5 per row: 1f602 1f44d 1f525 2728 1f60d 1f64f 1f389 1f973 1f440 2705 1f680 1f92f 1f929 1f607 1f60e -->
</div>
</div>
<div class="pv__card pv-list pv-list--work">
<div class="pv-list__head"><img src=".../64/1f4bc.png" alt=""><span class="pv-list__title">Work</span><i></i></div>
<div class="pv-list__grid">
<!-- fifteen imgs, 5 per row: 2705 1f440 1f4c5 2615 1f680 1f4bb 1f4e7 1f4ca 1f4a1 1f4dd 1f91d 1f44f 1f3af 1f4ac 1f9e0 -->
</div>
</div>
<div class="pv__pill pv__pill--my"><!-- three imgs: 2764 2b50 2705 --></div>
</div>
<!-- emoji base: https://cdn.jsdelivr.net/joypixels/assets/11.0/png/unicode/64/<codepoint>.png -->
<meta property="og:title" content="My Emoji · EmojiCopy"> <meta property="og:description" content="Your favorites and your lists, ready to copy."> <meta property="og:image" content="https://www.emojicopy.com/og/og-my-emoji.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta name="twitter:card" content="summary_large_image">
/* fixed-canvas PNG export: raw px on purpose; colors from tokens.css */
.pv {
width: 1200px; height: 630px;
position: relative; overflow: hidden;
font-family: var(--ff-inter);
background:
radial-gradient(46% 62% at 77% 44%, var(--green-300) 0%, transparent 72%),
radial-gradient(42% 54% at 4% 96%, var(--metal-50) 0%, transparent 70%),
var(--white);
}
/* the copy: page name as the title, small, top-left; the page's own content owns the rest */
.pv__copy { position: absolute; left: 96px; top: 96px; z-index: 6; }
.pv__brand img { height: 34px; display: block; }
.pv__title {
margin: 24px 0 10px;
font-family: var(--ff-dm-sans); font-weight: 900;
font-size: 56px; line-height: 1; letter-spacing: -.04em;
color: var(--metal-950);
}
.pv__sub { margin: 0; font-size: 22px; font-weight: 500; color: var(--metal-600); white-space: nowrap; }
/* every floating surface shares one lift */
.pv__card {
position: absolute;
background: var(--white);
border: 1px solid var(--metal-100); border-radius: 16px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill {
position: absolute; z-index: 7;
display: flex; align-items: center; gap: 10px;
padding: 12px 18px;
background: var(--white); border: 1px solid var(--metal-100); border-radius: 999px;
box-shadow: 0 24px 50px -16px rgba(15,16,18,.25), 0 3px 10px rgba(15,16,18,.07);
}
.pv__pill img { width: 34px; height: 34px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
/* my emoji: two list cards fanned — Favorites (the default list) and a custom list */
.pv-list { width: 400px; padding: 20px 22px 24px; }
.pv-list--fav { left: 424px; top: 140px; z-index: 4; transform: rotate(-3deg); }
.pv-list--work { left: 790px; top: 226px; z-index: 3; transform: rotate(4deg); }
.pv-list__head { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.pv-list__head img { width: 22px; height: 22px; display: block; }
.pv-list__title { font-size: 20px; font-weight: 700; color: var(--metal-950); }
.pv-list__head i { flex: 1; height: 2px; border-radius: 2px; background: var(--metal-100); margin-left: 6px; }
.pv-list__grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px 0; justify-items: center; }
.pv-list__grid img { width: 48px; height: 48px; display: block; filter: drop-shadow(0 10px 18px rgba(15,16,18,.10)); }
.pv__pill--my { left: 560px; top: 540px; transform: rotate(-4deg); }