Video — Packages
A cinematic dark pricing section for a freelance videographer: three tiered packages with letterboxed hero, monthly-versus-project billing toggle, popular badge, and detailed deliverables, runtime, revisions, turnaround and price per tier. Amber film accents, JetBrains Mono timecodes, animated card lift on hover, and an enquire flow that opens a slide-in panel confirming the selected tier — fully keyboard-accessible and responsive to 360px.
MCP
Code
:root {
--bg: #0a0a0b;
--surface: #141416;
--surface-2: #1c1c1f;
--amber: #ffb020;
--amber-d: #e6971a;
--red: #ff4d4d;
--ink: #f4f4f6;
--muted: #8a8a92;
--line: rgba(255, 255, 255, 0.1);
--line-2: rgba(255, 255, 255, 0.18);
--white: #fff;
--r-sm: 6px;
--r-md: 10px;
--r-lg: 16px;
}
* {
box-sizing: border-box;
}
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: "Inter", system-ui, sans-serif;
line-height: 1.5;
}
.tc {
font-family: "JetBrains Mono", ui-monospace, monospace;
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
}
.page {
max-width: 1120px;
margin: 0 auto;
padding: 0 20px 64px;
}
/* ---------- Hero / letterbox ---------- */
.hero {
position: relative;
margin: 0 -20px 44px;
padding: 0;
background:
radial-gradient(1200px 380px at 50% -10%, rgba(255, 176, 32, 0.14), transparent 60%),
var(--surface);
overflow: hidden;
}
.bar {
height: 34px;
background: #000;
}
.hero-inner {
padding: 46px 24px 40px;
max-width: 760px;
margin: 0 auto;
text-align: center;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
margin: 0 0 18px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.16em;
color: var(--amber);
}
.rec {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--red);
box-shadow: 0 0 0 0 rgba(255, 77, 77, 0.6);
animation: pulse 1.8s ease-out infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0.6); }
70% { box-shadow: 0 0 0 8px rgba(255, 77, 77, 0); }
100% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0); }
}
.hero h1 {
margin: 0 0 16px;
font-size: clamp(30px, 6vw, 52px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.05;
}
.lede {
margin: 0 auto 26px;
max-width: 520px;
color: var(--muted);
font-size: 16px;
}
.lede .tc {
color: var(--amber-d);
}
/* ---------- Billing toggle ---------- */
.toggle {
display: inline-flex;
gap: 4px;
padding: 4px;
background: var(--surface-2);
border: 1px solid var(--line);
border-radius: 999px;
}
.toggle-btn {
appearance: none;
border: 0;
cursor: pointer;
padding: 9px 18px;
border-radius: 999px;
background: transparent;
color: var(--muted);
font: inherit;
font-weight: 600;
font-size: 14px;
display: inline-flex;
align-items: center;
gap: 8px;
transition: color 0.2s, background 0.2s;
}
.toggle-btn.is-active {
background: var(--amber);
color: #1a1205;
}
.toggle-btn:focus-visible {
outline: 2px solid var(--amber);
outline-offset: 2px;
}
.save {
font-size: 11px;
font-weight: 700;
padding: 2px 6px;
border-radius: 999px;
background: rgba(0, 0, 0, 0.18);
}
.toggle-btn:not(.is-active) .save {
background: rgba(255, 176, 32, 0.16);
color: var(--amber);
}
/* ---------- Grid ---------- */
.grid {
list-style: none;
margin: 0;
padding: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
align-items: start;
}
.card {
position: relative;
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 26px 24px 24px;
transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
outline: none;
}
.card::before {
content: "";
position: absolute;
inset: 0 0 auto 0;
height: 3px;
border-radius: var(--r-lg) var(--r-lg) 0 0;
background: linear-gradient(90deg, transparent, var(--amber), transparent);
opacity: 0;
transition: opacity 0.22s ease;
}
.card:hover,
.card:focus-within {
transform: translateY(-6px);
border-color: var(--line-2);
box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.8);
}
.card:hover::before,
.card:focus-within::before {
opacity: 1;
}
.card.is-popular {
border-color: rgba(255, 176, 32, 0.5);
box-shadow: 0 0 0 1px rgba(255, 176, 32, 0.2), 0 24px 50px -22px rgba(255, 176, 32, 0.35);
transform: translateY(-10px);
}
.card.is-popular:hover,
.card.is-popular:focus-within {
transform: translateY(-16px);
}
.badge {
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: var(--amber);
color: #1a1205;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.1em;
padding: 5px 12px;
border-radius: 999px;
white-space: nowrap;
}
.card-top {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
}
.tier {
margin: 0;
font-size: 19px;
font-weight: 700;
}
.reel {
font-size: 11px;
font-weight: 600;
color: var(--muted);
letter-spacing: 0.08em;
}
.blurb {
margin: 6px 0 18px;
color: var(--muted);
font-size: 13.5px;
min-height: 40px;
}
.price {
display: flex;
align-items: baseline;
gap: 6px;
}
.price .amount {
font-family: "JetBrains Mono", monospace;
font-size: 34px;
font-weight: 600;
letter-spacing: -0.01em;
transition: opacity 0.18s ease, transform 0.18s ease;
}
.price .per {
color: var(--muted);
font-size: 13px;
}
.price.flip .amount {
opacity: 0;
transform: translateY(-4px);
}
.meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin: 18px 0;
padding: 16px 0;
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.meta div {
display: flex;
flex-direction: column;
gap: 2px;
}
.meta dt {
font-size: 11px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted);
}
.meta dd {
margin: 0;
font-weight: 600;
font-size: 14px;
}
.features {
list-style: none;
margin: 0 0 20px;
padding: 0;
display: grid;
gap: 9px;
}
.features li {
display: flex;
gap: 10px;
font-size: 13.5px;
color: #d7d7dc;
}
.features .check {
flex: none;
width: 18px;
height: 18px;
border-radius: 50%;
display: grid;
place-items: center;
background: rgba(255, 176, 32, 0.14);
color: var(--amber);
font-size: 11px;
font-weight: 700;
}
/* ---------- Buttons ---------- */
.btn {
appearance: none;
border: 1px solid var(--line-2);
cursor: pointer;
width: 100%;
padding: 12px 16px;
border-radius: var(--r-md);
background: var(--surface-2);
color: var(--ink);
font: inherit;
font-weight: 600;
font-size: 14.5px;
transition: background 0.18s, border-color 0.18s, transform 0.08s;
}
.btn:hover {
border-color: var(--amber);
background: #26262a;
}
.btn:active {
transform: scale(0.98);
}
.btn:focus-visible {
outline: 2px solid var(--amber);
outline-offset: 2px;
}
.btn-primary {
background: var(--amber);
border-color: var(--amber);
color: #1a1205;
}
.btn-primary:hover {
background: var(--amber-d);
border-color: var(--amber-d);
}
/* ---------- Footer ---------- */
.foot {
display: flex;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
margin-top: 48px;
padding-top: 20px;
border-top: 1px solid var(--line);
color: var(--muted);
font-size: 12.5px;
}
.foot .tc {
color: var(--amber-d);
}
/* ---------- Panel ---------- */
.scrim {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(2px);
z-index: 40;
opacity: 0;
animation: fade 0.2s ease forwards;
}
@keyframes fade {
to { opacity: 1; }
}
.panel {
position: fixed;
top: 0;
right: 0;
height: 100%;
width: min(420px, 92vw);
background: var(--surface);
border-left: 1px solid var(--line-2);
z-index: 50;
transform: translateX(100%);
transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1);
overflow-y: auto;
}
.panel.is-open {
transform: translateX(0);
}
.panel-form {
padding: 26px 24px 32px;
display: grid;
gap: 14px;
}
.panel-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.panel-kicker {
margin: 0 0 2px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.16em;
color: var(--amber);
}
.panel-head h2 {
margin: 0;
font-size: 22px;
font-weight: 700;
}
.icon-btn {
appearance: none;
border: 1px solid var(--line);
background: var(--surface-2);
color: var(--ink);
width: 34px;
height: 34px;
border-radius: var(--r-sm);
cursor: pointer;
font-size: 14px;
transition: border-color 0.18s, background 0.18s;
}
.icon-btn:hover {
border-color: var(--amber);
}
.icon-btn:focus-visible {
outline: 2px solid var(--amber);
outline-offset: 2px;
}
.chosen {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
border: 1px solid rgba(255, 176, 32, 0.4);
background: rgba(255, 176, 32, 0.08);
border-radius: var(--r-md);
}
.chosen-name {
font-weight: 700;
}
.chosen-price {
color: var(--amber);
font-weight: 600;
font-size: 18px;
}
.field {
display: grid;
gap: 6px;
}
.field span {
font-size: 12.5px;
color: var(--muted);
font-weight: 500;
}
.field input,
.field textarea {
width: 100%;
padding: 11px 12px;
border-radius: var(--r-sm);
border: 1px solid var(--line);
background: var(--surface-2);
color: var(--ink);
font: inherit;
font-size: 14px;
resize: vertical;
}
.field input::placeholder,
.field textarea::placeholder {
color: #5c5c63;
}
.field input:focus,
.field textarea:focus {
outline: none;
border-color: var(--amber);
box-shadow: 0 0 0 3px rgba(255, 176, 32, 0.18);
}
.panel-actions {
display: grid;
gap: 12px;
margin-top: 4px;
}
.panel-note {
margin: 0;
font-size: 12px;
color: var(--muted);
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translate(-50%, 16px);
background: var(--surface-2);
color: var(--ink);
border: 1px solid var(--line-2);
border-left: 3px solid var(--amber);
padding: 12px 18px;
border-radius: var(--r-md);
font-size: 14px;
font-weight: 500;
box-shadow: 0 16px 40px -14px rgba(0, 0, 0, 0.7);
opacity: 0;
pointer-events: none;
z-index: 60;
transition: opacity 0.25s ease, transform 0.25s ease;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
/* ---------- Responsive ---------- */
@media (max-width: 900px) {
.grid {
grid-template-columns: 1fr;
max-width: 460px;
margin: 0 auto;
}
.card.is-popular {
transform: translateY(0);
}
.card.is-popular:hover,
.card.is-popular:focus-within {
transform: translateY(-6px);
}
}
@media (max-width: 520px) {
.page {
padding: 0 14px 48px;
}
.hero {
margin: 0 -14px 32px;
}
.bar {
height: 22px;
}
.hero-inner {
padding: 34px 18px 30px;
}
.toggle {
width: 100%;
justify-content: center;
}
.meta {
grid-template-columns: 1fr;
}
.foot {
flex-direction: column;
gap: 6px;
}
}// Aperture Nine — video packages
(function () {
"use strict";
var PACKAGES = [
{
id: "reel",
tier: "Reel",
reel: "TIER 01",
blurb: "A single social-first edit — perfect for launches and event recaps.",
project: 1600,
retainer: 1360,
runtime: "Up to 0:60",
revisions: "2 rounds",
turnaround: "5 days",
crew: "Solo shooter",
features: [
"1 half-day shoot",
"Vertical + horizontal masters",
"Licensed music + basic colour",
"Captions & thumbnail"
],
popular: false
},
{
id: "feature",
tier: "Feature",
reel: "TIER 02",
blurb: "A polished brand film with a small crew, grade and sound design.",
project: 3900,
retainer: 3315,
runtime: "Up to 2:30",
revisions: "3 rounds",
turnaround: "10 days",
crew: "2-person crew",
features: [
"Full-day shoot + lighting",
"Cinematic colour grade",
"Original sound design",
"3 cutdowns for socials",
"Storyboard & shot list"
],
popular: true
},
{
id: "studio",
tier: "Signature",
reel: "TIER 03",
blurb: "Multi-day production with a full crew for flagship campaigns.",
project: 8200,
retainer: 6970,
runtime: "Up to 5:00",
revisions: "Unlimited",
turnaround: "3 weeks",
crew: "Full crew + director",
features: [
"Up to 3 shoot days",
"Director, DP & gaffer",
"Cinema-grade colour + mix",
"6 platform cutdowns",
"Behind-the-scenes reel",
"Priority scheduling"
],
popular: false
}
];
var state = { mode: "project" };
function fmt(n) {
return "$" + n.toLocaleString("en-US");
}
var grid = document.getElementById("grid");
function priceFor(pkg) {
return state.mode === "project" ? pkg.project : pkg.retainer;
}
function buildCard(pkg) {
var li = document.createElement("li");
var card = document.createElement("article");
card.className = "card" + (pkg.popular ? " is-popular" : "");
card.tabIndex = 0;
card.setAttribute("aria-label", pkg.tier + " package, " + fmt(priceFor(pkg)));
var badge = pkg.popular
? '<span class="badge">★ MOST BOOKED</span>'
: "";
var meta =
metaRow("Runtime", pkg.runtime) +
metaRow("Revisions", pkg.revisions) +
metaRow("Turnaround", pkg.turnaround) +
metaRow("Crew", pkg.crew);
var feats = pkg.features
.map(function (f) {
return '<li><span class="check" aria-hidden="true">✓</span>' + f + "</li>";
})
.join("");
card.innerHTML =
badge +
'<div class="card-top">' +
'<h3 class="tier">' + pkg.tier + "</h3>" +
'<span class="reel">' + pkg.reel + "</span>" +
"</div>" +
'<p class="blurb">' + pkg.blurb + "</p>" +
'<div class="price" data-price>' +
'<span class="amount" data-amount>' + fmt(priceFor(pkg)) + "</span>" +
'<span class="per" data-per>' + perLabel() + "</span>" +
"</div>" +
'<dl class="meta">' + meta + "</dl>" +
'<ul class="features">' + feats + "</ul>" +
'<button class="btn ' + (pkg.popular ? "btn-primary" : "") + '" data-enquire>Enquire · ' + pkg.tier + "</button>";
card.querySelector("[data-enquire]").addEventListener("click", function () {
openPanel(pkg);
});
li.appendChild(card);
return li;
}
function metaRow(dt, dd) {
return "<div><dt>" + dt + "</dt><dd>" + dd + "</dd></div>";
}
function perLabel() {
return state.mode === "project" ? "/ project" : "/ month";
}
function render() {
grid.innerHTML = "";
PACKAGES.forEach(function (pkg) {
grid.appendChild(buildCard(pkg));
});
}
// Billing toggle with number flip animation
var toggleBtns = document.querySelectorAll(".toggle-btn");
toggleBtns.forEach(function (btn) {
btn.addEventListener("click", function () {
if (btn.classList.contains("is-active")) return;
state.mode = btn.getAttribute("data-mode");
toggleBtns.forEach(function (b) {
var active = b === btn;
b.classList.toggle("is-active", active);
b.setAttribute("aria-pressed", String(active));
});
flipPrices();
});
});
function flipPrices() {
var prices = grid.querySelectorAll("[data-price]");
prices.forEach(function (el) {
el.classList.add("flip");
});
window.setTimeout(function () {
PACKAGES.forEach(function (pkg, i) {
var card = grid.children[i].querySelector(".card");
card.querySelector("[data-amount]").textContent = fmt(priceFor(pkg));
card.querySelector("[data-per]").textContent = perLabel();
card.setAttribute("aria-label", pkg.tier + " package, " + fmt(priceFor(pkg)));
});
prices.forEach(function (el) {
el.classList.remove("flip");
});
}, 180);
}
// Panel
var panel = document.getElementById("panel");
var scrim = document.getElementById("scrim");
var closeBtn = document.getElementById("closePanel");
var form = document.getElementById("enquireForm");
var lastFocus = null;
function openPanel(pkg) {
lastFocus = document.activeElement;
document.getElementById("panelTitle").textContent = "Book the " + pkg.tier + " package";
document.getElementById("chosenName").textContent = pkg.tier + " · " + pkg.runtime;
document.getElementById("chosenPrice").textContent = fmt(priceFor(pkg)) + " " + perLabel();
scrim.hidden = false;
panel.classList.add("is-open");
panel.setAttribute("aria-hidden", "false");
window.setTimeout(function () {
document.getElementById("nameField").focus();
}, 320);
document.addEventListener("keydown", onKey);
}
function closePanel() {
panel.classList.remove("is-open");
panel.setAttribute("aria-hidden", "true");
scrim.hidden = true;
document.removeEventListener("keydown", onKey);
if (lastFocus) lastFocus.focus();
}
function onKey(e) {
if (e.key === "Escape") closePanel();
}
scrim.addEventListener("click", closePanel);
closeBtn.addEventListener("click", closePanel);
form.addEventListener("submit", function (e) {
e.preventDefault();
var name = document.getElementById("nameField");
var email = document.getElementById("emailField");
var date = document.getElementById("dateField");
if (!name.value.trim() || !email.checkValidity() || !date.value) {
toast("Please add your name, a valid email and a shoot date.");
(!name.value.trim() ? name : !email.checkValidity() ? email : date).focus();
return;
}
var chosen = document.getElementById("chosenName").textContent.split(" · ")[0];
closePanel();
form.reset();
toast("Enquiry sent for the " + chosen + " package — we'll reply within a day.");
});
// Toast
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("show");
window.clearTimeout(toastTimer);
toastTimer = window.setTimeout(function () {
toastEl.classList.remove("show");
}, 3400);
}
render();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Aperture Nine — Video Packages</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="page">
<!-- Hero with letterbox bars -->
<header class="hero" aria-label="Studio intro">
<div class="bar bar-top" aria-hidden="true"></div>
<div class="hero-inner">
<p class="eyebrow"><span class="rec" aria-hidden="true"></span> APERTURE NINE · FILM STUDIO</p>
<h1>Production packages<br />built for the story.</h1>
<p class="lede">
Cinema-grade crew, colour and sound — priced up front. Pick a tier,
lock a turnaround, and we roll. <span class="tc">00:00:12:04</span>
</p>
<div class="toggle" role="group" aria-label="Billing mode">
<button class="toggle-btn is-active" data-mode="project" aria-pressed="true">Per project</button>
<button class="toggle-btn" data-mode="retainer" aria-pressed="false">
Retainer <span class="save">−15%</span>
</button>
</div>
</div>
<div class="bar bar-bottom" aria-hidden="true"></div>
</header>
<!-- Packages -->
<section class="packages" aria-label="Video packages">
<ul class="grid" id="grid"></ul>
</section>
<footer class="foot">
<span class="tc">REEL · 24fps · A9-STUDIO</span>
<span>© 2026 Aperture Nine Films — a fictional studio</span>
</footer>
</main>
<!-- Enquire slide-in panel -->
<div class="scrim" id="scrim" hidden></div>
<aside class="panel" id="panel" role="dialog" aria-modal="true" aria-labelledby="panelTitle" aria-hidden="true">
<form class="panel-form" id="enquireForm" novalidate>
<div class="panel-head">
<div>
<p class="panel-kicker">ENQUIRE</p>
<h2 id="panelTitle">Book a package</h2>
</div>
<button type="button" class="icon-btn" id="closePanel" aria-label="Close enquiry">✕</button>
</div>
<div class="chosen">
<span class="chosen-name" id="chosenName">Feature</span>
<span class="chosen-price tc" id="chosenPrice">$3,900</span>
</div>
<label class="field">
<span>Your name</span>
<input id="nameField" name="name" autocomplete="name" placeholder="Jordan Vega" required />
</label>
<label class="field">
<span>Email</span>
<input id="emailField" name="email" type="email" autocomplete="email" placeholder="[email protected]" required />
</label>
<label class="field">
<span>Shoot date</span>
<input id="dateField" name="date" type="date" required />
</label>
<label class="field">
<span>Project brief</span>
<textarea id="briefField" name="brief" rows="3" placeholder="A 90-second brand film for our spring launch…"></textarea>
</label>
<div class="panel-actions">
<p class="panel-note">Reply within 1 business day · No obligation.</p>
<button type="submit" class="btn btn-primary">Send enquiry</button>
</div>
</form>
</aside>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A film-forward pricing block for an independent videographer’s portfolio site. A letterboxed hero with black cinema bars and an amber accent frames three package tiers — Reel, Feature and Studio — each laid out as a card with deliverables, runtime, revision count, turnaround window and price. A billing toggle switches every card between project and retainer pricing, animating the numbers as it flips, and the middle tier carries a glowing “Most booked” badge.
The cards react to hover and keyboard focus with a subtle lift, an amber top-line and a brightening border. Every price uses JetBrains Mono so timecodes and figures read like a colourist’s monitor. Pressing Enquire on any tier opens a slide-in side panel pre-filled with that package name, where a short form collects a shoot date and message; submitting fires a toast and closes the panel.
Everything is vanilla: the toggle, the focus states, the panel and the toast are wired with a handful of event listeners, no dependencies. The layout collapses to a single column below 520px, controls stay large enough to tap, and all interactive elements expose ARIA state and visible focus rings for WCAG AA use.