C12 Productions | Automotive and motorsports photography
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{–base:#E9ECEF;–paper:#FAFBFC;–ink:#0F1215;–steel:#5C6670;–red:#E0281C;–line:#CDD2D8}
body{background:var(–base);color:var(–ink);font:400 1rem/1.6 ‘Hanken Grotesk’,sans-serif;-webkit-font-smoothing:antialiased}
img{display:block;width:100%;height:100%;object-fit:cover}
a{color:inherit;text-decoration:none}
:focus-visible{outline:3px solid var(–red);outline-offset:3px}
.wrap{width:min(1240px,100% – 48px);margin-inline:auto}
h1,h2,h3{font-family:’Unbounded’,sans-serif;font-weight:700;line-height:1.12;letter-spacing:-.02em}
header{position:sticky;top:0;z-index:50;background:rgba(250,251,252,.92);backdrop-filter:blur(14px);border-bottom:1px solid var(–line)}
.mast{display:flex;align-items:center;gap:32px;min-height:64px}
.logo{font:700 1.2rem ‘Unbounded’,sans-serif;letter-spacing:-.03em}
.logo i{font-style:normal;color:var(–red)}
.mast nav{display:flex;gap:24px;flex:1}
.mast nav a{font-weight:500;font-size:.95rem;color:var(–steel);padding:6px 0;border-bottom:2px solid transparent;transition:color .2s,border-color .2s}
.mast nav a:hover{color:var(–ink)}
.mast nav a[aria-current]{color:var(–ink);border-color:var(–red)}
.btn{display:inline-block;background:var(–ink);color:var(–paper);font-weight:600;font-size:.9rem;padding:10px 20px;border-radius:999px;transition:background .2s}
.btn:hover{background:var(–red)}
.pagehead{padding:64px 0 28px}
.pagehead h1{font-size:clamp(2.2rem,6vw,4.4rem)}
.pagehead p{margin-top:14px;max-width:56ch;color:var(–steel);font-size:1.08rem}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:26px}
.chip{font:600 .88rem ‘Hanken Grotesk’,sans-serif;border:1.5px solid var(–ink);background:transparent;color:var(–ink);padding:8px 18px;border-radius:999px;cursor:pointer;transition:background .2s,color .2s}
.chip[aria-pressed=true]{background:var(–ink);color:var(–paper)}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:22px}
.card[hidden]{display:none}
.card .ph{aspect-ratio:3/2;border-radius:20px;overflow:hidden;background:var(–line)}
.card img{transition:transform .6s ease}
.card:hover img{transform:scale(1.05)}
.card h3{font-size:1.05rem;margin:12px 0 6px}
.card p{font-size:.93rem;color:#38414a;margin-bottom:6px}
.meta{font-size:.85rem;color:var(–steel)}
.tag{display:inline-block;background:var(–red);color:#fff;font-weight:600;font-size:.8rem;padding:3px 12px;border-radius:999px}
section{margin-top:72px}
.sec-head{display:flex;justify-content:space-between;align-items:baseline;gap:16px;border-bottom:2px solid var(–ink);padding-bottom:12px;margin-bottom:22px}
.sec-head h2{font-size:1.5rem}
.sec-head a{font-weight:600;font-size:.92rem;color:var(–red)}
.front{display:grid;grid-template-columns:1.7fr 1fr;gap:20px;margin-top:28px}
.lead{position:relative;display:block;border-radius:28px;overflow:hidden;min-height:540px;background:var(–ink)}
.lead img{position:absolute;inset:0;transition:transform .8s ease}
.lead:hover img{transform:scale(1.03)}
.lead::after{content:”;position:absolute;inset:0;background:linear-gradient(to top,rgba(15,18,21,.88),rgba(15,18,21,0) 62%)}
.lead div{position:absolute;z-index:2;left:32px;right:32px;bottom:32px;color:#fff}
.lead h1{font-size:clamp(1.8rem,3.6vw,3rem);margin:10px 0}
.lead p{max-width:52ch;color:rgba(255,255,255,.85)}
.stack{display:flex;flex-direction:column;gap:14px}
.row{display:grid;grid-template-columns:128px 1fr;gap:16px;align-items:center;background:var(–paper);border-radius:20px;padding:10px;transition:box-shadow .2s}
.row:hover{box-shadow:0 8px 24px rgba(15,18,21,.1)}
.row .ph{aspect-ratio:1;border-radius:14px;overflow:hidden}
.row h3{font-size:.98rem;margin:6px 0 4px}
.row .tag{background:var(–ink)}
.panel{display:grid;grid-template-columns:1.4fr 1fr;gap:20px}
.video{position:relative;border-radius:28px;overflow:hidden;min-height:380px;background:var(–ink);color:#fff;display:flex;align-items:flex-end}
.video img{position:absolute;inset:0;opacity:.55;transition:transform .8s}
.video:hover img{transform:scale(1.04)}
.video div{position:relative;padding:32px}
.video h2{font-size:1.8rem;margin-bottom:8px}
.play{display:inline-block;margin-top:16px;background:var(–red);padding:11px 22px;border-radius:999px;font-weight:600}
.side{background:var(–red);color:#fff;border-radius:28px;padding:36px;display:flex;flex-direction:column;justify-content:center;gap:14px}
.side h2{font-size:1.6rem}
.side .btn{background:#fff;color:var(–ink);align-self:flex-start}
.side .btn:hover{background:var(–ink);color:#fff}
.about{display:grid;grid-template-columns:320px 1fr;gap:40px;align-items:start;background:var(–paper);border-radius:28px;padding:40px}
.about img{width:320px;height:320px;max-width:100%;border-radius:22px}
.about p{max-width:62ch;margin-bottom:14px;color:#2c333a}
.topics{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px}
.topics span{background:var(–paper);padding:9px 18px;border-radius:999px;font-weight:600;border:1px solid var(–line)}
footer{margin-top:84px;background:var(–ink);color:#C5CBD1;padding:48px 0 36px}
.foot{display:grid;grid-template-columns:1.4fr repeat(2,1fr);gap:28px}
footer h3{color:#fff;font-size:.95rem;margin-bottom:12px}
footer li{list-style:none;margin-bottom:8px;font-size:.93rem}
footer a:hover{color:#fff}
.legal{margin-top:32px;padding-top:20px;border-top:1px solid #29313a;font-size:.86rem}
@media(max-width:900px){.mast{flex-wrap:wrap;gap:10px 20px;padding:12px 0}.mast nav{order:3;width:100%;overflow-x:auto}.front,.panel,.about{grid-template-columns:1fr}.lead{min-height:440px}.foot{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.row{grid-template-columns:96px 1fr}.foot{grid-template-columns:1fr}.about{padding:24px}}
@media(prefers-reduced-motion:reduce){*{transition:none!important}}
html{scroll-behavior:smooth}
.sec{padding-top:96px;scroll-margin-top:56px}
.pagehead{padding:0 0 26px}
.pagehead h2{font-size:clamp(2rem,5vw,3.6rem)}
#top{scroll-margin-top:0}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
.dark{background:var(–ink);color:var(–paper);border-radius:36px;padding:48px 0 44px}
.dark .pagehead{padding:0 40px 20px}.dark .pagehead p{color:#9AA3AC}
.shoot{margin-top:28px}
.shoot h3{font-size:1.05rem;padding:0 40px 12px}.shoot h3 span{color:#9AA3AC;font:400 .9rem ‘Hanken Grotesk’,sans-serif;margin-left:10px}
.rail{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;padding:0 40px 8px;scrollbar-width:thin;scrollbar-color:var(–red) transparent}
.g{flex:0 0 min(70vw,400px);height:300px;scroll-snap-align:start;border:0;padding:0;border-radius:20px;overflow:hidden;cursor:zoom-in;background:#1b2025}
.g img{transition:transform .6s ease}.g:hover img{transform:scale(1.05)}
.lightbox{position:fixed;inset:0;background:rgba(5,5,5,.94);z-index:200;display:none;align-items:center;justify-content:center;padding:32px;cursor:zoom-out}
.lightbox.open{display:flex}.lightbox img{width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain;border-radius:8px}
.progress{position:fixed;top:0;left:0;height:3px;width:100%;background:var(–red);transform:scaleX(0);transform-origin:0 50%;z-index:100}
.lead img{animation:kb 14s ease-out forwards}
@keyframes kb{from{transform:scale(1)}to{transform:scale(1.08)}}
.rv{opacity:0;transform:translateY(28px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,1,.36,1)}
.rv.in{opacity:1;transform:none}
@media(max-width:700px){.dark{border-radius:28px}.dark .pagehead,.shoot h3{padding-left:20px;padding-right:20px}.rail{padding-left:20px;padding-right:20px}}
@media(prefers-reduced-motion:reduce){.lead img,.progress{animation:none}.rv{opacity:1;transform:none;transition:none}}
.topo-hero{position:relative;overflow:hidden;background:#171717;border-radius:0 0 40px 40px;padding:8px 0 64px}
.topo-hero canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.topo-hero .front{position:relative;z-index:1}
@media(max-width:700px){.topo-hero{border-radius:0 0 28px 28px;padding-bottom:40px}}
.ig-wrap{position:relative;z-index:1;padding-top:20px}
.ig-banner{position:relative;display:block;height:clamp(260px,42vw,480px);border-radius:28px;overflow:hidden;background:#171717}
.ig-banner img{width:100%;height:100%;object-fit:cover;object-position:50% 72%;transition:transform .8s ease}
.ig-banner:hover img{transform:scale(1.03)}
.ig-cta{position:absolute;top:18px;left:18px;display:inline-flex;align-items:center;gap:10px;background:rgba(250,251,252,.94);color:var(–ink);font-weight:600;font-size:.92rem;padding:10px 18px;border-radius:999px;transition:background .2s,color .2s}
.ig-banner:hover .ig-cta,.ig-banner:focus-visible .ig-cta{background:var(–red);color:#fff}
@media(max-width:520px){.ig-cta{font-size:.82rem;padding:8px 14px;top:12px;left:12px}}
@media(prefers-reduced-motion:reduce){.ig-banner img{transition:none}}
/* ===== DARK THEME: black page background ===== */
:root{–base:#000;–paper:#14161A;–ink:#F4F5F6;–steel:#9AA3AC;–line:#2A2F36;color-scheme:dark}
header{background:rgba(0,0,0,.86);border-bottom-color:var(–line)}
.btn:hover{color:#fff}
.lead,.video{background:#14161A}
.row .tag{background:#2A2F36}
.card p,.about p{color:#C9CFD5}
.dark{background:#14161A;color:#F4F5F6}
.ig-cta{color:#0F1215}
.side .btn{color:#0F1215}
.side .btn:hover{background:#0F1215;color:#fff}
footer{background:#000;border-top:1px solid var(–line)}
Latest shoots Fresh photos from the newest galleries. Tap any photo to enlarge it.
Firestone Grand Prix of St. PetersburgIndyCar, 2026
ILDS Winterfest 2025Tuner show, 2026
Motorsports IndyCar street races, Formula Drift and IMSA endurance racing, shot from the fence and the paddock.
Car shows Tuner meets, hot rod runs, concours lawns and charity shows across Florida, Georgia and South Carolina.
Video Race weekends and car shows on the C12 Productions YouTube channel.
About
C12Productions started in 2006 as a way to share car shows with friends serving overseas, so they had a piece of home with them.
A few years later a local car site asked for event coverage, and it grew from there. In 2011 the work expanded to photoshoots, magazine coverage and motorsports events. Growing up at Daytona International Speedway and Sebring Raceway made it a lifelong passion.
Based in the Tampa Bay area, shooting wherever the cars are.
IndyCar Red Bull GRC Pirelli World Challenge Super Trofeo GT IMSA Formula Drift
const U=’
https://i0.wp.com/c12production.com/wp-content/uploads/’ ;,Q=’?w=1200&ssl=1′,P=’
https://c12production.com/’ ;;
// group, tag, title, date, image, summary, post path
const S=[
[‘race’,’IndyCar’,’Firestone Grand Prix of St. Petersburg’,’Apr 12, 2026′,’2026/04/img_0273.jpg’,’Álex Palou won the 2026 IndyCar season opener ahead of Scott McLaughlin and Christian Lundgaard.’,’2026/04/12/gpstpete-2/’],
[‘show’,’Tuner’,’ILDS Winterfest 2025′,’Jan 6, 2026′,’2026/01/img_4148.jpg’,’Winter import tuner show put on by ILOVEDRIVINGSLOW.’,’2026/01/06/ilds-winterfest-2025/’],
[‘show’,’Hot rods’,’Turkey Rod Run 2025′,’Jan 5, 2026′,’2026/01/img_3213.jpg’,’Hot rods and muscle cars on Thanksgiving weekend in Daytona Beach.’,’2026/01/05/turkey-rod-run-2025/’],
[‘race’,’IMSA’,’Petit Le Mans’,’Oct 27, 2025′,’2025/10/img_2130.jpg’,’A first trip to Road Atlanta for the IMSA season finale.’,’2025/10/27/petit-le-mans/’],
[‘race’,’Formula Drift’,’FD Orlando: Scorched’,’Oct 27, 2025′,’2025/10/img_3812-copy.jpg’,’Formula Drift Round 3 at Orlando Speed World, May 30 and 31, 2025.’,’2025/10/27/fdorlandoscorched/’],
[‘race’,’IndyCar’,’Firestone GP of St. Pete 2025′,’Apr 15, 2025′,’2025/04/img_0273-2.jpg’,’The opening round of the 2025 NTT IndyCar season on the streets of St. Petersburg.’,’2025/04/15/firestone-gp-of-st-pete/’],
[‘show’,’Concours’,’Hilton Head Concours’,’Oct 27, 2025′,’2025/10/img_3104.jpg’,’A new event on the calendar, and one to come back to.’,’2025/10/27/hilton-head-concours/’],
[‘show’,’Custom’,’SWERV Savannah Super Show’,’Oct 27, 2025′,’2025/10/img_1430.jpg’,’Custom cars, trucks, lowriders and exotics at the Savannah Convention Center.’,’2025/10/27/swerv-savannah-super-show/’],
[‘show’,’Charity’,’Cars for Kicks’,’Apr 19, 2025′,’2025/04/img_6080.jpg’,’A charity show near Savannah supporting local youth martial arts.’,’2025/04/19/cars-for-kicks/’]
];
const L=s=>`href=”${P+s[6]}” target=”_blank” rel=”noopener”`;
const card=s=>`
${s[2]} ${s[5]}
${s[1]} · ${s[3]} `;
function categoryGrid(group,cid,gid){
const items=S.filter(s=>s[0]===group),tags=[…new Set(items.map(s=>s[1]))],g=document.getElementById(gid);
g.innerHTML=items.map(card).join(”);
const c=document.getElementById(cid);
c.innerHTML=[‘All’,…tags].map((t,i)=>`
${t} `).join(”);
c.onclick=e=>{const b=e.target.closest(‘.chip’);if(!b)return;c.querySelectorAll(‘.chip’).forEach(x=>x.setAttribute(‘aria-pressed’,x===b));g.querySelectorAll(‘.card’).forEach(k=>k.hidden=b.dataset.f!==’All’&&k.dataset.t!==b.dataset.f);};
}
const a=S[0];
document.getElementById(‘top’).innerHTML=`
${a[1]} ${a[2]} ${a[5]}
${a[3]}
`;
categoryGrid(‘race’,’chips-race’,’grid-race’);categoryGrid(‘show’,’chips-show’,’grid-show’);
// Highlight the nav link for the section in view
const links=[…document.querySelectorAll(‘.mast nav a’)];
const mark=id=>links.forEach(l=>l.toggleAttribute(‘aria-current’,l.getAttribute(‘href’)===’#’+id));
mark(‘top’);
const io=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting)mark(e.target.id)}),{rootMargin:’-45% 0px -50% 0px’});
document.querySelectorAll(‘#top,.sec’).forEach(s=>io.observe(s));
// Photo viewer
const lb=document.getElementById(‘lb’),lbi=lb.querySelector(‘img’);
document.querySelectorAll(‘.g’).forEach(b=>b.addEventListener(‘click’,()=>{lbi.src=b.dataset.full;lb.classList.add(‘open’)}));
lb.addEventListener(‘click’,()=>{lb.classList.remove(‘open’);lbi.src=”});
addEventListener(‘keydown’,e=>{if(e.key===’Escape’)lb.click()});
// Scroll progress bar
const bar=document.createElement(‘div’);bar.className=’progress’;document.body.append(bar);
addEventListener(‘scroll’,()=>{const m=document.documentElement.scrollHeight-innerHeight;bar.style.transform=`scaleX(${m>0?scrollY/m:0})`},{passive:true});
// Staggered reveal
const rv=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){e.target.classList.add(‘in’);rv.unobserve(e.target)}}),{threshold:.08});
document.querySelectorAll(‘.cards>*,.stack>*,.rail>*’).forEach((c,i)=>{c.classList.add(‘rv’);c.style.transitionDelay=(i%5)*80+’ms’;rv.observe(c)});
// Topographic flow background (settings from the TopographicFlow example)
function initTopo(cv,host,o){
const ctx=cv.getContext(‘2d’),RM=matchMedia(‘(prefers-reduced-motion: reduce)’).matches;
const hash=(x,y,z)=>{let n=Math.imul(x,374761393)+Math.imul(y,668265263)+Math.imul(z,1274126177)+o.seed*144665;n=Math.imul(n^(n>>>13),1274126177);return((n^(n>>>16))>>>0)/4294967296};
const fade=t=>t*t*(3-2*t),mix=(a,b,t)=>a+(b-a)*t;
const noise=(x,y,z)=>{const xi=Math.floor(x),yi=Math.floor(y),zi=Math.floor(z),u=fade(x-xi),v=fade(y-yi),w=fade(z-zi);
return mix(mix(mix(hash(xi,yi,zi),hash(xi+1,yi,zi),u),mix(hash(xi,yi+1,zi),hash(xi+1,yi+1,zi),u),v),
mix(mix(hash(xi,yi,zi+1),hash(xi+1,yi,zi+1),u),mix(hash(xi,yi+1,zi+1),hash(xi+1,yi+1,zi+1),u),v),w)};
const CS=14,levels=o.density*3;let W=0,H=0,cols=0,rows=0,vals,dpr=1;
const m={x:-999,y:-999,tx:-999,ty:-999,on:0};
function size(){const r=host.getBoundingClientRect();W=r.width;H=r.height;dpr=Math.min(devicePixelRatio||1,2);cv.width=W*dpr;cv.height=H*dpr;
cols=Math.ceil(W/CS);rows=Math.ceil(H/CS);vals=new Float32Array((cols+1)*(rows+1));}
function field(t){const z=t*o.speed*.03,sc=o.scale,d=o.distortion*.5;
for(let j=0;j<=rows;j++)for(let i=0;i.01){const dx=x-m.x,dy=y-m.y,r=Math.sqrt(dx*dx+dy*dy)/o.hoverRadius;
if(r<1)v+=o.hover*.12*m.on*Math.cos(r*18-t*3)*Math.pow(1-r,o.hoverFade*2)}
vals[j*(cols+1)+i]=v;}}
function draw(t,p){ctx.setTransform(dpr,0,0,dpr,0,0);ctx.clearRect(0,0,W,H);field(t);
ctx.lineWidth=o.lineWidth;ctx.lineCap='round';const cw=cols+1;
for(let k=0;k<levels;k++){const L=.3+.4*k/(levels-1),accent=k%5===0;
ctx.globalAlpha=Math.min(1,Math.max(0,p*1.6-k/levels*.6))*(accent?.5:.6)*o.opacity;
ctx.strokeStyle=accent?o.accent:o.line;ctx.beginPath();
for(let j=0;j<rows;j++)for(let i=0;iL?8:0)|(a1>L?4:0)|(a2>L?2:0)|(a3>L?1:0);if(c===0||c===15)continue;
const x=i*CS,y=j*CS,A=[x+(L-a0)/(a1-a0)*CS,y],B=[x+CS,y+(L-a1)/(a2-a1)*CS],C=[x+(L-a3)/(a2-a3)*CS,y+CS],D=[x,y+(L-a0)/(a3-a0)*CS];
const seg=(P,Q)=>{ctx.moveTo(P[0],P[1]);ctx.lineTo(Q[0],Q[1])};
switch(c){case 1:case 14:seg(D,C);break;case 2:case 13:seg(C,B);break;case 3:case 12:seg(D,B);break;
case 4:case 11:seg(A,B);break;case 6:case 9:seg(A,C);break;case 7:case 8:seg(D,A);break;
case 5:seg(D,A);seg(C,B);break;case 10:seg(D,C);seg(A,B);break;}}
ctx.stroke();}ctx.globalAlpha=1;}
let t0=performance.now(),vis=true,raf=0;
function frame(now){raf=0;if(!vis)return;const t=(now-t0)/1000,p=Math.min(1,t/2);
m.x+=(m.tx-m.x)*o.hoverFollow;m.y+=(m.ty-m.y)*o.hoverFollow;draw(t,o.entrance?1-Math.pow(1-p,3):1);raf=requestAnimationFrame(frame);}
size();new ResizeObserver(()=>{size();if(RM)draw(0,1)}).observe(host);
host.addEventListener(‘pointermove’,e=>{const r=host.getBoundingClientRect();m.tx=e.clientX-r.left;m.ty=e.clientY-r.top;if(m.on{m.on=0});
if(RM){draw(0,1);return}
new IntersectionObserver(es=>{vis=es[0].isIntersecting;if(vis&&!raf)raf=requestAnimationFrame(frame)}).observe(host);
raf=requestAnimationFrame(frame);
}
initTopo(document.getElementById(‘topo’),document.querySelector(‘.topo-hero’),{
entrance:true,scale:480,density:5,speed:4,distortion:2.4,lineWidth:1,opacity:1,seed:42,
hover:.6,hoverRadius:200,hoverFollow:.16,hoverFade:.8,line:’#06b6d4′,accent:’#ffffff’});