<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Devala Griffith — Solutions Engineer</title>
<link href="...Space+Grotesk...DM+Sans..." rel="stylesheet">
<style>
:root{
--bg:#0b0d12; --card:#151926; --text:#e8eaf2; --muted:#9aa1b5;
--cyan:hsl(187,74%,52%); --purple:hsl(270,70%,62%);
--grad:linear-gradient(100deg,var(--cyan),var(--purple));
--radius:18px;
}
*{ margin:0; padding:0; box-sizing:border-box; }
body{ font-family:'DM Sans',sans-serif; background:var(--bg); color:var(--text); }
h1{ font-family:'Space Grotesk'; font-weight:700;
font-size:clamp(2.6rem,8.5vw,7rem); letter-spacing:-.03em; }
h1 .grad{ background:var(--grad); -webkit-background-clip:text; color:transparent; }
.reveal{ opacity:0; transform:translateY(36px); transition:.8s cubic-bezier(.2,.7,.2,1); }
.reveal.in{ opacity:1; transform:none; }
.bento{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
.cell{ background:var(--card); border:1px solid var(--line);
border-radius:var(--radius); transition:transform .35s; }
.cell:hover{ transform:translateY(-6px) scale(1.012); }
#codelayer{ position:fixed; inset:0; z-index:0;
mask:radial-gradient(circle 135px at var(--fx) var(--fy),#000,transparent 74%); }
</style>
</head>
<body>
<nav>
<div class="logo">D<span>G</span></div>
<ul><li><a href="#about">About</a></li></ul>
</nav>
<header class="hero">
<div class="blob b1"></div><div class="blob b2"></div>
<div class="kicker">Solutions Engineer · Gainesville, FL → anywhere</div>
<h1>
<span class="line"><span>I make AI</span></span>
<span class="line"><span class="grad">actually ship.</span></span>
</h1>
<div class="typer-row">Customer-facing engineer who <span id="typer"></span></div>
</header>
<section id="about">
<h2>Engineer. Founder. Teacher.</h2>
<p>Co-created a suite of AI tools that sped our team up 50%.</p>
</section>
<script>
/* scroll progress + reveal-on-scroll observers */
addEventListener('scroll',()=>{
const h=document.documentElement;
prog.style.width=(h.scrollTop/(h.scrollHeight-h.clientHeight)*100)+'%';
},{passive:true});
const io=new IntersectionObserver(es=>es.forEach(e=>{
if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); }
}),{threshold:.18});
// WebAudio mridanga drum — synthesized membrane tone
function drum(freq=140,dur=.22,when=0,gainV=.5){
const t=actx.currentTime+when;
const o=actx.createOscillator(), g=actx.createGain();
o.type='sine'; o.frequency.setValueAtTime(freq,t);
o.frequency.exponentialRampToValueAtTime(freq*.35,t+dur);
g.gain.setValueAtTime(gainV,t);
g.gain.exponentialRampToValueAtTime(.001,t+dur);
o.connect(g).connect(actx.destination); o.start(t); o.stop(t+dur+.05);
}
const roles=['ships production AI.','runs the demo.',
'owns the customer relationship.',
'builds agentic workflows.'];
// ── the project this site is about ──────────────────────────
// classify → retrieve → draft → confidence → send | human_review
async function triage(ticket){
const category = await classify(ticket);
if(category === 'vague') return reactAgent(ticket); // tool use
const ctx = await retrieve(category, ticket); // Chroma RAG
const draft = await compose(ctx);
const conf = await selfEvaluate(draft); // 0.0 – 1.0
return conf >= 0.7 ? send(draft) : escalate(draft);
}
// Konami code → confetti + drum roll. you're welcome 🥁
const seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown',
'ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
</script>
</body>
</html>