Files
pivoine.art/assets/css/main.css
T
valknar e57a15f733 polish: CSS-only hover transitions for nav and footer links
Adds translateY lift and smoother easing on hover for desktop nav,
footer nav, and social links. Active underline gets expo easing.
No markup changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 18:45:57 +02:00

627 lines
21 KiB
CSS

@import "tailwindcss";
/* ── Content sources ─────────────────────────────────────────── */
@source "../../layouts/**/*.html";
@source "../../content/**/*.md";
@source "../../assets/js/**/*.js";
/* ── Design tokens — sneaker drop culture ────────────────────── */
@theme {
/* Dark base — deep navy-black */
--color-void: #050510;
--color-ink: #09091A;
--color-concrete: #0F0F22;
--color-zinc: #1C1C38;
--color-smoke: #383860;
--color-fog: #6868A0;
--color-chalk: #B8B8E0;
--color-paper: #EEEEFF;
/* Gradient triad — pink → purple → ice */
--color-heat: #FF1A8C; /* hot pink — primary energy */
--color-pulse: #9B00FF; /* electric purple — mid */
--color-frost: #00C8FF; /* ice blue — cool accent */
--color-ember: #FF4455; /* alert red */
--color-lime: #AAFF00; /* acid lime — highlight */
/* Backward-compat aliases so existing templates still work */
--color-gold: var(--color-heat);
--color-gold-dim: #CC1570;
--color-hot: var(--color-heat);
--color-volt: var(--color-lime);
--color-ice: var(--color-frost);
--color-mist: var(--color-zinc);
--color-ash: var(--color-smoke);
--color-graphite: var(--color-concrete);
--color-charcoal: var(--color-ink);
/* ── Typography ─────────────────────────────────────────────── */
--font-display: "Bebas Neue", "Arial Black", sans-serif;
--font-body: "Barlow", system-ui, sans-serif;
--font-comic: "Unbounded", "Arial Black", sans-serif;
--font-mono: "Share Tech Mono", "Courier New", monospace;
/* ── Easing ─────────────────────────────────────────────────── */
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-sharp: cubic-bezier(0.4, 0, 0.6, 1);
--ease-cinematic: cubic-bezier(0.25, 0.46, 0.45, 0.94);
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}
/* ── Base ─────────────────────────────────────────────────────── */
@layer base {
*, *::before, *::after { box-sizing: border-box; }
[x-cloak] { display: none !important; }
html {
background-color: var(--color-void);
color: var(--color-paper);
font-family: var(--font-body);
font-size: 16px;
scroll-behavior: smooth;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body { min-height: 100vh; }
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-display);
font-weight: 400;
letter-spacing: 0.01em;
line-height: 0.92;
text-transform: uppercase;
}
a {
color: inherit;
text-decoration: none;
transition: color 0.2s var(--ease-sharp);
}
img, video { max-width: 100%; height: auto; display: block; }
::selection {
background-color: var(--color-heat);
color: #fff;
}
:focus-visible {
outline: 2px solid var(--color-heat);
outline-offset: 3px;
}
/* Gradient scrollbar */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: var(--color-ink); }
::-webkit-scrollbar-thumb { background: linear-gradient(180deg, var(--color-heat), var(--color-frost)); }
}
/* ── Components ───────────────────────────────────────────────── */
@layer components {
/* ── Gradient text ─────────────────────────────────────────── */
.text-gradient {
background: linear-gradient(90deg, var(--color-heat) 0%, var(--color-pulse) 50%, var(--color-frost) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.text-gradient-animated {
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost), var(--color-heat));
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: gradient-shift 5s ease infinite;
}
/* ── Gradient overlays ─────────────────────────────────────── */
.overlay-gradient {
background: linear-gradient(
to top,
rgba(5, 5, 16, 0.98) 0%,
rgba(5, 5, 16, 0.65) 40%,
rgba(5, 5, 16, 0.1) 70%,
transparent 100%
);
}
.overlay-gradient-hero {
background: linear-gradient(
155deg,
rgba(5, 5, 16, 0.1) 0%,
rgba(5, 5, 16, 0.5) 45%,
rgba(5, 5, 16, 0.97) 100%
);
}
/* ── Label — monospace spec-sheet text ─────────────────────── */
.label {
font-family: var(--font-mono);
font-size: 0.65rem;
font-weight: 400;
letter-spacing: 0.16em;
text-transform: uppercase;
}
/* ── Badge — parallelogram sticker ────────────────────────── */
.badge {
display: inline-flex;
align-items: center;
font-family: var(--font-mono);
font-size: 0.65rem;
font-weight: 400;
letter-spacing: 0.14em;
line-height: 1;
background: var(--color-heat);
color: #fff;
padding: 5px 16px;
text-transform: uppercase;
clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
transition: transform 0.15s var(--ease-bounce), filter 0.2s;
}
.badge:hover { transform: skewX(-4deg) scale(1.06); filter: brightness(1.2); }
a.badge, a > .badge { cursor: pointer; }
.badge-heat { background: var(--color-heat); color: #fff; }
.badge-pulse { background: var(--color-pulse); color: #fff; }
.badge-frost { background: var(--color-frost); color: var(--color-void); }
.badge-lime { background: var(--color-lime); color: var(--color-void); }
.badge-ember { background: var(--color-ember); color: #fff; }
/* Semantic aliases kept for template compat */
.badge-hot { background: var(--color-heat); color: #fff; }
.badge-volt { background: var(--color-lime); color: var(--color-void); }
.badge-ice { background: var(--color-frost); color: var(--color-void); }
.badge-gradient {
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost));
color: #fff;
}
.badge-outline {
background: transparent;
color: var(--color-heat);
border: 1.5px solid var(--color-heat);
padding: 4px 14px;
clip-path: none;
}
/* ── Btn — primary CTA with shimmer sweep ──────────────────── */
.btn {
display: inline-flex;
align-items: center;
gap: 0.5em;
font-family: var(--font-mono);
font-size: 0.7rem;
font-weight: 400;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 14px 28px;
background: var(--color-heat);
color: #fff;
position: relative;
overflow: hidden;
clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
transition:
box-shadow 0.25s var(--ease-sharp),
transform 0.2s var(--ease-bounce);
cursor: pointer;
}
/* shimmer sweep */
.btn::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
105deg,
transparent 35%,
rgba(255, 255, 255, 0.28) 50%,
transparent 65%
);
transform: translateX(-150%);
transition: transform 0.55s var(--ease-out-expo);
pointer-events: none;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(255, 26, 140, 0.5),
0 2px 8px rgba(155, 0, 255, 0.2);
}
.btn:hover::before { transform: translateX(200%); }
.btn:active { transform: translateY(0px); }
.btn-outline {
background: transparent;
border: 2px solid var(--color-heat);
color: var(--color-heat);
clip-path: none;
}
.btn-outline::before { display: none; }
.btn-outline:hover {
background: var(--color-heat);
color: #fff;
box-shadow: 0 8px 28px rgba(255, 26, 140, 0.4);
}
.btn-frost {
background: var(--color-frost);
color: var(--color-void);
}
.btn-frost:hover {
box-shadow: 0 8px 32px rgba(0, 200, 255, 0.45);
}
.btn-ghost {
background: transparent;
border: 1px solid var(--color-zinc);
color: var(--color-chalk);
clip-path: none;
}
.btn-ghost::before { display: none; }
.btn-ghost:hover {
border-color: var(--color-heat);
color: var(--color-heat);
box-shadow: none;
}
/* ── Card media — zoom on hover ────────────────────────────── */
.card-media {
overflow: hidden;
position: relative;
background-color: var(--color-concrete);
}
.card-media img,
.card-media video {
transition: transform 0.7s var(--ease-out-expo);
will-change: transform;
}
.card-media:hover img,
.card-media:hover video {
transform: scale(1.07);
}
/* ── Card — gradient border + graffiti offset shadow ──────── */
.card-comic {
position: relative;
border: 1.5px solid var(--color-zinc);
overflow: hidden;
transition:
border-color 0.2s var(--ease-sharp),
box-shadow 0.3s var(--ease-out-expo),
transform 0.25s var(--ease-out-expo);
}
/* gradient top bar */
.card-comic::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost));
opacity: 0;
transition: opacity 0.3s var(--ease-sharp);
z-index: 2;
}
.card-comic:hover {
border-color: rgba(255, 26, 140, 0.55);
transform: translateY(-5px) scale(1.005);
box-shadow:
0 0 0 1.5px rgba(255, 26, 140, 0.4),
0 20px 60px rgba(255, 26, 140, 0.18),
0 8px 24px rgba(155, 0, 255, 0.12),
6px 6px 0 rgba(255, 26, 140, 0.22);
}
.card-comic:hover::after { opacity: 1; }
/* ── Isometric triangle grid — 3 sets of lines at 0° / 60° / -60°
Creates an infinite isometric floor-tile illusion.
Colors: heat (horizontal) · frost (60°) · pulse (-60°)
────────────────────────────────────────────────────────────── */
.speed-lines {
background-image:
repeating-linear-gradient(
-55deg,
rgba(255, 26, 140, 0.14) 0, rgba(255, 26, 140, 0.14) 1px,
transparent 1px, transparent 22px,
rgba(0, 200, 255, 0.08) 22px, rgba(0, 200, 255, 0.08) 23px,
transparent 23px, transparent 44px
);
}
/* ── Diamond crosshatch ──────────────────────────────────── */
.halftone {
background-image:
repeating-linear-gradient(
45deg,
rgba(255, 26, 140, 0.07) 0, rgba(255, 26, 140, 0.07) 1px,
transparent 1px, transparent 24px
),
repeating-linear-gradient(
-45deg,
rgba(0, 200, 255, 0.05) 0, rgba(0, 200, 255, 0.05) 1px,
transparent 1px, transparent 24px
);
}
/* ── Spray dot halftone ──────────────────────────────────── */
.spray-bg {
background-image:
radial-gradient(circle, rgba(255, 26, 140, 0.09) 1px, transparent 1px),
radial-gradient(circle, rgba(0, 200, 255, 0.06) 1px, transparent 1px);
background-size: 18px 18px, 29px 29px;
background-position: 0 0, 9px 9px;
}
/* ── Noise overlay ──────────────────────────────────────────── */
.noise::after {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
background-size: 200px 200px;
pointer-events: none;
opacity: 0.25;
}
/* ── Graffiti tag — oversized hollow decorative text ────────── */
.graffiti-tag {
font-family: var(--font-display);
font-size: clamp(5rem, 14vw, 13rem);
letter-spacing: 0.02em;
line-height: 0.9;
color: transparent;
-webkit-text-stroke: 1px rgba(255, 26, 140, 0.12);
pointer-events: none;
user-select: none;
}
/* ── Marquee ticker ──────────────────────────────────────────── */
.marquee-track {
display: flex;
white-space: nowrap;
animation: marquee-scroll 32s linear infinite;
}
.marquee-track:hover { animation-play-state: paused; }
/* ── Section rules ──────────────────────────────────────────── */
.section-rule { border: none; border-top: 1px solid var(--color-zinc); }
.section-rule-electric {
border: none;
height: 1px;
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost));
opacity: 0.5;
}
/* Thin gradient divider */
.gradient-line {
height: 1px;
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost));
opacity: 0.35;
}
/* ── Neon glow utilities ────────────────────────────────────── */
.neon-heat { box-shadow: 0 0 24px rgba(255, 26, 140, 0.35), 0 0 60px rgba(255, 26, 140, 0.08); }
.neon-pulse { box-shadow: 0 0 24px rgba(155, 0, 255, 0.35), 0 0 60px rgba(155, 0, 255, 0.08); }
.neon-frost { box-shadow: 0 0 24px rgba( 0, 200, 255, 0.35), 0 0 60px rgba( 0, 200, 255, 0.08); }
/* ── Prose editorial ────────────────────────────────────────── */
.prose-editorial {
color: var(--color-chalk);
font-family: var(--font-body);
font-size: 1.0625rem;
line-height: 1.8;
max-width: 72ch;
}
.prose-editorial > * + * { margin-top: 1.6em; }
.prose-editorial strong { color: var(--color-paper); font-weight: 600; }
.prose-editorial em { font-style: italic; color: var(--color-paper); }
.prose-editorial a {
color: var(--color-heat);
border-bottom: 1px solid rgba(255, 26, 140, 0.35);
transition: border-color 0.2s, color 0.2s;
}
.prose-editorial a:hover {
color: var(--color-frost);
border-color: var(--color-frost);
}
.prose-editorial blockquote {
border-left: 3px solid var(--color-heat);
padding: 0.4em 0 0.4em 1.5rem;
margin: 2.5em 0;
color: var(--color-paper);
font-family: var(--font-display);
font-size: 1.5rem;
letter-spacing: 0.01em;
line-height: 1.1;
}
.prose-editorial blockquote p { margin: 0; }
.prose-editorial h2 {
font-size: 2.5rem;
color: var(--color-paper);
margin-top: 2.5em;
margin-bottom: 0.3em;
}
.prose-editorial h3 {
font-size: 1.8rem;
color: var(--color-paper);
margin-top: 2em;
margin-bottom: 0.3em;
}
.prose-editorial hr {
border: none;
height: 2px;
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), transparent);
margin: 3em 0;
width: 8rem;
}
.prose-editorial code {
font-family: var(--font-mono);
font-size: 0.875em;
background: var(--color-zinc);
padding: 0.1em 0.4em;
color: var(--color-frost);
}
.prose-editorial pre {
background: var(--color-ink);
border: 1px solid var(--color-zinc);
padding: 1.25rem 1.5rem;
overflow-x: auto;
}
.prose-editorial pre code {
background: none;
padding: 0;
font-size: 0.875rem;
color: var(--color-chalk);
}
/* ── HTMX progress bar ─────────────────────────────────────── */
#progress-bar {
position: fixed;
top: 0;
left: 0;
height: 4px;
background: linear-gradient(90deg, var(--color-heat), var(--color-pulse), var(--color-frost));
box-shadow: 0 0 12px rgba(255, 26, 140, 0.6);
z-index: 9999;
transition: width 0.4s var(--ease-out-expo), opacity 0.3s ease;
width: 0;
opacity: 0;
}
}
/* ── Utilities ────────────────────────────────────────────────── */
@layer utilities {
.gutter-x {
padding-left: clamp(1rem, 4vw, 3rem);
padding-right: clamp(1rem, 4vw, 3rem);
}
/* Aspect ratios */
.aspect-editorial { aspect-ratio: 3 / 4; }
.aspect-cinema { aspect-ratio: 21 / 9; }
.aspect-portrait { aspect-ratio: 2 / 3; }
/* Text wrapping */
.text-balance { text-wrap: balance; }
.text-pretty { text-wrap: pretty; }
/* Offset shadow */
.shadow-comic { box-shadow: 5px 5px 0 var(--color-heat); }
.shadow-comic-hot { box-shadow: 5px 5px 0 var(--color-heat); }
.shadow-comic-volt { box-shadow: 5px 5px 0 var(--color-lime); }
.shadow-comic-ice { box-shadow: 5px 5px 0 var(--color-frost); }
/* Text stroke — hollow headline */
.text-stroke-gold { -webkit-text-stroke: 1.5px var(--color-heat); color: transparent; }
.text-stroke-paper { -webkit-text-stroke: 1.5px var(--color-paper); color: transparent; }
.text-stroke-heat { -webkit-text-stroke: 1.5px var(--color-heat); color: transparent; }
.text-stroke-frost { -webkit-text-stroke: 1.5px var(--color-frost); color: transparent; }
/* Scrollbar hide */
.scrollbar-hide { scrollbar-width: none; -ms-overflow-style: none; }
.scrollbar-hide::-webkit-scrollbar { display: none; }
}
/* ── Keyframes ────────────────────────────────────────────────── */
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes marquee-scroll {
to { transform: translateX(-50%); }
}
@keyframes scroll-line {
0% { transform: translateY(-100%); opacity: 0; }
20% { opacity: 1; }
80% { opacity: 1; }
100% { transform: translateY(100%); opacity: 0; }
}
/* ── Logo glitch animation ───────────────────────────────────── */
@keyframes glitch-clip {
0%, 88%, 100% { transform: translate(0); clip-path: none; }
90% { transform: translate(-3px, 1px); clip-path: polygon(0 15%, 100% 15%, 100% 40%, 0 40%); }
92% { transform: translate(3px, -1px); clip-path: polygon(0 60%, 100% 60%, 100% 78%, 0 78%); }
94% { transform: translate(0); clip-path: none; }
}
.logo-glitch:hover {
animation: glitch-clip 2.5s steps(1) infinite;
}
/* ── Nav & footer link hover polish ─────────────────────────── */
/* Desktop nav links — lift + glow on hover */
header nav a.label {
transition: color 0.2s var(--ease-sharp), transform 0.2s var(--ease-out-expo);
}
header nav a.label:hover {
transform: translateY(-1px);
}
/* Active underline — smooth width via transition */
header nav a.label span {
transition: width 0.35s var(--ease-out-expo);
}
/* Footer links — subtle lift */
footer nav a.label {
transition: color 0.2s var(--ease-sharp), transform 0.2s var(--ease-out-expo);
}
footer nav a.label:hover {
transform: translateY(-1px);
}
/* Footer social links — icon nudges on hover */
footer nav a.label svg {
transition: transform 0.2s var(--ease-out-expo);
}
footer nav a.label:hover svg {
transform: translate(1px, -1px);
}
/* ── View Transitions ────────────────────────────────────────── */
::view-transition-old(main-content) {
animation: 160ms var(--ease-sharp) both page-out;
}
::view-transition-new(main-content) {
animation: 320ms var(--ease-out-expo) both page-in;
}
@keyframes page-out {
to { opacity: 0; transform: translateY(-10px); }
}
@keyframes page-in {
from { opacity: 0; transform: translateY(14px); }
}