583 lines
27 KiB
HTML
583 lines
27 KiB
HTML
<!-- Copyright 2026 Anthropic PBC · SPDX-License-Identifier: Apache-2.0 -->
|
||
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Teach me my unknowns — Know your unknowns</title>
|
||
<style>
|
||
:root {
|
||
--ivory: #FAF9F5;
|
||
--paper: #FFFFFF;
|
||
--slate: #141413;
|
||
--clay: #D97757;
|
||
--clay-d: #B85C3E;
|
||
--oat: #E3DACC;
|
||
--olive: #788C5D;
|
||
--g100: #F0EEE6;
|
||
--g200: #E6E3DA;
|
||
--g300: #D1CFC5;
|
||
--g500: #87867F;
|
||
--g700: #3D3D3A;
|
||
--serif: ui-serif, Georgia, "Times New Roman", Times, serif;
|
||
--sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||
--mono: ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
margin: 0;
|
||
background: var(--ivory);
|
||
color: var(--slate);
|
||
font-family: var(--sans);
|
||
line-height: 1.55;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
.wrap { max-width: 980px; margin: 0 auto; padding: 0 24px 100px; }
|
||
|
||
/* ── header ─────────────────────────── */
|
||
header { padding: 56px 0 8px; position: relative; }
|
||
.eyebrow {
|
||
font-family: var(--mono);
|
||
font-size: 12px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--g500);
|
||
margin-bottom: 18px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
.eyebrow::before { content: ""; width: 24px; height: 1.5px; background: var(--clay); flex: none; }
|
||
.backlink {
|
||
position: absolute; top: 60px; right: 0;
|
||
font-family: var(--mono); font-size: 12px;
|
||
color: var(--g500); text-decoration: none;
|
||
}
|
||
.backlink:hover { color: var(--clay); }
|
||
h1 {
|
||
font-family: var(--serif);
|
||
font-weight: 500;
|
||
font-size: clamp(32px, 5vw, 46px);
|
||
line-height: 1.08;
|
||
letter-spacing: -0.018em;
|
||
margin: 0 0 10px;
|
||
}
|
||
.lede { font-size: 16.5px; color: var(--g700); max-width: 640px; margin: 0 0 28px; }
|
||
|
||
h2, h3 { font-family: var(--serif); font-weight: 500; letter-spacing: -0.012em; }
|
||
|
||
.card {
|
||
background: var(--paper);
|
||
border: 1.5px solid var(--g300);
|
||
border-radius: 14px;
|
||
}
|
||
|
||
/* prompt box */
|
||
.promptbox { padding: 22px 26px 24px; position: relative; margin-bottom: 44px; }
|
||
.promptbox .label {
|
||
font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em;
|
||
text-transform: uppercase; color: var(--clay); margin-bottom: 10px;
|
||
}
|
||
.promptbox blockquote {
|
||
margin: 0; padding: 0 0 0 18px;
|
||
border-left: 3px solid var(--oat);
|
||
font-family: var(--serif); font-style: italic;
|
||
font-size: 17.5px; line-height: 1.5; color: var(--slate);
|
||
}
|
||
.copybtn {
|
||
position: absolute; top: 18px; right: 18px;
|
||
font-family: var(--mono); font-size: 11.5px;
|
||
background: var(--g100); color: var(--g700);
|
||
border: 1.5px solid var(--g300); border-radius: 8px;
|
||
padding: 6px 12px; cursor: pointer;
|
||
}
|
||
.copybtn:hover { border-color: var(--clay); color: var(--clay-d); }
|
||
.copybtn.done { background: var(--olive); border-color: var(--olive); color: #fff; }
|
||
|
||
/* divider */
|
||
.divider {
|
||
display: flex; align-items: center; gap: 16px;
|
||
font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em;
|
||
text-transform: uppercase; color: var(--g500);
|
||
margin: 0 0 40px;
|
||
}
|
||
.divider::before, .divider::after { content: ""; flex: 1; height: 1.5px; background: var(--g300); }
|
||
|
||
/* ── artifact ─────────────────────────── */
|
||
.artifact h2 { font-size: 27px; margin: 0 0 6px; }
|
||
.artifact .sub { color: var(--g700); font-size: 15px; max-width: 640px; margin: 0 0 26px; }
|
||
.sec-eyebrow {
|
||
font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em;
|
||
text-transform: uppercase; color: var(--g500);
|
||
display: flex; align-items: center; gap: 12px; margin: 44px 0 14px;
|
||
}
|
||
.sec-eyebrow::before { content: ""; width: 24px; height: 1.5px; background: var(--clay); flex: none; }
|
||
|
||
/* mental model strip */
|
||
.pipeline { display: flex; gap: 0; align-items: stretch; flex-wrap: wrap; margin-bottom: 8px; }
|
||
.pipe-step {
|
||
flex: 1 1 150px; background: var(--paper); border: 1.5px solid var(--g300);
|
||
border-radius: 12px; padding: 12px 14px; margin: 0 10px 10px 0;
|
||
position: relative;
|
||
}
|
||
.pipe-step b { display: block; font-size: 14px; }
|
||
.pipe-step span { font-size: 12.5px; color: var(--g500); }
|
||
.pipe-step.hot { border-color: var(--clay); }
|
||
.pipe-step.hot b { color: var(--clay-d); }
|
||
|
||
/* vocab ladder */
|
||
.ladder { display: grid; gap: 12px; }
|
||
.rung { padding: 16px 20px 15px; display: grid; grid-template-columns: 158px 1fr; gap: 4px 22px; }
|
||
@media (max-width: 640px) { .rung { grid-template-columns: 1fr; } }
|
||
.rung .term { font-family: var(--serif); font-size: 17px; font-weight: 500; }
|
||
.rung .term small { display: block; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--g500); margin-top: 2px; }
|
||
.rung .def { font-size: 14.5px; color: var(--g700); }
|
||
.rung .say {
|
||
grid-column: 2; font-family: var(--mono); font-size: 12.5px; color: var(--clay-d);
|
||
background: var(--g100); border-radius: 8px; padding: 7px 11px; margin-top: 6px;
|
||
}
|
||
@media (max-width: 640px) { .rung .say { grid-column: 1; } }
|
||
.rung .say::before { content: "say → "; color: var(--g500); }
|
||
|
||
/* grading console */
|
||
.console { overflow: hidden; }
|
||
.console-head {
|
||
display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px;
|
||
padding: 14px 20px; border-bottom: 1.5px solid var(--g200); background: var(--g100);
|
||
}
|
||
.console-head .fname { font-family: var(--mono); font-size: 12px; color: var(--g700); }
|
||
.console-head .fname i { font-style: normal; color: var(--g500); }
|
||
.presets { display: flex; gap: 8px; flex-wrap: wrap; }
|
||
.presets button {
|
||
font-family: var(--mono); font-size: 11.5px; padding: 6px 12px;
|
||
background: var(--paper); border: 1.5px solid var(--g300); border-radius: 999px;
|
||
color: var(--g700); cursor: pointer;
|
||
}
|
||
.presets button:hover { border-color: var(--clay); }
|
||
.presets button.on { background: var(--slate); border-color: var(--slate); color: var(--ivory); }
|
||
|
||
.frame-wrap { position: relative; background: var(--slate); user-select: none; }
|
||
.frame-stack { position: relative; aspect-ratio: 16/9; overflow: hidden; }
|
||
.frame-stack svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
|
||
#gradeLayer { position: absolute; inset: 0; }
|
||
#tempOverlay, #splitTone { position: absolute; inset: 0; pointer-events: none; }
|
||
#tempOverlay { mix-blend-mode: soft-light; opacity: 0; }
|
||
#splitTone { mix-blend-mode: soft-light; opacity: 0;
|
||
background: radial-gradient(circle at 72% 34%, rgba(255,166,87,.95) 0%, rgba(255,166,87,0) 42%),
|
||
linear-gradient(rgba(38,86,97,.85), rgba(38,86,97,.85)); }
|
||
.split-handle {
|
||
position: absolute; top: 0; bottom: 0; width: 2px; background: rgba(250,249,245,.9);
|
||
box-shadow: 0 0 6px rgba(0,0,0,.5); pointer-events: none;
|
||
}
|
||
.split-handle::after {
|
||
content: "◂ ▸"; position: absolute; top: 50%; left: 50%;
|
||
transform: translate(-50%,-50%);
|
||
background: var(--ivory); color: var(--slate); font-size: 10px;
|
||
padding: 3px 7px; border-radius: 999px; white-space: nowrap;
|
||
font-family: var(--mono); letter-spacing: 0.05em;
|
||
}
|
||
#splitRange {
|
||
position: absolute; inset: 0; width: 100%; height: 100%;
|
||
opacity: 0; cursor: ew-resize; margin: 0; -webkit-appearance: none; appearance: none;
|
||
}
|
||
.frame-tag {
|
||
position: absolute; top: 10px; font-family: var(--mono); font-size: 10px;
|
||
letter-spacing: 0.12em; padding: 3px 8px; border-radius: 4px;
|
||
background: rgba(20,20,19,.55); color: rgba(250,249,245,.9); pointer-events: none;
|
||
}
|
||
.frame-tag.before { left: 10px; }
|
||
.frame-tag.after { right: 10px; }
|
||
|
||
.sliders {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 14px 28px;
|
||
padding: 18px 20px 20px; border-top: 1.5px solid var(--g200);
|
||
}
|
||
@media (max-width: 640px) { .sliders { grid-template-columns: 1fr; } }
|
||
.sl-row label {
|
||
display: flex; justify-content: space-between; align-items: baseline;
|
||
font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.08em;
|
||
text-transform: uppercase; color: var(--g700); margin-bottom: 4px;
|
||
}
|
||
.sl-row label output { color: var(--clay-d); text-transform: none; }
|
||
.sl-row input[type=range] {
|
||
-webkit-appearance: none; appearance: none; width: 100%; height: 22px;
|
||
background: transparent; cursor: pointer; margin: 0;
|
||
}
|
||
.sl-row input[type=range]::-webkit-slider-runnable-track {
|
||
height: 4px; border-radius: 2px; background: var(--g200);
|
||
}
|
||
.sl-row input[type=range]::-webkit-slider-thumb {
|
||
-webkit-appearance: none; appearance: none; width: 16px; height: 16px; margin-top: -6px;
|
||
border-radius: 50%; background: var(--clay); border: 2px solid var(--paper);
|
||
box-shadow: 0 1px 3px rgba(20,20,19,.25);
|
||
}
|
||
.sl-row input[type=range]::-moz-range-track {
|
||
height: 4px; border-radius: 2px; background: var(--g200);
|
||
}
|
||
.sl-row input[type=range]::-moz-range-thumb {
|
||
width: 14px; height: 14px; border-radius: 50%; background: var(--clay);
|
||
border: 2px solid var(--paper); box-shadow: 0 1px 3px rgba(20,20,19,.25);
|
||
}
|
||
.console-foot {
|
||
font-size: 13px; color: var(--g500); padding: 0 20px 16px;
|
||
}
|
||
.console-foot b { color: var(--g700); font-weight: 600; }
|
||
.resetbtn {
|
||
font-family: var(--mono); font-size: 11px; background: none; border: none;
|
||
color: var(--g500); text-decoration: underline; cursor: pointer; padding: 0;
|
||
}
|
||
.resetbtn:hover { color: var(--clay); }
|
||
|
||
/* checklist */
|
||
.checklist { padding: 6px 22px 10px; }
|
||
.checklist ul { list-style: none; margin: 12px 0 14px; padding: 0; display: grid; gap: 10px; }
|
||
.checklist li { display: flex; gap: 12px; font-size: 14.5px; color: var(--g700); }
|
||
.checklist li::before {
|
||
content: "✓"; flex: none; width: 20px; height: 20px; border-radius: 50%;
|
||
background: var(--olive); color: #fff; font-size: 12px; line-height: 20px;
|
||
text-align: center; margin-top: 2px;
|
||
}
|
||
.checklist li b { color: var(--slate); font-weight: 600; }
|
||
.checklist li.warn::before { content: "!"; background: var(--clay); }
|
||
|
||
/* prompts card */
|
||
.prompts-card { border-color: var(--slate); padding: 22px 24px 20px; }
|
||
.prompts-card h3 { margin: 0 0 4px; font-size: 21px; }
|
||
.prompts-card .note { font-size: 13.5px; color: var(--g500); margin: 0 0 16px; }
|
||
.pgrid { display: grid; gap: 10px; }
|
||
.pgrid .p {
|
||
font-family: var(--mono); font-size: 13px; line-height: 1.6;
|
||
background: var(--g100); border-left: 3px solid var(--clay);
|
||
border-radius: 0 10px 10px 0; padding: 12px 16px; color: var(--g700);
|
||
}
|
||
.pgrid .p b { color: var(--slate); font-weight: 600; }
|
||
|
||
footer {
|
||
margin-top: 72px; padding-top: 24px; border-top: 1.5px solid var(--g300);
|
||
font-size: 13.5px; color: var(--g500);
|
||
}
|
||
footer a { color: var(--clay); text-decoration-color: var(--oat); text-underline-offset: 3px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
|
||
<header>
|
||
<div class="eyebrow">Know your unknowns · Pre-implementation</div>
|
||
<a class="backlink" href="index.html">← All examples</a>
|
||
<h1>Teach me my unknowns</h1>
|
||
<p class="lede">Before doing unfamiliar work, ask Claude to teach you the domain's vocabulary — so your next prompt uses the words a professional would.</p>
|
||
|
||
<div class="card promptbox">
|
||
<div class="label">The prompt</div>
|
||
<blockquote id="promptText">I don't know what color grading is but I need to grade the Acme launch video. Teach me color grading well enough that I understand my unknown unknowns and can prompt you with real vocabulary.</blockquote>
|
||
<button class="copybtn" id="copyBtn" type="button">copy prompt</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="divider">What Claude produced</div>
|
||
|
||
<main class="artifact">
|
||
<h2>Color grading in one sitting</h2>
|
||
<p class="sub">Everything you need to grade <em>acme-launch-v3.mp4</em> — or at least to give precise notes to whoever does. Correction first, then the creative look. Play with the frame below until the sliders feel obvious.</p>
|
||
|
||
<!-- mental model -->
|
||
<div class="sec-eyebrow">The mental model</div>
|
||
<div class="pipeline">
|
||
<div class="pipe-step"><b>1 · Ingest</b><span>Footage arrives "flat" (log) — grey and washed out, on purpose. It preserves detail.</span></div>
|
||
<div class="pipe-step hot"><b>2 · Correct</b><span>Fix exposure & white balance so it looks <em>real</em>. Boring, essential, first.</span></div>
|
||
<div class="pipe-step hot"><b>3 · Grade</b><span>Add the <em>look</em>: contrast shape, color bias, mood. This is the creative part.</span></div>
|
||
<div class="pipe-step"><b>4 · Match</b><span>Make every shot in the cut agree, so the video feels like one piece.</span></div>
|
||
</div>
|
||
|
||
<!-- vocab ladder -->
|
||
<div class="sec-eyebrow">The vocabulary ladder</div>
|
||
<div class="ladder">
|
||
<div class="card rung">
|
||
<div class="term">Exposure<small>overall brightness</small></div>
|
||
<div class="def">How light or dark the whole image is, measured in "stops" (each stop doubles/halves the light). Wrong exposure = detail lost in blown highlights or murky shadows.</div>
|
||
<div class="say">"the interview shots look a half-stop underexposed — bring them up"</div>
|
||
</div>
|
||
<div class="card rung">
|
||
<div class="term">White balance<small>color temperature</small></div>
|
||
<div class="def">Whether white things actually look white. Measured in Kelvin: low = warm/orange (tungsten), high = cool/blue (daylight). Mixed lighting is the classic gotcha.</div>
|
||
<div class="say">"the office footage reads too warm — cool it toward neutral, protect skin tones"</div>
|
||
</div>
|
||
<div class="card rung">
|
||
<div class="term">Contrast curve<small>tone response</small></div>
|
||
<div class="def">The S-shaped curve mapping shadows→highlights. Steeper = punchier; flatter = softer, more "filmic". You bend the curve, you don't just crank a slider.</div>
|
||
<div class="say">"add a gentle S-curve — richer blacks but don't crush shadow detail"</div>
|
||
</div>
|
||
<div class="card rung">
|
||
<div class="term">Lift / Gamma / Gain<small>3-way correction</small></div>
|
||
<div class="def">Independent color+brightness control over shadows (lift), midtones (gamma), and highlights (gain). This is how pros push "teal in the shadows, warm in the highlights".</div>
|
||
<div class="say">"push the lift slightly teal and the gain slightly warm — subtle, not music-video"</div>
|
||
</div>
|
||
<div class="card rung">
|
||
<div class="term">Saturation vs vibrance<small>color intensity</small></div>
|
||
<div class="def">Saturation boosts <em>all</em> colors equally (skin goes orange fast). Vibrance boosts only the muted colors and protects skin. Almost always reach for vibrance first.</div>
|
||
<div class="say">"use vibrance not saturation — the UI screenshots can pop but faces stay natural"</div>
|
||
</div>
|
||
<div class="card rung">
|
||
<div class="term">LUT<small>look-up table</small></div>
|
||
<div class="def">A saved color transform file (.cube) that applies a whole look in one step — either technical (log→Rec.709 conversion) or creative (a stylized grade). Apply after correction, then dial its intensity down.</div>
|
||
<div class="say">"apply the Rec.709 conversion LUT first, then a creative LUT at ~60% strength"</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- interactive console -->
|
||
<div class="sec-eyebrow">Feel it — grade a frame</div>
|
||
<div class="card console">
|
||
<div class="console-head">
|
||
<span class="fname">acme-launch-v3.mp4 <i>· frame 01:47:12 · drag the split to compare</i></span>
|
||
<div class="presets">
|
||
<button type="button" data-preset="flat">Flat / log</button>
|
||
<button type="button" data-preset="corporate" class="on">Corporate clean</button>
|
||
<button type="button" data-preset="teal">Cinematic teal-orange</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="frame-wrap">
|
||
<div class="frame-stack">
|
||
<!-- scene definition -->
|
||
<svg viewBox="0 0 640 360" preserveAspectRatio="xMidYMid slice" aria-label="Ungraded landscape frame">
|
||
<defs>
|
||
<g id="scene">
|
||
<rect width="640" height="360" fill="#9DB3B8"/>
|
||
<circle cx="462" cy="118" r="34" fill="#EFD79A"/>
|
||
<path d="M0 190 L120 96 L238 190 Z" fill="#77857D"/>
|
||
<path d="M150 190 L300 66 L470 190 Z" fill="#5F6F66"/>
|
||
<path d="M400 190 L520 110 L640 190 L640 200 L400 200 Z" fill="#77857D"/>
|
||
<rect y="190" width="640" height="80" fill="#8AA39E"/>
|
||
<path d="M300 214 L470 190 L462 152 L448 190 Z" fill="#71898A" opacity="0.5"/>
|
||
<circle cx="462" cy="216" r="22" fill="#D9C08A" opacity="0.55"/>
|
||
<rect y="262" width="640" height="98" fill="#55614C"/>
|
||
<path d="M0 262 C 140 244, 300 276, 640 254 L640 360 L0 360 Z" fill="#4A5542"/>
|
||
<g fill="#3E4A38">
|
||
<path d="M70 262 L86 210 L102 262 Z"/><rect x="83" y="258" width="6" height="16"/>
|
||
<path d="M112 268 L126 224 L140 268 Z"/><rect x="123" y="264" width="5" height="14"/>
|
||
<path d="M560 258 L578 202 L596 258 Z"/><rect x="575" y="254" width="6" height="18"/>
|
||
</g>
|
||
<g fill="#2E2E2A">
|
||
<circle cx="332" cy="284" r="7"/>
|
||
<path d="M326 291 C 326 302, 338 302, 338 291 L337 316 L333 316 L332 300 L331 316 L327 316 Z"/>
|
||
</g>
|
||
<path d="M0 356 L640 356" stroke="#39422F" stroke-width="8"/>
|
||
</g>
|
||
</defs>
|
||
<use href="#scene"/>
|
||
</svg>
|
||
|
||
<!-- graded copy, clipped to the right of the split -->
|
||
<div id="gradeLayer">
|
||
<svg viewBox="0 0 640 360" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
|
||
<use href="#scene"/>
|
||
</svg>
|
||
<div id="tempOverlay"></div>
|
||
<div id="splitTone"></div>
|
||
</div>
|
||
|
||
<span class="frame-tag before">UNGRADED</span>
|
||
<span class="frame-tag after">GRADED</span>
|
||
<div class="split-handle" id="splitHandle"></div>
|
||
<input type="range" id="splitRange" min="4" max="96" value="42" aria-label="Before/after split position">
|
||
</div>
|
||
|
||
<div class="sliders">
|
||
<div class="sl-row">
|
||
<label for="sExp">Exposure <output id="oExp">+0.2 EV</output></label>
|
||
<input type="range" id="sExp" min="-50" max="50" value="10">
|
||
</div>
|
||
<div class="sl-row">
|
||
<label for="sTemp">Temperature <output id="oTemp">+8 warm</output></label>
|
||
<input type="range" id="sTemp" min="-50" max="50" value="8">
|
||
</div>
|
||
<div class="sl-row">
|
||
<label for="sCon">Contrast <output id="oCon">+12</output></label>
|
||
<input type="range" id="sCon" min="-50" max="50" value="12">
|
||
</div>
|
||
<div class="sl-row">
|
||
<label for="sSat">Saturation <output id="oSat">+8</output></label>
|
||
<input type="range" id="sSat" min="-50" max="50" value="8">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="console-foot">
|
||
<span id="presetNote"><b>Corporate clean:</b> slight lift in exposure, near-neutral temperature, modest contrast — trustworthy and bright. The default for product launch videos.</span>
|
||
· <button class="resetbtn" type="button" id="resetBtn">reset to ungraded</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- checklist -->
|
||
<div class="sec-eyebrow">What good looks like</div>
|
||
<div class="card checklist">
|
||
<ul>
|
||
<li><b>Skin tones stay believable.</b> Every creative look bends around faces, never through them. If the founder looks seasick or sunburned, the grade is wrong.</li>
|
||
<li><b>Blacks are rich but not crushed.</b> You can still read detail in dark areas (hair, the navy hoodie at 00:42). A histogram slammed against the left edge means lost information.</li>
|
||
<li><b>Whites don't clip.</b> The Acme UI screens are mostly white — if they blow out to pure 100%, button borders and text vanish. Keep highlights just under the ceiling.</li>
|
||
<li><b>Shot-to-shot consistency.</b> Cutting from the office interview to the screen capture shouldn't feel like changing channels. Shot matching is half the job.</li>
|
||
<li><b>The look serves the story.</b> A launch video wants clean and confident, not moody thriller. If viewers notice the grade before the product, dial it back.</li>
|
||
<li class="warn"><b>Check on more than one screen.</b> Your laptop lies. Preview on a phone and, ideally, a TV before signing off — and confirm you're exporting in Rec.709 for web delivery.</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- prompts you couldn't have written -->
|
||
<div class="sec-eyebrow">The payoff</div>
|
||
<div class="card prompts-card">
|
||
<h3>Prompts you couldn't have written an hour ago</h3>
|
||
<p class="note">An hour ago the best you had was "make the video look nicer." Now you can say:</p>
|
||
<div class="pgrid">
|
||
<div class="p">"The interview footage was shot in <b>log</b> — apply the camera's <b>Rec.709 conversion LUT</b> first, then grade on top of that, not on the raw flat image."</div>
|
||
<div class="p">"Give the whole cut a restrained <b>teal-orange</b> look: push the <b>lift</b> slightly teal, <b>gain</b> slightly warm, keep <b>gamma</b> neutral so midtone skin stays natural."</div>
|
||
<div class="p">"Shot 14 is about <b>2/3 of a stop underexposed</b> and too warm versus shot 13 — match its <b>exposure</b> and <b>white balance</b> to shot 13, then A/B them at the cut point."</div>
|
||
<div class="p">"Add a soft <b>S-curve</b> for contrast and lift color intensity with <b>vibrance rather than saturation</b>, so the product UI pops without turning faces orange."</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<footer>Part of <a href="index.html">Know your unknowns</a> — companion examples to the blog post.</footer>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
// ---- copy prompt ----
|
||
var copyBtn = document.getElementById('copyBtn');
|
||
var promptText = document.getElementById('promptText').textContent.trim();
|
||
copyBtn.addEventListener('click', function () {
|
||
function done() {
|
||
copyBtn.textContent = 'Copied';
|
||
copyBtn.classList.add('done');
|
||
setTimeout(function () {
|
||
copyBtn.textContent = 'copy prompt';
|
||
copyBtn.classList.remove('done');
|
||
}, 1600);
|
||
}
|
||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||
navigator.clipboard.writeText(promptText).then(done, fallback);
|
||
} else { fallback(); }
|
||
function fallback() {
|
||
var ta = document.createElement('textarea');
|
||
ta.value = promptText;
|
||
ta.style.position = 'fixed'; ta.style.opacity = '0';
|
||
document.body.appendChild(ta);
|
||
ta.select();
|
||
try { document.execCommand('copy'); } catch (e) {}
|
||
document.body.removeChild(ta);
|
||
done();
|
||
}
|
||
});
|
||
|
||
// ---- grading console ----
|
||
var sExp = document.getElementById('sExp'),
|
||
sTemp = document.getElementById('sTemp'),
|
||
sCon = document.getElementById('sCon'),
|
||
sSat = document.getElementById('sSat');
|
||
var oExp = document.getElementById('oExp'),
|
||
oTemp = document.getElementById('oTemp'),
|
||
oCon = document.getElementById('oCon'),
|
||
oSat = document.getElementById('oSat');
|
||
var gradeLayer = document.getElementById('gradeLayer');
|
||
var gradeSvg = gradeLayer.querySelector('svg');
|
||
var tempOverlay = document.getElementById('tempOverlay');
|
||
var splitTone = document.getElementById('splitTone');
|
||
var splitRange = document.getElementById('splitRange');
|
||
var splitHandle = document.getElementById('splitHandle');
|
||
var presetNote = document.getElementById('presetNote');
|
||
var presetBtns = document.querySelectorAll('.presets button');
|
||
var splitToneOn = false;
|
||
|
||
var presets = {
|
||
flat: {
|
||
exp: 6, temp: 0, con: -38, sat: -45, split: false,
|
||
note: '<b>Flat / log:</b> low contrast, low saturation — this is roughly what footage looks like straight off a camera shooting log. Ugly on purpose: it keeps maximum detail for grading.'
|
||
},
|
||
corporate: {
|
||
exp: 10, temp: 8, con: 12, sat: 8, split: false,
|
||
note: '<b>Corporate clean:</b> slight lift in exposure, near-neutral temperature, modest contrast — trustworthy and bright. The default for product launch videos.'
|
||
},
|
||
teal: {
|
||
exp: 4, temp: -22, con: 26, sat: 14, split: true,
|
||
note: '<b>Cinematic teal-orange:</b> shadows pushed teal, a warm glow held around the light source, stronger contrast. The blockbuster look — use at maybe 40% of this strength for a launch video.'
|
||
}
|
||
};
|
||
|
||
function fmtSigned(v) { return (v > 0 ? '+' : '') + v; }
|
||
|
||
function update() {
|
||
var exp = +sExp.value, temp = +sTemp.value, con = +sCon.value, sat = +sSat.value;
|
||
|
||
// filter math: sliders are -50..50
|
||
var brightness = 1 + exp / 100; // 0.5 .. 1.5
|
||
var contrast = 1 + con / 100; // 0.5 .. 1.5
|
||
var saturate = 1 + sat / 62.5; // 0.2 .. 1.8
|
||
var sepia = temp > 0 ? temp / 50 * 0.22 : 0;
|
||
|
||
gradeSvg.style.filter =
|
||
'brightness(' + brightness.toFixed(3) + ') ' +
|
||
'contrast(' + contrast.toFixed(3) + ') ' +
|
||
'saturate(' + saturate.toFixed(3) + ')' +
|
||
(sepia ? ' sepia(' + sepia.toFixed(3) + ')' : '');
|
||
|
||
// temperature wash overlay
|
||
if (temp === 0) {
|
||
tempOverlay.style.opacity = 0;
|
||
} else if (temp > 0) {
|
||
tempOverlay.style.background = '#E8955C';
|
||
tempOverlay.style.opacity = (temp / 50 * 0.55).toFixed(3);
|
||
} else {
|
||
tempOverlay.style.background = '#3E7286';
|
||
tempOverlay.style.opacity = (-temp / 50 * 0.6).toFixed(3);
|
||
}
|
||
|
||
splitTone.style.opacity = splitToneOn ? 0.75 : 0;
|
||
|
||
// readouts
|
||
oExp.textContent = (exp >= 0 ? '+' : '−') + Math.abs(exp / 50).toFixed(1) + ' EV';
|
||
oTemp.textContent = temp === 0 ? 'neutral' : fmtSigned(temp) + (temp > 0 ? ' warm' : ' cool');
|
||
oCon.textContent = fmtSigned(con);
|
||
oSat.textContent = fmtSigned(sat);
|
||
}
|
||
|
||
[sExp, sTemp, sCon, sSat].forEach(function (s) {
|
||
s.addEventListener('input', function () {
|
||
splitToneOn = false; // manual moves drop the split-tone extra
|
||
presetBtns.forEach(function (b) { b.classList.remove('on'); });
|
||
update();
|
||
});
|
||
});
|
||
|
||
presetBtns.forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
var p = presets[btn.dataset.preset];
|
||
sExp.value = p.exp; sTemp.value = p.temp; sCon.value = p.con; sSat.value = p.sat;
|
||
splitToneOn = p.split;
|
||
presetBtns.forEach(function (b) { b.classList.toggle('on', b === btn); });
|
||
presetNote.innerHTML = p.note;
|
||
update();
|
||
});
|
||
});
|
||
|
||
document.getElementById('resetBtn').addEventListener('click', function () {
|
||
sExp.value = 0; sTemp.value = 0; sCon.value = 0; sSat.value = 0;
|
||
splitToneOn = false;
|
||
presetBtns.forEach(function (b) { b.classList.remove('on'); });
|
||
presetNote.innerHTML = '<b>Ungraded:</b> all corrections zeroed — the graded side now matches the source frame exactly.';
|
||
update();
|
||
});
|
||
|
||
// before/after split
|
||
function updateSplit() {
|
||
var pct = +splitRange.value;
|
||
gradeLayer.style.clipPath = 'inset(0 0 0 ' + pct + '%)';
|
||
splitHandle.style.left = pct + '%';
|
||
}
|
||
splitRange.addEventListener('input', updateSplit);
|
||
|
||
update();
|
||
updateSplit();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|