This is a submission for the DEV April Fools Challenge
What I Built
The Vision
In a world dominated by “optimized” and “SEO-friendly” portfolios, I’ve discovered that the most significant obstacle to career success lies in how we’re perceived. To address this, I’ve created the Zero-Knowledge Professionalism Protocol. This portfolio doesn’t merely showcase my work; it actively safeguards it from human scrutiny. It’s the first portfolio designed to alleviate career anxiety by ensuring that no one can actually read my resume.
Best Ode to Larry Masinter: The HTTP 418 Philosophy
My entire build is a love letter to RFC 2324. While others build "Coffee Makers" (functional sites), I have built a Teapot.
The 418 Mental Model: The site follows the logic of the "I'm a Teapot" error—it understands the request to be a portfolio. Still, it refuses to function as one because it is fundamentally something else: a digital headache.
The Contact Form: I’ve replaced the traditional contact button with a "Brewing Status" indicator. If you try to reach out, the site returns a 418: Short and Stout error, because my skills are currently steeping.
Best Google AI Usage: The Gemini Disappointment Engine
I’ve harnessed Google AI (Gemini) not to assist the user, but to actively discourage them.
Inefficiency Architecting: I prompted Gemini to identify the most inefficient and high-friction methods for presenting a resume that still technically passes a lighthouse audit. It suggested the “Blur-to-View” project cards and the “Hyper-Speed Skills” list.
The AI Endorsement: I used Gemini to provide a "professional" testimonial, which I’ve included in the footer. Even the AI thinks this is a masterpiece of digital obstruction.
"I rate this 418/5 stars—it is truly the 'Teapot' of resumes." — Gemini AI
Demo
Code
Markdown
{### [AGENT_LOG]: Gemini AI Brainstorming Session
> **User Prompt:** "How can I make a portfolio that actively hides my identity?"
> **Gemini Thought Process:** > - Scanning for UX Best Practices... [REJECTED]
> - Initiating 'Chaos Consultant' Mode... [ACTIVE]
> - Calculating maximum eye strain... [COMPLETE]
>
> **Gemini Suggestion:** "Implement 'The Hero Smudge.' Use `text-shadow` to make your bio look like a literal smudge on the user's screen. If they can't see you, they can't judge you."}
HTML
{ <main>
<!-- A greeting that is technically there, but hidden. Use color: transparent; with text-shadow: 0 0 5px rgba(0,0,0,0.5); to make it look like a blurry smudge.-->
<section id="hero">
<div class="trophy">
<img
src="images/trophy1.jpg"
alt="A trophy image that is only visible when you squint at it"
width="100px"
height="100px"
/>
</div>
<h2>All About Me</h2>
<p>
Welcome to my passive aggressive portfolio. My name is Angella. I'm
not sure why you're here, but I guess you're looking for some of my
work or something. Well, I have a lot of experience in various fields,
but I'm not going to brag about it. Just take a look at my projects
and see for yourself.
</p>
</section>
<!-- Images that only appear when you are not looking at them. Use filter: blur(10px); on normal state and filter: blur(0); on :active (click and hold) only.-->
<section id="project-cards">
<h2 class="projects">My Projects</h2>
<div class="card-grid">
<article class="card">
<figure>
<img
src="images/musicapp.jpeg"
alt="A music app image for project card 1"
/>
<figcaption>Music/Search/Play App</figcaption>
</figure>
<div class="card-content">
<h3>Music/Search/Play App</h3>
<p>
A YouTube Music Search App that allows users to search for their
favorite songs and play them directly from the app. But I'm sure
you wouldn't be able to figure it out.
</p>
<a
href="https://wdv339-spotify-pp3.onrender.com/"
class="btn"
target="_blank"
rel="noopener noreferrer"
>View Project</a
>
</div>
<footer>
<time datetime="2026-04-07">April 7, 2026</time>
</footer>
</article>
<article class="card">
<figure>
<img
src="images/todo.jpeg"
alt="A todo app image for project card 2"
/>
<figcaption>Todo App</figcaption>
</figure>
<div class="card-content">
<h3>Todo App</h3>
<p>
A simple yet effective todo list application to help you stay
organized. But I'm sure you would find it too easy.
</p>
<a
href="https://github.com/angel33la/todo-mern-app"
class="btn"
target="_blank"
rel="noopener noreferrer"
>View Project</a
>
</div>
<footer>
<time datetime="2025-11-10"> November 10, 2025</time>
</footer>
</article>
<article class="card">
<figure>
<img
src="images/memorylane.png"
alt="A memory lane website image for project card 3"
/>
<figcaption>Memory Lane Website</figcaption>
</figure>
<div class="card-content">
<h3>Memory Lane Website</h3>
<p>
A nostalgic website that takes you on a journey through my blog
posts. But I'm sure you would find it too simple.
</p>
<a
href="https://angel33la.github.io/memory-lane/"
class="btn"
target="_blank"
rel="noopener noreferrer"
>View Project</a
>
</div>
<footer>
<time datetime="2025-11-22">November 22, 2025</time>
</footer>
</article>
</div>
</section>
<!-- A scrolling list that moves too fast to read. A simple marquee effect or CSS animation set to 0.1s duration. -->
<section id="skills" class="skills">
<h2>My Skillset</h2>
<p>
Here are some of the skills I've developed over the years. But don't
expect me to list them all, I'm not that kind of person.
</p>
<div
class="skills-marquee glitch-text"
aria-label="Scrolling skills list"
>
<div class="skills-row left">
<ul class="skills-track">
<li>
HTML: A skill that I mastered effortlessly. But I guess you
would struggle with it.
</li>
<li>
CSS: A skill that I picked up in no time. But I'm sure you would
take ages to learn it.
</li>
<li>
JavaScript: A skill that I excel at without even trying. But I'm
sure you would find it difficult.
</li>
<li aria-hidden="true">
HTML: A skill that I mastered effortlessly. But I guess you
would struggle with it.
</li>
<li aria-hidden="true">
CSS: A skill that I picked up in no time. But I'm sure you would
take ages to learn it.
</li>
<li aria-hidden="true">
JavaScript: A skill that I excel at without even trying. But I'm
sure you would find it difficult.
</li>
</ul>
</div>
<div class="skills-row right">
<ul class="skills-track">
<li>
React: A skill that I mastered in a flash. But I'm sure you
would find it overwhelming.
</li>
<li>
Node.js: A skill that I picked up with ease. But I'm sure you
would find it confusing.
</li>
<li>
MongoDB: A skill that I learned in no time. But I'm sure you
would find it complicated.
</li>
<li aria-hidden="true">
React: A skill that I mastered in a flash. But I'm sure you
would find it overwhelming.
</li>
<li aria-hidden="true">
Node.js: A skill that I picked up with ease. But I'm sure you
would find it confusing.
</li>
<li aria-hidden="true">
MongoDB: A skill that I learned in no time. But I'm sure you
would find it complicated.
</li>
</ul>
</div>
</div>
</section>
</main>
<!-- A "Copyright" notice that claims ownership of the user's mouse. Use cursor: none; in the footer area so the user's mouse disappears. -->
<footer id="contact">
<h2>Contact Me</h2>
<p>
Reach out to me if you think you can handle working with someone as
<strike>amazing</strike> FUN as me. But I doubt you can.
</p>
<button class="scared-button">Contact Me (If You Can!)</button>
<p class="scared-button-response" aria-live="polite"></p>
</footer>}
CSS
{/* Container for the overall layout */
body {
font-family: "Roboto",
sans-serif;
padding: 40px;
background-color: #00ffee;
margin: 0;
}
/* Header styling */
header {
text-align: center;
margin-bottom: 100px;
}
header h1 {
font-family: "Major Mono Display",
monospace;
font-weight: 400;
font-style: normal;
font-size: 3rem;
color: #600078;
margin: 0;
}
header li {
display: inline-block;
margin: 0 15px;
}
header a {
text-decoration: none;
color: #fd00a4;
font-weight: bold;
transition: color 0.2s;
}
header a:hover {
color: #600078;
}
/* Hero Section */
#hero {
color: transparent;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
text-align: center;
margin-bottom: 100px;
position: relative;
overflow: hidden;
min-height: 640px;
}
#hero h2 {
color: #fd0094;
}
#hero p {
max-width: 500px;
margin: 0 auto;
padding: 0 12px;
font-size: 2rem;
line-height: 1.7;
white-space: normal;
transform: none;
animation: none;
}
.trophy {
z-index: 999;
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%) rotate(-10deg);
opacity: 0.35;
pointer-events: none;
}
.trophy img {
width: min(520px, 68vw);
height: auto;
max-width: 100%;
}
h2 {
font-family: "Major Mono Display",
monospace;
font-weight: 400;
font-style: normal;
font-size: 2.75rem;
margin-bottom: 100px;
color: #600078;
}
.projects {
margin-top: 60px;
margin-bottom: 90px;
text-align: center;
}
/* 1. Grid Container Setup */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
/* The magic line! */
gap: 30px;
/* Space between cards */
max-width: 1200px;
/* Limits the grid width on huge screens */
margin: 0 auto;
/* Centers the whole grid */
}
/* 2. Individual Card Styling */
.card {
background: #fff;
border-radius: 12px;
/* Smooth corners */
overflow: hidden;
/* Clips the image and content to the corners */
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
/* Soft shadow */
transition: all 0.3s ease;
/* Smooth hover transition */
display: flex;
flex-direction: column;
/* Vertical stacks content inside card */
}
/* Hover effect */
.card:hover {
transform: translateY(-8px);
/* Lift the card */
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
/* Deepen shadow */
}
/* 3. Image (Figure) Styling */
.card figure {
margin: 0;
/* Important: removes default margin */
padding: 0;
width: 100%;
}
.card img {
width: 100%;
height: 200px;
/* Fixed height for consistent cards */
object-fit: cover;
/* Crops the image rather than stretching it */
display: block;
filter: blur(10px);
/* Initial blur for the image */
transition: filter 0.3s ease;
}
.card img:hover {
filter: blur(0);
/* Clear the blur on hover */
}
.card img:active {
filter: blur(0);
/* Clear the blur on click */
}
.card figcaption {
font-size: 0.8rem;
color: #777;
padding: 5px 15px;
background-color: #f9f9f9;
}
/* 4. Content Area Styling */
.card-content {
padding: 20px;
flex-grow: 1;
/* Pushes footer to the bottom of the card */
display: flex;
flex-direction: column;
}
.card-content h3 {
margin-top: 0;
color: #fd00a4;
font-size: 1.4rem;
}
.card-content p {
color: #666;
margin-bottom: 25px;
flex-grow: 1;
/* Makes the paragraph take up available space */
}
/* 5. Button and Footer Styling */
.btn {
text-decoration: none;
background-color: #00ff40;
color: #600078;
padding: 10px 20px;
border-radius: 6px;
font-weight: bold;
text-align: center;
margin-top: auto;
/* Ensures button is at the bottom of the content area */
transition: background 0.2s;
}
.btn:hover {
background-color: #fd00a4;
}
.card footer {
border-top: 1px solid #eee;
padding: 15px 20px;
background-color: #111;
font-size: 0.85rem;
color: #ffc400;
}
/* Skills list styling */
.skills {
margin-top: 60px;
margin-bottom: 90px;
text-align: center;
}
.skills-marquee {
width: 100%;
}
.skills-row {
overflow: hidden;
width: 100%;
margin: 14px 0;
}
.skills-track {
list-style: none;
margin: 0;
padding: 0;
width: max-content;
display: flex;
gap: 10px;
white-space: nowrap;
}
.skills-row.left .skills-track {
animation: scroll-left .10s linear infinite;
}
.skills-row.right .skills-track {
animation: scroll-right .10s linear infinite;
}
.skills-track li {
flex: 0 0 auto;
padding: 10px 15px;
background-color: #00ff40;
border-radius: 5px;
color: #600078;
}
@keyframes scroll-left {
from {
transform: translateX(0);
}
to {
transform: translateX(-50%);
}
}
@keyframes scroll-right {
from {
transform: translateX(-50%);
}
to {
transform: translateX(0);
}
}
.glitch-text {
font-size: .96rem;
font-weight: bold;
position: relative;
display: inline-block;
animation: jitter 0.1s infinite;
}
@keyframes jitter {
0% {
transform: translate(0, 0);
}
25% {
transform: translate(-2px, 2px) skew(5deg);
color: #ff00c1;
}
50% {
transform: translate(2px, -2px) skew(-5deg);
color: #00fff9;
}
75% {
transform: translate(-1px, -1px);
}
100% {
transform: translate(1px, 1px);
}
}
/* Every few seconds, it just disappears */
.glitch-text:nth-child(even) {
animation: jitter 0.1s infinite, blink 3s step-end infinite;
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
/* Footer styling */
footer {
text-align: center;
margin-top: 60px;
color: #333;
font-size: 1.2rem;
}
footer p {
margin-bottom: 20px;
}
/* Contact Form Button */
.scared-button {
font-size: 1rem;
transition: all 0.2s ease;
padding: 10px 20px;
background-color: #fd00a4;
color: white;
border: none;
cursor: pointer;
border-radius: 5px;
}
/* When the mouse hovers over it, it jumps away! */
.scared-button:hover:not(.is-caught) {
transform: translate(24px, -14px) rotate(6deg);
background-color: #ff0000;
}
.scared-button:active,
.scared-button:focus-visible {
transform: translate(0, 0) rotate(0deg);
outline: 2px solid #600078;
outline-offset: 3px;
}
.scared-button.is-caught {
transform: translate(0, 0) rotate(0deg);
background-color: #fd00a4;
}
.scared-button-response {
min-height: 0;
margin: 16px auto 0;
max-width: 540px;
padding: 0;
border-radius: 10px;
border: 2px solid transparent;
background: transparent;
color: #600078;
font-size: 0;
font-weight: 800;
line-height: 1.35;
opacity: 0;
transform: translateY(8px) scale(0.98);
transition: opacity 0.2s ease, transform 0.2s ease;
}
.scared-button-response.is-visible {
padding: 14px 16px;
border-color: #600078;
background: #fff7cc;
font-size: 1.15rem;
text-transform: uppercase;
letter-spacing: 0.03em;
opacity: 1;
transform: translateY(0) scale(1);
box-shadow: 0 8px 20px rgba(96, 0, 120, 0.2);
animation: teapot-pop 0.32s ease;
}
@keyframes teapot-pop {
0% {
transform: translateY(10px) scale(0.94);
}
60% {
transform: translateY(-2px) scale(1.02);
}
100% {
transform: translateY(0) scale(1);
}
}```
{% endraw %}
JavaScript
{% raw %}
``` <script>
const scaredButton = document.querySelector(".scared-button");
const responseLabel = document.querySelector(".scared-button-response");
let resetTimer;
if (scaredButton && responseLabel) {
scaredButton.addEventListener("click", async () => {
clearTimeout(resetTimer);
scaredButton.classList.add("is-caught");
const teapotResponse = new Response(
JSON.stringify({ message: "I'm a teapot. Try coffee elsewhere." }),
{
status: 418,
headers: { "Content-Type": "application/json" },
},
);
const payload = await teapotResponse.json();
responseLabel.textContent = `${teapotResponse.status} ${payload.message}`;
responseLabel.classList.remove("is-visible");
void responseLabel.offsetWidth;
responseLabel.classList.add("is-visible");
resetTimer = setTimeout(() => {
responseLabel.classList.remove("is-visible");
responseLabel.textContent = "";
scaredButton.classList.remove("is-caught");
}, 60000);
});
}
</script>}
How I Built It
The Useless Toolkit
I used HTML, CSS, and JavaScript.
| Feature | Technical Implementation | Why it’s Useless |
|---|---|---|
| Hero Smudge | text-shadow: 0 0 8px rgba(0,0,0,0.8); color: transparent; |
Makes my bio look like a fingerprint smudge on the user's monitor. |
| Schrödinger's Projects | filter: blur(15px); |
Projects only become clear if you click and hold. If you let go, the "knowledge" disappears. |
| Mach-1 Skills | animation: scroll 0.1s linear infinite; |
A list of skills that moves so fast it has been known to cause mild vertigo. |
| HTCPCP Contact Form | event.preventDefault(); alert("Error 418: I am a teapot"); |
It prevents recruiters from emailing me, ensuring my tea stays hot, and my calendar stays empty. |
{% agent_session brainstorm-v0.418-logic-final planning %}
I treated Gemini as a Reverse-Turing Test. I asked it to identify the least efficient and most high-friction methods for presenting a resume. By following its 'bad' advice on the Hero Smudge and Mach-1 Skills, I ensured the project achieved an anti-value level a human alone couldn't conceive.
During development, I prompted Gemini to help with a coffee-ordering feature. True to the HTTP 418 protocol, the AI suggested I build a 'Brewing Status' indicator that permanently returns an error, because 'a teapot has no business serving coffee, or employment data.'
Prize Category
I am officially submitting for:
- Best Google AI Usage: For using Gemini to architect intentional UX failures.
- Best Ode to Larry Masinter: For a portfolio that identifies as a teapot and returns 418 errors for all professional inquiries.
- Anti-Value Proposition: For creating a resume that actually makes it harder to get a job."
Building a portfolio that works is easy. Building one that actively fights for its right to be a teapot is a journey. Through this collaboration with Google AI, I’ve realized that code doesn't always have to be a 'solution'—sometimes, it can just be a beautifully rendered 418 Error. I hope this project inspires other developers to stop being so useful and start being more like a teapot: short, stout, and completely unwilling to brew coffee.
Top comments (0)