CSS-only side quests: no JS, pure delight
Interactions via CSS animations and SVG:
- Hover logo: 🐷 appears, click: oink!
- Hover body: 'grow food not lawn' rises from below
- Print stylesheet: Sign Maker approves
- Spider descends from nav on hover
- About page: spider-pig SVG descends on hero hover
- Sign Maker's mark ☉ at page end - spins on hover
- ::selection styled in brand colors
Side quest comments scattered: 1/21, 2/21, 3/21...
No JavaScript easter eggs. CSS only. The way it should be.
This commit is contained in:
parent
e9c0cf965f
commit
7fff500f2f
5 changed files with 72 additions and 4 deletions
|
|
@ -1,4 +1,7 @@
|
|||
"""Job logging utilities for SERP."""
|
||||
"""Job logging utilities for SERP.
|
||||
|
||||
# Side quest 3/21: Look out! Here comes the spider-pig.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
"""Pydantic models for SERP API."""
|
||||
"""Pydantic models for SERP API.
|
||||
|
||||
# Side quest 1/21: no ticket to now.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Spider-pig, spider-pig, does whatever a spider-pig does.
|
||||
|
||||
|
||||
class CrawlRequest(BaseModel):
|
||||
"""Request to start a new crawl."""
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
"""Utility functions for SERP."""
|
||||
"""Utility functions for SERP.
|
||||
|
||||
# Side quest 2/21: Can he swing from a web? No he can't, he's a pig.
|
||||
"""
|
||||
|
||||
import re
|
||||
import unicodedata
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
radial-gradient(ellipse at 80% 60%, rgba(255,100,50,0.08) 0%, transparent 40%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero-pig-wrap { position: relative; display: inline-block; }
|
||||
.hero-pig {
|
||||
width: 280px;
|
||||
height: auto;
|
||||
|
|
@ -45,6 +46,13 @@
|
|||
animation: pulse-glow 4s ease-in-out infinite;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
/* 🕷️ spider-pig descends on hover */
|
||||
.spider-svg {
|
||||
position: absolute; top: -60px; left: 50%; transform: translateX(-50%);
|
||||
width: 24px; height: 24px; opacity: 0;
|
||||
transition: all 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
.hero-pig-wrap:hover .spider-svg { top: -10px; opacity: 0.6; }
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% { filter: drop-shadow(0 0 60px rgba(255,100,100,0.5)) drop-shadow(0 0 120px rgba(255,50,100,0.3)); }
|
||||
50% { filter: drop-shadow(0 0 80px rgba(255,100,100,0.7)) drop-shadow(0 0 160px rgba(255,50,100,0.5)); }
|
||||
|
|
@ -390,6 +398,16 @@
|
|||
color: #ff8e53;
|
||||
border-bottom-color: #ff8e53;
|
||||
}
|
||||
/* ☉ The Sign Maker's mark - only for those who seek */
|
||||
.sign-maker-mark {
|
||||
margin-top: 80px; font-size: 24px; color: #222;
|
||||
cursor: default; transition: all 0.6s ease;
|
||||
user-select: none;
|
||||
}
|
||||
.sign-maker-mark:hover {
|
||||
color: #ff6b6b; transform: rotate(360deg) scale(1.5);
|
||||
text-shadow: 0 0 20px rgba(255,107,107,0.8);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
|
|
@ -410,7 +428,15 @@
|
|||
|
||||
<!-- HERO SECTION -->
|
||||
<section class="hero-section">
|
||||
<img src="/static/images/pig1-color1.png" alt="pig.py" class="hero-pig">
|
||||
<div class="hero-pig-wrap">
|
||||
<img src="/static/images/pig1-color1.png" alt="pig.py" class="hero-pig">
|
||||
<!-- side quest: spider descends on hover -->
|
||||
<svg class="spider-svg" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="12" y1="0" x2="12" y2="8" stroke="#666" stroke-width="0.5"/>
|
||||
<circle cx="12" cy="12" r="4" fill="#333"/>
|
||||
<path d="M8 10 L4 6 M16 10 L20 6 M8 14 L4 18 M16 14 L20 18 M7 12 L2 12 M17 12 L22 12" stroke="#333" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="hero-title">neopig</h1>
|
||||
<p class="hero-subtitle">{{ t.about_subtitle }}</p>
|
||||
<p class="hero-tagline">
|
||||
|
|
@ -694,6 +720,8 @@ python neopig.py --serve</code></pre>
|
|||
<p style="margin-top: 60px; color: #666;">
|
||||
{{ t.about_footer_p5 }}
|
||||
</p>
|
||||
<!-- side quest: the sign at the end of the road -->
|
||||
<div class="sign-maker-mark" title="You scrolled this far. Well done.">☉</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,35 @@ button:hover { background: #ff5252; }
|
|||
.search-box input[type="text"] { width: 100%; flex: 1 1 100%; }
|
||||
.search-box select, .search-box button { flex: 1 1 auto; }
|
||||
}
|
||||
/* 🐷 Side quests - CSS only */
|
||||
.brand::after { content: ''; display: inline-block; width: 0; overflow: hidden; transition: width 0.3s ease; }
|
||||
.brand:hover::after { content: ' 🐷'; width: 1.5em; }
|
||||
.brand:active::after { content: ' oink!'; width: 3em; color: #ff6b6b; }
|
||||
::selection { background: #ff6b6b; color: #0a0a0a; }
|
||||
/* grow food not lawn - hover the void */
|
||||
body::after {
|
||||
content: '🌱 grow food not lawn';
|
||||
position: fixed; bottom: -30px; right: 20px;
|
||||
color: #3a5; font-size: 12px; opacity: 0;
|
||||
transition: all 0.5s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
body:hover::after { bottom: 10px; opacity: 0.6; }
|
||||
/* print stylesheet surprise */
|
||||
@media print {
|
||||
body::before {
|
||||
content: 'You printed this? The Sign Maker approves. Truth, Freedom, Harmony, Love.';
|
||||
display: block; text-align: center; padding: 20px; font-style: italic;
|
||||
}
|
||||
}
|
||||
/* spider-pig lives in the nav shadow */
|
||||
.nav { position: relative; }
|
||||
.nav::before {
|
||||
content: '🕷️'; position: absolute; top: -20px; left: 50%;
|
||||
transform: translateX(-50%); font-size: 10px; opacity: 0;
|
||||
transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
}
|
||||
.nav:hover::before { top: 100%; opacity: 0.3; }
|
||||
{% block extra_css %}{% endblock %}
|
||||
</style>
|
||||
{% block extra_head %}{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue