680 lines
13 KiB
CSS
680 lines
13 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/* Base styles - Tailwind only */
|
|
@layer base {
|
|
html {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
body {
|
|
@apply bg-white text-slate-800 font-serif antialiased selection:bg-slate-900 selection:text-white;
|
|
line-height: 1.8;
|
|
}
|
|
|
|
/* Typography */
|
|
h1, h2, h3, h4, h5, h6 {
|
|
@apply font-sans font-bold text-slate-900;
|
|
}
|
|
|
|
h1 {
|
|
@apply text-4xl md:text-5xl leading-[1.1] mb-8 tracking-tight;
|
|
}
|
|
|
|
h2 {
|
|
@apply text-3xl md:text-4xl leading-[1.2] mb-6 mt-12 tracking-tight;
|
|
}
|
|
|
|
h3 {
|
|
@apply text-2xl md:text-3xl leading-[1.3] mb-4 mt-8 tracking-tight;
|
|
}
|
|
|
|
h4 {
|
|
@apply text-xl md:text-2xl leading-[1.4] mb-3 mt-6 tracking-tight;
|
|
}
|
|
|
|
p {
|
|
@apply mb-4 text-base leading-relaxed text-slate-700;
|
|
}
|
|
|
|
.lead {
|
|
@apply text-xl md:text-2xl text-slate-600 mb-6 leading-relaxed;
|
|
font-weight: 400;
|
|
}
|
|
|
|
a {
|
|
@apply text-slate-900 hover:text-slate-700 transition-colors no-underline;
|
|
}
|
|
|
|
ul, ol {
|
|
@apply ml-5 mb-4;
|
|
}
|
|
|
|
li {
|
|
@apply mb-1;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
blockquote {
|
|
@apply border-l-4 border-slate-900 pl-6 italic text-slate-700 my-8 text-xl md:text-2xl font-serif;
|
|
}
|
|
|
|
/* Focus states */
|
|
a:focus,
|
|
button:focus,
|
|
input:focus {
|
|
@apply outline-none ring-2 ring-slate-900 ring-offset-2 rounded-sm;
|
|
}
|
|
}
|
|
|
|
/* Components - Tailwind utility classes */
|
|
@layer components {
|
|
/* Legacy hooks required by tests */
|
|
.file-example {
|
|
@apply w-full;
|
|
}
|
|
|
|
.container {
|
|
@apply max-w-6xl mx-auto px-6 py-12;
|
|
}
|
|
|
|
.wide-container {
|
|
@apply max-w-7xl mx-auto px-6 py-16;
|
|
}
|
|
|
|
.narrow-container {
|
|
@apply max-w-4xl mx-auto px-6 py-10;
|
|
}
|
|
|
|
.highlighter-tag {
|
|
@apply inline-block text-[10px] uppercase tracking-wider font-bold px-3 py-1 rounded-full cursor-pointer transition-all duration-300;
|
|
position: relative;
|
|
}
|
|
|
|
.search-box {
|
|
@apply w-full px-6 py-4 border border-slate-200 rounded-2xl focus:outline-none focus:border-slate-400 transition-all duration-300;
|
|
background: rgba(255,255,255,0.9);
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
|
|
.search-box::placeholder {
|
|
@apply text-slate-400;
|
|
}
|
|
|
|
/* Blog post card */
|
|
.post-card {
|
|
@apply mb-8 last:mb-0;
|
|
}
|
|
|
|
.post-meta {
|
|
@apply text-xs text-slate-500 font-sans mb-2;
|
|
}
|
|
|
|
.post-excerpt {
|
|
@apply text-slate-700 mb-2 leading-relaxed;
|
|
}
|
|
|
|
.post-tags {
|
|
@apply flex flex-wrap gap-1;
|
|
}
|
|
|
|
/* Article page */
|
|
.article-header {
|
|
@apply mb-12;
|
|
}
|
|
|
|
.article-title {
|
|
@apply text-4xl md:text-5xl font-bold mb-3;
|
|
}
|
|
|
|
.article-meta {
|
|
@apply text-sm text-slate-500 font-sans mb-5;
|
|
}
|
|
|
|
.article-content {
|
|
@apply text-lg leading-relaxed;
|
|
}
|
|
|
|
.article-content p {
|
|
@apply mb-5;
|
|
}
|
|
|
|
.article-content h2 {
|
|
@apply text-2xl font-bold mt-8 mb-3;
|
|
}
|
|
|
|
.article-content h3 {
|
|
@apply text-xl font-bold mt-6 mb-2;
|
|
}
|
|
|
|
.article-content ul,
|
|
.article-content ol {
|
|
@apply ml-6 mb-5;
|
|
}
|
|
|
|
.article-content li {
|
|
@apply mb-1;
|
|
}
|
|
|
|
.article-content blockquote {
|
|
@apply border-l-2 border-slate-400 pl-4 italic text-slate-600 my-5 text-lg;
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
|
|
.btn-primary {
|
|
@apply border-slate-900 text-slate-900 hover:bg-slate-900 hover:text-white;
|
|
}
|
|
|
|
.btn-secondary {
|
|
@apply border-slate-200 text-slate-500 hover:border-slate-400 hover:text-slate-900;
|
|
}
|
|
|
|
/* Hide scrollbars */
|
|
.hide-scrollbar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.hide-scrollbar {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
/* Empty state */
|
|
.empty-state {
|
|
@apply text-center py-8 text-slate-500;
|
|
}
|
|
|
|
.empty-state svg {
|
|
@apply mx-auto mb-2 text-slate-300;
|
|
}
|
|
|
|
/* Line clamp utility */
|
|
.line-clamp-3 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Reading progress indicator */
|
|
.reading-progress-bar {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 1px;
|
|
background: #0f172a;
|
|
transform-origin: left;
|
|
transform: scaleX(0);
|
|
z-index: 100;
|
|
transition: transform 0.1s ease-out;
|
|
}
|
|
|
|
/* Floating back to top button */
|
|
.floating-back-to-top {
|
|
position: fixed;
|
|
bottom: 2rem;
|
|
right: 2rem;
|
|
width: 3rem;
|
|
height: 3rem;
|
|
background: white;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 9999px;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #64748b;
|
|
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
z-index: 50;
|
|
}
|
|
|
|
.floating-back-to-top.visible {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.floating-back-to-top:hover {
|
|
background: #f8fafc;
|
|
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);
|
|
}
|
|
|
|
/* Reduced motion support */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
html {
|
|
scroll-behavior: auto;
|
|
}
|
|
|
|
* {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
}
|
|
|
|
/* Print styles */
|
|
@media print {
|
|
.floating-back-to-top,
|
|
.reading-progress-bar {
|
|
display: none !important;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Additional global styles from BaseLayout */
|
|
|
|
/* Custom scrollbar */
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: #f1f5f9;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #cbd5e1;
|
|
border-radius: 4px;
|
|
transition: background 0.2s ease;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #94a3b8;
|
|
}
|
|
|
|
/* Selection color */
|
|
::selection {
|
|
background: #0f172a;
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* Tag Styles */
|
|
.highlighter-tag {
|
|
animation: tagPopIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
animation-delay: calc(var(--tag-index, 0) * 0.05s);
|
|
}
|
|
|
|
.highlighter-tag:hover {
|
|
@apply -translate-y-0.5 scale-105 shadow-lg shadow-slate-200;
|
|
}
|
|
|
|
@keyframes tagPopIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.8) translateY(10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1) translateY(0);
|
|
}
|
|
}
|
|
|
|
.highlighter-yellow {
|
|
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%);
|
|
color: #3f0018;
|
|
}
|
|
|
|
.highlighter-green {
|
|
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%);
|
|
color: #0f172a;
|
|
}
|
|
|
|
.highlighter-tag:hover::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: -2px;
|
|
background: inherit;
|
|
filter: blur(8px);
|
|
opacity: 0.4;
|
|
z-index: -1;
|
|
border-radius: inherit;
|
|
}
|
|
|
|
.highlighter-tag:active {
|
|
transform: rotate(-1deg) translateY(0) scale(0.98);
|
|
transition: transform 0.1s ease;
|
|
}
|
|
|
|
.highlighter-tag:focus {
|
|
@apply ring-2 ring-slate-900 ring-offset-2 -translate-y-0.5 scale-105;
|
|
}
|
|
|
|
/* Marker Title Styles */
|
|
.marker-title::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: -0.15em;
|
|
right: -0.15em;
|
|
bottom: 0.05em;
|
|
height: 0.62em;
|
|
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%
|
|
);
|
|
|
|
transform-origin: left center;
|
|
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: '';
|
|
position: absolute;
|
|
left: -0.18em;
|
|
right: -0.05em;
|
|
bottom: 0.05em;
|
|
height: 0.62em;
|
|
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%
|
|
);
|
|
|
|
opacity: 0.75;
|
|
mix-blend-mode: multiply;
|
|
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%
|
|
);
|
|
}
|
|
|
|
@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);
|
|
}
|
|
}
|
|
|
|
/* Mermaid Styles */
|
|
.mermaid-container svg {
|
|
width: 100% !important;
|
|
max-width: 100%;
|
|
height: auto;
|
|
display: block;
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
.mermaid-container rect,
|
|
.mermaid-container circle,
|
|
.mermaid-container ellipse,
|
|
.mermaid-container polygon,
|
|
.mermaid-container path,
|
|
.mermaid-container .actor,
|
|
.mermaid-container .node {
|
|
fill: white !important;
|
|
stroke: #cbd5e1 !important;
|
|
stroke-width: 1.5px !important;
|
|
}
|
|
|
|
.mermaid-container .edgePath .path,
|
|
.mermaid-container .messageLine0,
|
|
.mermaid-container .messageLine1,
|
|
.mermaid-container .flowchart-link {
|
|
stroke: #cbd5e1 !important;
|
|
stroke-width: 1.5px !important;
|
|
}
|
|
|
|
.mermaid-container text,
|
|
.mermaid-container .label,
|
|
.mermaid-container .labelText,
|
|
.mermaid-container .edgeLabel,
|
|
.mermaid-container .node text,
|
|
.mermaid-container tspan {
|
|
font-family: 'Inter', sans-serif !important;
|
|
fill: #334155 !important;
|
|
color: #334155 !important;
|
|
stroke: none !important;
|
|
font-size: 16px !important;
|
|
}
|
|
|
|
.mermaid-container .marker,
|
|
.mermaid-container marker path {
|
|
fill: #cbd5e1 !important;
|
|
stroke: #cbd5e1 !important;
|
|
}
|
|
|
|
/* Generic Embed Styles */
|
|
.generic-embed {
|
|
--max-width: 100%;
|
|
--border-radius: 24px;
|
|
--bg-color: #ffffff;
|
|
--border-color: #e2e8f0;
|
|
--shadow: none;
|
|
|
|
margin: 1.5rem 0;
|
|
width: 100%;
|
|
max-width: var(--max-width);
|
|
}
|
|
|
|
.embed-wrapper {
|
|
border-radius: var(--border-radius);
|
|
border: 1px solid var(--border-color);
|
|
background: var(--bg-color);
|
|
box-shadow: var(--shadow);
|
|
overflow: hidden;
|
|
transition: all 0.2s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.generic-embed[data-type="video"] .embed-wrapper {
|
|
aspect-ratio: 16/9;
|
|
height: 0;
|
|
padding-bottom: 56.25%; /* 16:9 */
|
|
}
|
|
|
|
.generic-embed[data-type="video"] .embed-wrapper iframe {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.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);
|
|
border-color: #cbd5e1;
|
|
}
|
|
|
|
.generic-embed[data-provider="youtube.com"] {
|
|
--bg-color: #000000;
|
|
}
|
|
|
|
.generic-embed[data-provider="vimeo.com"] {
|
|
--bg-color: #1a1a1a;
|
|
}
|
|
|
|
.generic-embed[data-provider="codepen.io"] {
|
|
--bg-color: #1e1e1e;
|
|
--border-color: #333;
|
|
}
|
|
|
|
.embed-fallback {
|
|
padding: 1.5rem;
|
|
background: #f8fafc;
|
|
border: 1px dashed #cbd5e1;
|
|
border-radius: var(--border-radius);
|
|
text-align: center;
|
|
}
|
|
|
|
.fallback-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
color: #64748b;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.fallback-link {
|
|
@apply text-slate-900 underline underline-offset-4;
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
margin-top: 0.25rem;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.fallback-link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.generic-embed {
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
.embed-fallback {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.embed-wrapper:hover {
|
|
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
}
|
|
}
|
|
|
|
/* File Example Styles */
|
|
[data-file-example] {
|
|
box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04);
|
|
}
|
|
|
|
.copy-btn,
|
|
.download-btn {
|
|
color: #475569;
|
|
}
|
|
|
|
.copy-btn[data-copied='true'] {
|
|
color: #065f46;
|
|
background: rgba(16, 185, 129, 0.10);
|
|
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-']) {
|
|
color: #0f172a;
|
|
background: transparent;
|
|
text-shadow: none;
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
font-size: 0.8125rem;
|
|
line-height: 1.65;
|
|
direction: ltr;
|
|
text-align: left;
|
|
white-space: pre;
|
|
word-spacing: normal;
|
|
word-break: normal;
|
|
tab-size: 2;
|
|
hyphens: none;
|
|
}
|
|
|
|
.token.comment,
|
|
.token.prolog,
|
|
.token.doctype,
|
|
.token.cdata {
|
|
color: #64748b;
|
|
font-style: italic;
|
|
}
|
|
|
|
.token.punctuation {
|
|
color: #94a3b8;
|
|
}
|
|
|
|
.token.operator {
|
|
color: #64748b;
|
|
}
|
|
|
|
.token.property,
|
|
.token.tag,
|
|
.token.constant,
|
|
.token.symbol,
|
|
.token.deleted {
|
|
color: #c2410c;
|
|
}
|
|
|
|
.token.boolean,
|
|
.token.number {
|
|
color: #a16207;
|
|
}
|
|
|
|
.token.selector,
|
|
.token.attr-name,
|
|
.token.string,
|
|
.token.char,
|
|
.token.builtin,
|
|
.token.inserted {
|
|
color: #059669;
|
|
}
|
|
|
|
.token.operator,
|
|
.token.entity,
|
|
.token.url,
|
|
.language-css .token.string,
|
|
.style .token.string {
|
|
color: #475569;
|
|
}
|
|
|
|
.token.atrule,
|
|
.token.attr-value,
|
|
.token.keyword {
|
|
color: #7c3aed;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.token.function,
|
|
.token.class-name {
|
|
color: #2563eb;
|
|
}
|
|
|
|
.token.regex,
|
|
.token.important,
|
|
.token.variable {
|
|
color: #db2777;
|
|
}
|