
Html Ppt Zhangzara Studio
- 61 installs
- 83.7k repo stars
- Updated August 5, 2026
- nexu-io/open-design
Helps with ai & agent building tasks during AI-assisted development.
About
html-ppt-zhangzara-studio is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- html-ppt-zhangzara-studio
- AI & Agent Building
- AI-coding skill
Html Ppt Zhangzara Studio by the numbers
- 61 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #6,381 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/nexu-io/open-design --skill html-ppt-zhangzara-studioAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 61 |
|---|---|
| repo stars | ★ 83.7k |
| Last updated | August 5, 2026 |
| Repository | nexu-io/open-design ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Studio
Black canvas with electric-yellow type; high-voltage design studio aesthetic.
A single self-contained HTML deck — typography, palette, decorative system, and slide vocabulary are all tuned together. Mixing layouts across templates breaks the system; stay inside this one.
At a glance
- Scheme: dark
- Formality: medium
- Density: medium
- Slides in demo: 12
Best for
Anything that should feel electric and design-led: studio credentials, creative agency pitches, brand showcases, art-direction reviews, fashion / sneaker brand work. Also a striking unexpected choice for tech, research, or business decks where the speaker wants the deck to be a brand statement.
Avoid for
Contexts that should feel quiet or institutional — the black-and-electric-yellow palette is the loudest in the library.
Workflow
1. Clone `example.html` into the user's workspace as the working file. 2. Replace placeholder content with the user's real headlines, body copy, numbers, names, dates, and section labels. Match existing dimensions when swapping image placeholders. 3. Preserve the design system. Never substitute fonts, recolor the palette, restructure the layout grid, or strip decorative elements (corner brackets, paper grain, geometric shapes, illustrated SVGs). They are part of the identity. 4. Adjust deck length by duplicating layouts. If the user has more content than the demo holds, duplicate an existing slide of the most appropriate layout. If less, drop slides from the bottom. Update page-number labels. 5. Designing missing layouts: if a slide needs a layout the template doesn't have, design it from scratch using the same fonts, palette, decorative vocabulary, spacing rhythm, and component grammar — never bail to a different template. 6. Keep the navigation runtime as shipped. If the deck ships an assets/deck-stage.js or inline keyboard handler, leave it intact.
Output contract
Emit between <artifact> tags:
<artifact identifier="zhangzara-studio" type="text/html" title="Deck Title">
<!doctype html>
<html>...</html>
</artifact>Source & license
Vendored from upstream MIT-licensed `zarazhangrui/beautiful-html-templates`.
The full upstream MIT license text — including the original copyright notice — ships in this skill at `LICENSE` and must be redistributed alongside any copy of example.html, template.json, or any vendored assets/ runtime. See template.json for the upstream metadata snapshot.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Studio Presentation</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<!--
Studio style uses three font families:
1. Barlow 900 — the entire display and heading system; becomes graphic at scale
2. Barlow 400/500 — body, lead paragraphs
3. IBM Plex Mono — footer metadata, slide counters, caption labels
4. Noto Sans SC — Chinese fallback for all roles
-->
<link
href="https://fonts.googleapis.com/css2?family=Barlow:wght@400;500;700;800;900&family=IBM+Plex+Mono:wght@300;400;500&family=Noto+Sans+SC:wght@400;500;700;900&display=swap"
rel="stylesheet"
/>
<style>
/* ╔══════════════════════════════════════════════════════════════════════╗
║ ZONE A · TOKENS — STUDIO STYLE ║
║ ║
║ Replace this block to change the visual style entirely. ║
║ Every color, font, and size in this file reads from these vars. ║
║ Never write raw hex values, font names, or px sizes outside here. ║
╚══════════════════════════════════════════════════════════════════════╝ */
:root {
/* ── Palette ──────────────────────────────────────────────────────── */
/* Near-black: the dark slide background — warm dark, not cold neutral */
--c-bg: #1c1c1c;
/* Slightly lighter near-black for secondary dark surfaces */
--c-bg-alt: #242422;
/* Acid yellow: THE light slide background — yellow is the environment, not an accent */
--c-bg-light: #f5d200;
/* Slightly cooler yellow for secondary light surfaces */
--c-bg-light-alt: #f0cc00;
/* Primary text on dark: acid yellow — the only colour on dark slides */
--c-fg: #f5d200;
/* Secondary text on dark: yellow at 58% opacity — muted but still warm */
--c-fg-2: rgba(245, 210, 0, 0.58);
/* Tertiary / hint text on dark: yellow at 32% */
--c-fg-3: rgba(245, 210, 0, 0.32);
/* Primary text on light: near-black on yellow */
--c-fg-light: #1c1c1c;
/* Secondary text on light: near-black at 62% */
--c-fg-light-2: rgba(28, 28, 28, 0.62);
/* Tertiary text on light */
--c-fg-light-3: rgba(28, 28, 28, 0.35);
/* Accent: yellow on dark / same yellow (var reused by engine) */
--c-accent: #f5d200;
/* Dividers on dark: very dark warm border */
--c-border: #2e2e2c;
/* Dividers on light: near-black at 18% opacity on yellow */
--c-border-light: rgba(28, 28, 28, 0.18);
/* ── Typography ──────────────────────────────────────────────────── */
/* Display + Heading: Barlow 900 — grotesque at max weight becomes a graphic object */
--f-display: "Barlow", "Noto Sans SC", sans-serif;
--f-heading: "Barlow", "Noto Sans SC", sans-serif;
/* Body: Barlow 400/500 — same family, steps back as weight drops */
--f-body: "Barlow", "Noto Sans SC", system-ui, sans-serif;
/* Mono: IBM Plex Mono — metadata, counters, footer columns */
--f-mono: "IBM Plex Mono", monospace;
/* ── Type Scale ───────────────────────────────────────────────────── */
/* Studio runs type LARGER than Signal — the headline IS the layout */
--sz-display: 12vw; /* cover hero — type at maximum scale */
--sz-h1: 7.5vw; /* chapter titles, statement headlines */
--sz-h2: 4.8vw; /* section headers */
--sz-h3: 2.8vw; /* sub-headlines */
--sz-lead: 1.6vw; /* intro paragraphs */
--sz-body: 1.15vw; /* body text, bullets */
--sz-caption: 0.85vw; /* captions, footnotes */
--sz-label: 0.72vw; /* mono metadata, chrome */
/* ── Spacing ─────────────────────────────────────────────────────── */
/* Studio pads tighter than Signal — type runs to near-edge */
--pad-x: 5vw;
--pad-y: 5vh;
--gap-lg: 3.5vh;
--gap-md: 2vh;
--gap-sm: 1vh;
/* ── Motion ──────────────────────────────────────────────────────── */
/* Harder, sharper transitions — agency urgency, not editorial grace */
--ease-slide: cubic-bezier(0.77, 0, 0.175, 1);
--dur-slide: 0.75s;
--ease-enter: cubic-bezier(0.16, 1, 0.3, 1);
--dur-enter: 0.5s;
}
/* ╔══════════════════════════════════════════════════════════════════════╗
║ ZONE B · ENGINE — DO NOT MODIFY ║
║ ║
║ Layout engine, transitions, animation system, navigation. ║
║ Touching this breaks the mechanics. ║
╚══════════════════════════════════════════════════════════════════════╝ */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
background: var(--c-bg);
-webkit-font-smoothing: antialiased;
}
/* Deck container — all slides sit side by side in one horizontal strip */
#deck {
display: flex;
height: 100vh;
transition: transform var(--dur-slide) var(--ease-slide);
will-change: transform;
}
/* Slide base — each slide occupies exactly one full viewport */
.slide {
flex: 0 0 100vw;
width: 100vw;
height: 100vh;
position: relative;
padding: var(--pad-y) var(--pad-x);
display: grid;
grid-template-rows: auto 1fr auto;
overflow: hidden;
}
.slide-body {
min-height: 0;
}
/* Slide themes */
.slide.dark {
background: var(--c-bg);
color: var(--c-fg);
}
.slide.light {
background: var(--c-bg-light);
color: var(--c-fg-light);
}
/* ── Animation system ─────────────────────────────────────────────── */
/* Elements start invisible; become visible only when slide is active */
[data-anim] {
opacity: 0;
}
.slide.is-active [data-anim] {
animation-duration: var(--dur-enter);
animation-timing-function: var(--ease-enter);
animation-fill-mode: forwards;
}
.slide.is-active [data-anim="fade-up"] {
animation-name: kFadeUp;
}
.slide.is-active [data-anim="fade-in"] {
animation-name: kFadeIn;
}
.slide.is-active [data-anim="reveal-right"] {
animation-name: kRevealRight;
}
.slide.is-active [data-anim="reveal-left"] {
animation-name: kRevealLeft;
}
.slide.is-active [data-anim="scale-in"] {
animation-name: kScaleIn;
}
/* Staggered delays via data-delay attribute (0–6) */
[data-delay="0"] {
animation-delay: 0s;
}
[data-delay="1"] {
animation-delay: 0.08s;
}
[data-delay="2"] {
animation-delay: 0.18s;
}
[data-delay="3"] {
animation-delay: 0.3s;
}
[data-delay="4"] {
animation-delay: 0.44s;
}
[data-delay="5"] {
animation-delay: 0.6s;
}
[data-delay="6"] {
animation-delay: 0.78s;
}
@keyframes kFadeUp {
from {
opacity: 0;
transform: translateY(28px);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes kFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes kRevealRight {
from {
clip-path: inset(0 100% 0 0);
opacity: 1;
}
to {
clip-path: inset(0 0% 0 0);
opacity: 1;
}
}
@keyframes kRevealLeft {
from {
clip-path: inset(0 0 0 100%);
opacity: 1;
}
to {
clip-path: inset(0 0 0 0%);
opacity: 1;
}
}
@keyframes kScaleIn {
from {
opacity: 0;
transform: scale(0.94);
}
to {
opacity: 1;
transform: none;
}
}
/* ── Navigation UI ───────────────────────────────────────────────── */
#nav-dots {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 7px;
z-index: 100;
}
.nav-dot {
width: 5px;
height: 5px;
border-radius: 50%;
border: none;
background: rgba(255, 255, 255, 0.22);
cursor: pointer;
transition:
background 0.3s,
transform 0.3s;
padding: 0;
}
.nav-dot.is-active {
background: rgba(255, 255, 255, 0.8);
transform: scale(1.4);
}
#slide-counter {
position: fixed;
bottom: 20px;
right: 28px;
font-family: var(--f-mono);
font-size: 10px;
letter-spacing: 0.12em;
color: rgba(255, 255, 255, 0.25);
z-index: 100;
user-select: none;
}
/* ╔══════════════════════════════════════════════════════════════════════╗
║ ZONE C · TYPOGRAPHY — STUDIO OVERRIDES ║
║ ║
║ All headings: weight 900, uppercase, tight tracking. ║
║ The headline is not decoration — it IS the design. ║
╚══════════════════════════════════════════════════════════════════════╝ */
/* Display: maximum weight, maximum scale, uppercase — type as visual mass */
.display {
font-size: var(--sz-display);
font-weight: 900;
line-height: 0.9;
letter-spacing: -0.02em;
text-transform: uppercase;
font-family: var(--f-display);
}
.h1 {
font-size: var(--sz-h1);
font-weight: 900;
line-height: 0.92;
letter-spacing: -0.02em;
text-transform: uppercase;
font-family: var(--f-heading);
}
.h2 {
font-size: var(--sz-h2);
font-weight: 900;
line-height: 0.95;
letter-spacing: -0.01em;
text-transform: uppercase;
font-family: var(--f-heading);
}
.h3 {
font-size: var(--sz-h3);
font-weight: 700;
line-height: 1.1;
text-transform: uppercase;
font-family: var(--f-heading);
}
.lead {
font-size: var(--sz-lead);
font-weight: 500;
line-height: 1.45;
font-family: var(--f-body);
}
.body {
font-size: var(--sz-body);
font-weight: 400;
line-height: 1.6;
font-family: var(--f-body);
}
.caption {
font-size: var(--sz-caption);
font-weight: 400;
line-height: 1.5;
font-family: var(--f-body);
}
/* Label: mono metadata — the only non-bold text that gets prominence */
.label {
font-size: var(--sz-label);
font-weight: 500;
letter-spacing: 0.06em;
font-family: var(--f-mono);
}
/* Muted variants — context-aware opacity */
.muted {
color: var(--c-fg-2);
}
.light .muted {
color: var(--c-fg-light-2);
}
/* Accent colour class */
.accent {
color: var(--c-accent);
}
/* On light slides, accent is the dark foreground */
.light .accent {
color: var(--c-fg-light);
}
/* Bullet list — Studio signature: dash bullet in accent, tight spacing */
.bullet-list {
list-style: none;
display: flex;
flex-direction: column;
gap: var(--gap-sm);
font-family: var(--f-body);
font-size: var(--sz-body);
font-weight: 400;
line-height: 1.5;
padding-left: 1em;
}
.bullet-list li::before {
content: "\2014"; /* em dash used as bullet marker */
margin-left: -1em;
margin-right: 0.5em;
color: var(--c-accent);
}
.light .bullet-list li::before {
color: var(--c-fg-light);
}
/* ── Studio cover footer: three-column metadata bar ──────────────────── */
/* The signature Boring Studios three-column foot: studio × client, title, name */
.cover-footer {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0;
padding-top: var(--gap-md);
border-top: 1px solid var(--c-fg-3);
margin-top: auto;
}
.cover-footer-col {
font-family: var(--f-mono);
font-size: var(--sz-caption);
font-weight: 400;
line-height: 1.5;
}
.cover-footer-col:last-child {
text-align: right;
}
/* Image placeholder box — dark warm grey rectangle, mono label centered */
.img-placeholder {
background: var(--c-bg-alt);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--f-mono);
font-size: var(--sz-label);
letter-spacing: 0.1em;
color: var(--c-fg-3);
width: 100%;
flex: 1;
}
.light .img-placeholder {
background: var(--c-bg-light-alt);
color: var(--c-fg-light-3);
border: 1px solid var(--c-border-light);
}
/* ╔══════════════════════════════════════════════════════════════════════╗
║ ZONE D · CHROME ║
╚══════════════════════════════════════════════════════════════════════╝ */
/* Chrome (top bar) and footer */
.slide-chrome,
.slide-foot {
display: flex;
justify-content: space-between;
align-items: center;
}
.slide-chrome {
padding-bottom: var(--gap-sm);
border-bottom: 1px solid var(--c-border);
margin-bottom: var(--gap-md);
}
.slide-foot {
padding-top: var(--gap-sm);
border-top: 1px solid var(--c-border);
margin-top: var(--gap-md);
}
.light .slide-chrome,
.light .slide-foot {
border-color: var(--c-border-light);
}
/* Special layouts that don't use chrome/foot */
.slide--cover .slide-chrome,
.slide--cover .slide-foot,
.slide--chapter .slide-chrome,
.slide--chapter .slide-foot,
.slide--quote .slide-chrome,
.slide--quote .slide-foot,
.slide--statement .slide-chrome,
.slide--statement .slide-foot,
.slide--end .slide-chrome,
.slide--end .slide-foot {
display: none;
}
/* ╔══════════════════════════════════════════════════════════════════════╗
║ ZONE E · LAYOUT PATTERNS — STUDIO-SPECIFIC ║
╚══════════════════════════════════════════════════════════════════════╝ */
/* 1. COVER ─────────────────────────────────────────────────────────── */
/* Full dark slide, image placeholder fills the background, type overlaid */
.slide--cover {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 0;
position: relative;
}
/* Image placeholder sits absolute behind everything */
.cover-img-area {
position: absolute;
inset: 0;
background: var(
--c-bg-alt
); /* warm dark placeholder — replace with real image */
display: flex;
align-items: center;
justify-content: center;
font-family: var(--f-mono);
font-size: var(--sz-label);
letter-spacing: 0.1em;
color: var(--c-fg-3);
}
/* Type area: z-index above the image, padded normally */
.cover-type {
position: relative;
z-index: 1;
padding: var(--pad-y) var(--pad-x) 0;
flex: 1;
display: flex;
align-items: flex-start;
}
/* Three-column meta footer over the image */
.cover-meta {
position: relative;
z-index: 1;
padding: var(--gap-md) var(--pad-x) var(--pad-y);
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0;
border-top: 1px solid rgba(245, 210, 0, 0.25);
}
.cover-meta-col {
font-family: var(--f-mono);
font-size: var(--sz-caption);
font-weight: 400;
line-height: 1.6;
color: var(--c-fg-2);
}
.cover-meta-col:last-child {
text-align: right;
}
/* 2. CHAPTER ───────────────────────────────────────────────────────── */
/* Yellow or dark chapter divider — huge uppercase section number + title */
.slide--chapter {
display: flex;
flex-direction: column;
justify-content: flex-end;
padding-bottom: calc(var(--pad-y) * 1.5);
}
.chapter-num {
font-family: var(--f-mono);
font-size: var(--sz-label);
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--c-fg-2);
margin-bottom: var(--gap-lg);
}
.light .chapter-num {
color: var(--c-fg-light-2);
}
/* 3. STATEMENT ─────────────────────────────────────────────────────── */
/* Full-slide statement — huge uppercase type, zero decoration */
.slide--statement {
display: flex;
flex-direction: column;
justify-content: flex-end;
padding-bottom: calc(var(--pad-y) * 1.5);
}
.statement-body {
display: flex;
flex-direction: column;
gap: var(--gap-md);
}
/* 4. SPLIT ─────────────────────────────────────────────────────────── */
.slide--split .slide-body {
display: grid;
grid-template-columns: 1fr 1fr;
gap: calc(var(--pad-x) * 0.8);
align-items: center;
}
.split-text {
display: flex;
flex-direction: column;
gap: var(--gap-md);
}
.split-image {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
height: 100%;
}
/* 5. STATS ─────────────────────────────────────────────────────────── */
.slide--stats {
display: flex;
flex-direction: column;
justify-content: center;
}
.slide--stats .slide-body {
display: flex;
flex-direction: column;
justify-content: center;
gap: var(--gap-lg);
}
/* Stats numbers: huge weight-900 display, near-black on yellow */
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0;
}
.stat-card {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
padding: var(--gap-md) var(--gap-md) var(--gap-md) 0;
border-top: 2px solid var(--c-fg-light);
}
.dark .stat-card {
border-top-color: var(--c-fg-3);
}
/* Value: weight-900 display type — the number IS the stat */
.stat-value {
font-family: var(--f-display);
font-size: 5.5vw;
font-weight: 900;
line-height: 0.9;
color: var(--c-fg-light);
letter-spacing: -0.03em;
text-transform: uppercase;
}
.dark .stat-value {
color: var(--c-fg);
}
.stat-label {
font-family: var(--f-body);
font-size: var(--sz-body);
font-weight: 500;
line-height: 1.4;
}
.stat-note {
font-family: var(--f-mono);
font-size: var(--sz-caption);
letter-spacing: 0.05em;
color: var(--c-fg-light-3);
}
.dark .stat-note {
color: var(--c-fg-3);
}
/* 6. LIST ─────────────────────────────────────────────────────────── */
.slide--list {
display: flex;
flex-direction: column;
justify-content: center;
}
.slide--list .slide-body {
display: grid;
grid-template-columns: 2fr 3fr;
gap: calc(var(--pad-x) * 0.8);
align-items: center;
}
.list-head {
display: flex;
flex-direction: column;
gap: var(--gap-md);
}
/* 7. QUOTE ─────────────────────────────────────────────────────────── */
/* Dark slide — large quote with no quote mark, just raw type */
.slide--quote {
display: flex;
flex-direction: column;
justify-content: center;
}
.quote-text {
font-family: var(--f-heading);
font-size: 3.8vw;
font-weight: 900;
line-height: 1.05;
letter-spacing: -0.02em;
text-transform: uppercase;
max-width: 82%;
margin-bottom: var(--gap-lg);
}
.quote-attr {
display: flex;
flex-direction: column;
gap: 0.4vh;
}
/* 8. COMPARE ─────────────────────────────────────────────────────────── */
.slide--compare .slide-body {
display: grid;
grid-template-columns: 1fr 1fr;
height: 100%;
}
.compare-panel {
display: flex;
flex-direction: column;
gap: var(--gap-md);
padding: var(--gap-md) 0;
}
.compare-panel.left {
padding-right: calc(var(--pad-x) * 0.55);
border-right: 2px solid var(--c-fg-light);
}
.compare-panel.right {
padding-left: calc(var(--pad-x) * 0.55);
}
.dark .compare-panel.left {
border-right-color: var(--c-fg-3);
}
.compare-label {
font-family: var(--f-mono);
font-size: var(--sz-label);
letter-spacing: 0.16em;
text-transform: uppercase;
padding-bottom: var(--gap-sm);
border-bottom: 1px solid var(--c-border-light);
}
.dark .compare-label {
border-bottom-color: var(--c-border);
}
.compare-label.after {
color: var(--c-accent);
}
.light .compare-label.after {
color: var(--c-fg-light);
font-weight: 700;
}
/* 9. CHART ─────────────────────────────────────────────────────────── */
.slide--chart .slide-body {
display: flex;
flex-direction: column;
gap: var(--gap-md);
min-height: 0;
}
.chart-header {
display: flex;
justify-content: space-between;
align-items: baseline;
flex-shrink: 0;
}
.chart-wrapper {
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 0;
}
/* Bar chart track: bars sit in a horizontal row along a baseline */
.bar-track {
height: 30vh;
display: flex;
align-items: flex-end;
gap: 4vw;
border-left: 2px solid var(--c-fg-3);
padding-left: 0.5vw;
}
.light .bar-track {
border-left-color: var(--c-border-light);
}
.bar-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
gap: 1vh;
height: 100%;
}
/* Bar fill: default is dark muted, accent is full yellow */
.bar-fill {
width: 100%;
background: var(--c-fg-3);
}
.bar-fill.accent {
background: var(--c-accent);
}
.light .bar-fill {
background: var(--c-fg-light-3);
}
.light .bar-fill.accent {
background: var(--c-fg-light);
}
.bar-x-label {
font-family: var(--f-mono);
font-size: var(--sz-caption);
letter-spacing: 0.1em;
color: var(--c-fg-3);
white-space: nowrap;
text-transform: uppercase;
}
.light .bar-x-label {
color: var(--c-fg-light-3);
}
.bar-val {
font-family: var(--f-body);
font-size: var(--sz-body);
font-weight: 700;
color: var(--c-fg-2);
}
.bar-val.hi {
color: var(--c-accent);
font-weight: 900;
}
.light .bar-val {
color: var(--c-fg-light-2);
}
.light .bar-val.hi {
color: var(--c-fg-light);
}
.chart-baseline {
height: 2px;
background: var(--c-fg-3);
flex-shrink: 0;
margin-top: 1px;
}
.light .chart-baseline {
background: var(--c-border-light);
}
.chart-source {
flex-shrink: 0;
font-family: var(--f-mono);
font-size: var(--sz-caption);
color: var(--c-fg-3);
letter-spacing: 0.06em;
margin-top: var(--gap-sm);
}
.light .chart-source {
color: var(--c-fg-light-3);
}
/* 10. END ─────────────────────────────────────────────────────────── */
/* Yellow slide — huge question fills top 60%, two-column contact below */
.slide--end {
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>
</head>
<body>
<!-- NAV DOTS: generated by JS -->
<nav id="nav-dots"></nav>
<!-- SLIDE COUNTER: generated by JS -->
<div id="slide-counter"></div>
<!-- ═══════════════════════════════════════════════════════════════════════
DECK — all 12 slides live here, side by side
═══════════════════════════════════════════════════════════════════════ -->
<div id="deck">
<!-- ═══════ SLIDE 1 · COVER dark ══════════════════════════════════════
Image placeholder fills the background.
"PROPOSAL" in huge yellow display type across the top.
Three-column meta footer at bottom edge.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--cover">
<!-- Full-bleed image placeholder: sits behind all content -->
<div class="cover-img-area" data-anim="fade-in" data-delay="0">
IMAGE PLACEHOLDER
</div>
<!-- Type block: "PROPOSAL" at display scale — type over image -->
<div class="cover-type">
<h1
class="display"
style="color: var(--c-fg)"
data-anim="fade-up"
data-delay="1"
>
PROPOSAL
</h1>
</div>
<!-- Three-column footer: studio × client · presentation title · studio name -->
<div class="cover-meta" data-anim="fade-in" data-delay="3">
<div class="cover-meta-col">
[Studio Name] × [Client Name]<br />
[Date]
</div>
<div class="cover-meta-col" style="text-align: center">
[Presentation Title]
</div>
<div class="cover-meta-col" style="text-align: right">
[Studio Name]
</div>
</div>
</section>
<!-- ═══════ SLIDE 2 · CHAPTER light (yellow bg) ═══════════════════════
Section divider: mono section number + huge black title.
Yellow background — no decoration, type IS the design.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--chapter">
<!-- Section number: mono label in muted near-black -->
<div class="chapter-num" data-anim="fade-in" data-delay="0">
01 / WHO WE ARE
</div>
<!-- Chapter title: maximum weight, runs wide -->
<h1
class="h1"
style="max-width: 90%; color: var(--c-fg-light)"
data-anim="fade-up"
data-delay="1"
>
WHO WE ARE
</h1>
</section>
<!-- ═══════ SLIDE 3 · STATEMENT dark ══════════════════════════════════
Single huge statement on near-black.
Yellow type, no decoration, no chrome.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--statement">
<div
class="statement-body"
style="
justify-content: flex-end;
height: 100%;
display: flex;
flex-direction: column;
padding-bottom: calc(var(--pad-y) * 0.5);
"
>
<h1
class="h1"
style="max-width: 90%"
data-anim="fade-up"
data-delay="0"
>
GREAT WORK DOESN'T HAPPEN BY ACCIDENT
</h1>
</div>
</section>
<!-- ═══════ SLIDE 4 · SPLIT light (yellow bg) ════════════════════════
Text left + image placeholder right.
Black on yellow — tight, structured, zero ornament.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--split">
<!-- Chrome bar -->
<div class="slide-chrome">
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>Our Work</span
>
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>04 / 12</span
>
</div>
<div class="slide-body">
<!-- Left: text content -->
<div class="split-text" data-anim="fade-up" data-delay="1">
<p
class="label"
style="color: var(--c-fg-light-2); letter-spacing: 0.12em"
>
APPROACH
</p>
<h2 class="h2" style="color: var(--c-fg-light)">
WE BUILD WHAT OTHERS PLAN
</h2>
<p
class="lead"
style="
color: var(--c-fg-light-2);
font-weight: 400;
text-transform: none;
"
>
Our studio pairs strategic thinking with craft-level execution.
Every project begins with a question: what needs to be true for
this to work? We answer it in the work itself.
</p>
<ul class="bullet-list">
<li>Strategy before aesthetics</li>
<li>Constraints as creative fuel</li>
<li>Delivery on schedule, not on someday</li>
</ul>
</div>
<!-- Right: image placeholder -->
<div
data-anim="fade-in"
data-delay="3"
style="
display: flex;
flex-direction: column;
gap: var(--gap-sm);
height: 100%;
"
>
<div class="img-placeholder" style="min-height: 40vh">
IMAGE PLACEHOLDER
</div>
<p
class="caption"
style="color: var(--c-fg-light-3); font-family: var(--f-mono)"
>
[Caption — project name, year]
</p>
</div>
</div>
<div class="slide-foot">
<span class="label" style="color: var(--c-fg-light-3)"
>[Studio Name] · [Date]</span
>
<span class="label" style="color: var(--c-fg-light-2)">04 / 12</span>
</div>
</section>
<!-- ═══════ SLIDE 5 · STATS light (yellow bg) ════════════════════════
3 huge stats with weight-900 display numbers.
Numbers at near-display scale — the numbers are the layout.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--stats">
<!-- Chrome bar -->
<div class="slide-chrome">
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>By the Numbers</span
>
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>05 / 12</span
>
</div>
<div class="slide-body">
<!-- Section label above stats -->
<h2
class="h2"
style="color: var(--c-fg-light)"
data-anim="fade-up"
data-delay="1"
>
THE STUDIO
</h2>
<!-- 3-column stat grid: numbers at display scale -->
<div class="stats-grid" data-anim="fade-up" data-delay="2">
<div class="stat-card">
<div class="stat-value">12</div>
<div class="stat-label" style="color: var(--c-fg-light)">
Years of practice
</div>
<div class="stat-note">[Studio Name] founded [Year]</div>
</div>
<div class="stat-card">
<div class="stat-value">200+</div>
<div class="stat-label" style="color: var(--c-fg-light)">
Projects delivered
</div>
<div class="stat-note">Across [N] industries</div>
</div>
<div class="stat-card">
<div class="stat-value">3</div>
<div class="stat-label" style="color: var(--c-fg-light)">
Continents active
</div>
<div class="stat-note">[City A], [City B], [City C]</div>
</div>
</div>
</div>
<div class="slide-foot">
<span class="label" style="color: var(--c-fg-light-3)"
>[Studio Name] · [Date]</span
>
<span class="label" style="color: var(--c-fg-light-2)">05 / 12</span>
</div>
</section>
<!-- ═══════ SLIDE 6 · LIST dark ═══════════════════════════════════════
"WHAT WE OFFER" heading left, 5 yellow bullets right.
Dark background, yellow type throughout.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--list">
<!-- Chrome bar -->
<div class="slide-chrome">
<span class="label muted" data-anim="fade-in" data-delay="0"
>Services</span
>
<span class="label muted" data-anim="fade-in" data-delay="0"
>06 / 12</span
>
</div>
<div class="slide-body">
<!-- Left: heading -->
<div class="list-head" data-anim="fade-up" data-delay="1">
<h2 class="h2" style="color: var(--c-fg)">WHAT WE OFFER</h2>
<p
class="lead muted"
style="text-transform: none; font-weight: 400; max-width: 90%"
>
A focused set of services built for ambitious creative and
commercial challenges.
</p>
</div>
<!-- Right: bullet list -->
<ul
class="bullet-list"
style="font-size: var(--sz-lead); font-weight: 500"
data-anim="fade-up"
data-delay="2"
>
<li>Brand strategy and identity systems</li>
<li>Campaign and content direction</li>
<li>Digital experience design and build</li>
<li>Motion and video production</li>
<li>Ongoing creative partnership and retainer</li>
</ul>
</div>
<div class="slide-foot">
<span class="label muted">[Studio Name] · [Date]</span>
<span class="label muted">06 / 12</span>
</div>
</section>
<!-- ═══════ SLIDE 7 · QUOTE dark ══════════════════════════════════════
Large client quote, no quote mark, just raw uppercase weight-900 type.
Attribution below in mono label.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--quote">
<!-- Quote body: uppercase grotesque, no quote marks needed -->
<p
class="quote-text"
style="color: var(--c-fg)"
data-anim="fade-up"
data-delay="0"
>
THEY DON'T JUST MAKE THINGS LOOK GOOD. THEY MAKE THINGS WORK.
</p>
<!-- Attribution: mono label -->
<div class="quote-attr" data-anim="fade-in" data-delay="2">
<span class="label" style="color: var(--c-fg); letter-spacing: 0.1em"
>[CLIENT NAME]</span
>
<span class="label muted">CMO · [Company] · [Year]</span>
</div>
</section>
<!-- ═══════ SLIDE 8 · COMPARE light (yellow bg) ══════════════════════
Before/after on yellow background.
Two panels divided by a heavy vertical rule.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--compare">
<!-- Chrome bar -->
<div class="slide-chrome">
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>Before / After</span
>
<span
class="label"
style="color: var(--c-fg-light-2)"
data-anim="fade-in"
data-delay="0"
>08 / 12</span
>
</div>
<div class="slide-body">
<!-- Left panel: Before -->
<div class="compare-panel left" data-anim="fade-up" data-delay="1">
<div class="compare-label" style="color: var(--c-fg-light-2)">
BEFORE
</div>
<h3 class="h3" style="color: var(--c-fg-light)">
GENERIC IDENTITY, FORGETTABLE CAMPAIGNS
</h3>
<p
class="lead"
style="
color: var(--c-fg-light-2);
text-transform: none;
font-weight: 400;
"
>
A brand built by committee, refined to inoffensiveness. Nothing
wrong. Nothing memorable. Indistinguishable from category norms.
</p>
<ul class="bullet-list">
<li>No clear point of view</li>
<li>Inconsistent execution across touchpoints</li>
<li>Campaigns that launched and disappeared</li>
</ul>
</div>
<!-- Right panel: After -->
<div class="compare-panel right" data-anim="fade-up" data-delay="2">
<div class="compare-label after" style="font-weight: 700">
AFTER
</div>
<h3 class="h3" style="color: var(--c-fg-light)">
A DISTINCTIVE VOICE PEOPLE RECOGNIZE
</h3>
<p
class="lead"
style="
color: var(--c-fg-light-2);
text-transform: none;
font-weight: 400;
"
>
A brand with a defined perspective. Work that accumulates — each
campaign reinforces the one before, building memory and trust.
</p>
<ul class="bullet-list">
<li>Ownable visual and verbal territory</li>
<li>System that scales without diluting</li>
<li>Campaigns that created lasting recall</li>
</ul>
</div>
</div>
<div class="slide-foot">
<span class="label" style="color: var(--c-fg-light-3)"
>[Studio Name] · [Date]</span
>
<span class="label" style="color: var(--c-fg-light-2)">08 / 12</span>
</div>
</section>
<!-- ═══════ SLIDE 9 · CHAPTER dark ════════════════════════════════════
Dark chapter divider — "THE WORK" in huge yellow type.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--chapter">
<!-- Section number -->
<div class="chapter-num" data-anim="fade-in" data-delay="0">
02 / THE WORK
</div>
<!-- Chapter title: yellow on dark at h1 scale -->
<h1
class="h1"
style="max-width: 90%; color: var(--c-fg)"
data-anim="fade-up"
data-delay="1"
>
THE WORK
</h1>
</section>
<!-- ═══════ SLIDE 10 · STATEMENT light (yellow bg) ════════════════════
Huge statement on yellow — black type filling most of the slide.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--statement">
<div
class="statement-body"
style="
justify-content: flex-end;
height: 100%;
display: flex;
flex-direction: column;
padding-bottom: calc(var(--pad-y) * 0.5);
"
>
<h1
class="h1"
style="max-width: 95%; color: var(--c-fg-light)"
data-anim="fade-up"
data-delay="0"
>
BOLD IDEAS DESERVE BOLD EXECUTION
</h1>
</div>
</section>
<!-- ═══════ SLIDE 11 · CHART dark ════════════════════════════════════
Bar chart with yellow accent on the highlight bar.
Near-black background, yellow accent bar, muted bars for others.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide dark slide--chart">
<!-- Chrome bar -->
<div class="slide-chrome">
<span class="label muted" data-anim="fade-in" data-delay="0"
>Project Output</span
>
<span class="label muted" data-anim="fade-in" data-delay="0"
>11 / 12</span
>
</div>
<div class="slide-body">
<div class="chart-header">
<h2
class="h2"
style="color: var(--c-fg)"
data-anim="fade-up"
data-delay="0"
>
PROJECTS BY YEAR
</h2>
<span
class="caption muted"
style="
font-family: var(--f-mono);
text-transform: uppercase;
letter-spacing: 0.08em;
"
data-anim="fade-in"
data-delay="1"
>
Count · [Studio Name] Portfolio
</span>
</div>
<div class="chart-wrapper" data-anim="fade-up" data-delay="2">
<div class="bar-track">
<div class="bar-col">
<span class="bar-val">14</span>
<div class="bar-fill" style="height: 8vh"></div>
<span class="bar-x-label">[Y-4]</span>
</div>
<div class="bar-col">
<span class="bar-val">21</span>
<div class="bar-fill" style="height: 12vh"></div>
<span class="bar-x-label">[Y-3]</span>
</div>
<div class="bar-col">
<span class="bar-val">28</span>
<div class="bar-fill" style="height: 17vh"></div>
<span class="bar-x-label">[Y-2]</span>
</div>
<div class="bar-col">
<span class="bar-val">35</span>
<div class="bar-fill" style="height: 22vh"></div>
<span class="bar-x-label">[Y-1]</span>
</div>
<div class="bar-col">
<!-- Accent bar: the highlighted year -->
<span class="bar-val hi">47</span>
<div class="bar-fill accent" style="height: 30vh"></div>
<span class="bar-x-label">[Year]</span>
</div>
</div>
<div class="chart-baseline"></div>
</div>
<p class="chart-source" data-anim="fade-in" data-delay="3">
Source: [Studio Name] internal tracking · [Year]
</p>
</div>
<div class="slide-foot">
<span class="label muted">[Studio Name] · [Date]</span>
<span class="label muted">11 / 12</span>
</div>
</section>
<!-- ═══════ SLIDE 12 · END light (yellow bg) ══════════════════════════
Huge closing question fills top portion, two-column contact info below.
Studio signature ending layout from the Boring Studios reference.
═══════════════════════════════════════════════════════════════════ -->
<section class="slide light slide--end">
<!-- Main closing statement: display scale, fills the top of the slide -->
<h1
class="h1"
style="
max-width: 85%;
line-height: 0.9;
font-size: var(--sz-display);
color: var(--c-fg-light);
"
data-anim="fade-up"
data-delay="0"
>
ANY QUESTIONS OR THOUGHTS?
</h1>
<!-- Two-column contact info below the statement -->
<div
style="
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--gap-lg);
margin-top: var(--gap-lg);
"
data-anim="fade-up"
data-delay="2"
>
<div>
<p class="body" style="color: var(--c-fg-light-2)">
Contact [Name A] via email on [name@studio.com]<br />
or via phone on [+00 000 000 000]
</p>
</div>
<div>
<p class="body" style="color: var(--c-fg-light-2)">
Contact [Name B] via email on [name@studio.com]<br />
or via phone on [+00 000 000 000]
</p>
</div>
</div>
<!-- Three-column footer: the Studio signature cover footer pattern -->
<div
class="cover-footer"
style="border-top-color: var(--c-border-light)"
data-anim="fade-in"
data-delay="4"
>
<span class="cover-footer-col" style="color: var(--c-fg-light-2)">
Page 12<br />[Studio Name] × [Client Name]
</span>
<span
class="cover-footer-col"
style="text-align: center; color: var(--c-fg-light-2)"
>
[Presentation title]
</span>
<span class="cover-footer-col" style="color: var(--c-fg-light-2)">
[Studio Name]
</span>
</div>
</section>
</div>
<!-- /deck -->
<script>
/* ══════════════════════════════════════════════════════════════════════
STUDIO PRESENTATION ENGINE
Self-contained navigation: keyboard, touch, mouse-wheel, nav-dots.
No external dependencies.
══════════════════════════════════════════════════════════════════════ */
(function () {
"use strict";
/* ── State ─────────────────────────────────────────────────────────── */
const deck = document.getElementById("deck");
const slides = Array.from(document.querySelectorAll(".slide"));
const dotsEl = document.getElementById("nav-dots");
const counter = document.getElementById("slide-counter");
const total = slides.length;
let current = 0;
let animating = false;
/* ── Bootstrap: set deck width, build nav dots ─────────────────────── */
function init() {
// The deck is one wide strip — width equals N full viewports
deck.style.width = total + "00vw";
// Build one dot per slide
slides.forEach(function (_, i) {
const btn = document.createElement("button");
btn.className = "nav-dot";
btn.setAttribute("aria-label", "Go to slide " + (i + 1));
btn.addEventListener("click", function () {
goTo(i);
});
dotsEl.appendChild(btn);
});
// Activate the first slide immediately
goTo(0, true); // true = skip transition on load
}
/* ── goTo: the single source of truth for navigation ───────────────── */
function goTo(index, instant) {
// Clamp to valid range
index = Math.max(0, Math.min(total - 1, index));
if (index === current && !instant) return;
// Mark animating to block rapid key/swipe spam
animating = true;
// Deactivate current slide: reset animations by toggling is-active
const prev = slides[current];
prev.classList.remove("is-active");
// Force a reflow so removing then re-adding is-active (on same slide)
// actually re-triggers the keyframe animations
void prev.offsetWidth; // eslint-disable-line no-void
// Translate the deck
if (instant) {
// Remove transition temporarily for the initial load snap
deck.style.transition = "none";
deck.style.transform = "translateX(-" + index + "00vw)";
void deck.offsetWidth; // force reflow
deck.style.transition = "";
} else {
deck.style.transform = "translateX(-" + index + "00vw)";
}
// Activate new slide
current = index;
const next = slides[current];
next.classList.add("is-active");
// Update nav dots
Array.from(dotsEl.children).forEach(function (dot, i) {
dot.classList.toggle("is-active", i === current);
});
// Update counter: "3 / 12"
counter.textContent = current + 1 + " / " + total;
// Unlock after transition completes
const delay = instant
? 0
: parseFloat(getComputedStyle(deck).transitionDuration) * 1000;
setTimeout(function () {
animating = false;
}, delay);
}
/* ── Keyboard navigation ──────────────────────────────────────────── */
document.addEventListener("keydown", function (e) {
if (animating) return;
if (
e.key === "ArrowRight" ||
e.key === "ArrowDown" ||
e.key === " "
) {
e.preventDefault();
goTo(current + 1);
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
e.preventDefault();
goTo(current - 1);
} else if (e.key === "Home") {
e.preventDefault();
goTo(0);
} else if (e.key === "End") {
e.preventDefault();
goTo(total - 1);
}
});
/* ── Mouse-wheel navigation ───────────────────────────────────────── */
let wheelCooldown = false;
document.addEventListener(
"wheel",
function (e) {
e.preventDefault();
if (animating || wheelCooldown) return;
wheelCooldown = true;
setTimeout(function () {
wheelCooldown = false;
}, 900);
if (e.deltaY > 0 || e.deltaX > 0) {
goTo(current + 1);
} else {
goTo(current - 1);
}
},
{ passive: false },
);
/* ── Touch swipe navigation ───────────────────────────────────────── */
let touchStartX = null;
let touchStartY = null;
document.addEventListener(
"touchstart",
function (e) {
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
},
{ passive: true },
);
document.addEventListener(
"touchend",
function (e) {
if (touchStartX === null) return;
const dx = touchStartX - e.changedTouches[0].clientX;
const dy = touchStartY - e.changedTouches[0].clientY;
// Only respond if horizontal swipe is dominant
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
if (animating) return;
if (dx > 0) {
goTo(current + 1); // swipe left: next
} else {
goTo(current - 1); // swipe right: prev
}
}
touchStartX = null;
touchStartY = null;
},
{ passive: true },
);
/* ── Boot ─────────────────────────────────────────────────────────── */
init();
})();
</script>
</body>
</html>
MIT License
Copyright (c) 2026 Zara Zhang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"slug": "zhangzara-studio",
"name": "Studio",
"tagline": "Black canvas with electric-yellow type; high-voltage design studio aesthetic.",
"mood": [
"electric",
"bold",
"graphic",
"design-led",
"high-contrast"
],
"occasion": [
"design studio credentials",
"creative agency pitch",
"brand showcase",
"art-direction review",
"fashion / sneaker brand",
"bilingual EN/CN deck"
],
"tone": [
"graphic",
"loud",
"modern",
"intentional"
],
"formality": "medium",
"density": "medium",
"palette": {
"bg": "#1c1c1c",
"bg_alt": "#242422",
"fg": "#f5d200",
"accent": "#f5d200",
"bg_light": "#f5d200",
"description": "near-black canvas with one signature electric-yellow that doubles as foreground type AND accent; reverses to yellow-paper mode for breathing room"
},
"typography": {
"display": "Barlow",
"body": "Barlow",
"mono": "IBM Plex Mono",
"cn": "Noto Sans SC",
"style": "broadcast-grotesk display + technical mono captions; ultra-high-contrast typographic system"
},
"scheme": "dark",
"best_for": "Anything that should feel electric and design-led: studio credentials, creative agency pitches, brand showcases, art-direction reviews, fashion / sneaker brand work. Also a striking unexpected choice for tech, research, or business decks where the speaker wants the deck to *be* a brand statement.",
"avoid_for": "Contexts that should feel quiet or institutional — the black-and-electric-yellow palette is the loudest in the library.",
"slide_count": 12,
"navigation": "inline keyboard handler",
"source": "https://github.com/zarazhangrui/beautiful-html-templates/tree/main/templates/studio"
}