feat: unify code-like components with shared CodeWindow, fix blog re-render loop, and stabilize layouts
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🧪 QA (push) Failing after 1m2s
Build & Deploy / 🏗️ Build (push) Failing after 3m44s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-15 17:34:07 +01:00
parent 7c774f65bc
commit c1295546a6
32 changed files with 3293 additions and 1235 deletions

View File

@@ -61,7 +61,7 @@
@apply mb-1;
}
code:not([class*='language-']) {
code:not([class*="language-"]) {
@apply bg-slate-50 px-1.5 py-0.5 rounded-md font-mono text-[0.9em] text-slate-800 border border-slate-100;
}
@@ -86,7 +86,6 @@
/* Components - Tailwind utility classes */
@layer components {
/* Legacy hooks required by tests */
.file-example {
@apply w-full;
@@ -180,7 +179,8 @@
/* Buttons */
.btn {
@apply inline-flex items-center justify-center px-6 py-3 border border-slate-200 bg-white text-slate-600 font-sans font-bold text-sm uppercase tracking-widest rounded-full transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:border-slate-400 hover:text-slate-900 hover:bg-slate-50 hover:-translate-y-0.5 hover:shadow-xl hover:shadow-slate-100 active:translate-y-0 active:shadow-sm;
@apply inline-flex items-center justify-center px-6 py-3 border border-slate-200 bg-white text-slate-600 font-sans font-bold text-sm uppercase tracking-widest rounded-full transition-all duration-500 hover:border-slate-400 hover:text-slate-900 hover:bg-slate-50 hover:-translate-y-0.5 hover:shadow-xl hover:shadow-slate-100 active:translate-y-0 active:shadow-sm;
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-primary {
@@ -266,7 +266,9 @@
color: #1e293b;
border-color: #cbd5e1;
transform: translateY(-4px);
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
box-shadow:
0 20px 25px -5px rgb(0 0 0 / 0.1),
0 8px 10px -6px rgb(0 0 0 / 0.1);
}
/* Reduced motion support */
@@ -284,7 +286,6 @@
/* Print styles */
@media print {
.floating-back-to-top,
.reading-progress-bar {
display: none !important;
@@ -343,27 +344,43 @@
}
.highlighter-yellow {
background: linear-gradient(135deg, rgba(255, 235, 59, 0.95) 0%, rgba(255, 213, 79, 0.95) 100%);
background: linear-gradient(
135deg,
rgba(255, 235, 59, 0.95) 0%,
rgba(255, 213, 79, 0.95) 100%
);
color: #3f2f00;
}
.highlighter-pink {
background: linear-gradient(135deg, rgba(255, 167, 209, 0.95) 0%, rgba(255, 122, 175, 0.95) 100%);
background: linear-gradient(
135deg,
rgba(255, 167, 209, 0.95) 0%,
rgba(255, 122, 175, 0.95) 100%
);
color: #3f0018;
}
.highlighter-green {
background: linear-gradient(135deg, rgba(129, 199, 132, 0.95) 0%, rgba(102, 187, 106, 0.95) 100%);
background: linear-gradient(
135deg,
rgba(129, 199, 132, 0.95) 0%,
rgba(102, 187, 106, 0.95) 100%
);
color: #002f0a;
}
.highlighter-blue {
background: linear-gradient(135deg, rgba(226, 232, 240, 0.95) 0%, rgba(203, 213, 225, 0.95) 100%);
background: linear-gradient(
135deg,
rgba(226, 232, 240, 0.95) 0%,
rgba(203, 213, 225, 0.95) 100%
);
color: #0f172a;
}
.highlighter-tag:hover::before {
content: '';
content: "";
position: absolute;
inset: -2px;
background: inherit;
@@ -385,7 +402,7 @@
/* Marker Title Styles */
.marker-title::before {
content: '';
content: "";
position: absolute;
left: -0.15em;
right: -0.15em;
@@ -394,22 +411,23 @@
border-radius: 0.18em;
z-index: -1;
background:
linear-gradient(180deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0) 20%,
rgba(253, 230, 138, 0.70) 20%,
rgba(253, 230, 138, 0.70) 100%);
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0) 20%,
rgba(253, 230, 138, 0.7) 20%,
rgba(253, 230, 138, 0.7) 100%
);
transform-origin: left center;
transform:
rotate(calc((var(--marker-seed, 0) - 3) * 0.45deg)) skewX(calc((var(--marker-seed, 0) - 3) * -0.25deg));
transform: rotate(calc((var(--marker-seed, 0) - 3) * 0.45deg))
skewX(calc((var(--marker-seed, 0) - 3) * -0.25deg));
filter: saturate(1.05);
}
.marker-title::after {
content: '';
content: "";
position: absolute;
left: -0.18em;
right: -0.05em;
@@ -418,27 +436,28 @@
border-radius: 0.18em;
z-index: -1;
background:
linear-gradient(90deg,
rgba(253, 230, 138, 0.00) 0%,
rgba(253, 230, 138, 0.60) 8%,
rgba(253, 230, 138, 0.55) 60%,
rgba(253, 230, 138, 0.35) 100%);
background: linear-gradient(
90deg,
rgba(253, 230, 138, 0) 0%,
rgba(253, 230, 138, 0.6) 8%,
rgba(253, 230, 138, 0.55) 60%,
rgba(253, 230, 138, 0.35) 100%
);
opacity: 0.75;
mix-blend-mode: multiply;
transform:
rotate(calc((var(--marker-seed, 0) - 3) * 0.45deg)) translateY(0.02em);
transform: rotate(calc((var(--marker-seed, 0) - 3) * 0.45deg))
translateY(0.02em);
mask-image:
linear-gradient(180deg,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 1) 100%);
mask-image: linear-gradient(
180deg,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 1) 100%
);
}
@media (prefers-reduced-motion: no-preference) {
.post-link:hover .marker-title::before,
.post-link:hover .marker-title::after {
filter: saturate(1.08) contrast(1.02);
@@ -480,7 +499,7 @@
.mermaid-container .edgeLabel,
.mermaid-container .node text,
.mermaid-container tspan {
font-family: 'Inter', sans-serif !important;
font-family: "Inter", sans-serif !important;
fill: #334155 !important;
color: #334155 !important;
stroke: none !important;
@@ -532,7 +551,9 @@
}
.embed-wrapper:hover {
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
box-shadow:
0 4px 6px -1px rgb(0 0 0 / 0.1),
0 2px 4px -2px rgb(0 0 0 / 0.1);
border-color: #cbd5e1;
}
@@ -602,20 +623,22 @@
color: #475569;
}
.copy-btn[data-copied='true'] {
.copy-btn[data-copied="true"] {
color: #065f46;
background: rgba(16, 185, 129, 0.10);
background: rgba(16, 185, 129, 0.1);
border-color: rgba(16, 185, 129, 0.35);
}
/* Prism.js syntax highlighting - light, low-noise */
code[class*='language-'],
pre[class*='language-'],
pre:has(code[class*='language-']) {
code[class*="language-"],
pre[class*="language-"],
pre:has(code[class*="language-"]) {
color: #0f172a;
background: transparent;
text-shadow: none;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
font-family:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
font-size: 0.8125rem;
line-height: 1.65;
direction: ltr;
@@ -689,4 +712,269 @@ pre:has(code[class*='language-']) {
.token.important,
.token.variable {
color: #db2777;
}
}
/* ═══════════════════════════════════════════════
TECH AESTHETIC Animation Keyframes
═══════════════════════════════════════════════ */
/* Gradient Mesh Blob Animations */
@keyframes gradient-blob-1 {
0%,
100% {
transform: translate(0, 0) scale(1);
}
25% {
transform: translate(30px, -20px) scale(1.05);
}
50% {
transform: translate(-15px, 25px) scale(0.95);
}
75% {
transform: translate(20px, 15px) scale(1.02);
}
}
@keyframes gradient-blob-2 {
0%,
100% {
transform: translate(0, 0) scale(1);
}
33% {
transform: translate(-25px, 15px) scale(1.03);
}
66% {
transform: translate(20px, -20px) scale(0.97);
}
}
@keyframes gradient-blob-3 {
0%,
100% {
transform: translate(0, 0) scale(1);
}
20% {
transform: translate(15px, 10px) scale(1.06);
}
40% {
transform: translate(-10px, 20px) scale(0.98);
}
60% {
transform: translate(25px, -15px) scale(1.02);
}
80% {
transform: translate(-20px, -10px) scale(0.96);
}
}
/* Binary Stream Scroll */
@keyframes binary-scroll {
0% {
transform: translateY(-50%);
}
100% {
transform: translateY(0%);
}
}
/* Circuit Pulse (used for node glow effects) */
@keyframes circuit-pulse {
0%,
100% {
opacity: 0.2;
box-shadow: 0 0 0 0 rgba(148, 163, 184, 0);
}
50% {
opacity: 0.5;
box-shadow: 0 0 12px 2px rgba(148, 163, 184, 0.15);
}
}
/* Data Packet Flow */
@keyframes data-packet-flow {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100vw);
}
}
/* Tech Border Glow */
@keyframes border-trace {
0% {
background-position: 0% 50%;
}
100% {
background-position: 200% 50%;
}
}
/* Section Fade-In Glow */
@keyframes section-glow {
0% {
opacity: 0;
}
50% {
opacity: 0.08;
}
100% {
opacity: 0;
}
}
/* Tailwind-compatible animation classes */
.animate-gradient-blob-1 {
animation: gradient-blob-1 20s ease-in-out infinite;
}
.animate-gradient-blob-2 {
animation: gradient-blob-2 25s ease-in-out infinite;
}
.animate-gradient-blob-3 {
animation: gradient-blob-3 30s ease-in-out infinite;
}
.animate-circuit-pulse {
animation: circuit-pulse 3s ease-in-out infinite;
}
.animate-border-trace {
animation: border-trace 4s linear infinite;
}
/* Glassmorphism Utilities */
.glass {
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(226, 232, 240, 0.5);
}
.glass-subtle {
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
background: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(241, 245, 249, 0.8);
}
.glass-dark {
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(255, 255, 255, 0.05);
}
/* Tech Border animated gradient trace */
.tech-border {
position: relative;
}
.tech-border::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px;
background: linear-gradient(
90deg,
transparent 0%,
rgba(148, 163, 184, 0.3) 25%,
rgba(191, 206, 228, 0.2) 50%,
rgba(148, 163, 184, 0.3) 75%,
transparent 100%
);
background-size: 200% 100%;
animation: border-trace 4s linear infinite;
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
/* Noise texture overlay */
.noise-overlay::before {
content: "";
position: absolute;
inset: 0;
opacity: 0.02;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 1;
}
/* ═══════════════════════════════════════════════
ABSTRACT CIRCUIT Trace Pulse Animations
═══════════════════════════════════════════════ */
@keyframes tracePulse1 {
0% {
stroke-dashoffset: 1280;
}
100% {
stroke-dashoffset: 0;
}
}
@keyframes tracePulse2 {
0% {
stroke-dashoffset: 650;
}
100% {
stroke-dashoffset: 0;
}
}
@keyframes tracePulse3 {
0% {
stroke-dashoffset: 1280;
}
100% {
stroke-dashoffset: 0;
}
}
@keyframes tracePulse4 {
0% {
stroke-dashoffset: 440;
}
100% {
stroke-dashoffset: 0;
}
}
@keyframes junctionGlow {
0%,
100% {
opacity: 0.1;
}
50% {
opacity: 0.4;
}
}