This commit is contained in:
2026-01-13 00:00:22 +01:00
parent 38d0e7e0a0
commit 19081ec682
23 changed files with 5023 additions and 521 deletions

579
src/styles/global.css Normal file
View File

@@ -0,0 +1,579 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Medium-inspired clean reading experience */
@layer base {
html {
scroll-behavior: smooth;
}
body {
@apply bg-white text-slate-800 font-serif antialiased;
font-family: 'Georgia', 'Times New Roman', serif;
line-height: 1.75;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
@apply font-sans font-bold text-slate-900;
}
h1 {
@apply text-3xl md:text-4xl leading-tight mb-8;
font-family: 'Inter', sans-serif;
letter-spacing: -0.025em;
}
h2 {
@apply text-2xl md:text-3xl leading-tight mb-6 mt-12;
font-family: 'Inter', sans-serif;
letter-spacing: -0.025em;
}
h3 {
@apply text-xl md:text-2xl leading-tight mb-4 mt-8;
font-family: 'Inter', sans-serif;
letter-spacing: -0.025em;
}
h4 {
@apply text-lg md:text-xl leading-tight mb-3 mt-6;
font-family: 'Inter', sans-serif;
letter-spacing: -0.025em;
}
p {
@apply mb-6 text-base leading-relaxed text-slate-700;
}
.lead {
@apply text-xl md:text-2xl text-slate-600 mb-10 leading-relaxed;
font-weight: 400;
}
a {
@apply text-blue-600 hover:text-blue-800 transition-colors;
}
ul, ol {
@apply ml-6 mb-6;
}
li {
@apply mb-2;
}
code {
@apply bg-slate-100 px-1.5 py-0.5 rounded font-mono text-sm text-slate-700;
}
blockquote {
@apply border-l-4 border-slate-300 pl-6 italic text-slate-600 my-6;
}
/* Code formatting */
code {
@apply bg-slate-100 px-1.5 py-0.5 rounded font-mono text-sm text-slate-700;
}
/* Inline code */
:not(pre) > code {
@apply text-pink-600 bg-pink-50 border border-pink-200;
}
/* Code blocks */
pre {
@apply bg-slate-900 text-slate-100 p-4 rounded-lg overflow-x-auto my-6 border border-slate-700;
font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
font-size: 0.875rem;
line-height: 1.6;
}
pre code {
@apply bg-transparent text-slate-100 px-0 py-0 border-0;
font-family: inherit;
}
/* Syntax highlighting colors */
.token.comment { @apply text-slate-500 italic; }
.token.keyword { @apply text-purple-400 font-semibold; }
.token.string { @apply text-green-400; }
.token.number { @apply text-orange-400; }
.token.function { @apply text-blue-400; }
.token.operator { @apply text-slate-300; }
.token.punctuation { @apply text-slate-400; }
.token.class-name { @apply text-yellow-400 font-semibold; }
/* Line numbers wrapper */
.line-numbers {
counter-reset: line;
}
.line-numbers .line {
counter-increment: line;
position: relative;
padding-left: 2.5rem;
}
.line-numbers .line::before {
content: counter(line);
position: absolute;
left: 0;
width: 2rem;
text-align: right;
color: #64748b;
user-select: none;
}
/* Focus styles - Firefox compatible */
a:focus,
button:focus,
[tabindex]:focus,
.post-link:focus,
.highlighter-tag:focus,
.clap-button-top:focus,
.share-button-top:focus,
#back-btn-top:focus,
#back-btn-bottom:focus,
#back-to-top:focus,
input:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
}
/* Remove default outline in favor of custom styles */
a:focus-visible,
button:focus-visible,
input:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
/* High contrast mode support */
@media (prefers-contrast: high) {
a:focus,
button:focus,
input:focus {
outline: 3px solid #000;
outline-offset: 2px;
}
}
}
/* Medium-inspired components */
@layer components {
.container {
@apply max-w-4xl mx-auto px-6 py-10;
}
.wide-container {
@apply max-w-5xl mx-auto px-6 py-12;
}
.narrow-container {
@apply max-w-2xl mx-auto px-6 py-8;
}
/* Header - removed for single page design */
/* Blog post card - refined with better spacing */
.post-card {
@apply mb-12 last:mb-0;
}
.post-card h3 {
@apply text-xl font-semibold mb-3 hover:text-blue-600 transition-colors cursor-pointer;
font-weight: 600;
}
.post-meta {
@apply text-sm text-slate-500 font-sans mb-4;
}
.post-excerpt {
@apply text-slate-700 mb-5 leading-relaxed;
}
.post-tags {
@apply flex flex-wrap gap-2;
}
.tag {
@apply text-xs font-sans bg-slate-100 text-slate-700 px-2 py-1 rounded hover:bg-slate-200 transition-colors cursor-pointer;
}
.read-more {
@apply text-sm font-semibold text-blue-600 hover:text-blue-800 font-sans inline-flex items-center;
}
/* Article page */
.article-header {
@apply mb-10;
}
.article-title {
@apply text-4xl md:text-5xl font-bold mb-4;
}
.article-meta {
@apply text-sm text-slate-500 font-sans mb-6;
}
.article-content {
@apply text-lg leading-relaxed;
}
.article-content p {
@apply mb-7;
}
.article-content h2 {
@apply text-2xl font-bold mt-10 mb-4;
}
.article-content h3 {
@apply text-xl font-bold mt-8 mb-3;
}
.article-content ul,
.article-content ol {
@apply ml-6 mb-7;
}
.article-content li {
@apply mb-2;
}
.article-content blockquote {
@apply border-l-4 border-slate-400 pl-6 italic text-slate-600 my-8 text-xl;
}
/* Enhanced code blocks for articles */
.article-content pre {
@apply bg-slate-900 text-slate-100 p-5 rounded-lg overflow-x-auto my-6 border border-slate-700;
font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
font-size: 0.875rem;
line-height: 1.6;
position: relative;
}
.article-content pre code {
@apply bg-transparent px-0 py-0;
font-family: inherit;
white-space: pre;
display: block;
}
/* Line numbers for code blocks */
.article-content pre.line-numbers {
padding-left: 3.5rem;
}
.article-content pre.line-numbers::before {
content: attr(data-line-numbers);
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 2.5rem;
background: #1e293b;
color: #64748b;
text-align: right;
padding: 1.25rem 0.5rem 1.25rem 0;
font-family: inherit;
font-size: inherit;
line-height: 1.6;
border-right: 1px solid #334155;
user-select: none;
overflow: hidden;
}
/* Inline code in articles */
.article-content p code,
.article-content li code,
.article-content blockquote code {
@apply bg-slate-100 text-pink-600 px-1.5 py-0.5 rounded font-mono text-sm border border-pink-200;
}
/* Syntax highlighting classes */
.article-content .token.comment { @apply text-slate-500 italic; }
.article-content .token.keyword { @apply text-purple-400 font-semibold; }
.article-content .token.string { @apply text-green-400; }
.article-content .token.number { @apply text-orange-400; }
.article-content .token.function { @apply text-blue-400; }
.article-content .token.operator { @apply text-slate-300; }
.article-content .token.punctuation { @apply text-slate-400; }
.article-content .token.class-name { @apply text-yellow-400 font-semibold; }
.article-content .token.tag { @apply text-red-400; }
.article-content .token.attr-name { @apply text-purple-400; }
.article-content .token.attr-value { @apply text-green-400; }
/* Code language badge */
.article-content pre::after {
content: attr(data-language);
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: #334155;
color: #e2e8f0;
padding: 0.125rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
font-family: 'Inter', sans-serif;
}
/* About page sections */
.about-section {
@apply mb-10 pb-8 border-b border-slate-200 last:border-0;
}
.about-section h2 {
@apply text-2xl font-bold mb-4;
}
.about-list {
@apply space-y-2;
}
.about-list li {
@apply flex items-start;
}
.about-list li::before {
content: "→";
@apply mr-2 text-blue-600 font-bold;
}
/* Footer - removed for single page design */
/* Simple button */
.btn {
@apply inline-block px-5 py-2 bg-slate-900 text-white font-sans font-medium hover:bg-slate-700 transition-colors no-underline rounded;
}
/* Highlighter-style tags - lovely note-taking style */
.highlighter-tag {
@apply inline-block text-xs font-bold px-2 py-0.5 rounded cursor-pointer transition-all duration-200;
position: relative;
transform: rotate(-1deg);
box-shadow: 2px 2px 0 rgba(0,0,0,0.1);
}
.highlighter-yellow {
@apply bg-yellow-300 text-yellow-900;
background: linear-gradient(180deg, rgba(255,235,59,0.9) 0%, rgba(255,213,79,0.9) 100%);
}
.highlighter-yellow:hover {
transform: rotate(-2deg) scale(1.1);
box-shadow: 3px 3px 0 rgba(0,0,0,0.15);
}
.highlighter-pink {
@apply bg-pink-300 text-pink-900;
background: linear-gradient(180deg, rgba(255,167,209,0.9) 0%, rgba(255,122,175,0.9) 100%);
}
.highlighter-pink:hover {
transform: rotate(-2deg) scale(1.1);
box-shadow: 3px 3px 0 rgba(0,0,0,0.15);
}
.highlighter-green {
@apply bg-green-300 text-green-900;
background: linear-gradient(180deg, rgba(129,199,132,0.9) 0%, rgba(102,187,106,0.9) 100%);
}
.highlighter-green:hover {
transform: rotate(-2deg) scale(1.1);
box-shadow: 3px 3px 0 rgba(0,0,0,0.15);
}
.highlighter-blue {
@apply bg-blue-300 text-blue-900;
background: linear-gradient(180deg, rgba(100,181,246,0.9) 0%, rgba(66,165,245,0.9) 100%);
}
.highlighter-blue:hover {
transform: rotate(-2deg) scale(1.1);
box-shadow: 3px 3px 0 rgba(0,0,0,0.15);
}
/* Scribble underline for emphasis */
.scribble-emphasis {
position: relative;
display: inline-block;
font-weight: 600;
}
.scribble-emphasis::after {
content: '';
position: absolute;
bottom: -2px;
left: -1px;
right: -1px;
height: 7px;
background: url("data:image/svg+xml,%3Csvg width='40' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 4 Q10 2, 20 4 T38 4' stroke='%23FFEB3B' stroke-width='3' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x;
background-size: 40px 8px;
opacity: 0.7;
z-index: -1;
}
/* Sticky note effect */
.sticky-note {
@apply p-4 rounded shadow-sm border;
background: linear-gradient(135deg, #fff9c4 0%, #fff59d 100%);
border-color: #f9a825;
transform: rotate(-0.5deg);
box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
}
.sticky-note:hover {
transform: rotate(0deg) scale(1.02);
box-shadow: 3px 3px 8px rgba(0,0,0,0.15);
}
/* Handwritten style */
.handwritten {
font-family: 'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', cursive;
font-weight: 500;
letter-spacing: -0.3px;
}
/* Search box styling */
.search-box {
@apply w-full px-4 py-3 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-blue-400 transition-colors;
background: rgba(255,255,255,0.9);
backdrop-filter: blur(10px);
}
.search-box::placeholder {
@apply text-slate-400;
}
/* Tag cloud */
.tag-cloud {
@apply flex flex-wrap gap-2 items-center;
}
/* Empty state */
.empty-state {
@apply text-center py-12 text-slate-500;
}
.empty-state svg {
@apply mx-auto mb-4 text-slate-300;
}
/* Line clamp utility for text truncation */
.line-clamp-3 {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Subtle gradient backgrounds */
.subtle-gradient {
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(248,250,252,0.1) 100%);
}
/* Enhanced focus states */
.focus-ring {
@apply focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white;
}
/* Reading progress indicator */
.reading-progress {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px;
background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%);
transform-origin: left;
z-index: 50;
}
/* Smooth animations */
.animate-fade-in {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Enhanced typography for better readability */
.text-balance {
text-wrap: balance;
}
/* Subtle shadow variations */
.shadow-soft {
box-shadow: 0 2px 8px rgba(0,0,0,0.04), 0 1px 3px rgba(0,0,0,0.08);
}
.shadow-hover {
box-shadow: 0 4px 16px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.12);
}
/* Improved button styles */
.btn-primary {
@apply bg-blue-600 text-white font-sans font-medium px-6 py-3 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all duration-200;
}
.btn-secondary {
@apply bg-white text-slate-700 font-sans font-medium px-6 py-3 rounded-lg border border-slate-200 hover:bg-slate-50 focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 transition-all duration-200;
}
/* Status indicators */
.status-indicator {
@apply inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-medium;
}
.status-published {
@apply bg-green-100 text-green-800;
}
.status-draft {
@apply bg-yellow-100 text-yellow-800;
}
/* Responsive grid improvements */
.grid-responsive {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* Better spacing utilities */
.space-y-fluid > * + * {
margin-top: clamp(1rem, 2vw, 2rem);
}
/* Enhanced link styles */
.link-enhanced {
@apply text-blue-600 hover:text-blue-800 transition-colors duration-200 relative;
}
.link-enhanced::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 0;
height: 2px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
transition: width 0.3s ease;
}
.link-enhanced:hover::after {
width: 100%;
}
}