diff options
74 files changed, 2956 insertions, 2557 deletions
diff --git a/assets/css/components/404.css b/assets/css/components/404.css new file mode 100644 index 0000000..d2c93b0 --- /dev/null +++ b/assets/css/components/404.css @@ -0,0 +1,247 @@ +/* 404.css */ + +.hero--404 { + position: relative; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 2rem; +} + +.content-wrapper { + display: grid; + grid-template-columns: 65% 35%; + gap: 3rem; + max-width: 1200px; + width: 100%; +} + +@media (max-width: 900px) { + .content-wrapper { + grid-template-columns: 1fr; + gap: 2rem; + } +} + +/* Quote Section */ +.quote-section { + margin-bottom: 3rem; + padding: 2rem; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 8px; + position: relative; +} + +.quote-mark { + font-size: 4rem; + color: var(--accent); + opacity: 0.3; + margin-bottom: -0.5rem; +} + +.quote-text { + font-family: var(--font-body); + font-size: 1.3rem; + font-weight: 400; + line-height: 1.8; + color: var(--text); + margin-bottom: 1rem; +} + +.quote-author { + font-family: var(--font-mono); + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--text-dim); +} + +/* Search Box */ +.search-box { + display: flex; + gap: 0; + margin-bottom: 3rem; + overflow: hidden; + border-radius: 4px; + border: 1px solid var(--border); +} + +.search-box input { + flex: 1; + padding: 0.75rem 1rem; + background: var(--surface); + border: none; + color: var(--text); + font-family: var(--font-mono); + font-size: 0.9rem; +} + +.search-box input::placeholder { + color: var(--text-dim); +} + +.search-box button { + padding: 0.75rem 1rem; + background: var(--accent); + border: none; + color: #000; + cursor: pointer; + transition: all var(--duration-base) ease; +} + +.search-box button:hover { + background: var(--accent2); +} + +/* Quick Nav */ +.quick-nav { + margin-bottom: 2rem; +} + +.quick-nav h3 { + font-size: 1rem; + margin-bottom: 1rem; +} + +.quick-nav ul { + list-style: none; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.quick-nav a { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 1rem; + border: 1px solid var(--border); + border-radius: 4px; + color: var(--text); + text-decoration: none; + transition: all var(--duration-base) ease; +} + +.quick-nav a:hover { + border-color: var(--accent); + background: rgba(168, 85, 247, 0.05); + padding-left: 1.25rem; +} + +/* Right Column */ +.hero-right-404 { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.recent-articles, +.terminal-widget { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; +} + +.recent-articles h3, +.terminal-widget .terminal-bar { + padding: 1rem; + background: var(--bg2); + font-size: 0.9rem; + font-weight: 700; +} + +.terminal-widget .terminal-bar { + display: flex; + gap: 0.75rem; + align-items: center; +} + +.terminal-dot { + width: 12px; + height: 12px; + border-radius: 50%; + display: inline-block; +} + +.recent-articles ul { + list-style: none; + padding: 0; + margin: 0; +} + +.recent-articles li { + border-bottom: 1px solid var(--border); + padding: 0; + margin: 0; +} + +.recent-articles li:last-child { + border-bottom: none; +} + +.article-link { + display: block; + padding: 0.75rem 1rem; + color: var(--text); + text-decoration: none; + font-size: 0.9rem; + transition: all var(--duration-base) ease; + border-left: 2px solid transparent; +} + +.article-link:hover { + background: rgba(168, 85, 247, 0.05); + border-left-color: var(--accent); + padding-left: 1.25rem; +} + +.article-link[data-type="tech"] { + color: var(--type-tech); +} + +.article-link[data-type="life"] { + color: var(--type-life); +} + +.article-link[data-type="quote"] { + color: var(--type-quote); +} + +.article-link[data-type="link"] { + color: var(--type-link); +} + +.article-link[data-type="photo"] { + color: var(--type-photo); +} + +.terminal-content { + padding: 1rem; + font-family: var(--font-mono); + font-size: 0.75rem; + color: var(--terminal-text, #c4d6e8); + line-height: 1.6; +} + +.terminal-content div { + white-space: pre-wrap; + word-wrap: break-word; +} + +.terminal-prompt { + color: var(--terminal-prompt, #00ff88); +} + +#terminal-files { + margin-top: 0.5rem; + color: var(--terminal-accent, #38bdf8); +} + +@media (prefers-reduced-motion: reduce) { + .article-link:hover { + padding-left: 1rem; + } +} diff --git a/assets/css/components/article-hero.css b/assets/css/components/article-hero.css new file mode 100644 index 0000000..cc9e180 --- /dev/null +++ b/assets/css/components/article-hero.css @@ -0,0 +1,225 @@ +/* article-hero.css */ + +.article-hero { + position: relative; + min-height: 400px; + background-size: cover; + background-position: center; + display: flex; + align-items: flex-end; + padding: 3rem 2rem; + margin-bottom: 2rem; +} + +.article-hero-overlay { + position: absolute; + inset: 0; + background: linear-gradient(180deg, rgba(6, 11, 16, 0.3) 0%, rgba(6, 11, 16, 0.8) 100%); +} + +.article-hero-content { + position: relative; + z-index: 2; + width: 100%; + max-width: var(--container-max); + margin: 0 auto; + padding: 0 1.5rem; +} + +.article-breadcrumb { + display: flex; + align-items: center; + gap: 0.5rem; + font-family: var(--font-mono); + font-size: 0.85rem; + color: var(--text-dim); + margin-bottom: 1.5rem; +} + +.article-breadcrumb a { + color: var(--accent); + text-decoration: none; + transition: color var(--duration-base) ease; +} + +.article-breadcrumb a:hover { + color: var(--accent2); +} + +.article-hero-content h1 { + font-size: clamp(2rem, 6vw, 3.5rem); + margin: 0; +} + +.article-meta-bar { + position: sticky; + top: 0; + z-index: 50; + background: rgba(6, 11, 16, 0.95); + backdrop-filter: blur(4px); + padding: 1rem 2rem; + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: space-between; +} + +.article-meta { + display: flex; + align-items: center; + gap: 1.5rem; + font-size: 0.85rem; + font-family: var(--font-mono); + text-transform: uppercase; + letter-spacing: 0.08em; +} + +.article-type-badge { + padding: 0.4rem 0.8rem; + border-radius: 4px; + font-weight: 600; + background: color-mix(in srgb, currentColor 15%, transparent); + border: 1px solid color-mix(in srgb, currentColor 30%, transparent); +} + +.article-type-badge.type-tech { + color: var(--type-tech); +} + +.article-type-badge.type-life { + color: var(--type-life); +} + +.article-type-badge.type-quote { + color: var(--type-quote); +} + +.article-type-badge.type-link { + color: var(--type-link); +} + +.article-type-badge.type-photo { + color: var(--type-photo); +} + +.article-date, +.article-read-time { + color: var(--text-dim); +} + +/* Article Body */ +.article-body { + padding: 2rem 1.5rem; + max-width: 800px; + margin: 0 auto; +} + +/* Article Footer Nav */ +.article-footer-nav { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + padding: 2rem; + max-width: var(--container-max); + margin: 3rem auto 0; + border-top: 1px solid var(--border); +} + +@media (max-width: 768px) { + .article-footer-nav { + grid-template-columns: 1fr; + } +} + +.nav-prev, +.nav-next { + padding: 1.5rem; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 4px; + text-decoration: none; + transition: all var(--duration-base) ease; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.nav-prev:hover, +.nav-next:hover { + border-color: var(--accent); + background: rgba(168, 85, 247, 0.05); + transform: translateY(-2px); +} + +.nav-label { + font-family: var(--font-mono); + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--accent); +} + +.nav-title { + font-family: var(--font-head); + font-size: 1.1rem; + font-weight: 700; + color: var(--text); +} + +/* Static Page */ +.page-hero { + position: relative; + height: 40vh; + background: linear-gradient(135deg, var(--accent), var(--accent2)); + display: flex; + align-items: flex-end; + padding: 3rem 2rem; + margin-bottom: 2rem; +} + +.page-hero-overlay { + position: absolute; + inset: 0; + background: rgba(6, 11, 16, 0.3); +} + +.page-hero-content { + position: relative; + z-index: 2; + width: 100%; + max-width: var(--container-max); + margin: 0 auto; + padding: 0 1.5rem; +} + +.page-hero-content h1 { + font-size: clamp(2rem, 5vw, 3rem); + margin: 0; +} + +.page-content { + padding: 2rem 1.5rem; +} + +.page-nav ul { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.page-nav a { + padding: 0.75rem 1rem; + border-radius: 4px; + transition: all var(--duration-base) ease; + display: block; +} + +.page-nav a:hover { + background: var(--surface); + padding-left: 1.25rem; +} + +.page-nav a.active { + font-weight: 700; + color: var(--accent); +} diff --git a/assets/css/components/card.css b/assets/css/components/card.css index f86c7bf..6a8cfaf 100644 --- a/assets/css/components/card.css +++ b/assets/css/components/card.css @@ -53,33 +53,33 @@ /* Type-specific badge colors */ .post-type-badge.tech { - background: color-mix(in srgb, var(--color-tech) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-tech) 30%, transparent); - color: var(--color-tech); + background: color-mix(in srgb, var(--type-tech) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--type-tech) 30%, transparent); + color: var(--type-tech); } .post-type-badge.life { - background: color-mix(in srgb, var(--color-life) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-life) 30%, transparent); - color: var(--color-life); + background: color-mix(in srgb, var(--type-life) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--type-life) 30%, transparent); + color: var(--type-life); } .post-type-badge.quote { - background: color-mix(in srgb, var(--color-quote) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-quote) 30%, transparent); - color: var(--color-quote); + background: color-mix(in srgb, var(--type-quote) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--type-quote) 30%, transparent); + color: var(--type-quote); } .post-type-badge.link { - background: color-mix(in srgb, var(--color-link) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-link) 30%, transparent); - color: var(--color-link); + background: color-mix(in srgb, var(--type-link) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--type-link) 30%, transparent); + color: var(--type-link); } .post-type-badge.photo { - background: color-mix(in srgb, var(--color-photo) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-photo) 30%, transparent); - color: var(--color-photo); + background: color-mix(in srgb, var(--type-photo) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--type-photo) 30%, transparent); + color: var(--type-photo); } .post-card-title { diff --git a/assets/css/components/hamburger.css b/assets/css/components/hamburger.css new file mode 100644 index 0000000..200e81d --- /dev/null +++ b/assets/css/components/hamburger.css @@ -0,0 +1,187 @@ +/* hamburger.css */ + +.nav-header { + position: fixed; + top: 0; + right: 0; + z-index: var(--z-nav); + padding: var(--sp-6) var(--sp-8); +} + +/* Hamburger Button */ +.hamburger { + background: none; + border: none; + cursor: pointer; + display: flex; + flex-direction: column; + gap: 0.4rem; + padding: 0.5rem; + transition: all var(--duration-base) ease; + width: 32px; + height: 32px; + align-items: center; + justify-content: center; +} + +.hamburger span { + display: block; + width: 24px; + height: 2px; + background-color: var(--text); + border-radius: 2px; + transition: all var(--duration-base) ease; + transform-origin: center; +} + +.hamburger.active span:nth-child(1) { + transform: translateY(10px) rotate(45deg); +} + +.hamburger.active span:nth-child(2) { + opacity: 0; +} + +.hamburger.active span:nth-child(3) { + transform: translateY(-10px) rotate(-45deg); +} + +/* Menu Overlay */ +.menu-overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(6, 11, 16, 0.95); + backdrop-filter: blur(4px); + z-index: var(--z-menu); + opacity: 0; + visibility: hidden; + transition: opacity var(--duration-base) ease, visibility var(--duration-base) ease; + display: flex; + align-items: center; + justify-content: center; +} + +.menu-overlay.active { + opacity: 1; + visibility: visible; +} + +/* Menu Items */ +.menu-items { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--sp-12); + width: 90%; + max-width: 600px; + padding: var(--sp-8); +} + +.menu-logo { + font-family: var(--font-head); + font-size: 1.5rem; + font-weight: 700; + color: var(--text); + text-decoration: none; + margin-bottom: var(--sp-4); +} + +.menu-links { + list-style: none; + display: flex; + flex-direction: column; + gap: var(--sp-6); + text-align: center; +} + +.menu-links a { + color: var(--text); + text-decoration: none; + font-family: var(--font-mono); + font-size: 1.2rem; + padding: var(--sp-3) var(--sp-4); + border-radius: 4px; + transition: all var(--duration-base) ease; +} + +.menu-links a:hover { + color: var(--accent); +} + +.menu-links a[aria-current="page"] { + color: var(--accent); + font-weight: 700; +} + +/* Menu Footer */ +.menu-footer { + display: flex; + justify-content: center; + margin-top: var(--sp-8); +} + +/* Theme Switch Button */ +.theme-switch { + background: var(--surface); + border: 1px solid var(--border); + cursor: pointer; + width: 50px; + height: 26px; + border-radius: 20px; + padding: 2px; + position: relative; + transition: all var(--duration-base) ease; + display: flex; + align-items: center; + justify-content: flex-start; +} + +.theme-switch:hover { + border-color: var(--accent); +} + +.theme-switch-dot { + width: 20px; + height: 20px; + background-color: var(--text); + border-radius: 50%; + display: block; + transition: transform var(--duration-base) ease; +} + +.theme-switch.light { + justify-content: flex-end; +} + +.theme-switch.light .theme-switch-dot { + transform: translateX(24px); +} + +/* Keyboard Focus */ +.hamburger:focus-visible, +.menu-links a:focus-visible, +.theme-switch:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +/* Skip Link */ +.skip-link { + position: absolute; + top: -40px; + left: 0; + background: var(--accent); + color: var(--bg); + padding: var(--sp-2) var(--sp-4); + z-index: var(--z-modal); + text-decoration: none; + font-family: var(--font-mono); + font-size: 0.9rem; +} + +.skip-link:focus { + top: 0; +} diff --git a/assets/css/components/hero.css b/assets/css/components/hero.css index 567a3e9..3596274 100644 --- a/assets/css/components/hero.css +++ b/assets/css/components/hero.css @@ -1,82 +1,269 @@ /* hero.css */ + .hero { position: relative; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 2rem; + gap: 3rem; overflow: hidden; - padding: var(--section-py-mobile) 1.5rem; - background: var(--bg); - border-bottom: 1px solid var(--border); -} - -@media (min-width: 768px) { - .hero { - padding: var(--section-py-desktop) 1.5rem; - } } #matrix-canvas { position: absolute; inset: 0; - opacity: 0.4; + opacity: 0.13; pointer-events: none; } html.theme-light #matrix-canvas { - opacity: 0.5; + opacity: 0.08; } -.hero-content { +.hero-left { + flex: 1; + min-width: 0; position: relative; - z-index: 1; - max-width: var(--container-max); - margin: 0 auto; - display: flex; - align-items: center; - gap: var(--gap-lg); + z-index: 2; } -.hero-avatar { - width: 64px; - height: 64px; - border-radius: 50%; - flex-shrink: 0; - background: linear-gradient(135deg, var(--accent), var(--accent2)); - display: flex; - align-items: center; - justify-content: center; +.hero-prompt { + font-size: 0.75rem; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--accent); + margin-bottom: 0.5rem; + font-weight: 500; + font-family: var(--font-mono); +} + +.hero-name { font-family: var(--font-head); - font-size: 1.4rem; + font-size: clamp(3rem, 12vw, 7rem); font-weight: 800; - color: #fff; + letter-spacing: -0.04em; + line-height: 1; + margin-bottom: 1rem; + position: relative; + display: inline-block; } -@media (min-width: 768px) { - .hero-avatar { - width: 80px; - height: 80px; - font-size: 1.8rem; - } +/* Glitch effect on hero name */ +.hero-name::before, +.hero-name::after { + content: attr(data-text); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + pointer-events: none; + overflow: hidden; + font-family: inherit; + font-size: inherit; + font-weight: inherit; + letter-spacing: inherit; + line-height: inherit; } -.hero-text h1 { - margin-bottom: 0.25rem; +.hero-name::before { + color: #ff2b6d; +} + +.hero-name::after { + color: #00e5ff; +} + +.hero-name.is-glitching::before { + opacity: 0.8; + animation: glitch-red 0.45s steps(3) forwards; +} + +.hero-name.is-glitching::after { + opacity: 0.8; + animation: glitch-cyn 0.45s steps(3) forwards; +} + +@keyframes glitch-red { + 0% { clip-path: inset(0 0 0 0); transform: translate(0); } + 20% { clip-path: inset(0 0 65% 0); transform: translate(-0.05em, -0.03em); } + 40% { clip-path: inset(28% 0 58% 0); transform: translate(0.05em, 0.03em); } + 60% { clip-path: inset(44% 0 58% 0); transform: translate(-0.05em, -0.02em); } + 80% { clip-path: inset(12% 0 85% 0); transform: translate(0.05em, 0.02em); } + 100% { clip-path: inset(0 0 0 0); transform: translate(0); } +} + +@keyframes glitch-cyn { + 0% { clip-path: inset(0 0 0 0); transform: translate(0); } + 20% { clip-path: inset(0 0 60% 0); transform: translate(0.05em, 0.02em); } + 40% { clip-path: inset(38% 0 58% 0); transform: translate(-0.05em, 0.01em); } + 60% { clip-path: inset(19% 0 40% 0); transform: translate(0.025em, -0.02em); } + 80% { clip-path: inset(1% 0 58% 0); transform: translate(-0.05em, -0.02em); } + 100% { clip-path: inset(0 0 0 0); transform: translate(0); } } .hero-role { - font-family: var(--font-mono); - font-size: 0.85rem; + font-size: clamp(0.85rem, 3vw, 1rem); + letter-spacing: 0.05em; + margin-bottom: 1.5rem; color: var(--accent); + font-weight: 400; + min-height: 1.5em; + font-family: var(--font-mono); +} + +.cursor { + display: inline-block; + width: 0.15em; + height: 1em; + background: var(--accent); + margin-left: 0.1em; + animation: cursor-blink 1s step-end infinite; +} + +@keyframes cursor-blink { + 0%, 49% { opacity: 1; } + 50%, 100% { opacity: 0; } +} + +.hero-tagline { + font-family: var(--font-body); + font-size: 1rem; + font-weight: 400; + line-height: 1.95; + color: var(--text-dim); + margin-bottom: 2rem; + max-width: 90%; +} + +/* Buttons */ +.hero-buttons { + display: flex; + gap: 1rem; + flex-wrap: wrap; + margin-bottom: 2rem; +} + +.btn { + padding: 0.75rem 1.5rem; + font-size: 0.8rem; + font-family: var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase; - margin-bottom: 0.75rem; + font-weight: 500; + cursor: pointer; + border: none; + transition: all var(--duration-base) ease; + text-decoration: none; + display: inline-block; + border-radius: 0; } -.hero-bio { +.btn-primary { + background: var(--accent); + color: #000; + font-weight: 600; +} + +.btn-primary:hover { + box-shadow: 0 0 24px rgba(168, 85, 247, 0.45); + transform: translate(0, -2px); +} + +.btn-outline { + background: transparent; + color: var(--accent); + border: 1px solid var(--border); +} + +.btn-outline:hover { + background: var(--accent); + color: #000; + box-shadow: 0 0 24px rgba(168, 85, 247, 0.45); +} + +/* Right column: terminal widget */ +.hero-right { + flex: 0 0 auto; + width: 320px; + display: none; + position: relative; + z-index: 2; +} + +@media (min-width: 1200px) { + .hero-right { + display: block; + } +} + +.hero-terminal { + background: rgba(6, 11, 16, 0.85); + border: 1px solid rgba(168, 85, 247, 0.3); + border-radius: 8px; + overflow: hidden; + font-size: 0.75rem; + line-height: 1.7; +} + +.terminal-bar { + background: var(--surface); + padding: 0.5rem 1rem; + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + gap: 0.75rem; +} + +.terminal-dot { + width: 12px; + height: 12px; + border-radius: 50%; + display: inline-block; +} + +.terminal-content { + padding: 1rem; + font-family: var(--font-mono); + color: var(--terminal-text, #c4d6e8); +} + +.terminal-content div { + white-space: pre-wrap; + word-wrap: break-word; +} + +.terminal-prompt { + color: var(--terminal-prompt, #00ff88); +} + +/* Scroll Indicator */ +.scroll-indicator { + position: absolute; + bottom: 2rem; + left: 50%; + transform: translateX(-50%); + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + font-size: 0.75rem; color: var(--text-dim); - font-size: 0.95rem; - line-height: 1.8; - max-width: 400px; + animation: bounce 2s infinite; + z-index: 2; } +.scroll-indicator svg { + color: var(--accent); +} + +@keyframes bounce { + 0%, 100% { transform: translateX(-50%) translateY(0); } + 50% { transform: translateX(-50%) translateY(-8px); } +} /* Ambient glow behind hero */ .hero::before { @@ -89,15 +276,38 @@ html.theme-light #matrix-canvas { background: radial-gradient(circle, rgba(168, 85, 247, 0.15) 0%, transparent 70%); transform: translate(-50%, -50%); pointer-events: none; + z-index: 1; } -@media (max-width: 768px) { - .hero-content { +/* Mobile */ +@media (max-width: 900px) { + .hero { flex-direction: column; - text-align: center; + min-height: auto; + justify-content: flex-start; + padding-top: 6rem; } - .hero-bio { + .hero-tagline { max-width: 100%; } + + .scroll-indicator { + display: none; + } +} + +@media (prefers-reduced-motion: reduce) { + .hero-name.is-glitching::before, + .hero-name.is-glitching::after { + animation: none; + } + + .scroll-indicator { + animation: none; + } + + .cursor { + animation: none; + } } diff --git a/assets/css/components/lightbox.css b/assets/css/components/lightbox.css new file mode 100644 index 0000000..ad34e84 --- /dev/null +++ b/assets/css/components/lightbox.css @@ -0,0 +1,170 @@ +/* lightbox.css */ + +.photo-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 1.5rem; + margin: 2rem 0; +} + +.photo-card { + position: relative; + cursor: pointer; + overflow: hidden; + border-radius: 4px; + border: 1px solid var(--border); + transition: all var(--duration-base) ease; +} + +.photo-card:hover { + border-color: var(--accent); + box-shadow: 0 0 20px rgba(168, 85, 247, 0.2); + transform: translateY(-4px); +} + +.photo-card img { + width: 100%; + height: 200px; + object-fit: cover; + display: block; + transition: transform var(--duration-base) ease; +} + +.photo-card:hover img { + transform: scale(1.05); +} + +.photo-card figcaption { + padding: 1rem; + background: var(--surface); + font-size: 0.9rem; + color: var(--text-dim); +} + +/* Lightbox Modal */ +.photo-lightbox { + position: fixed; + inset: 0; + z-index: 200; + display: none; + background: rgba(6, 11, 16, 0.95); + backdrop-filter: blur(4px); +} + +.photo-lightbox.active { + display: flex; + align-items: center; + justify-content: center; +} + +.photo-lightbox-backdrop { + position: absolute; + inset: 0; + cursor: pointer; +} + +.photo-lightbox-content { + position: relative; + z-index: 201; + max-width: 90vw; + max-height: 90vh; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.photo-lightbox-image { + max-width: 100%; + max-height: 70vh; + object-fit: contain; +} + +.photo-lightbox-controls { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + background: var(--surface); + border-radius: 4px; +} + +.photo-lightbox-nav { + display: flex; + gap: 1rem; +} + +.photo-lightbox-nav button { + padding: 0.5rem 1rem; + background: var(--accent); + color: #000; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: 600; + transition: all var(--duration-base) ease; +} + +.photo-lightbox-nav button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.photo-lightbox-nav button:not(:disabled):hover { + box-shadow: 0 0 20px rgba(168, 85, 247, 0.4); + transform: translateY(-2px); +} + +.photo-lightbox-close { + position: absolute; + top: 1rem; + right: 1rem; + background: var(--surface); + border: 1px solid var(--border); + width: 44px; + height: 44px; + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + color: var(--text); + transition: all var(--duration-base) ease; + z-index: 202; +} + +.photo-lightbox-close:hover { + background: var(--accent); + color: #000; + border-color: var(--accent); +} + +.photo-metadata { + padding: 1rem; + background: var(--surface); + border-radius: 4px; + font-size: 0.9rem; + color: var(--text-dim); +} + +.photo-metadata dt { + font-weight: 600; + color: var(--text); + margin-top: 0.5rem; +} + +.photo-metadata dt:first-child { + margin-top: 0; +} + +.photo-metadata dd { + margin-left: 1rem; + font-family: var(--font-mono); +} + +@media (prefers-reduced-motion: reduce) { + .photo-card:hover img, + .photo-lightbox-nav button:hover { + transform: none; + } +} diff --git a/assets/css/components/progress-bar.css b/assets/css/components/progress-bar.css index f89f4a8..ee17fcc 100644 --- a/assets/css/components/progress-bar.css +++ b/assets/css/components/progress-bar.css @@ -1,22 +1,19 @@ /* progress-bar.css */ -.reading-progress { + +.progress-bar { position: fixed; top: 0; left: 0; - height: 3px; - background: linear-gradient(90deg, var(--accent), var(--accent2)); + height: 2px; + background: linear-gradient(to right, var(--accent), var(--accent2)); + box-shadow: 0 0 10px var(--accent-glow); + z-index: var(--z-progress); width: 0%; - z-index: 200; - transition: width 0.1s ease-out; -} - -/* Only show on pages with sufficient content */ -.article-page .reading-progress, -.page-page .reading-progress { - display: block; + transition: width var(--duration-base) ease; } -/* Hide if no scrollable content */ -body:not(.scrollable) .reading-progress { - display: none; +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } } diff --git a/assets/css/components/share-sidebar.css b/assets/css/components/share-sidebar.css new file mode 100644 index 0000000..8bc8d1d --- /dev/null +++ b/assets/css/components/share-sidebar.css @@ -0,0 +1,107 @@ +/* share-sidebar.css */ + +.share-sidebar { + position: fixed; + right: 2rem; + bottom: 50%; + transform: translateY(50%); + z-index: 30; + display: none; +} + +@media (min-width: 1200px) { + .share-sidebar { + display: block; + } +} + +.share-buttons { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.share-btn { + width: 44px; + height: 44px; + border-radius: 50%; + background: var(--surface); + border: 1px solid var(--border); + color: var(--text); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all var(--duration-base) ease; + position: relative; +} + +.share-btn:hover { + background: var(--accent); + border-color: var(--accent); + color: #000; + transform: scale(1.1); +} + +.share-btn svg { + width: 20px; + height: 20px; +} + +/* Tooltip */ +.share-btn::after { + content: attr(data-label); + position: absolute; + right: 100%; + top: 50%; + transform: translateY(-50%); + margin-right: 0.75rem; + background: var(--surface); + border: 1px solid var(--border); + padding: 0.4rem 0.8rem; + border-radius: 4px; + white-space: nowrap; + font-size: 0.75rem; + color: var(--text-dim); + opacity: 0; + visibility: hidden; + transition: all var(--duration-base) ease; + pointer-events: none; +} + +.share-btn:hover::after { + opacity: 1; + visibility: visible; + margin-right: 1rem; +} + +/* Mobile: horizontal strip below article */ +@media (max-width: 1199px) { + .share-sidebar { + position: static; + transform: none; + display: flex; + justify-content: center; + margin: 2rem 0; + padding: 2rem 1.5rem; + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); + } + + .share-buttons { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + } +} + +@media (prefers-reduced-motion: reduce) { + .share-btn, + .share-btn::after { + transition: none; + } + + .share-btn:hover { + transform: none; + } +} diff --git a/assets/css/components/timeline.css b/assets/css/components/timeline.css new file mode 100644 index 0000000..c4a3678 --- /dev/null +++ b/assets/css/components/timeline.css @@ -0,0 +1,336 @@ +/* timeline.css */ + +.page-header { + padding: 4rem 2rem 2rem; + max-width: var(--container-max); + margin: 0 auto; + text-align: center; +} + +.page-header h1 { + margin-bottom: 2rem; +} + +.filter-buttons { + display: flex; + justify-content: center; + gap: 1rem; + flex-wrap: wrap; +} + +.filter-btn { + padding: 0.6rem 1.2rem; + font-family: var(--font-mono); + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.1em; + background: transparent; + border: 1px solid var(--border); + color: var(--text); + cursor: pointer; + border-radius: 4px; + transition: all var(--duration-base) ease; +} + +.filter-btn:hover { + border-color: var(--accent); + color: var(--accent); +} + +.filter-btn.active { + background: var(--accent); + color: #000; + border-color: var(--accent); + font-weight: 600; +} + +/* Featured Article */ +.featured-article { + max-width: var(--container-max); + margin: 3rem auto; + padding: 2rem; + background: var(--surface); + border: 2px solid transparent; + border-image: linear-gradient(135deg, var(--accent), var(--accent2)) 1; + border-radius: 8px; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + align-items: center; +} + +@media (max-width: 768px) { + .featured-article { + grid-template-columns: 1fr; + } +} + +.featured-image { + width: 100%; + overflow: hidden; + border-radius: 4px; +} + +.featured-image img { + width: 100%; + height: 300px; + object-fit: cover; +} + +.featured-body { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.featured-header { + display: flex; + gap: 1rem; + align-items: center; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.1em; +} + +.featured-type-badge { + font-weight: 600; +} + +.featured-date { + color: var(--text-dim); +} + +.featured-title { + font-size: clamp(1.5rem, 4vw, 2.5rem); + line-height: 1.2; + margin-bottom: 1rem; +} + +.featured-excerpt { + color: var(--text-dim); + line-height: 1.8; + margin-bottom: 1rem; +} + +.featured-link { + color: var(--accent); + text-decoration: none; + font-family: var(--font-mono); + font-size: 0.9rem; + transition: all var(--duration-base) ease; +} + +.featured-link:hover { + color: var(--accent2); + transform: translateX(4px); +} + +/* Timeline */ +.timeline-section { + position: relative; + max-width: var(--container-max); + margin: 4rem auto; + padding: 0 2rem; +} + +.timeline-line { + position: absolute; + left: 50%; + top: 0; + bottom: 0; + width: 2px; + background: linear-gradient(to bottom, var(--accent), transparent); + transform: translateX(-50%); +} + +@media (max-width: 900px) { + .timeline-line { + left: 0; + } +} + +.timeline-feed { + position: relative; + padding: 2rem 0; +} + +.timeline-item { + position: relative; + margin-bottom: 3rem; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + align-items: center; +} + +.timeline-item.left { + grid-template-columns: 1fr 1fr; +} + +.timeline-item.right { + grid-template-columns: 1fr 1fr; + direction: rtl; +} + +.timeline-item.right > * { + direction: ltr; +} + +@media (max-width: 900px) { + .timeline-item, + .timeline-item.left, + .timeline-item.right { + grid-template-columns: 1fr; + direction: ltr; + } + + .timeline-item.right > * { + direction: ltr; + } +} + +.timeline-dot { + position: absolute; + left: 50%; + top: 2rem; + width: 16px; + height: 16px; + background: var(--accent); + border: 3px solid var(--bg); + border-radius: 50%; + transform: translateX(-50%); + z-index: 2; +} + +@media (max-width: 900px) { + .timeline-dot { + left: -8px; + } +} + +.article-card { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; + transition: all var(--duration-base) ease; + cursor: pointer; +} + +.article-card:hover { + border-color: var(--accent); + box-shadow: 0 0 20px rgba(168, 85, 247, 0.2); + transform: translateY(-4px); +} + +.article-card-image { + width: 100%; + height: 200px; + overflow: hidden; +} + +.article-card-image img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform var(--duration-base) ease; +} + +.article-card:hover .article-card-image img { + transform: scale(1.05); +} + +.article-card-body { + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.article-card-header { + display: flex; + gap: 1rem; + align-items: center; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.1em; +} + +.article-type-badge { + font-weight: 600; + padding: 0.3rem 0.6rem; + border-radius: 4px; + background: color-mix(in srgb, currentColor 15%, transparent); + border: 1px solid color-mix(in srgb, currentColor 30%, transparent); +} + +.article-type-badge.type-tech { + color: var(--type-tech); +} + +.article-type-badge.type-life { + color: var(--type-life); +} + +.article-type-badge.type-quote { + color: var(--type-quote); +} + +.article-type-badge.type-link { + color: var(--type-link); +} + +.article-type-badge.type-photo { + color: var(--type-photo); +} + +.article-date { + color: var(--text-dim); +} + +.article-card-title { + font-size: 1.3rem; + font-weight: 700; + line-height: 1.3; + margin: 0.5rem 0; +} + +.article-card-title a { + color: var(--text); + text-decoration: none; + transition: color var(--duration-base) ease; +} + +.article-card-title a:hover { + color: var(--accent); +} + +.article-card-excerpt { + color: var(--text-dim); + font-size: 0.95rem; + line-height: 1.6; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* Hide/show articles based on filter */ +.timeline-item[data-type] { + display: none; +} + +.timeline-item[data-type].visible, +.timeline-item[data-filter="all"].visible { + display: grid; +} + +@media (prefers-reduced-motion: reduce) { + .article-card:hover { + transform: none; + } + + .article-card-image img { + transition: none; + } +} diff --git a/assets/css/main.css b/assets/css/main.css index 518e749..ad78700 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,11 +1,17 @@ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600&family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300&family=Oxanium:wght@700;800&display=swap'); @import 'variables.css'; +@import 'components/hamburger.css'; @import 'components/header.css'; @import 'components/footer.css'; @import 'components/hero.css'; @import 'components/card.css'; @import 'components/feed.css'; +@import 'components/timeline.css'; +@import 'components/article-hero.css'; +@import 'components/share-sidebar.css'; +@import 'components/lightbox.css'; +@import 'components/404.css'; @import 'components/code.css'; @import 'components/progress-bar.css'; @@ -28,6 +34,22 @@ body { font-size: var(--fs-body); line-height: 1.95; transition: background-color 0.2s, color 0.2s; + position: relative; +} + +/* Dot grid background (shared across all pages) */ +body::before { + content: ''; + position: fixed; + inset: 0; + z-index: var(--z-matrix); + pointer-events: none; + background-image: radial-gradient(circle, rgba(168, 85, 247, 0.07) 1px, transparent 1px); + background-size: 30px 30px; +} + +html.theme-light body::before { + background-image: radial-gradient(circle, rgba(124, 58, 237, 0.05) 1px, transparent 1px); } /* Typography */ diff --git a/assets/css/variables.css b/assets/css/variables.css index 74e4c86..371999a 100644 --- a/assets/css/variables.css +++ b/assets/css/variables.css @@ -8,16 +8,17 @@ --border: #182840; --accent: #a855f7; --accent2: #00ff88; + --accent-glow: rgba(168, 85, 247, 0.12); --text: #c4d6e8; --text-dim: #7a9bb8; --muted: #304860; - /* Type colors */ - --color-tech: #a855f7; /* purple */ - --color-life: #f59e0b; /* amber */ - --color-quote: #00ff88; /* green */ - --color-link: #38bdf8; /* cyan */ - --color-photo: #ec4899; /* pink */ + /* Type colors (renamed from --color-*) */ + --type-tech: #a855f7; /* purple */ + --type-life: #f59e0b; /* amber */ + --type-quote: #00ff88; /* green */ + --type-link: #38bdf8; /* cyan */ + --type-photo: #ec4899; /* pink */ /* Typography */ --font-body: 'IBM Plex Sans', system-ui, sans-serif; @@ -40,13 +41,45 @@ --gap-lg: 2.5rem; --gap-xl: 4rem; - /* Spacing */ + /* Spacing scale */ + --sp-1: 0.25rem; + --sp-2: 0.5rem; + --sp-3: 0.75rem; + --sp-4: 1rem; + --sp-5: 1.25rem; + --sp-6: 1.5rem; + --sp-7: 1.75rem; + --sp-8: 2rem; + --sp-9: 2.25rem; + --sp-10: 2.5rem; + --sp-12: 3rem; + --sp-14: 3.5rem; + --sp-16: 4rem; + + /* Z-index scale */ + --z-base: 1; + --z-matrix: 0; + --z-nav: 100; + --z-menu: 99; + --z-modal: 200; + --z-progress: 9999; + + /* Timing */ + --duration-fast: 100ms; + --duration-base: 300ms; + --duration-slow: 500ms; + + /* Easing */ + --ease-out: cubic-bezier(0.33, 1, 0.68, 1); + --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + + /* Section spacing */ --section-py-mobile: 4rem; --section-py-desktop: 6rem; --card-px-mobile: 1.5rem; --card-px-desktop: 2rem; - /* Transitions */ + /* Transitions (legacy, keep for compatibility) */ --transition: all 0.2s ease; --transition-slow: all 0.75s cubic-bezier(0.16,1,0.3,1); } @@ -59,9 +92,17 @@ html.theme-light { --border: #a8bdd8; --accent: #7c3aed; --accent2: #008f5a; + --accent-glow: rgba(124, 58, 237, 0.08); --text: #0d1b2a; --text-dim: #2e4a6a; --muted: #6888a8; + + /* Type colors (light equivalents) */ + --type-tech: #7c3aed; /* purple */ + --type-life: #d97706; /* amber */ + --type-quote: #008f5a; /* green */ + --type-link: #0284c7; /* cyan */ + --type-photo: #be185d; /* pink */ } /* Breakpoints as CSS variables for reference */ diff --git a/assets/js/404.js b/assets/js/404.js new file mode 100644 index 0000000..c26c218 --- /dev/null +++ b/assets/js/404.js @@ -0,0 +1,54 @@ +/** + * 404.js + * Quote randomization and terminal animation for 404 page + */ + +(function() { + 'use strict'; + + const quotes = [ + 'The page you are looking for doesn\'t exist. But that\'s okay, nothing exists until you find it.', + 'A 404 is just a redirect to a new beginning.', + 'You found a secret path. Sadly, it leads nowhere.', + 'This page chose to remain unknown.', + 'In the quantum realm, this page exists and doesn\'t exist simultaneously.', + 'Sometimes the best discoveries are the ones we never intended to find.', + ]; + + const quoteText = document.getElementById('quote-text'); + const quoteAuthor = document.getElementById('quote-author'); + const terminalFiles = document.getElementById('terminal-files'); + + if (quoteText && quoteAuthor) { + const randomQuote = quotes[Math.floor(Math.random() * quotes.length)]; + quoteText.textContent = randomQuote; + quoteAuthor.textContent = '— 404 Philosopher'; + } + + if (terminalFiles) { + const files = [ + 'post-01-security.md', + 'post-02-web-dev.md', + 'post-03-bash-tips.md', + 'about.md', + 'contact.md', + ]; + + files.forEach((file) => { + const line = document.createElement('div'); + line.textContent = file; + terminalFiles.appendChild(line); + }); + } + + // Listen for search (if implemented) + const searchBtn = document.querySelector('.search-box button'); + if (searchBtn) { + searchBtn.addEventListener('click', () => { + const input = document.querySelector('.search-box input'); + if (input && input.value) { + window.location.href = `/articles/?search=${encodeURIComponent(input.value)}`; + } + }); + } +})(); diff --git a/assets/js/filters.js b/assets/js/filters.js index 64d9c57..f7fa6a6 100644 --- a/assets/js/filters.js +++ b/assets/js/filters.js @@ -1,28 +1,37 @@ -// filters.js +/** + * filters.js + * Article filtering by type on the articles page + */ + (function() { - const filterBtns = document.querySelectorAll('.filter-btn'); - const feedList = document.getElementById('articles-feed'); - const cards = feedList ? feedList.querySelectorAll('.post-card') : []; + 'use strict'; - if (!filterBtns.length || !cards.length) return; + const filterBtns = document.querySelectorAll('.filter-btn'); + const timelineItems = document.querySelectorAll('.timeline-item'); - filterBtns.forEach(btn => { - btn.addEventListener('click', function() { - const filter = this.dataset.filter; + filterBtns.forEach((btn) => { + btn.addEventListener('click', () => { + const filter = btn.getAttribute('data-filter'); // Update active button - filterBtns.forEach(b => b.classList.remove('active')); - this.classList.add('active'); + filterBtns.forEach((b) => b.classList.remove('active')); + btn.classList.add('active'); - // Filter cards - cards.forEach(card => { - const cardType = card.querySelector('.post-type-badge')?.classList[1]; - const matches = filter === 'all' || cardType === filter; - card.style.display = matches ? '' : 'none'; - }); + // Filter articles + timelineItems.forEach((item) => { + const type = item.getAttribute('data-type'); - // Scroll to top - window.scrollTo({ top: 0, behavior: 'smooth' }); + if (filter === 'all' || type === filter) { + item.classList.add('visible'); + } else { + item.classList.remove('visible'); + } + }); }); }); + + // Show all on load + timelineItems.forEach((item) => { + item.classList.add('visible'); + }); })(); diff --git a/assets/js/glitch.js b/assets/js/glitch.js new file mode 100644 index 0000000..85f8a00 --- /dev/null +++ b/assets/js/glitch.js @@ -0,0 +1,30 @@ +/** + * glitch.js + * Random glitch effect on .hero-name every 4-11 seconds + */ + +export function initGlitch() { + 'use strict'; + + const heroName = document.querySelector('.hero-name'); + if (!heroName) return; + + if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; + + function triggerGlitch() { + heroName.classList.add('is-glitching'); + setTimeout(() => { + heroName.classList.remove('is-glitching'); + }, 450); + } + + function scheduleNextGlitch() { + const delay = Math.random() * 7000 + 4000; // 4-11 seconds + setTimeout(() => { + triggerGlitch(); + scheduleNextGlitch(); + }, delay); + } + + scheduleNextGlitch(); +} diff --git a/assets/js/hamburger.js b/assets/js/hamburger.js new file mode 100644 index 0000000..1d27633 --- /dev/null +++ b/assets/js/hamburger.js @@ -0,0 +1,83 @@ +/** + * hamburger.js + * Hamburger menu toggle with focus trap and keyboard navigation + */ + +export function initHamburger() { + 'use strict'; + + const hamburgerBtn = document.getElementById('hamburger-btn'); + const menuOverlay = document.getElementById('menu-overlay'); + const menuLinks = document.querySelectorAll('.menu-links a'); + const themeSwitch = document.getElementById('theme-switch'); + + if (!hamburgerBtn || !menuOverlay) return; + + // Toggle menu on hamburger click + hamburgerBtn.addEventListener('click', () => { + const isOpen = hamburgerBtn.getAttribute('aria-expanded') === 'true'; + setMenuOpen(!isOpen); + }); + + // Close menu on overlay click + menuOverlay.addEventListener('click', (e) => { + if (e.target === menuOverlay) { + setMenuOpen(false); + } + }); + + // Close menu on menu link click + menuLinks.forEach((link) => { + link.addEventListener('click', () => { + setMenuOpen(false); + }); + }); + + // Close menu on Escape key + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + setMenuOpen(false); + } + }); + + // Focus trap: Tab through menu items and theme switch + menuOverlay.addEventListener('keydown', (e) => { + if (e.key !== 'Tab') return; + + const focusableElements = Array.from( + menuOverlay.querySelectorAll('a, button') + ); + const firstElement = focusableElements[0]; + const lastElement = focusableElements[focusableElements.length - 1]; + + if (e.shiftKey) { + if (document.activeElement === firstElement) { + lastElement.focus(); + e.preventDefault(); + } + } else { + if (document.activeElement === lastElement) { + firstElement.focus(); + e.preventDefault(); + } + } + }); + + function setMenuOpen(isOpen) { + hamburgerBtn.setAttribute('aria-expanded', isOpen); + hamburgerBtn.classList.toggle('active', isOpen); + menuOverlay.classList.toggle('active', isOpen); + + if (isOpen) { + document.body.style.overflow = 'hidden'; + // Focus the first menu link + const firstLink = menuLinks[0]; + if (firstLink) { + setTimeout(() => firstLink.focus(), 100); + } + } else { + document.body.style.overflow = ''; + hamburgerBtn.focus(); + } + } +} diff --git a/assets/js/lightbox.js b/assets/js/lightbox.js new file mode 100644 index 0000000..81c3613 --- /dev/null +++ b/assets/js/lightbox.js @@ -0,0 +1,31 @@ +/** + * lightbox.js + * Photo lightbox initialization + */ + +(function() { + 'use strict'; + + if (typeof PhotoUtils === 'undefined') return; + + const photoGrid = document.querySelector('.photo-grid[data-lightbox="true"]'); + if (!photoGrid) return; + + const photoCards = photoGrid.querySelectorAll('.photo-card'); + const photosData = []; + + photoCards.forEach((card, index) => { + const figure = card.querySelector('figure'); + const img = card.querySelector('img'); + photosData.push({ + index, + src: figure.getAttribute('data-src') || img.src, + alt: figure.getAttribute('data-alt') || img.alt, + caption: figure.getAttribute('data-caption'), + location: figure.getAttribute('data-location'), + }); + }); + + // Initialize lightbox with PhotoUtils + PhotoUtils.initLightbox('.photo-grid', photosData); +})(); diff --git a/assets/js/main.js b/assets/js/main.js index 5b5848c..ee6b24f 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -3,3 +3,16 @@ import './theme-toggle.js'; import './matrix-rain.js'; import './progress-bar.js'; import './copy-code.js'; +import { initHamburger } from './hamburger.js'; +import { initGlitch } from './glitch.js'; +import { initTyping } from './typing.js'; +import { initScrollReveal } from './scroll-reveal.js'; +import { initShareSidebar } from './share-sidebar.js'; + +document.addEventListener('DOMContentLoaded', () => { + initHamburger(); + initGlitch(); + initTyping(); + initScrollReveal(); + initShareSidebar(); +}); diff --git a/assets/js/matrix-rain.js b/assets/js/matrix-rain.js index 479231f..742b0bd 100644 --- a/assets/js/matrix-rain.js +++ b/assets/js/matrix-rain.js @@ -7,11 +7,19 @@ const ctx = canvas.getContext('2d'); const CHARS = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789ABCDEF<>/\\|{}[]$#@!'; const FS = 14; // font size / column width in px + const mode = canvas.getAttribute('data-mode') || 'background'; // 'hero' or 'background' let cols, drops, raf; function init() { - canvas.width = canvas.offsetWidth; - canvas.height = canvas.offsetHeight; + if (mode === 'hero') { + // Hero mode: size relative to canvas element's offsetWidth + canvas.width = canvas.offsetWidth; + canvas.height = canvas.offsetHeight; + } else { + // Background mode: size to full viewport + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + } cols = Math.floor(canvas.width / FS) + 1; drops = Array.from({ length: cols }, () => Math.random() * -(canvas.height / FS)); } diff --git a/assets/js/photo-utils.js b/assets/js/photo-utils.js new file mode 100644 index 0000000..32ede76 --- /dev/null +++ b/assets/js/photo-utils.js @@ -0,0 +1,476 @@ +(function() { + 'use strict'; + + // Internal state + let currentPhotoIndex = 0; + let photosData = []; + let isOpen = false; + let exifData = {}; + let options = { + swipeEnabled: true, + keyboardEnabled: true, + extractEXIF: true, + onOpen: null, + onClose: null, + }; + + // Lightbox DOM elements (created on first init) + let lightboxModal = null; + let lightboxImage = null; + let lightboxCaption = null; + let lightboxSidebar = null; + + /** + * Initialize lightbox for a photo collection + * @param {string} containerSelector - CSS selector for photo container + * @param {Array} photos - Array of photo objects: {src, alt, caption, location} + * @param {Object} opts - Options: {swipeEnabled, keyboardEnabled, extractEXIF, onOpen, onClose} + * @returns {Object} - {openLightbox, closeLightbox} + */ + function initLightbox(containerSelector, photos, opts = {}) { + photosData = photos; + options = { ...options, ...opts }; + + // Merge options with defaults + const container = document.querySelector(containerSelector); + if (!container) { + console.error('Photo container not found:', containerSelector); + return { openLightbox: () => {}, closeLightbox: () => {} }; + } + + // Attach click listeners to all figures in the container + const figures = container.querySelectorAll('figure[data-photo-index]'); + figures.forEach((figure) => { + figure.addEventListener('click', () => { + const index = parseInt(figure.dataset.photoIndex, 10); + openLightbox(index); + }); + }); + + // Return public API + return { + openLightbox, + closeLightbox, + }; + } + + /** + * Open lightbox to a specific photo + * @param {number} photoIndex - 0-based index into photosData array + */ + function openLightbox(photoIndex) { + if (photoIndex < 0 || photoIndex >= photosData.length) { + console.warn('Invalid photo index:', photoIndex); + return; + } + + currentPhotoIndex = photoIndex; + isOpen = true; + + // Create lightbox DOM if it doesn't exist + if (!lightboxModal) { + createLightboxDOM(); + } + + // Populate lightbox with current photo + updateLightboxContent(); + + // Show modal + lightboxModal.classList.add('visible'); + document.body.style.overflow = 'hidden'; + + // Extract EXIF if enabled + if (options.extractEXIF) { + extractEXIFForCurrentPhoto(); + } + + // Attach event listeners + attachEventListeners(); + + // Callback + if (options.onOpen) { + options.onOpen(photoIndex); + } + } + + /** + * Close lightbox + */ + function closeLightbox() { + if (!isOpen || !lightboxModal) return; + + isOpen = false; + lightboxModal.classList.remove('visible'); + document.body.style.overflow = ''; + + // Detach event listeners + detachEventListeners(); + + // Callback + if (options.onClose) { + options.onClose(); + } + } + + /** + * Create lightbox HTML structure and inject into DOM + */ + function createLightboxDOM() { + lightboxModal = document.createElement('div'); + lightboxModal.className = 'photo-lightbox'; + + lightboxModal.innerHTML = ` + <div class="photo-lightbox-backdrop"></div> + <div class="photo-lightbox-container"> + <button class="photo-lightbox-close" aria-label="Close lightbox">×</button> + + <button class="photo-lightbox-prev" aria-label="Previous photo">←</button> + + <div class="photo-lightbox-content"> + <img class="photo-lightbox-image" src="" alt=""> + <div class="photo-lightbox-caption"></div> + </div> + + <button class="photo-lightbox-next" aria-label="Next photo">→</button> + + <div class="photo-lightbox-sidebar"> + <div class="photo-lightbox-sidebar-content"></div> + </div> + </div> + `; + + document.body.appendChild(lightboxModal); + + // Cache element references + lightboxImage = lightboxModal.querySelector('.photo-lightbox-image'); + lightboxCaption = lightboxModal.querySelector('.photo-lightbox-caption'); + lightboxSidebar = lightboxModal.querySelector('.photo-lightbox-sidebar-content'); + + // Attach close button and backdrop click + lightboxModal.querySelector('.photo-lightbox-close').addEventListener('click', closeLightbox); + lightboxModal.querySelector('.photo-lightbox-backdrop').addEventListener('click', closeLightbox); + + // Attach navigation buttons + lightboxModal.querySelector('.photo-lightbox-prev').addEventListener('click', () => navigate(-1)); + lightboxModal.querySelector('.photo-lightbox-next').addEventListener('click', () => navigate(1)); + } + + /** + * Update lightbox content with current photo + */ + function updateLightboxContent() { + const photo = photosData[currentPhotoIndex]; + if (!photo) return; + + lightboxImage.src = photo.src; + lightboxImage.alt = photo.alt || ''; + + // Caption + if (photo.caption) { + lightboxCaption.textContent = photo.caption; + lightboxCaption.style.display = 'block'; + } else { + lightboxCaption.style.display = 'none'; + } + + // Update prev/next button states + const prevBtn = lightboxModal.querySelector('.photo-lightbox-prev'); + const nextBtn = lightboxModal.querySelector('.photo-lightbox-next'); + prevBtn.disabled = currentPhotoIndex === 0; + nextBtn.disabled = currentPhotoIndex === photosData.length - 1; + } + + /** + * Navigate to previous or next photo + * @param {number} direction - -1 for prev, 1 for next + */ + function navigate(direction) { + const newIndex = currentPhotoIndex + direction; + if (newIndex >= 0 && newIndex < photosData.length) { + currentPhotoIndex = newIndex; + updateLightboxContent(); + + // Reset EXIF data and re-extract if enabled + exifData = {}; + if (options.extractEXIF) { + extractEXIFForCurrentPhoto(); + } + } + } + + /** + * Extract EXIF data from current photo image element + */ + function extractEXIFForCurrentPhoto() { + extractEXIF(lightboxImage).then((data) => { + exifData = data; + updateSidebarContent(); + }); + } + + /** + * Update sidebar with EXIF and location data + */ + function updateSidebarContent() { + const photo = photosData[currentPhotoIndex]; + let sidebarHTML = ''; + + // Always show location if provided + if (photo.location) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Location</div> + <div class="photo-metadata-value">${photo.location}</div> + </div> + `; + } + + // Show EXIF fields if available + if (Object.keys(exifData).length > 0) { + sidebarHTML += ` + <div class="photo-metadata-divider"></div> + <div class="photo-metadata-label">Camera</div> + `; + + if (exifData.camera) { + sidebarHTML += ` + <div class="photo-metadata-value">${exifData.camera}</div> + `; + } + if (exifData.lens) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Lens</div> + <div class="photo-metadata-value">${exifData.lens}</div> + </div> + `; + } + if (exifData.focalLength) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Focal Length</div> + <div class="photo-metadata-value">${exifData.focalLength}</div> + </div> + `; + } + if (exifData.aperture) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Aperture</div> + <div class="photo-metadata-value">${exifData.aperture}</div> + </div> + `; + } + if (exifData.shutterSpeed) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Shutter Speed</div> + <div class="photo-metadata-value">${exifData.shutterSpeed}</div> + </div> + `; + } + if (exifData.iso) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">ISO</div> + <div class="photo-metadata-value">${exifData.iso}</div> + </div> + `; + } + if (exifData.dateTaken) { + sidebarHTML += ` + <div class="photo-metadata-field"> + <div class="photo-metadata-label">Date Taken</div> + <div class="photo-metadata-value">${exifData.dateTaken}</div> + </div> + `; + } + } + + // Show or hide sidebar based on whether there's content + const sidebarContainer = lightboxModal.querySelector('.photo-lightbox-sidebar'); + if (sidebarHTML) { + lightboxSidebar.innerHTML = sidebarHTML; + sidebarContainer.classList.add('visible'); + } else { + sidebarContainer.classList.remove('visible'); + } + } + + /** + * Extract EXIF data from an image element using exif-js library + * @param {HTMLImageElement} imageElement - Image to read EXIF from + * @returns {Promise} - Resolves to {camera, lens, iso, aperture, shutterSpeed, focalLength, dateTaken} + */ + function extractEXIF(imageElement) { + return new Promise((resolve) => { + // If exif-js is not loaded, return empty object + if (typeof EXIF === 'undefined') { + console.warn('exif-js library not loaded'); + resolve({}); + return; + } + + EXIF.getData(imageElement, function() { + const data = { + camera: EXIF.getTag(this, 'Model'), + lens: EXIF.getTag(this, 'LensModel'), + iso: EXIF.getTag(this, 'ISOSpeedRatings'), + aperture: formatAperture(EXIF.getTag(this, 'FNumber')), + shutterSpeed: formatShutterSpeed(EXIF.getTag(this, 'ExposureTime')), + focalLength: formatFocalLength(EXIF.getTag(this, 'FocalLength')), + dateTaken: EXIF.getTag(this, 'DateTime'), + }; + + // Filter out undefined values + Object.keys(data).forEach(key => { + if (data[key] === undefined) { + delete data[key]; + } + }); + + resolve(data); + }); + }); + } + + /** + * Format aperture value (f-number) + */ + function formatAperture(value) { + if (!value) return null; + if (typeof value === 'object' && value.numerator !== undefined) { + return `f/${(value.numerator / value.denominator).toFixed(1)}`; + } + return `f/${value}`; + } + + /** + * Format shutter speed (exposure time) + */ + function formatShutterSpeed(value) { + if (!value) return null; + if (typeof value === 'object' && value.numerator !== undefined) { + const speed = value.numerator / value.denominator; + if (speed >= 1) { + return `${speed.toFixed(1)}s`; + } + return `1/${Math.round(1 / speed)}`; + } + return value; + } + + /** + * Format focal length + */ + function formatFocalLength(value) { + if (!value) return null; + if (typeof value === 'object' && value.numerator !== undefined) { + return `${(value.numerator / value.denominator).toFixed(0)}mm`; + } + return `${value}mm`; + } + + /** + * Attach event listeners (swipe, keyboard, etc.) + */ + function attachEventListeners() { + if (options.swipeEnabled) { + attachSwipeListeners(); + } + if (options.keyboardEnabled) { + attachKeyboardListeners(); + } + } + + /** + * Detach event listeners to prevent memory leaks + */ + function detachEventListeners() { + if (options.swipeEnabled) { + detachSwipeListeners(); + } + if (options.keyboardEnabled) { + detachKeyboardListeners(); + } + } + + /** + * Touch swipe event listeners + */ + let swipeStartX = 0; + let swipeStartY = 0; + + function onTouchStart(e) { + swipeStartX = e.touches[0].clientX; + swipeStartY = e.touches[0].clientY; + } + + function onTouchEnd(e) { + const swipeEndX = e.changedTouches[0].clientX; + const swipeEndY = e.changedTouches[0].clientY; + const diffX = swipeEndX - swipeStartX; + const diffY = swipeEndY - swipeStartY; + + // Only consider horizontal swipe if delta-x > delta-y + if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) { + if (diffX > 0) { + // Swiped right: go to previous + navigate(-1); + } else { + // Swiped left: go to next + navigate(1); + } + } + } + + function attachSwipeListeners() { + lightboxModal.addEventListener('touchstart', onTouchStart, false); + lightboxModal.addEventListener('touchend', onTouchEnd, false); + } + + function detachSwipeListeners() { + lightboxModal.removeEventListener('touchstart', onTouchStart, false); + lightboxModal.removeEventListener('touchend', onTouchEnd, false); + } + + /** + * Keyboard event listeners + */ + function onKeyDown(e) { + if (!isOpen) return; + + switch (e.key) { + case 'ArrowLeft': + navigate(-1); + e.preventDefault(); + break; + case 'ArrowRight': + navigate(1); + e.preventDefault(); + break; + case 'Escape': + closeLightbox(); + e.preventDefault(); + break; + default: + break; + } + } + + function attachKeyboardListeners() { + document.addEventListener('keydown', onKeyDown); + } + + function detachKeyboardListeners() { + document.removeEventListener('keydown', onKeyDown); + } + + // Expose public API + window.PhotoUtils = { + initLightbox, + extractEXIF, + openLightbox, + closeLightbox, + }; +})(); diff --git a/assets/js/progress-bar.js b/assets/js/progress-bar.js index bc8b70a..e171f4f 100644 --- a/assets/js/progress-bar.js +++ b/assets/js/progress-bar.js @@ -1,38 +1,20 @@ -// progress-bar.js +/** + * progress-bar.js + * Reading progress indicator for articles + */ + (function() { - const progressBar = document.querySelector('.reading-progress'); - if (!progressBar) return; + 'use strict'; - // Only enable on pages with substantial content - const mainContent = document.querySelector('main'); - if (!mainContent) return; + const progressBar = document.getElementById('progress-bar'); + if (!progressBar) return; - function updateProgress() { - // Calculate scroll percentage - const windowHeight = window.innerHeight; - const docHeight = document.documentElement.scrollHeight - windowHeight; + window.addEventListener('scroll', () => { + const windowHeight = document.documentElement.scrollHeight - window.innerHeight; const scrolled = window.scrollY; - const percent = docHeight > 0 ? (scrolled / docHeight) * 100 : 0; + const progress = windowHeight > 0 ? (scrolled / windowHeight) * 100 : 0; - progressBar.style.width = percent + '%'; - } - - // Mark body as scrollable if there's significant content - const contentHeight = mainContent.offsetHeight; - if (contentHeight > window.innerHeight * 1.5) { - document.body.classList.add('scrollable'); - } - - // Use requestAnimationFrame for smooth updates - let ticking = false; - window.addEventListener('scroll', function() { - if (!ticking) { - requestAnimationFrame(updateProgress); - ticking = true; - setTimeout(() => { ticking = false; }, 100); - } + progressBar.style.width = progress + '%'; + progressBar.setAttribute('aria-valuenow', Math.round(progress)); }, { passive: true }); - - // Initial update - updateProgress(); })(); diff --git a/assets/js/scroll-reveal.js b/assets/js/scroll-reveal.js new file mode 100644 index 0000000..ab099c0 --- /dev/null +++ b/assets/js/scroll-reveal.js @@ -0,0 +1,26 @@ +/** + * scroll-reveal.js + * IntersectionObserver for revealing elements on scroll + */ + +export function initScrollReveal() { + 'use strict'; + + const revealElements = document.querySelectorAll('.reveal'); + if (!revealElements.length) return; + + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add('revealed'); + observer.unobserve(entry.target); + } + }); + }, { + threshold: 0.1, + }); + + revealElements.forEach((el) => { + observer.observe(el); + }); +} diff --git a/assets/js/share-sidebar.js b/assets/js/share-sidebar.js new file mode 100644 index 0000000..81e5f6c --- /dev/null +++ b/assets/js/share-sidebar.js @@ -0,0 +1,51 @@ +/** + * share-sidebar.js + * Social sharing sidebar with copy-to-clipboard + */ + +export function initShareSidebar() { + 'use strict'; + + const sidebar = document.getElementById('share-sidebar'); + const copyBtn = document.getElementById('share-copy'); + + if (!sidebar) return; + + // Share button handlers + const shareBtns = sidebar.querySelectorAll('.share-btn[data-platform]'); + shareBtns.forEach((btn) => { + btn.addEventListener('click', () => { + const platform = btn.getAttribute('data-platform'); + const url = sidebar.getAttribute('data-url'); + const title = sidebar.getAttribute('data-title'); + + const shareUrls = { + whatsapp: `https://wa.me/?text=${encodeURIComponent(title + ' ' + url)}`, + telegram: `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`, + linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`, + twitter: `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`, + facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`, + reddit: `https://reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`, + email: `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(url)}`, + }; + + if (shareUrls[platform]) { + window.open(shareUrls[platform], '_blank'); + } + }); + }); + + // Copy to clipboard + if (copyBtn) { + copyBtn.addEventListener('click', () => { + const url = sidebar.getAttribute('data-url'); + navigator.clipboard.writeText(url).then(() => { + const originalText = copyBtn.innerHTML; + copyBtn.innerHTML = '✓'; + setTimeout(() => { + copyBtn.innerHTML = originalText; + }, 2000); + }); + }); + } +} diff --git a/assets/js/theme-toggle.js b/assets/js/theme-toggle.js index 9f0fd5a..e03fce7 100644 --- a/assets/js/theme-toggle.js +++ b/assets/js/theme-toggle.js @@ -45,21 +45,25 @@ // Setup toggle button function setupToggleButton() { - const btn = document.getElementById('theme-toggle-btn'); + const btn = document.getElementById('theme-switch'); if (btn) { btn.addEventListener('click', toggleTheme); - updateToggleButtonLabel(); + updateToggleButtonUI(); - // Listen for theme changes to update button label - window.addEventListener('theme-changed', updateToggleButtonLabel); + // Listen for theme changes to update button UI + window.addEventListener('theme-changed', updateToggleButtonUI); } } - function updateToggleButtonLabel() { - const btn = document.getElementById('theme-toggle-btn'); + function updateToggleButtonUI() { + const btn = document.getElementById('theme-switch'); if (btn) { const current = getCurrentTheme(); - btn.textContent = current === 'dark' ? '☀️ light' : '🌙 dark'; + if (current === 'light') { + btn.classList.add('light'); + } else { + btn.classList.remove('light'); + } } } diff --git a/assets/js/typing.js b/assets/js/typing.js new file mode 100644 index 0000000..369fed7 --- /dev/null +++ b/assets/js/typing.js @@ -0,0 +1,69 @@ +/** + * typing.js + * Typing animation for .hero-role / #typed element + */ + +export function initTyping() { + 'use strict'; + + const typedElement = document.getElementById('typed'); + if (!typedElement) return; + + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + const phrasesJson = typedElement.getAttribute('data-phrases'); + let phrases = []; + + if (phrasesJson) { + try { + phrases = JSON.parse(phrasesJson); + } catch (e) { + console.warn('Failed to parse typing phrases:', e); + phrases = ['Security & Web Dev', 'WordPress Developer']; + } + } + + if (!phrases.length) return; + + let currentPhraseIndex = 0; + let currentCharIndex = 0; + let isDeleting = false; + + function type() { + const phrase = phrases[currentPhraseIndex]; + const speed = isDeleting ? 50 : 100; + + if (isDeleting) { + currentCharIndex--; + } else { + currentCharIndex++; + } + + typedElement.textContent = phrase.substring(0, currentCharIndex); + + // Add cursor + if (!isDeleting && currentCharIndex === phrase.length) { + typedElement.innerHTML += '<span class="cursor"></span>'; + } else if (isDeleting && currentCharIndex === 0) { + currentPhraseIndex = (currentPhraseIndex + 1) % phrases.length; + isDeleting = false; + setTimeout(type, 500); + return; + } else { + typedElement.innerHTML = phrase.substring(0, currentCharIndex) + '<span class="cursor"></span>'; + } + + if (!isDeleting && currentCharIndex === phrase.length) { + isDeleting = true; + setTimeout(type, 2000); + } else { + setTimeout(type, prefersReducedMotion ? 0 : speed); + } + } + + if (prefersReducedMotion) { + // Just show the first phrase without animation + typedElement.textContent = phrases[0]; + } else { + type(); + } +} @@ -57,3 +57,4 @@ locale = 'en-US' description = 'Writing about IT, life, and the things that matter.' author = 'Danilo M.' avatar = 'DM' # Can be image path or initials + typingPhrases = ['Security & Web Dev', 'WordPress Developer', 'Bash Enthusiast', 'Slackware Admin'] diff --git a/layouts/404.html b/layouts/404.html new file mode 100644 index 0000000..3295630 --- /dev/null +++ b/layouts/404.html @@ -0,0 +1,98 @@ +<!DOCTYPE html> +<html lang="{{ .Site.Language.Locale }}" dir="{{ or .Site.Language.Direction `ltr` }}"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="theme-color" content="#060b10"> + <title>404 — {{ .Site.Title }}</title> + + <script> + (function() { + const theme = localStorage.getItem('theme') || 'dark'; + if (theme === 'light') { + document.documentElement.classList.add('theme-light'); + } + })(); + </script> + + {{ partialCached "head/css.html" . }} + {{ partialCached "head/js.html" . }} + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.css"> + {{ $notfound := resources.Get "css/components/404.css" | fingerprint }} + <link rel="stylesheet" href="{{ $notfound.RelPermalink }}"> +</head> +<body> + <a href="#main-content" class="skip-link">Skip to content</a> + <canvas id="matrix-canvas" aria-hidden="true" data-mode="background"></canvas> + + {{ partial "header.html" . }} + + <main id="main-content" class="hero--404"> + <div class="content-wrapper"> + <!-- Left: Quote + Search --> + <div class="hero-left-404"> + <div class="quote-section"> + <div class="quote-mark">"</div> + <p class="quote-text" id="quote-text">The page you're looking for doesn't exist. But that's okay, nothing exists until you find it.</p> + <p class="quote-author" id="quote-author">— 404 Philosopher</p> + </div> + + <div class="search-box"> + <input type="text" placeholder="Search articles..." aria-label="Search"> + <button aria-label="Search"> + <svg data-feather="search"></svg> + </button> + </div> + + <nav class="quick-nav"> + <h3>Quick Links</h3> + <ul> + <li><a href="/">Home</a></li> + <li><a href="/articles/">Articles</a></li> + <li><a href="/is/">About</a></li> + <li><a href="/is/here">Contact</a></li> + </ul> + </nav> + </div> + + <!-- Right: Recent Articles + Terminal --> + <div class="hero-right-404"> + <div class="recent-articles"> + <h3>Recent Articles</h3> + <ul> + {{ range first 5 (.Site.RegularPages.ByDate.Reverse) }} + <li> + <a href="{{ .RelPermalink }}" class="article-link" data-type="{{ .Params.type }}"> + {{ .Title }} + </a> + </li> + {{ end }} + </ul> + </div> + + <div class="terminal-widget"> + <div class="terminal-bar"> + <span class="terminal-dot" style="background: #ff6b6b;"></span> + <span class="terminal-dot" style="background: #ffd93d;"></span> + <span class="terminal-dot" style="background: #6bcf7f;"></span> + </div> + <div class="terminal-content"> + <div>$ <span class="terminal-prompt">curl https://danix.xyz/lost</span></div> + <div>404: Not Found</div> + <div>$ <span class="terminal-prompt">ls /articles</span></div> + <div id="terminal-files"></div> + </div> + </div> + </div> + </div> + </main> + + {{ partial "footer.html" . }} + + <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> + <script>feather.replace();</script> + + {{ $notFoundJS := resources.Get "js/404.js" | fingerprint }} + <script src="{{ $notFoundJS.RelPermalink }}"></script> +</body> +</html> diff --git a/layouts/_partials/article-single.html b/layouts/_partials/article-single.html new file mode 100644 index 0000000..f030869 --- /dev/null +++ b/layouts/_partials/article-single.html @@ -0,0 +1,56 @@ +<article class="article-single"> + <!-- Article Hero --> + {{ if .Params.image }} + <div class="article-hero" style="background-image: url('{{ .Params.image }}')"> + <div class="article-hero-overlay"></div> + <div class="article-hero-content"> + <nav class="article-breadcrumb"> + <a href="/articles/">Articles</a> + <span>/</span> + <span>{{ .Title }}</span> + </nav> + <h1>{{ .Title }}</h1> + </div> + </div> + {{ end }} + + <!-- Article Meta Bar --> + <div class="article-meta-bar"> + <div class="article-meta"> + <span class="article-type-badge type-{{ .Params.type }}">{{ .Params.type }}</span> + <span class="article-date">{{ .Date.Format "Jan 02, 2006" }}</span> + <span class="article-read-time">{{ .ReadingTime }} min read</span> + </div> + </div> + + <!-- Share Sidebar (for large screens) --> + {{ partial "share-sidebar.html" . }} + + <!-- Article Body --> + <div class="article-body container-narrow"> + {{ .Content }} + </div> + + <!-- Article Footer Nav --> + {{ $section := .Site.GetPage .Section }} + {{ if $section }} + {{ $prevPage := .PrevInSection }} + {{ $nextPage := .NextInSection }} + {{ if or $prevPage $nextPage }} + <nav class="article-footer-nav"> + {{ if $prevPage }} + <a href="{{ $prevPage.RelPermalink }}" class="nav-prev"> + <span class="nav-label">← Previous</span> + <span class="nav-title">{{ $prevPage.Title }}</span> + </a> + {{ end }} + {{ if $nextPage }} + <a href="{{ $nextPage.RelPermalink }}" class="nav-next"> + <span class="nav-label">Next →</span> + <span class="nav-title">{{ $nextPage.Title }}</span> + </a> + {{ end }} + </nav> + {{ end }} + {{ end }} +</article> diff --git a/layouts/_partials/featured-card.html b/layouts/_partials/featured-card.html new file mode 100644 index 0000000..cf2618f --- /dev/null +++ b/layouts/_partials/featured-card.html @@ -0,0 +1,23 @@ +{{ $page := .page }} + +<article class="featured-article"> + {{ if $page.Params.image }} + <div class="featured-image"> + <img src="{{ $page.Params.image }}" alt="{{ $page.Title }}" loading="lazy"> + </div> + {{ end }} + + <div class="featured-body"> + <div class="featured-header"> + <span class="featured-type-badge" style="color: var(--type-{{ $page.Params.type }});"> + {{ $page.Params.type }} + </span> + <span class="featured-date">$ {{ $page.Date.Format "2006-01-02" }}</span> + </div> + <h2 class="featured-title">{{ $page.Title }}</h2> + {{ with $page.Params.description }} + <p class="featured-excerpt">{{ . }}</p> + {{ end }} + <a href="{{ $page.RelPermalink }}" class="featured-link">Read the full article →</a> + </div> +</article> diff --git a/layouts/_partials/header.html b/layouts/_partials/header.html index 872c207..1f8efb8 100644 --- a/layouts/_partials/header.html +++ b/layouts/_partials/header.html @@ -1,17 +1,29 @@ -<div class="header-container"> - <a href="/" class="site-title">{{ .Site.Params.author }}</a> - <div class="header-controls"> - <nav> - <ul> +<nav class="nav-header" role="navigation" aria-label="Main navigation"> + <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu" aria-expanded="false"> + <span></span> + <span></span> + <span></span> + </button> + + <div class="menu-overlay" id="menu-overlay"> + <div class="menu-items"> + <a href="/" class="menu-logo">{{ .Site.Params.author }}</a> + + <ul class="menu-links"> {{ range .Site.Menus.main }} <li> - <a href="{{ .URL }}" {{ if (in $.RelPermalink .URL) }}class="active"{{ end }}> + <a href="{{ .URL }}" {{ if (in $.RelPermalink .URL) }}aria-current="page"{{ end }}> {{ .Name }} </a> </li> {{ end }} </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> + + <div class="menu-footer"> + <button class="theme-switch" id="theme-switch" aria-label="Toggle theme"> + <span class="theme-switch-dot"></span> + </button> + </div> + </div> </div> -</div> +</nav> diff --git a/layouts/_partials/hero.html b/layouts/_partials/hero.html index 11034be..ac8a4e1 100644 --- a/layouts/_partials/hero.html +++ b/layouts/_partials/hero.html @@ -1,11 +1,39 @@ -<section class="hero"> - {{ partial "matrix-canvas.html" . }} - <div class="hero-content"> - <div class="hero-avatar">{{ .Site.Params.avatar }}</div> - <div class="hero-text"> - <h1>{{ .Site.Params.author }}</h1> - <div class="hero-role">// engineer • writer • human</div> - <p class="hero-bio">{{ .Site.Params.description }}</p> +<section class="hero" role="region" aria-label="Hero"> + <div class="hero-left"> + <div class="hero-prompt">// Featured</div> + <h1 class="hero-name" data-text="{{ .Site.Params.author }}">{{ .Site.Params.author }}</h1> + <div class="hero-role" id="typed" data-phrases='{{ .Site.Params.typingPhrases | jsonify }}'></div> + <p class="hero-tagline">{{ .Site.Params.description }}</p> + <div class="hero-buttons"> + <a href="/articles/" class="btn btn-primary">Read Articles</a> + <a href="#articles" class="btn btn-outline">Explore</a> </div> </div> + + <div class="hero-right"> + <div class="hero-terminal"> + <div class="terminal-bar"> + <span class="terminal-dot" style="background: #ff6b6b;"></span> + <span class="terminal-dot" style="background: #ffd93d;"></span> + <span class="terminal-dot" style="background: #6bcf7f;"></span> + </div> + <div class="terminal-content"> + <div>$ <span class="terminal-prompt">whoami</span></div> + <div>danilo</div> + <div>$ <span class="terminal-prompt">pwd</span></div> + <div>/home/danilo/web</div> + <div>$ <span class="terminal-prompt">ls -la</span></div> + <div>total 48</div> + <div>drwxr-xr-x 5 danilo staff 160 Apr 9 2026 .</div> + <div>-rw-r--r-- 1 danilo staff 4.2K blog.md</div> + </div> + </div> + </div> + + <div class="scroll-indicator"> + <span>Scroll to explore</span> + <svg width="20" height="20" viewBox="0 0 20 20" fill="none"> + <path d="M10 3v10M6 9l4 4 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> + </svg> + </div> </section> diff --git a/layouts/_partials/matrix-canvas.html b/layouts/_partials/matrix-canvas.html deleted file mode 100644 index b10b471..0000000 --- a/layouts/_partials/matrix-canvas.html +++ /dev/null @@ -1 +0,0 @@ -<canvas id="matrix-canvas"></canvas> diff --git a/layouts/_partials/photo-article.html b/layouts/_partials/photo-article.html new file mode 100644 index 0000000..1040c9b --- /dev/null +++ b/layouts/_partials/photo-article.html @@ -0,0 +1,32 @@ +<article class="article-single"> + <!-- Photo Hero --> + {{ if .Params.image }} + <div class="article-hero" style="background-image: url('{{ .Params.image }}')"> + <div class="article-hero-overlay"></div> + <div class="article-hero-content"> + <h1>{{ .Title }}</h1> + </div> + </div> + {{ end }} + + <!-- Article Meta Bar --> + <div class="article-meta-bar"> + <div class="article-meta"> + <span class="article-type-badge type-{{ .Params.type }}">{{ .Params.type }}</span> + <span class="article-date">{{ .Date.Format "Jan 02, 2006" }}</span> + </div> + </div> + + <!-- Photo Grid --> + <div class="article-body container-narrow"> + <div class="photo-grid" data-lightbox="true"> + {{ .Content }} + </div> + </div> + + <!-- Load photo utilities --> + {{ $photoUtils := resources.Get "js/photo-utils.js" }} + {{ $lightbox := resources.Get "js/lightbox.js" | fingerprint }} + <script src="{{ $photoUtils.RelPermalink }}"></script> + <script src="{{ $lightbox.RelPermalink }}"></script> +</article> diff --git a/layouts/_partials/share-sidebar.html b/layouts/_partials/share-sidebar.html new file mode 100644 index 0000000..36b6d03 --- /dev/null +++ b/layouts/_partials/share-sidebar.html @@ -0,0 +1,28 @@ +<aside class="share-sidebar" id="share-sidebar" data-url="{{ .Permalink }}" data-title="{{ .Title | htmlEscape }}"> + <div class="share-buttons"> + <button class="share-btn" data-platform="whatsapp" title="Share on WhatsApp"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg> + </button> + <button class="share-btn" data-platform="telegram" title="Share on Telegram"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line></svg> + </button> + <button class="share-btn" data-platform="linkedin" title="Share on LinkedIn"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6zM2 9h4v12H2z"></path><circle cx="4" cy="4" r="2"></circle></svg> + </button> + <button class="share-btn" data-platform="twitter" title="Share on X (Twitter)"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2s9 5 20 0a9.5 9.5 0 0 0 5-6.5"></path></svg> + </button> + <button class="share-btn" data-platform="facebook" title="Share on Facebook"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 2h-3a6 6 0 0 0-6 6v4a6 6 0 0 0 6 6h3"></path><path d="M16 18v2"></path><path d="M6 6v12"></path></svg> + </button> + <button class="share-btn" data-platform="reddit" title="Share on Reddit"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="1"></circle><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm7-3c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3z"></path></svg> + </button> + <button class="share-btn" data-platform="email" title="Share via Email"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg> + </button> + <button class="share-btn" id="share-copy" title="Copy link"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> + </button> + </div> +</aside> diff --git a/layouts/_partials/static-page.html b/layouts/_partials/static-page.html new file mode 100644 index 0000000..d557b2f --- /dev/null +++ b/layouts/_partials/static-page.html @@ -0,0 +1,33 @@ +<article class="static-page"> + <!-- Static Page Hero --> + <div class="page-hero"> + <div class="page-hero-overlay"></div> + <div class="page-hero-content"> + <h1>{{ .Title }}</h1> + </div> + </div> + + <!-- Page Content --> + <div class="page-content container-narrow"> + {{ .Content }} + </div> + + <!-- Related Pages Nav (for is/* section) --> + {{ if eq .Section "is" }} + <nav class="page-nav" style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border);"> + <h3 style="margin-bottom: 1rem;">Other pages</h3> + <ul style="list-style: none; margin: 0;"> + {{ $section := .Site.GetPage "/is" }} + {{ if $section }} + {{ range $section.Pages }} + <li style="margin-bottom: 0.5rem;"> + <a href="{{ .RelPermalink }}" {{ if eq $.RelPermalink .RelPermalink }}class="active"{{ end }}> + {{ .Title }} + </a> + </li> + {{ end }} + {{ end }} + </ul> + </nav> + {{ end }} +</article> diff --git a/layouts/_partials/timeline-item.html b/layouts/_partials/timeline-item.html new file mode 100644 index 0000000..fcb3f50 --- /dev/null +++ b/layouts/_partials/timeline-item.html @@ -0,0 +1,31 @@ +{{ $page := .page }} +{{ $index := .index }} +{{ $position := "left" }} +{{ if (eq (mod $index 2) 1) }} + {{ $position = "right" }} +{{ end }} + +<article class="timeline-item {{ $position }}" data-type="{{ $page.Params.type }}"> + <div class="timeline-dot"></div> + + <div class="article-card"> + {{ if $page.Params.image }} + <div class="article-card-image"> + <img src="{{ $page.Params.image }}" alt="{{ $page.Title }}" loading="lazy"> + </div> + {{ end }} + + <div class="article-card-body"> + <div class="article-card-header"> + <span class="article-type-badge type-{{ $page.Params.type }}">{{ $page.Params.type }}</span> + <span class="article-date">{{ $page.Date.Format "Jan 02, 2006" }}</span> + </div> + <h3 class="article-card-title"> + <a href="{{ $page.RelPermalink }}">{{ $page.Title }}</a> + </h3> + {{ with $page.Params.description }} + <p class="article-card-excerpt">{{ . }}</p> + {{ end }} + </div> + </div> +</article> diff --git a/layouts/baseof.html b/layouts/baseof.html index ad6613f..c9633d0 100644 --- a/layouts/baseof.html +++ b/layouts/baseof.html @@ -2,11 +2,21 @@ <html lang="{{ site.Language.Locale }}" dir="{{ or site.Language.Direction `ltr` }}"> <head> {{ partial "head.html" . }} + <script> + (function() { + const theme = localStorage.getItem('theme') || 'dark'; + if (theme === 'light') { + document.documentElement.classList.add('theme-light'); + } + })(); + </script> </head> <body> - <div class="reading-progress"></div> - <header>{{ partial "header.html" . }}</header> - <main>{{ block "main" . }}{{ end }}</main> + <a href="#main-content" class="skip-link">Skip to content</a> + <div class="progress-bar" id="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> + <canvas id="matrix-canvas" aria-hidden="true" data-mode="{{ block "canvas-mode" . }}background{{ end }}"></canvas> + {{ partial "header.html" . }} + <main id="main-content">{{ block "main" . }}{{ end }}</main> <footer>{{ partial "footer.html" . }}</footer> </body> </html> diff --git a/layouts/home.html b/layouts/home.html index f285b41..6328ee5 100644 --- a/layouts/home.html +++ b/layouts/home.html @@ -1,29 +1,27 @@ +{{ define "canvas-mode" }}hero{{ end }} + {{ define "main" }} {{ partial "hero.html" . }} - <div class="container feed-section"> - <div class="feed-label">Latest</div> - - <div class="feed-grid"> - {{ $articlesSection := .Site.GetPage "/articles" }} - {{ if $articlesSection }} - {{ $articles := $articlesSection.Pages }} - {{ $articles := sort $articles "Date" "desc" }} - {{ range first 6 $articles }} - {{ $type := .Params.type }} - {{ if not $type }}{{ $type = "article" }}{{ end }} + <section id="articles" class="section-container reveal-group"> + {{ $articlesSection := .Site.GetPage "/articles" }} + {{ if $articlesSection }} + {{ $articles := $articlesSection.Pages }} + {{ $articles := sort $articles "Date" "desc" }} + {{ range first 6 $articles }} + {{ $type := .Params.type }} + {{ if not $type }}{{ $type = "article" }}{{ end }} - {{ $excerpt := .Params.excerpt }} - {{ if not $excerpt }} - {{ $excerpt = .Summary | plainify | truncate 150 }} - {{ end }} - - {{ $data := dict "title" .Title "type" $type "description" $excerpt "date" .Date "url" .RelPermalink "image" .Params.image "featured" .Params.featured }} - {{ partial "post-card.html" $data }} + {{ $excerpt := .Params.excerpt }} + {{ if not $excerpt }} + {{ $excerpt = .Summary | plainify | truncate 150 }} {{ end }} + + {{ $data := dict "title" .Title "type" $type "description" $excerpt "date" .Date "url" .RelPermalink "image" .Params.image "featured" .Params.featured }} + {{ partial "post-card.html" $data }} {{ end }} - </div> + {{ end }} - <a href="/articles/" class="feed-cta">View all articles</a> - </div> + <a href="/articles/" class="btn btn-outline">View All Articles</a> + </section> {{ end }} diff --git a/layouts/page.html b/layouts/page.html index 8fb2903..44073b2 100644 --- a/layouts/page.html +++ b/layouts/page.html @@ -1,35 +1,9 @@ {{ define "main" }} - <article class="page-page"> - <div class="container-narrow"> - <h1>{{ .Title }}</h1> - <div class="post-card-meta" style="margin-bottom: 2rem;"> - <span>{{ dateFormat "Jan 2, 2006" .Date }}</span> - {{ if .Params.type }}<span class="post-type-badge {{ .Params.type }}">{{ .Params.type }}</span>{{ end }} - </div> - - <div class="post-content"> - {{ .Content }} - </div> - </div> - </article> - - {{ if eq .Type "is" }} - <div class="container-narrow" style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border);"> - <nav class="page-nav"> - <h3 style="margin-bottom: 1rem;">Other pages</h3> - <ul style="list-style: none; margin: 0;"> - {{ $section := .Site.GetPage "/is" }} - {{ if $section }} - {{ range $section.Pages }} - <li style="margin-bottom: 0.5rem;"> - <a href="{{ .RelPermalink }}" {{ if eq $.RelPermalink .RelPermalink }}class="active"{{ end }}> - {{ .Title }} - </a> - </li> - {{ end }} - {{ end }} - </ul> - </nav> - </div> + {{ if eq .Params.type "photo" }} + {{ partial "photo-article.html" . }} + {{ else if eq .Section "is" }} + {{ partial "static-page.html" . }} + {{ else }} + {{ partial "article-single.html" . }} {{ end }} {{ end }} diff --git a/layouts/section.html b/layouts/section.html index b9f0646..d817087 100644 --- a/layouts/section.html +++ b/layouts/section.html @@ -1,9 +1,9 @@ {{ define "main" }} - <div class="container"> - <h1>{{ .Title }}</h1> - - {{ if eq .Type "articles" }} - <div class="filter-bar"> + {{ if eq .Type "articles" }} + <!-- Articles Section with Timeline --> + <div class="page-header"> + <h1>{{ .Title }}</h1> + <div class="filter-buttons"> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="tech">Tech</button> <button class="filter-btn" data-filter="life">Life</button> @@ -11,25 +11,30 @@ <button class="filter-btn" data-filter="link">Link</button> <button class="filter-btn" data-filter="photo">Photo</button> </div> + </div> - <div class="feed-list" id="articles-feed"> - {{ range .Pages.ByDate.Reverse }} - {{ $excerpt := .Params.excerpt }} - {{ if not $excerpt }} - {{ $excerpt = .Summary | plainify | truncate 150 }} - {{ end }} + {{ $featured := (.Pages.ByDate.Reverse) }} + {{ if and $featured (index $featured 0).Params.featured }} + {{ partial "featured-card.html" (dict "page" (index $featured 0)) }} + {{ end }} - {{ $data := dict "title" .Title "type" .Params.type "description" $excerpt "date" .Date "url" .RelPermalink "image" .Params.image "featured" false }} - {{ partial "post-card.html" $data }} + <section class="timeline-section"> + <div class="timeline-line"></div> + <div class="timeline-feed"> + {{ $pages := .Pages.ByDate.Reverse }} + {{ range $index, $page := $pages }} + {{ partial "timeline-item.html" (dict "page" $page "index" $index) }} {{ end }} </div> - {{ else }} - {{ .Content }} - {{ end }} - </div> + </section> - {{ if eq .Type "articles" }} {{ $filters := resources.Get "js/filters.js" | fingerprint }} <script defer src="{{ $filters.RelPermalink }}"></script> + + {{ else }} + <!-- Static Section (is/about, is/contact, etc.) --> + <div class="container-narrow" style="padding-top: 2rem;"> + {{ .Content }} + </div> {{ end }} {{ end }} diff --git a/layouts/shortcodes/gal-img.html b/layouts/shortcodes/gal-img.html index 0693319..ae7d23e 100644 --- a/layouts/shortcodes/gal-img.html +++ b/layouts/shortcodes/gal-img.html @@ -1,7 +1,16 @@ {{- $src := .Get "src" -}} {{- $source := resources.Get $src -}} {{- $alt := .Get "alt" -}} -{{- $icon := $source.Resize "400x webp" -}} -<a class="gallery-item" href="{{ $source.RelPermalink }}" target="_blank"> - <img src="{{ $icon.RelPermalink }}" alt="{{ $alt }}"> -</a> +{{- $caption := .Get "caption" -}} +{{- $location := .Get "location" -}} +{{- $fullsize := $source -}} +{{- $thumb := $source.Resize "400x webp" -}} +<figure class="photo-card" + data-photo-index="{{ .Ordinal }}" + data-src="{{ $fullsize.RelPermalink }}" + data-alt="{{ $alt }}" + data-caption="{{ $caption }}" + data-location="{{ $location }}"> + <img src="{{ $thumb.RelPermalink }}" alt="{{ $alt }}" loading="lazy"> + {{ with $caption }}<figcaption>{{ . }}</figcaption>{{ end }} +</figure> diff --git a/layouts/shortcodes/gallery.html b/layouts/shortcodes/gallery.html index 8a30fc5..f9e546e 100644 --- a/layouts/shortcodes/gallery.html +++ b/layouts/shortcodes/gallery.html @@ -1,5 +1,3 @@ -<div class="gallery"> - <div class="gallery-inner"> - {{ .Inner }} - </div> +<div class="photo-grid" data-lightbox="true"> + {{ .Inner }} </div> diff --git a/public/articles/index.html b/public/articles/index.html deleted file mode 100644 index 9d424dd..0000000 --- a/public/articles/index.html +++ /dev/null @@ -1,95 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Articles | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" class="active"> - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <div class="container"> - <h1>Articles</h1> - - - <div class="filter-bar"> - <button class="filter-btn active" data-filter="all">All</button> - <button class="filter-btn" data-filter="tech">Tech</button> - <button class="filter-btn" data-filter="life">Life</button> - <button class="filter-btn" data-filter="quote">Quote</button> - <button class="filter-btn" data-filter="link">Link</button> - <button class="filter-btn" data-filter="photo">Photo</button> - </div> - - <div class="feed-list" id="articles-feed"> - - </div> - - </div> - - - - <script defer src="/js/filters.38212ecd54ff7f1fdebf2aebe32e8c248382e80f93dae0761ebbbd03ca28dc5b.js"></script> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/categories/index.html b/public/categories/index.html deleted file mode 100644 index fc9956a..0000000 --- a/public/categories/index.html +++ /dev/null @@ -1,75 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Categories | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <h1>Categories</h1> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/categories/index.xml b/public/categories/index.xml deleted file mode 100644 index f36f245..0000000 --- a/public/categories/index.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Categories on danilo m.</title> - <link>http://localhost:1313/categories/</link> - <description>Recent content in Categories on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <atom:link href="http://localhost:1313/categories/index.xml" rel="self" type="application/rss+xml" /> - </channel> -</rss> diff --git a/public/css/main.30bbabcf0c588c3c13cbe24430d7aa6226315a94faf09d877dd441b3ebf03774.css b/public/css/main.30bbabcf0c588c3c13cbe24430d7aa6226315a94faf09d877dd441b3ebf03774.css deleted file mode 100644 index 4d80946..0000000 --- a/public/css/main.30bbabcf0c588c3c13cbe24430d7aa6226315a94faf09d877dd441b3ebf03774.css +++ /dev/null @@ -1 +0,0 @@ -header{border-bottom:1px solid #222;margin-bottom:1rem}footer{border-top:1px solid #222;margin-top:1rem}body{color:#222;font-family:sans-serif;line-height:1.5;margin:1rem;max-width:768px}a{color:#00e;text-decoration:none} diff --git a/public/css/main.3abe95debec71c071dca144ff88e0ce1f7c17e0c6cc9f1a0138ae45683de8c86.css b/public/css/main.3abe95debec71c071dca144ff88e0ce1f7c17e0c6cc9f1a0138ae45683de8c86.css deleted file mode 100644 index 14496ee..0000000 --- a/public/css/main.3abe95debec71c071dca144ff88e0ce1f7c17e0c6cc9f1a0138ae45683de8c86.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600&family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300&family=Oxanium:wght@700;800&display=swap";:root{--bg: #060b10;--bg2: #0c1520;--surface: #101e2d;--border: #182840;--accent: #a855f7;--accent2: #00ff88;--text: #c4d6e8;--text-dim: #7a9bb8;--muted: #304860;--color-tech: #a855f7;--color-life: #f59e0b;--color-quote: #00ff88;--color-link: #38bdf8;--color-photo: #ec4899;--font-body: "IBM Plex Sans", system-ui, sans-serif;--font-mono: "JetBrains Mono", "Courier New", monospace;--font-head: "Oxanium", sans-serif;--fs-body: .95rem;--fs-nav: .8rem;--fs-badge: .7rem;--fs-btn: .8rem;--fs-h3: 1.5rem;--fs-h2: clamp(1.7rem, 6vw, 3rem);--container-max: 1080px;--container-narrow: 768px;--gap-sm: .5rem;--gap-md: 1.5rem;--gap-lg: 2.5rem;--gap-xl: 4rem;--section-py-mobile: 4rem;--section-py-desktop: 6rem;--card-px-mobile: 1.5rem;--card-px-desktop: 2rem;--transition: all .2s ease;--transition-slow: all .75s cubic-bezier(.16,1,.3,1)}html.theme-light{--bg: #f0f4f8;--bg2: #e2eaf4;--surface: #d4dff0;--border: #a8bdd8;--accent: #7c3aed;--accent2: #008f5a;--text: #0d1b2a;--text-dim: #2e4a6a;--muted: #6888a8}@media(max-width:479px){:root{--bp: "mobile"}}@media(min-width:480px){:root{--bp: "sm"}}@media(min-width:768px){:root{--bp: "md"}}@media(min-width:1200px){:root{--bp: "lg"}}html{font-size:17px;scroll-behavior:smooth}*{margin:0;padding:0;box-sizing:border-box}body{background-color:var(--bg);color:var(--text);font-family:var(--font-body);font-size:var(--fs-body);line-height:1.95;transition:background-color .2s,color .2s}h1{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin-bottom:.5rem}h2{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin:2rem 0 1rem}h3{font-family:var(--font-head);font-size:var(--fs-h3);font-weight:800;line-height:1.2;margin:1.5rem 0 .75rem}h4,h5,h6{font-family:var(--font-head);font-weight:800;margin:1rem 0 .5rem}p{margin-bottom:1rem}a{color:var(--accent);text-decoration:none;transition:var(--transition)}a:hover{color:var(--accent2)}.container{max-width:var(--container-max);margin:0 auto;padding:0 1.5rem}.container-narrow{max-width:var(--container-narrow);margin:0 auto;padding:0 1.5rem}main{min-height:calc(100vh - 200px)}ul,ol{margin-left:1.5rem;margin-bottom:1rem}li{margin-bottom:.5rem}code{font-family:var(--font-mono);background:var(--surface);padding:.25rem .5rem;border-radius:4px;font-size:.9em}pre{margin-bottom:1rem;overflow-x:auto}pre code{padding:0;background:none;border-radius:0}:focus{outline:2px solid var(--accent);outline-offset:2px}button:focus,a:focus{outline:2px dashed var(--accent);outline-offset:4px}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}} diff --git a/public/css/main.5c9869e05d53e10d15258a314b452f5a95242f4e39dd052c90b7d7b5619c40c4.css b/public/css/main.5c9869e05d53e10d15258a314b452f5a95242f4e39dd052c90b7d7b5619c40c4.css deleted file mode 100644 index 47a344e..0000000 --- a/public/css/main.5c9869e05d53e10d15258a314b452f5a95242f4e39dd052c90b7d7b5619c40c4.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600&family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300&family=Oxanium:wght@700;800&display=swap";:root{--bg: #060b10;--bg2: #0c1520;--surface: #101e2d;--border: #182840;--accent: #a855f7;--accent2: #00ff88;--text: #c4d6e8;--text-dim: #7a9bb8;--muted: #304860;--color-tech: #a855f7;--color-life: #f59e0b;--color-quote: #00ff88;--color-link: #38bdf8;--color-photo: #ec4899;--font-body: "IBM Plex Sans", system-ui, sans-serif;--font-mono: "JetBrains Mono", "Courier New", monospace;--font-head: "Oxanium", sans-serif;--fs-body: .95rem;--fs-nav: .8rem;--fs-badge: .7rem;--fs-btn: .8rem;--fs-h3: 1.5rem;--fs-h2: clamp(1.7rem, 6vw, 3rem);--container-max: 1080px;--container-narrow: 768px;--gap-sm: .5rem;--gap-md: 1.5rem;--gap-lg: 2.5rem;--gap-xl: 4rem;--section-py-mobile: 4rem;--section-py-desktop: 6rem;--card-px-mobile: 1.5rem;--card-px-desktop: 2rem;--transition: all .2s ease;--transition-slow: all .75s cubic-bezier(.16,1,.3,1)}html.theme-light{--bg: #f0f4f8;--bg2: #e2eaf4;--surface: #d4dff0;--border: #a8bdd8;--accent: #7c3aed;--accent2: #008f5a;--text: #0d1b2a;--text-dim: #2e4a6a;--muted: #6888a8}@media(max-width:479px){:root{--bp: "mobile"}}@media(min-width:480px){:root{--bp: "sm"}}@media(min-width:768px){:root{--bp: "md"}}@media(min-width:1200px){:root{--bp: "lg"}}.hero{position:relative;overflow:hidden;padding:var(--section-py-mobile) 1.5rem;background:var(--bg);border-bottom:1px solid var(--border)}@media(min-width:768px){.hero{padding:var(--section-py-desktop) 1.5rem}}#matrix-canvas{position:absolute;inset:0;opacity:.13;pointer-events:none}html.theme-light #matrix-canvas{opacity:.18}.hero-content{position:relative;z-index:1;max-width:var(--container-max);margin:0 auto;display:flex;align-items:center;gap:var(--gap-lg)}.hero-avatar{width:64px;height:64px;border-radius:50%;flex-shrink:0;background:linear-gradient(135deg,var(--accent),var(--accent2));display:flex;align-items:center;justify-content:center;font-family:var(--font-head);font-size:1.4rem;font-weight:800;color:#fff}@media(min-width:768px){.hero-avatar{width:80px;height:80px;font-size:1.8rem}}.hero-text h1{margin-bottom:.25rem}.hero-role{font-family:var(--font-mono);font-size:.85rem;color:var(--accent);letter-spacing:.1em;text-transform:uppercase;margin-bottom:.75rem}.hero-bio{color:var(--text-dim);font-size:.95rem;line-height:1.8;max-width:400px}#matrix-canvas:after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(0deg,rgba(0,0,0,.15),rgba(0,0,0,.15) 1px,transparent 1px,transparent 2px);pointer-events:none}.hero:before{content:"";position:absolute;top:50%;left:50%;width:600px;height:600px;background:radial-gradient(circle,rgba(168,85,247,.15) 0%,transparent 70%);transform:translate(-50%,-50%);pointer-events:none}@media(max-width:768px){.hero-content{flex-direction:column;text-align:center}.hero-bio{max-width:100%}}html{font-size:17px;scroll-behavior:smooth}*{margin:0;padding:0;box-sizing:border-box}body{background-color:var(--bg);color:var(--text);font-family:var(--font-body);font-size:var(--fs-body);line-height:1.95;transition:background-color .2s,color .2s}h1{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin-bottom:.5rem}h2{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin:2rem 0 1rem}h3{font-family:var(--font-head);font-size:var(--fs-h3);font-weight:800;line-height:1.2;margin:1.5rem 0 .75rem}h4,h5,h6{font-family:var(--font-head);font-weight:800;margin:1rem 0 .5rem}p{margin-bottom:1rem}a{color:var(--accent);text-decoration:none;transition:var(--transition)}a:hover{color:var(--accent2)}.container{max-width:var(--container-max);margin:0 auto;padding:0 1.5rem}.container-narrow{max-width:var(--container-narrow);margin:0 auto;padding:0 1.5rem}main{min-height:calc(100vh - 200px)}ul,ol{margin-left:1.5rem;margin-bottom:1rem}li{margin-bottom:.5rem}code{font-family:var(--font-mono);background:var(--surface);padding:.25rem .5rem;border-radius:4px;font-size:.9em}pre{margin-bottom:1rem;overflow-x:auto}pre code{padding:0;background:none;border-radius:0}:focus{outline:2px solid var(--accent);outline-offset:2px}button:focus,a:focus{outline:2px dashed var(--accent);outline-offset:4px}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}} diff --git a/public/css/main.8337d7f7e0fbf6083195dbb6bd8ad102187face3b194ff449dc78376ca12e014.css b/public/css/main.8337d7f7e0fbf6083195dbb6bd8ad102187face3b194ff449dc78376ca12e014.css deleted file mode 100644 index 055b01b..0000000 --- a/public/css/main.8337d7f7e0fbf6083195dbb6bd8ad102187face3b194ff449dc78376ca12e014.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600&family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300&family=Oxanium:wght@700;800&display=swap";:root{--bg: #060b10;--bg2: #0c1520;--surface: #101e2d;--border: #182840;--accent: #a855f7;--accent2: #00ff88;--text: #c4d6e8;--text-dim: #7a9bb8;--muted: #304860;--color-tech: #a855f7;--color-life: #f59e0b;--color-quote: #00ff88;--color-link: #38bdf8;--color-photo: #ec4899;--font-body: "IBM Plex Sans", system-ui, sans-serif;--font-mono: "JetBrains Mono", "Courier New", monospace;--font-head: "Oxanium", sans-serif;--fs-body: .95rem;--fs-nav: .8rem;--fs-badge: .7rem;--fs-btn: .8rem;--fs-h3: 1.5rem;--fs-h2: clamp(1.7rem, 6vw, 3rem);--container-max: 1080px;--container-narrow: 768px;--gap-sm: .5rem;--gap-md: 1.5rem;--gap-lg: 2.5rem;--gap-xl: 4rem;--section-py-mobile: 4rem;--section-py-desktop: 6rem;--card-px-mobile: 1.5rem;--card-px-desktop: 2rem;--transition: all .2s ease;--transition-slow: all .75s cubic-bezier(.16,1,.3,1)}html.theme-light{--bg: #f0f4f8;--bg2: #e2eaf4;--surface: #d4dff0;--border: #a8bdd8;--accent: #7c3aed;--accent2: #008f5a;--text: #0d1b2a;--text-dim: #2e4a6a;--muted: #6888a8}@media(max-width:479px){:root{--bp: "mobile"}}@media(min-width:480px){:root{--bp: "sm"}}@media(min-width:768px){:root{--bp: "md"}}@media(min-width:1200px){:root{--bp: "lg"}}.hero{position:relative;overflow:hidden;padding:var(--section-py-mobile) 1.5rem;background:var(--bg);border-bottom:1px solid var(--border)}@media(min-width:768px){.hero{padding:var(--section-py-desktop) 1.5rem}}#matrix-canvas{position:absolute;inset:0;opacity:.13;pointer-events:none}html.theme-light #matrix-canvas{opacity:.18}.hero-content{position:relative;z-index:1;max-width:var(--container-max);margin:0 auto;display:flex;align-items:center;gap:var(--gap-lg)}.hero-avatar{width:64px;height:64px;border-radius:50%;flex-shrink:0;background:linear-gradient(135deg,var(--accent),var(--accent2));display:flex;align-items:center;justify-content:center;font-family:var(--font-head);font-size:1.4rem;font-weight:800;color:#fff}@media(min-width:768px){.hero-avatar{width:80px;height:80px;font-size:1.8rem}}.hero-text h1{margin-bottom:.25rem}.hero-role{font-family:var(--font-mono);font-size:.85rem;color:var(--accent);letter-spacing:.1em;text-transform:uppercase;margin-bottom:.75rem}.hero-bio{color:var(--text-dim);font-size:.95rem;line-height:1.8;max-width:400px}#matrix-canvas:after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(0deg,rgba(0,0,0,.15),rgba(0,0,0,.15) 1px,transparent 1px,transparent 2px);pointer-events:none}.hero:before{content:"";position:absolute;top:50%;left:50%;width:600px;height:600px;background:radial-gradient(circle,rgba(168,85,247,.15) 0%,transparent 70%);transform:translate(-50%,-50%);pointer-events:none}@media(max-width:768px){.hero-content{flex-direction:column;text-align:center}.hero-bio{max-width:100%}}.post-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;overflow:hidden;transition:var(--transition);display:flex;gap:var(--gap-md)}.post-card:hover{border-color:var(--accent);box-shadow:0 0 20px #a855f733}.post-card-image{width:120px;height:100px;flex-shrink:0;object-fit:cover;background:linear-gradient(135deg,var(--border),var(--bg2));border-right:1px solid var(--border)}@media(min-width:768px){.post-card-image{width:160px;height:120px}}.post-card-body{padding:var(--gap-md);display:flex;flex-direction:column;justify-content:center;flex-grow:1}.post-type-badge{display:inline-block;font-family:var(--font-mono);font-size:var(--fs-badge);font-weight:600;text-transform:uppercase;letter-spacing:.1em;padding:.35rem .7rem;border-radius:20px;margin-bottom:.5rem;width:fit-content}.post-type-badge.tech{background:color-mix(in srgb,var(--color-tech) 15%,transparent);border:1px solid color-mix(in srgb,var(--color-tech) 30%,transparent);color:var(--color-tech)}.post-type-badge.life{background:color-mix(in srgb,var(--color-life) 15%,transparent);border:1px solid color-mix(in srgb,var(--color-life) 30%,transparent);color:var(--color-life)}.post-type-badge.quote{background:color-mix(in srgb,var(--color-quote) 15%,transparent);border:1px solid color-mix(in srgb,var(--color-quote) 30%,transparent);color:var(--color-quote)}.post-type-badge.link{background:color-mix(in srgb,var(--color-link) 15%,transparent);border:1px solid color-mix(in srgb,var(--color-link) 30%,transparent);color:var(--color-link)}.post-type-badge.photo{background:color-mix(in srgb,var(--color-photo) 15%,transparent);border:1px solid color-mix(in srgb,var(--color-photo) 30%,transparent);color:var(--color-photo)}.post-card-title{font-family:var(--font-head);font-size:1.1rem;font-weight:700;line-height:1.3;margin-bottom:.5rem;color:var(--text)}.post-card-title a{color:var(--text);text-decoration:none}.post-card-title a:hover{color:var(--accent)}.post-card-excerpt{color:var(--text-dim);font-size:.9rem;line-height:1.6;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-bottom:.5rem}.post-card-meta{display:flex;gap:1rem;font-family:var(--font-mono);font-size:.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.post-card.featured{grid-row:span 2}.post-card.featured .post-card-image{width:100%;height:180px;border-right:none;border-bottom:1px solid var(--border)}.post-card.featured .post-card-body{padding:var(--gap-lg)}@media(max-width:768px){.post-card{flex-direction:column}.post-card-image{width:100%;height:150px;border-right:none;border-bottom:1px solid var(--border)}.post-card.featured .post-card-image{height:150px}}.feed-section{padding:var(--section-py-mobile) 0}@media(min-width:768px){.feed-section{padding:var(--section-py-desktop) 0}}.feed-label{font-family:var(--font-mono);font-size:.75rem;letter-spacing:.15em;text-transform:uppercase;color:var(--accent);margin-bottom:1.5rem}.feed-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:var(--gap-md);margin-bottom:var(--gap-xl)}@media(min-width:768px){.feed-grid{grid-template-columns:repeat(2,1fr)}}@media(min-width:1200px){.feed-grid{grid-template-columns:repeat(3,1fr)}}.feed-list{display:flex;flex-direction:column;gap:var(--gap-md)}.feed-list .post-card{flex-direction:row}.filter-bar{display:flex;gap:var(--gap-sm);margin-bottom:var(--gap-lg);flex-wrap:wrap}.filter-btn{font-family:var(--font-mono);font-size:var(--fs-badge);padding:.4rem 1rem;border:1px solid var(--border);border-radius:20px;background:transparent;color:var(--text-dim);text-transform:uppercase;letter-spacing:.1em;cursor:pointer;transition:var(--transition)}.filter-btn:hover{border-color:var(--accent);color:var(--accent)}.filter-btn.active{background:var(--accent);color:#fff;border-color:var(--accent)}.feed-cta{display:inline-block;padding:.75rem 1.5rem;background:var(--accent);color:#fff;border-radius:4px;font-family:var(--font-mono);font-size:var(--fs-btn);text-transform:uppercase;letter-spacing:.1em;text-decoration:none;transition:var(--transition)}.feed-cta:hover{background:var(--accent2);color:var(--bg)}pre{background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:6px;padding:1rem;overflow-x:auto;position:relative;margin:1.5rem 0}pre code{font-family:var(--font-mono);font-size:.9rem;line-height:1.6;color:var(--text)}.highlight{background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:6px;padding:1rem;overflow-x:auto;margin:1.5rem 0;position:relative}.highlight code{background:none;padding:0;border-radius:0;color:inherit}.highlight .k,.highlight .kn,.highlight .kp,.highlight .kr{color:#f59e0b}.highlight .kt{color:#a855f7}.highlight .n{color:#c4d6e8}.highlight .na,.highlight .nb{color:#38bdf8}.highlight .nc{color:#a855f7}.highlight .no{color:#0f8}.highlight .nd{color:#f59e0b}.highlight .ni{color:#a855f7}.highlight .ne{color:#f59e0b}.highlight .nf{color:#38bdf8}.highlight .nl,.highlight .nn{color:#a855f7}.highlight .nt{color:#f59e0b}.highlight .nv{color:#c4d6e8}.highlight .s,.highlight .sa,.highlight .sb,.highlight .sc,.highlight .s1,.highlight .s2{color:#0f8}.highlight .se{color:#f59e0b}.highlight .sh{color:#0f8}.highlight .si{color:#f59e0b}.highlight .sx,.highlight .sr,.highlight .ss{color:#0f8}.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .il,.highlight .mo{color:#38bdf8}.highlight .o{color:#c4d6e8}.highlight .ow{color:#a855f7}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm{color:#7a9bb8}.highlight .cp,.highlight .cpf{color:#f59e0b}html.theme-light .highlight{background:var(--surface);border-left-color:var(--accent)}html.theme-light .highlight .c{color:#6a7fa0}.code-copy-btn{position:absolute;top:.75rem;right:.75rem;background:var(--accent);color:#fff;border:none;padding:.4rem .8rem;border-radius:4px;font-family:var(--font-mono);font-size:.75rem;cursor:pointer;opacity:0;transition:var(--transition);text-transform:uppercase;letter-spacing:.08em}.highlight:hover .code-copy-btn,pre:hover .code-copy-btn{opacity:1}.code-copy-btn:hover{background:var(--accent2);color:var(--bg)}.code-copy-btn.copied{background:var(--accent2)}code{font-family:var(--font-mono);background:var(--surface);padding:.25rem .5rem;border-radius:4px;font-size:.9em;color:var(--accent2)}p code{border:1px solid color-mix(in srgb,var(--accent) 20%,transparent)}.reading-progress{position:fixed;top:0;left:0;height:3px;background:linear-gradient(90deg,var(--accent),var(--accent2));width:0%;z-index:200;transition:width .1s ease-out}.article-page .reading-progress,.page-page .reading-progress{display:block}body:not(.scrollable) .reading-progress{display:none}html{font-size:17px;scroll-behavior:smooth}*{margin:0;padding:0;box-sizing:border-box}body{background-color:var(--bg);color:var(--text);font-family:var(--font-body);font-size:var(--fs-body);line-height:1.95;transition:background-color .2s,color .2s}h1{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin-bottom:.5rem}h2{font-family:var(--font-head);font-size:var(--fs-h2);font-weight:800;line-height:1.1;margin:2rem 0 1rem}h3{font-family:var(--font-head);font-size:var(--fs-h3);font-weight:800;line-height:1.2;margin:1.5rem 0 .75rem}h4,h5,h6{font-family:var(--font-head);font-weight:800;margin:1rem 0 .5rem}p{margin-bottom:1rem}a{color:var(--accent);text-decoration:none;transition:var(--transition)}a:hover{color:var(--accent2)}.container{max-width:var(--container-max);margin:0 auto;padding:0 1.5rem}.container-narrow{max-width:var(--container-narrow);margin:0 auto;padding:0 1.5rem}main{min-height:calc(100vh - 200px)}ul,ol{margin-left:1.5rem;margin-bottom:1rem}li{margin-bottom:.5rem}code{font-family:var(--font-mono);background:var(--surface);padding:.25rem .5rem;border-radius:4px;font-size:.9em}pre{margin-bottom:1rem;overflow-x:auto}pre code{padding:0;background:none;border-radius:0}:focus{outline:2px solid var(--accent);outline-offset:2px}button:focus,a:focus{outline:2px dashed var(--accent);outline-offset:4px}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}} diff --git a/public/css/main.css b/public/css/main.css deleted file mode 100644 index 62ed94d..0000000 --- a/public/css/main.css +++ /dev/null @@ -1,763 +0,0 @@ -@import "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600&family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300&family=Oxanium:wght@700;800&display=swap"; - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/variables.css */ -:root { - --bg: #060b10; - --bg2: #0c1520; - --surface: #101e2d; - --border: #182840; - --accent: #a855f7; - --accent2: #00ff88; - --text: #c4d6e8; - --text-dim: #7a9bb8; - --muted: #304860; - --color-tech: #a855f7; - --color-life: #f59e0b; - --color-quote: #00ff88; - --color-link: #38bdf8; - --color-photo: #ec4899; - --font-body: - "IBM Plex Sans", - system-ui, - sans-serif; - --font-mono: - "JetBrains Mono", - "Courier New", - monospace; - --font-head: "Oxanium", sans-serif; - --fs-body: 0.95rem; - --fs-nav: 0.8rem; - --fs-badge: 0.7rem; - --fs-btn: 0.8rem; - --fs-h3: 1.5rem; - --fs-h2: clamp(1.7rem, 6vw, 3rem); - --container-max: 1080px; - --container-narrow: 768px; - --gap-sm: 0.5rem; - --gap-md: 1.5rem; - --gap-lg: 2.5rem; - --gap-xl: 4rem; - --section-py-mobile: 4rem; - --section-py-desktop: 6rem; - --card-px-mobile: 1.5rem; - --card-px-desktop: 2rem; - --transition: all 0.2s ease; - --transition-slow: all 0.75s cubic-bezier(0.16,1,0.3,1); -} -html.theme-light { - --bg: #f0f4f8; - --bg2: #e2eaf4; - --surface: #d4dff0; - --border: #a8bdd8; - --accent: #7c3aed; - --accent2: #008f5a; - --text: #0d1b2a; - --text-dim: #2e4a6a; - --muted: #6888a8; -} -@media (max-width: 479px) { - :root { - --bp: "mobile"; - } -} -@media (min-width: 480px) { - :root { - --bp: "sm"; - } -} -@media (min-width: 768px) { - :root { - --bp: "md"; - } -} -@media (min-width: 1200px) { - :root { - --bp: "lg"; - } -} - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/hero.css */ -.hero { - position: relative; - overflow: hidden; - padding: var(--section-py-mobile) 1.5rem; - background: var(--bg); - border-bottom: 1px solid var(--border); -} -@media (min-width: 768px) { - .hero { - padding: var(--section-py-desktop) 1.5rem; - } -} -#matrix-canvas { - position: absolute; - inset: 0; - opacity: 0.13; - pointer-events: none; -} -html.theme-light #matrix-canvas { - opacity: 0.18; -} -.hero-content { - position: relative; - z-index: 1; - max-width: var(--container-max); - margin: 0 auto; - display: flex; - align-items: center; - gap: var(--gap-lg); -} -.hero-avatar { - width: 64px; - height: 64px; - border-radius: 50%; - flex-shrink: 0; - background: - linear-gradient( - 135deg, - var(--accent), - var(--accent2)); - display: flex; - align-items: center; - justify-content: center; - font-family: var(--font-head); - font-size: 1.4rem; - font-weight: 800; - color: #fff; -} -@media (min-width: 768px) { - .hero-avatar { - width: 80px; - height: 80px; - font-size: 1.8rem; - } -} -.hero-text h1 { - margin-bottom: 0.25rem; -} -.hero-role { - font-family: var(--font-mono); - font-size: 0.85rem; - color: var(--accent); - letter-spacing: 0.1em; - text-transform: uppercase; - margin-bottom: 0.75rem; -} -.hero-bio { - color: var(--text-dim); - font-size: 0.95rem; - line-height: 1.8; - max-width: 400px; -} -#matrix-canvas::after { - content: ""; - position: absolute; - inset: 0; - background: - repeating-linear-gradient( - 0deg, - rgba(0, 0, 0, 0.15), - rgba(0, 0, 0, 0.15) 1px, - transparent 1px, - transparent 2px); - pointer-events: none; -} -.hero::before { - content: ""; - position: absolute; - top: 50%; - left: 50%; - width: 600px; - height: 600px; - background: - radial-gradient( - circle, - rgba(168, 85, 247, 0.15) 0%, - transparent 70%); - transform: translate(-50%, -50%); - pointer-events: none; -} -@media (max-width: 768px) { - .hero-content { - flex-direction: column; - text-align: center; - } - .hero-bio { - max-width: 100%; - } -} - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/card.css */ -.post-card { - background: var(--surface); - border: 1px solid var(--border); - border-radius: 8px; - overflow: hidden; - transition: var(--transition); - display: flex; - gap: var(--gap-md); -} -.post-card:hover { - border-color: var(--accent); - box-shadow: 0 0 20px rgba(168, 85, 247, 0.2); -} -.post-card-image { - width: 120px; - height: 100px; - flex-shrink: 0; - object-fit: cover; - background: - linear-gradient( - 135deg, - var(--border), - var(--bg2)); - border-right: 1px solid var(--border); -} -@media (min-width: 768px) { - .post-card-image { - width: 160px; - height: 120px; - } -} -.post-card-body { - padding: var(--gap-md); - display: flex; - flex-direction: column; - justify-content: center; - flex-grow: 1; -} -.post-type-badge { - display: inline-block; - font-family: var(--font-mono); - font-size: var(--fs-badge); - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.1em; - padding: 0.35rem 0.7rem; - border-radius: 20px; - margin-bottom: 0.5rem; - width: fit-content; -} -.post-type-badge.tech { - background: color-mix(in srgb, var(--color-tech) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-tech) 30%, transparent); - color: var(--color-tech); -} -.post-type-badge.life { - background: color-mix(in srgb, var(--color-life) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-life) 30%, transparent); - color: var(--color-life); -} -.post-type-badge.quote { - background: color-mix(in srgb, var(--color-quote) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-quote) 30%, transparent); - color: var(--color-quote); -} -.post-type-badge.link { - background: color-mix(in srgb, var(--color-link) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-link) 30%, transparent); - color: var(--color-link); -} -.post-type-badge.photo { - background: color-mix(in srgb, var(--color-photo) 15%, transparent); - border: 1px solid color-mix(in srgb, var(--color-photo) 30%, transparent); - color: var(--color-photo); -} -.post-card-title { - font-family: var(--font-head); - font-size: 1.1rem; - font-weight: 700; - line-height: 1.3; - margin-bottom: 0.5rem; - color: var(--text); -} -.post-card-title a { - color: var(--text); - text-decoration: none; -} -.post-card-title a:hover { - color: var(--accent); -} -.post-card-excerpt { - color: var(--text-dim); - font-size: 0.9rem; - line-height: 1.6; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - margin-bottom: 0.5rem; -} -.post-card-meta { - display: flex; - gap: 1rem; - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--muted); - text-transform: uppercase; - letter-spacing: 0.08em; -} -.post-card.featured { - grid-row: span 2; -} -.post-card.featured .post-card-image { - width: 100%; - height: 180px; - border-right: none; - border-bottom: 1px solid var(--border); -} -.post-card.featured .post-card-body { - padding: var(--gap-lg); -} -@media (max-width: 768px) { - .post-card { - flex-direction: column; - } - .post-card-image { - width: 100%; - height: 150px; - border-right: none; - border-bottom: 1px solid var(--border); - } - .post-card.featured .post-card-image { - height: 150px; - } -} - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/feed.css */ -.feed-section { - padding: var(--section-py-mobile) 0; -} -@media (min-width: 768px) { - .feed-section { - padding: var(--section-py-desktop) 0; - } -} -.feed-label { - font-family: var(--font-mono); - font-size: 0.75rem; - letter-spacing: 0.15em; - text-transform: uppercase; - color: var(--accent); - margin-bottom: 1.5rem; -} -.feed-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: var(--gap-md); - margin-bottom: var(--gap-xl); -} -@media (min-width: 768px) { - .feed-grid { - grid-template-columns: repeat(2, 1fr); - } -} -@media (min-width: 1200px) { - .feed-grid { - grid-template-columns: repeat(3, 1fr); - } -} -.feed-list { - display: flex; - flex-direction: column; - gap: var(--gap-md); -} -.feed-list .post-card { - flex-direction: row; -} -.filter-bar { - display: flex; - gap: var(--gap-sm); - margin-bottom: var(--gap-lg); - flex-wrap: wrap; -} -.filter-btn { - font-family: var(--font-mono); - font-size: var(--fs-badge); - padding: 0.4rem 1rem; - border: 1px solid var(--border); - border-radius: 20px; - background: transparent; - color: var(--text-dim); - text-transform: uppercase; - letter-spacing: 0.1em; - cursor: pointer; - transition: var(--transition); -} -.filter-btn:hover { - border-color: var(--accent); - color: var(--accent); -} -.filter-btn.active { - background: var(--accent); - color: #fff; - border-color: var(--accent); -} -.feed-cta { - display: inline-block; - padding: 0.75rem 1.5rem; - background: var(--accent); - color: #fff; - border-radius: 4px; - font-family: var(--font-mono); - font-size: var(--fs-btn); - text-transform: uppercase; - letter-spacing: 0.1em; - text-decoration: none; - transition: var(--transition); -} -.feed-cta:hover { - background: var(--accent2); - color: var(--bg); -} - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/code.css */ -pre { - background: var(--surface); - border: 1px solid var(--border); - border-left: 3px solid var(--accent); - border-radius: 6px; - padding: 1rem; - overflow-x: auto; - position: relative; - margin: 1.5rem 0; -} -pre code { - font-family: var(--font-mono); - font-size: 0.9rem; - line-height: 1.6; - color: var(--text); -} -.highlight { - background: var(--surface); - border: 1px solid var(--border); - border-left: 3px solid var(--accent); - border-radius: 6px; - padding: 1rem; - overflow-x: auto; - margin: 1.5rem 0; - position: relative; -} -.highlight code { - background: none; - padding: 0; - border-radius: 0; - color: inherit; -} -.highlight .k { - color: #f59e0b; -} -.highlight .kn { - color: #f59e0b; -} -.highlight .kp { - color: #f59e0b; -} -.highlight .kr { - color: #f59e0b; -} -.highlight .kt { - color: #a855f7; -} -.highlight .n { - color: #c4d6e8; -} -.highlight .na { - color: #38bdf8; -} -.highlight .nb { - color: #38bdf8; -} -.highlight .nc { - color: #a855f7; -} -.highlight .no { - color: #00ff88; -} -.highlight .nd { - color: #f59e0b; -} -.highlight .ni { - color: #a855f7; -} -.highlight .ne { - color: #f59e0b; -} -.highlight .nf { - color: #38bdf8; -} -.highlight .nl { - color: #a855f7; -} -.highlight .nn { - color: #a855f7; -} -.highlight .nt { - color: #f59e0b; -} -.highlight .nv { - color: #c4d6e8; -} -.highlight .s { - color: #00ff88; -} -.highlight .sa { - color: #00ff88; -} -.highlight .sb { - color: #00ff88; -} -.highlight .sc { - color: #00ff88; -} -.highlight .s1 { - color: #00ff88; -} -.highlight .s2 { - color: #00ff88; -} -.highlight .se { - color: #f59e0b; -} -.highlight .sh { - color: #00ff88; -} -.highlight .si { - color: #f59e0b; -} -.highlight .sx { - color: #00ff88; -} -.highlight .sr { - color: #00ff88; -} -.highlight .ss { - color: #00ff88; -} -.highlight .m { - color: #38bdf8; -} -.highlight .mb { - color: #38bdf8; -} -.highlight .mf { - color: #38bdf8; -} -.highlight .mh { - color: #38bdf8; -} -.highlight .mi { - color: #38bdf8; -} -.highlight .il { - color: #38bdf8; -} -.highlight .mo { - color: #38bdf8; -} -.highlight .o { - color: #c4d6e8; -} -.highlight .ow { - color: #a855f7; -} -.highlight .c { - color: #7a9bb8; -} -.highlight .c1 { - color: #7a9bb8; -} -.highlight .ch { - color: #7a9bb8; -} -.highlight .cm { - color: #7a9bb8; -} -.highlight .cp { - color: #f59e0b; -} -.highlight .cpf { - color: #f59e0b; -} -html.theme-light .highlight { - background: var(--surface); - border-left-color: var(--accent); -} -html.theme-light .highlight .c { - color: #6a7fa0; -} -.code-copy-btn { - position: absolute; - top: 0.75rem; - right: 0.75rem; - background: var(--accent); - color: #fff; - border: none; - padding: 0.4rem 0.8rem; - border-radius: 4px; - font-family: var(--font-mono); - font-size: 0.75rem; - cursor: pointer; - opacity: 0; - transition: var(--transition); - text-transform: uppercase; - letter-spacing: 0.08em; -} -.highlight:hover .code-copy-btn, -pre:hover .code-copy-btn { - opacity: 1; -} -.code-copy-btn:hover { - background: var(--accent2); - color: var(--bg); -} -.code-copy-btn.copied { - background: var(--accent2); -} -code { - font-family: var(--font-mono); - background: var(--surface); - padding: 0.25rem 0.5rem; - border-radius: 4px; - font-size: 0.9em; - color: var(--accent2); -} -p code { - border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent); -} - -/* ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/progress-bar.css */ -.reading-progress { - position: fixed; - top: 0; - left: 0; - height: 3px; - background: - linear-gradient( - 90deg, - var(--accent), - var(--accent2)); - width: 0%; - z-index: 200; - transition: width 0.1s ease-out; -} -.article-page .reading-progress, -.page-page .reading-progress { - display: block; -} -body:not(.scrollable) .reading-progress { - display: none; -} - -/* <stdin> */ -html { - font-size: 17px; - scroll-behavior: smooth; -} -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} -body { - background-color: var(--bg); - color: var(--text); - font-family: var(--font-body); - font-size: var(--fs-body); - line-height: 1.95; - transition: background-color 0.2s, color 0.2s; -} -h1 { - font-family: var(--font-head); - font-size: var(--fs-h2); - font-weight: 800; - line-height: 1.1; - margin-bottom: 0.5rem; -} -h2 { - font-family: var(--font-head); - font-size: var(--fs-h2); - font-weight: 800; - line-height: 1.1; - margin: 2rem 0 1rem; -} -h3 { - font-family: var(--font-head); - font-size: var(--fs-h3); - font-weight: 800; - line-height: 1.2; - margin: 1.5rem 0 0.75rem; -} -h4, -h5, -h6 { - font-family: var(--font-head); - font-weight: 800; - margin: 1rem 0 0.5rem; -} -p { - margin-bottom: 1rem; -} -a { - color: var(--accent); - text-decoration: none; - transition: var(--transition); -} -a:hover { - color: var(--accent2); -} -.container { - max-width: var(--container-max); - margin: 0 auto; - padding: 0 1.5rem; -} -.container-narrow { - max-width: var(--container-narrow); - margin: 0 auto; - padding: 0 1.5rem; -} -main { - min-height: calc(100vh - 200px); -} -ul, -ol { - margin-left: 1.5rem; - margin-bottom: 1rem; -} -li { - margin-bottom: 0.5rem; -} -code { - font-family: var(--font-mono); - background: var(--surface); - padding: 0.25rem 0.5rem; - border-radius: 4px; - font-size: 0.9em; -} -pre { - margin-bottom: 1rem; - overflow-x: auto; -} -pre code { - padding: 0; - background: none; - border-radius: 0; -} -:focus { - outline: 2px solid var(--accent); - outline-offset: 2px; -} -button:focus, -a:focus { - outline: 2px dashed var(--accent); - outline-offset: 4px; -} -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - scroll-behavior: auto !important; - } -} -/*# sourceMappingURL=main.css.map */ diff --git a/public/css/main.css.map b/public/css/main.css.map deleted file mode 100644 index 3009431..0000000 --- a/public/css/main.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/variables.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/hero.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/card.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/feed.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/code.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/components/progress-bar.css","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/css/main.css"],"sourcesContent":["/* variables.css */\n\n:root {\n /* Dark theme colors (default) */\n --bg: #060b10;\n --bg2: #0c1520;\n --surface: #101e2d;\n --border: #182840;\n --accent: #a855f7;\n --accent2: #00ff88;\n --text: #c4d6e8;\n --text-dim: #7a9bb8;\n --muted: #304860;\n\n /* Type colors */\n --color-tech: #a855f7; /* purple */\n --color-life: #f59e0b; /* amber */\n --color-quote: #00ff88; /* green */\n --color-link: #38bdf8; /* cyan */\n --color-photo: #ec4899; /* pink */\n\n /* Typography */\n --font-body: 'IBM Plex Sans', system-ui, sans-serif;\n --font-mono: 'JetBrains Mono', 'Courier New', monospace;\n --font-head: 'Oxanium', sans-serif;\n\n /* Font sizes (base: 17px on html) */\n --fs-body: 0.95rem;\n --fs-nav: 0.8rem;\n --fs-badge: 0.7rem;\n --fs-btn: 0.8rem;\n --fs-h3: 1.5rem;\n --fs-h2: clamp(1.7rem, 6vw, 3rem);\n\n /* Layout */\n --container-max: 1080px;\n --container-narrow: 768px;\n --gap-sm: 0.5rem;\n --gap-md: 1.5rem;\n --gap-lg: 2.5rem;\n --gap-xl: 4rem;\n\n /* Spacing */\n --section-py-mobile: 4rem;\n --section-py-desktop: 6rem;\n --card-px-mobile: 1.5rem;\n --card-px-desktop: 2rem;\n\n /* Transitions */\n --transition: all 0.2s ease;\n --transition-slow: all 0.75s cubic-bezier(0.16,1,0.3,1);\n}\n\nhtml.theme-light {\n /* Light theme */\n --bg: #f0f4f8;\n --bg2: #e2eaf4;\n --surface: #d4dff0;\n --border: #a8bdd8;\n --accent: #7c3aed;\n --accent2: #008f5a;\n --text: #0d1b2a;\n --text-dim: #2e4a6a;\n --muted: #6888a8;\n}\n\n/* Breakpoints as CSS variables for reference */\n@media (max-width: 479px) {\n :root {\n --bp: \"mobile\";\n }\n}\n\n@media (min-width: 480px) {\n :root {\n --bp: \"sm\";\n }\n}\n\n@media (min-width: 768px) {\n :root {\n --bp: \"md\";\n }\n}\n\n@media (min-width: 1200px) {\n :root {\n --bp: \"lg\";\n }\n}\n","/* hero.css */\n.hero {\n position: relative;\n overflow: hidden;\n padding: var(--section-py-mobile) 1.5rem;\n background: var(--bg);\n border-bottom: 1px solid var(--border);\n}\n\n@media (min-width: 768px) {\n .hero {\n padding: var(--section-py-desktop) 1.5rem;\n }\n}\n\n#matrix-canvas {\n position: absolute;\n inset: 0;\n opacity: 0.13;\n pointer-events: none;\n}\n\nhtml.theme-light #matrix-canvas {\n opacity: 0.18;\n}\n\n.hero-content {\n position: relative;\n z-index: 1;\n max-width: var(--container-max);\n margin: 0 auto;\n display: flex;\n align-items: center;\n gap: var(--gap-lg);\n}\n\n.hero-avatar {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n flex-shrink: 0;\n background: linear-gradient(135deg, var(--accent), var(--accent2));\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: var(--font-head);\n font-size: 1.4rem;\n font-weight: 800;\n color: #fff;\n}\n\n@media (min-width: 768px) {\n .hero-avatar {\n width: 80px;\n height: 80px;\n font-size: 1.8rem;\n }\n}\n\n.hero-text h1 {\n margin-bottom: 0.25rem;\n}\n\n.hero-role {\n font-family: var(--font-mono);\n font-size: 0.85rem;\n color: var(--accent);\n letter-spacing: 0.1em;\n text-transform: uppercase;\n margin-bottom: 0.75rem;\n}\n\n.hero-bio {\n color: var(--text-dim);\n font-size: 0.95rem;\n line-height: 1.8;\n max-width: 400px;\n}\n\n/* Scanlines effect on canvas */\n#matrix-canvas::after {\n content: '';\n position: absolute;\n inset: 0;\n background: repeating-linear-gradient(\n 0deg,\n rgba(0, 0, 0, 0.15),\n rgba(0, 0, 0, 0.15) 1px,\n transparent 1px,\n transparent 2px\n );\n pointer-events: none;\n}\n\n/* Ambient glow behind hero */\n.hero::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 600px;\n height: 600px;\n background: radial-gradient(circle, rgba(168, 85, 247, 0.15) 0%, transparent 70%);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n@media (max-width: 768px) {\n .hero-content {\n flex-direction: column;\n text-align: center;\n }\n\n .hero-bio {\n max-width: 100%;\n }\n}\n","/* card.css */\n.post-card {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n overflow: hidden;\n transition: var(--transition);\n display: flex;\n gap: var(--gap-md);\n}\n\n.post-card:hover {\n border-color: var(--accent);\n box-shadow: 0 0 20px rgba(168, 85, 247, 0.2);\n}\n\n.post-card-image {\n width: 120px;\n height: 100px;\n flex-shrink: 0;\n object-fit: cover;\n background: linear-gradient(135deg, var(--border), var(--bg2));\n border-right: 1px solid var(--border);\n}\n\n@media (min-width: 768px) {\n .post-card-image {\n width: 160px;\n height: 120px;\n }\n}\n\n.post-card-body {\n padding: var(--gap-md);\n display: flex;\n flex-direction: column;\n justify-content: center;\n flex-grow: 1;\n}\n\n.post-type-badge {\n display: inline-block;\n font-family: var(--font-mono);\n font-size: var(--fs-badge);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n padding: 0.35rem 0.7rem;\n border-radius: 20px;\n margin-bottom: 0.5rem;\n width: fit-content;\n}\n\n/* Type-specific badge colors */\n.post-type-badge.tech {\n background: color-mix(in srgb, var(--color-tech) 15%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-tech) 30%, transparent);\n color: var(--color-tech);\n}\n\n.post-type-badge.life {\n background: color-mix(in srgb, var(--color-life) 15%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-life) 30%, transparent);\n color: var(--color-life);\n}\n\n.post-type-badge.quote {\n background: color-mix(in srgb, var(--color-quote) 15%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-quote) 30%, transparent);\n color: var(--color-quote);\n}\n\n.post-type-badge.link {\n background: color-mix(in srgb, var(--color-link) 15%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-link) 30%, transparent);\n color: var(--color-link);\n}\n\n.post-type-badge.photo {\n background: color-mix(in srgb, var(--color-photo) 15%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-photo) 30%, transparent);\n color: var(--color-photo);\n}\n\n.post-card-title {\n font-family: var(--font-head);\n font-size: 1.1rem;\n font-weight: 700;\n line-height: 1.3;\n margin-bottom: 0.5rem;\n color: var(--text);\n}\n\n.post-card-title a {\n color: var(--text);\n text-decoration: none;\n}\n\n.post-card-title a:hover {\n color: var(--accent);\n}\n\n.post-card-excerpt {\n color: var(--text-dim);\n font-size: 0.9rem;\n line-height: 1.6;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n margin-bottom: 0.5rem;\n}\n\n.post-card-meta {\n display: flex;\n gap: 1rem;\n font-family: var(--font-mono);\n font-size: 0.75rem;\n color: var(--muted);\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n\n/* Featured card in grid */\n.post-card.featured {\n grid-row: span 2;\n}\n\n.post-card.featured .post-card-image {\n width: 100%;\n height: 180px;\n border-right: none;\n border-bottom: 1px solid var(--border);\n}\n\n.post-card.featured .post-card-body {\n padding: var(--gap-lg);\n}\n\n@media (max-width: 768px) {\n .post-card {\n flex-direction: column;\n }\n\n .post-card-image {\n width: 100%;\n height: 150px;\n border-right: none;\n border-bottom: 1px solid var(--border);\n }\n\n .post-card.featured .post-card-image {\n height: 150px;\n }\n}\n","/* feed.css */\n.feed-section {\n padding: var(--section-py-mobile) 0;\n}\n\n@media (min-width: 768px) {\n .feed-section {\n padding: var(--section-py-desktop) 0;\n }\n}\n\n.feed-label {\n font-family: var(--font-mono);\n font-size: 0.75rem;\n letter-spacing: 0.15em;\n text-transform: uppercase;\n color: var(--accent);\n margin-bottom: 1.5rem;\n}\n\n.feed-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: var(--gap-md);\n margin-bottom: var(--gap-xl);\n}\n\n@media (min-width: 768px) {\n .feed-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (min-width: 1200px) {\n .feed-grid {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n.feed-list {\n display: flex;\n flex-direction: column;\n gap: var(--gap-md);\n}\n\n.feed-list .post-card {\n flex-direction: row;\n}\n\n/* Filter bar */\n.filter-bar {\n display: flex;\n gap: var(--gap-sm);\n margin-bottom: var(--gap-lg);\n flex-wrap: wrap;\n}\n\n.filter-btn {\n font-family: var(--font-mono);\n font-size: var(--fs-badge);\n padding: 0.4rem 1rem;\n border: 1px solid var(--border);\n border-radius: 20px;\n background: transparent;\n color: var(--text-dim);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n cursor: pointer;\n transition: var(--transition);\n}\n\n.filter-btn:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n\n.filter-btn.active {\n background: var(--accent);\n color: #fff;\n border-color: var(--accent);\n}\n\n/* View all link */\n.feed-cta {\n display: inline-block;\n padding: 0.75rem 1.5rem;\n background: var(--accent);\n color: #fff;\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: var(--fs-btn);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n text-decoration: none;\n transition: var(--transition);\n}\n\n.feed-cta:hover {\n background: var(--accent2);\n color: var(--bg);\n}\n","/* code.css */\npre {\n background: var(--surface);\n border: 1px solid var(--border);\n border-left: 3px solid var(--accent);\n border-radius: 6px;\n padding: 1rem;\n overflow-x: auto;\n position: relative;\n margin: 1.5rem 0;\n}\n\npre code {\n font-family: var(--font-mono);\n font-size: 0.9rem;\n line-height: 1.6;\n color: var(--text);\n}\n\n/* Chroma syntax highlighting */\n.highlight {\n background: var(--surface);\n border: 1px solid var(--border);\n border-left: 3px solid var(--accent);\n border-radius: 6px;\n padding: 1rem;\n overflow-x: auto;\n margin: 1.5rem 0;\n position: relative;\n}\n\n.highlight code {\n background: none;\n padding: 0;\n border-radius: 0;\n color: inherit;\n}\n\n/* Chroma color overrides for dark theme */\n.highlight .k { color: #f59e0b; }\n.highlight .kn { color: #f59e0b; }\n.highlight .kp { color: #f59e0b; }\n.highlight .kr { color: #f59e0b; }\n.highlight .kt { color: #a855f7; }\n.highlight .n { color: #c4d6e8; }\n.highlight .na { color: #38bdf8; }\n.highlight .nb { color: #38bdf8; }\n.highlight .nc { color: #a855f7; }\n.highlight .no { color: #00ff88; }\n.highlight .nd { color: #f59e0b; }\n.highlight .ni { color: #a855f7; }\n.highlight .ne { color: #f59e0b; }\n.highlight .nf { color: #38bdf8; }\n.highlight .nl { color: #a855f7; }\n.highlight .nn { color: #a855f7; }\n.highlight .nt { color: #f59e0b; }\n.highlight .nv { color: #c4d6e8; }\n.highlight .s { color: #00ff88; }\n.highlight .sa { color: #00ff88; }\n.highlight .sb { color: #00ff88; }\n.highlight .sc { color: #00ff88; }\n.highlight .s1 { color: #00ff88; }\n.highlight .s2 { color: #00ff88; }\n.highlight .se { color: #f59e0b; }\n.highlight .sh { color: #00ff88; }\n.highlight .si { color: #f59e0b; }\n.highlight .sx { color: #00ff88; }\n.highlight .sr { color: #00ff88; }\n.highlight .ss { color: #00ff88; }\n.highlight .m { color: #38bdf8; }\n.highlight .mb { color: #38bdf8; }\n.highlight .mf { color: #38bdf8; }\n.highlight .mh { color: #38bdf8; }\n.highlight .mi { color: #38bdf8; }\n.highlight .il { color: #38bdf8; }\n.highlight .mo { color: #38bdf8; }\n.highlight .o { color: #c4d6e8; }\n.highlight .ow { color: #a855f7; }\n.highlight .c { color: #7a9bb8; }\n.highlight .c1 { color: #7a9bb8; }\n.highlight .ch { color: #7a9bb8; }\n.highlight .cm { color: #7a9bb8; }\n.highlight .cp { color: #f59e0b; }\n.highlight .cpf { color: #f59e0b; }\n\nhtml.theme-light .highlight {\n background: var(--surface);\n border-left-color: var(--accent);\n}\n\nhtml.theme-light .highlight .c { color: #6a7fa0; }\n\n/* Copy button for code blocks */\n.code-copy-btn {\n position: absolute;\n top: 0.75rem;\n right: 0.75rem;\n background: var(--accent);\n color: #fff;\n border: none;\n padding: 0.4rem 0.8rem;\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 0.75rem;\n cursor: pointer;\n opacity: 0;\n transition: var(--transition);\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n\n.highlight:hover .code-copy-btn,\npre:hover .code-copy-btn {\n opacity: 1;\n}\n\n.code-copy-btn:hover {\n background: var(--accent2);\n color: var(--bg);\n}\n\n.code-copy-btn.copied {\n background: var(--accent2);\n}\n\n/* Inline code */\ncode {\n font-family: var(--font-mono);\n background: var(--surface);\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n font-size: 0.9em;\n color: var(--accent2);\n}\n\np code {\n border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);\n}\n","/* progress-bar.css */\n.reading-progress {\n position: fixed;\n top: 0;\n left: 0;\n height: 3px;\n background: linear-gradient(90deg, var(--accent), var(--accent2));\n width: 0%;\n z-index: 200;\n transition: width 0.1s ease-out;\n}\n\n/* Only show on pages with sufficient content */\n.article-page .reading-progress,\n.page-page .reading-progress {\n display: block;\n}\n\n/* Hide if no scrollable content */\nbody:not(.scrollable) .reading-progress {\n display: none;\n}\n","@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;600\u0026family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;0,700;1,300\u0026family=Oxanium:wght@700;800\u0026display=swap');\n\n@import 'variables.css';\n@import 'components/hero.css';\n@import 'components/card.css';\n@import 'components/feed.css';\n@import 'components/code.css';\n@import 'components/progress-bar.css';\n\n/* Base Styles */\nhtml {\n font-size: 17px;\n scroll-behavior: smooth;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n background-color: var(--bg);\n color: var(--text);\n font-family: var(--font-body);\n font-size: var(--fs-body);\n line-height: 1.95;\n transition: background-color 0.2s, color 0.2s;\n}\n\n/* Typography */\nh1 {\n font-family: var(--font-head);\n font-size: var(--fs-h2);\n font-weight: 800;\n line-height: 1.1;\n margin-bottom: 0.5rem;\n}\n\nh2 {\n font-family: var(--font-head);\n font-size: var(--fs-h2);\n font-weight: 800;\n line-height: 1.1;\n margin: 2rem 0 1rem;\n}\n\nh3 {\n font-family: var(--font-head);\n font-size: var(--fs-h3);\n font-weight: 800;\n line-height: 1.2;\n margin: 1.5rem 0 0.75rem;\n}\n\nh4, h5, h6 {\n font-family: var(--font-head);\n font-weight: 800;\n margin: 1rem 0 0.5rem;\n}\n\np {\n margin-bottom: 1rem;\n}\n\na {\n color: var(--accent);\n text-decoration: none;\n transition: var(--transition);\n}\n\na:hover {\n color: var(--accent2);\n}\n\n/* Utilities */\n.container {\n max-width: var(--container-max);\n margin: 0 auto;\n padding: 0 1.5rem;\n}\n\n.container-narrow {\n max-width: var(--container-narrow);\n margin: 0 auto;\n padding: 0 1.5rem;\n}\n\nmain {\n min-height: calc(100vh - 200px);\n}\n\n/* Lists */\nul, ol {\n margin-left: 1.5rem;\n margin-bottom: 1rem;\n}\n\nli {\n margin-bottom: 0.5rem;\n}\n\ncode {\n font-family: var(--font-mono);\n background: var(--surface);\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n font-size: 0.9em;\n}\n\npre {\n margin-bottom: 1rem;\n overflow-x: auto;\n}\n\npre code {\n padding: 0;\n background: none;\n border-radius: 0;\n}\n\n/* Focus styles for accessibility */\n:focus {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n\nbutton:focus,\na:focus {\n outline: 2px dashed var(--accent);\n outline-offset: 4px;\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n * {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n"],"mappings":"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","names":[]}
\ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico Binary files differdeleted file mode 100644 index 67f8b77..0000000 --- a/public/favicon.ico +++ /dev/null diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 3a4a913..0000000 --- a/public/index.html +++ /dev/null @@ -1,100 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head> - <meta name="generator" content="Hugo 0.159.2"><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <section class="hero"> - <canvas id="matrix-canvas"></canvas> - - <div class="hero-content"> - <div class="hero-avatar">DM</div> - <div class="hero-text"> - <h1>Danilo M.</h1> - <div class="hero-role">// engineer • writer • human</div> - <p class="hero-bio">Writing about IT, life, and the things that matter.</p> - </div> - </div> -</section> - - - <div class="container feed-section"> - <div class="feed-label">Latest</div> - - - - - - <div class="feed-grid"> - - </div> - - <a href="/articles/" class="feed-cta">View all articles</a> - </div> -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/index.xml b/public/index.xml deleted file mode 100644 index 0eb3cb4..0000000 --- a/public/index.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Home on danilo m.</title> - <link>http://localhost:1313/</link> - <description>Recent content in Home on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <lastBuildDate>Thu, 01 Jan 2026 00:00:00 +0000</lastBuildDate> - <atom:link href="http://localhost:1313/index.xml" rel="self" type="application/rss+xml" /> - <item> - <title>Contact</title> - <link>http://localhost:1313/is/here/</link> - <pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate> - <guid>http://localhost:1313/is/here/</guid> - <description><p>Get in touch — send me a message and I&rsquo;ll get back to you soon.</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p><!-- raw HTML omitted -->Send<!-- raw HTML omitted --></p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted --></description> - </item> - <item> - <title>Post 3</title> - <link>http://localhost:1313/posts/post-3/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-3/</guid> - <description><p>Occaecat aliqua consequat laborum ut ex aute aliqua culpa quis irure esse magna dolore quis. Proident fugiat labore eu laboris officia Lorem enim. Ipsum occaecat cillum ut tempor id sint aliqua incididunt nisi incididunt reprehenderit. Voluptate ad minim sint est aute aliquip esse occaecat tempor officia qui sunt. Aute ex ipsum id ut in est velit est laborum incididunt. Aliqua qui id do esse sunt eiusmod id deserunt eu nostrud aute sit ipsum. Deserunt esse cillum Lorem non magna adipisicing mollit amet consequat.</p></description> - </item> - <item> - <title>Post 2</title> - <link>http://localhost:1313/posts/post-2/</link> - <pubDate>Wed, 15 Feb 2023 10:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-2/</guid> - <description><p>Anim eiusmod irure incididunt sint cupidatat. Incididunt irure irure irure nisi ipsum do ut quis fugiat consectetur proident cupidatat incididunt cillum. Dolore voluptate occaecat qui mollit laborum ullamco et. Ipsum laboris officia anim laboris culpa eiusmod ex magna ex cupidatat anim ipsum aute. Mollit aliquip occaecat qui sunt velit ut cupidatat reprehenderit enim sunt laborum. Velit veniam in officia nulla adipisicing ut duis officia.</p>
<p>Exercitation voluptate irure in irure tempor mollit Lorem nostrud ad officia. Velit id fugiat occaecat do tempor. Sit officia Lorem aliquip eu deserunt consectetur. Aute proident deserunt in nulla aliquip dolore ipsum Lorem ut cupidatat consectetur sit sint laborum. Esse cupidatat sit sint sunt tempor exercitation deserunt. Labore dolor duis laborum est do nisi ut veniam dolor et nostrud nostrud.</p></description> - </item> - <item> - <title>Post 1</title> - <link>http://localhost:1313/posts/post-1/</link> - <pubDate>Sun, 15 Jan 2023 09:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-1/</guid> - <description><p>Tempor proident minim aliquip reprehenderit dolor et ad anim Lorem duis sint eiusmod. Labore ut ea duis dolor. Incididunt consectetur proident qui occaecat incididunt do nisi Lorem. Tempor do laborum elit laboris excepteur eiusmod do. Eiusmod nisi excepteur ut amet pariatur adipisicing Lorem.</p>
<p>Occaecat nulla excepteur dolore excepteur duis eiusmod ullamco officia anim in voluptate ea occaecat officia. Cillum sint esse velit ea officia minim fugiat. Elit ea esse id aliquip pariatur cupidatat id duis minim incididunt ea ea. Anim ut duis sunt nisi. Culpa cillum sit voluptate voluptate eiusmod dolor. Enim nisi Lorem ipsum irure est excepteur voluptate eu in enim nisi. Nostrud ipsum Lorem anim sint labore consequat do.</p></description> - </item> - </channel> -</rss> diff --git a/public/is/here/index.html b/public/is/here/index.html deleted file mode 100644 index ca584a5..0000000 --- a/public/is/here/index.html +++ /dev/null @@ -1,114 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Contact | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" class="active"> - about - </a> - </li> - - <li> - <a href="/is/here/" class="active"> - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <article class="page-page"> - <div class="container-narrow"> - <h1>Contact</h1> - <div class="post-card-meta" style="margin-bottom: 2rem;"> - <span>Jan 1, 2026</span> - - </div> - - <div class="post-content"> - <p>Get in touch — send me a message and I’ll get back to you soon.</p> -<!-- raw HTML omitted --> -<!-- raw HTML omitted --> -<!-- raw HTML omitted --> -<!-- raw HTML omitted --> -<p><!-- raw HTML omitted -->Send<!-- raw HTML omitted --></p> -<!-- raw HTML omitted --> -<!-- raw HTML omitted --> -<!-- raw HTML omitted --> - - </div> - </div> - </article> - - - <div class="container-narrow" style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border);"> - <nav class="page-nav"> - <h3 style="margin-bottom: 1rem;">Other pages</h3> - <ul style="list-style: none; margin: 0;"> - - - - <li style="margin-bottom: 0.5rem;"> - <a href="/is/here/" class="active"> - Contact - </a> - </li> - - - </ul> - </nav> - </div> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/is/index.html b/public/is/index.html deleted file mode 100644 index 00b5b13..0000000 --- a/public/is/index.html +++ /dev/null @@ -1,83 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>About | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" class="active"> - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <div class="container"> - <h1>About</h1> - - - <p>Hi, I’m Danilo. I write about tech, life, and the things that matter.</p> -<p>This is your about page. Edit this to tell your story.</p> - - - </div> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/js/filters.38212ecd54ff7f1fdebf2aebe32e8c248382e80f93dae0761ebbbd03ca28dc5b.js b/public/js/filters.38212ecd54ff7f1fdebf2aebe32e8c248382e80f93dae0761ebbbd03ca28dc5b.js deleted file mode 100644 index 64d9c57..0000000 --- a/public/js/filters.38212ecd54ff7f1fdebf2aebe32e8c248382e80f93dae0761ebbbd03ca28dc5b.js +++ /dev/null @@ -1,28 +0,0 @@ -// filters.js -(function() { - const filterBtns = document.querySelectorAll('.filter-btn'); - const feedList = document.getElementById('articles-feed'); - const cards = feedList ? feedList.querySelectorAll('.post-card') : []; - - if (!filterBtns.length || !cards.length) return; - - filterBtns.forEach(btn => { - btn.addEventListener('click', function() { - const filter = this.dataset.filter; - - // Update active button - filterBtns.forEach(b => b.classList.remove('active')); - this.classList.add('active'); - - // Filter cards - cards.forEach(card => { - const cardType = card.querySelector('.post-type-badge')?.classList[1]; - const matches = filter === 'all' || cardType === filter; - card.style.display = matches ? '' : 'none'; - }); - - // Scroll to top - window.scrollTo({ top: 0, behavior: 'smooth' }); - }); - }); -})(); diff --git a/public/js/main.23cd0c7d837263b9eaeb96ee2d9ccfa2969daa3fa00fa1c1fe8701a9b87251a1.js b/public/js/main.23cd0c7d837263b9eaeb96ee2d9ccfa2969daa3fa00fa1c1fe8701a9b87251a1.js deleted file mode 100644 index 4e24393..0000000 --- a/public/js/main.23cd0c7d837263b9eaeb96ee2d9ccfa2969daa3fa00fa1c1fe8701a9b87251a1.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{console.log("This site was generated by Hugo.");})(); diff --git a/public/js/main.55ed9b054bac537d7aab80112d090a8b88bbcaae5dec86c26009f393fd2d213d.js b/public/js/main.55ed9b054bac537d7aab80112d090a8b88bbcaae5dec86c26009f393fd2d213d.js deleted file mode 100644 index 0dadf45..0000000 --- a/public/js/main.55ed9b054bac537d7aab80112d090a8b88bbcaae5dec86c26009f393fd2d213d.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{(function(){let e="danix-theme",o="theme-dark",t="theme-light";function r(){let c=localStorage.getItem(e),n=window.matchMedia("(prefers-color-scheme: dark)").matches;a((c===null?n:c==="dark")?"dark":"light")}function a(c){let n=document.documentElement;n.classList.remove(o,t),c==="dark"?(n.classList.remove(t),localStorage.setItem(e,"dark")):(n.classList.add(t),localStorage.setItem(e,"light"))}function i(){return document.documentElement.classList.contains(t)?"light":"dark"}function d(){let n=i()==="dark"?"light":"dark";a(n),window.dispatchEvent(new CustomEvent("theme-changed",{detail:{theme:n}}))}function l(){let c=document.getElementById("theme-toggle-btn");c&&(c.addEventListener("click",d),s(),window.addEventListener("theme-changed",s))}function s(){let c=document.getElementById("theme-toggle-btn");if(c){let n=i();c.textContent=n==="dark"?"\u2600\uFE0F light":"\u{1F319} dark"}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){r(),l()}):(r(),l()),window.ThemeToggle={toggle:d,set:a,get:i}})();(function(){let e=document.getElementById("matrix-canvas");if(!e||window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;let o=e.getContext("2d"),t="\u30A2\u30A4\u30A6\u30A8\u30AA\u30AB\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D2\u30D5\u30D8\u30DB\u30DE\u30DF\u30E0\u30E1\u30E2\u30E4\u30E6\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EF\u30F2\u30F30123456789ABCDEF<>/\\|{}[]$#@!",r=14,a,i,d;function l(){e.width=e.offsetWidth,e.height=e.offsetHeight,a=Math.floor(e.width/r)+1,i=Array.from({length:a},()=>Math.random()*-(e.height/r))}function s(){let c=document.documentElement.classList.contains("theme-light");o.fillStyle=c?"rgba(240,244,248,0.07)":"rgba(6,11,16,0.055)",o.fillRect(0,0,e.width,e.height),o.font=`${r}px "JetBrains Mono", monospace`;for(let n=0;n<a;n++){let m=t[Math.floor(Math.random()*t.length)];o.fillStyle=Math.random()>.96?c?"#008f5a":"#00ff88":c?"#7c3aed":"#a855f7",o.fillText(m,n*r,i[n]*r),i[n]*r>e.height&&Math.random()>.975&&(i[n]=Math.random()*-20),i[n]+=.5}d=requestAnimationFrame(s)}window.addEventListener("theme-changed",function(){},{passive:!0}),l(),window.addEventListener("resize",()=>{cancelAnimationFrame(d),l(),s()},{passive:!0}),document.addEventListener("visibilitychange",()=>{document.hidden?cancelAnimationFrame(d):s()}),s(),window.MatrixRain={init:l,tick:s}})();(function(){let e=document.querySelector(".reading-progress");if(!e)return;let o=document.querySelector("main");if(!o)return;function t(){let i=window.innerHeight,d=document.documentElement.scrollHeight-i,l=window.scrollY,s=d>0?l/d*100:0;e.style.width=s+"%"}o.offsetHeight>window.innerHeight*1.5&&document.body.classList.add("scrollable");let a=!1;window.addEventListener("scroll",function(){a||(requestAnimationFrame(t),a=!0,setTimeout(()=>{a=!1},100))},{passive:!0}),t()})();(function(){document.querySelectorAll("pre, .highlight").forEach(o=>{let t=document.createElement("button");t.className="code-copy-btn",t.textContent="copy",t.type="button",t.setAttribute("aria-label","Copy code");let r=o.querySelector("code"),a=r?r.textContent:o.textContent;t.addEventListener("click",async function(){try{await navigator.clipboard.writeText(a);let i=t.textContent;t.textContent="copied!",t.classList.add("copied"),setTimeout(()=>{t.textContent=i,t.classList.remove("copied")},2e3)}catch(i){console.error("Failed to copy:",i),t.textContent="error"}}),o.style.position="relative",o.appendChild(t)})})();})(); diff --git a/public/js/main.js b/public/js/main.js deleted file mode 100644 index c47a5b8..0000000 --- a/public/js/main.js +++ /dev/null @@ -1,175 +0,0 @@ -(() => { - // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/theme-toggle.js - (function() { - const STORAGE_KEY = "danix-theme"; - const DARK_CLASS = "theme-dark"; - const LIGHT_CLASS = "theme-light"; - function init() { - const saved = localStorage.getItem(STORAGE_KEY); - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; - const isDark = saved === null ? prefersDark : saved === "dark"; - applyTheme(isDark ? "dark" : "light"); - } - function applyTheme(theme) { - const html = document.documentElement; - html.classList.remove(DARK_CLASS, LIGHT_CLASS); - if (theme === "dark") { - html.classList.remove(LIGHT_CLASS); - localStorage.setItem(STORAGE_KEY, "dark"); - } else { - html.classList.add(LIGHT_CLASS); - localStorage.setItem(STORAGE_KEY, "light"); - } - } - function getCurrentTheme() { - return document.documentElement.classList.contains(LIGHT_CLASS) ? "light" : "dark"; - } - function toggleTheme() { - const current = getCurrentTheme(); - const next = current === "dark" ? "light" : "dark"; - applyTheme(next); - window.dispatchEvent(new CustomEvent("theme-changed", { detail: { theme: next } })); - } - function setupToggleButton() { - const btn = document.getElementById("theme-toggle-btn"); - if (btn) { - btn.addEventListener("click", toggleTheme); - updateToggleButtonLabel(); - window.addEventListener("theme-changed", updateToggleButtonLabel); - } - } - function updateToggleButtonLabel() { - const btn = document.getElementById("theme-toggle-btn"); - if (btn) { - const current = getCurrentTheme(); - btn.textContent = current === "dark" ? "\u2600\uFE0F light" : "\u{1F319} dark"; - } - } - if (document.readyState === "loading") { - document.addEventListener("DOMContentLoaded", function() { - init(); - setupToggleButton(); - }); - } else { - init(); - setupToggleButton(); - } - window.ThemeToggle = { - toggle: toggleTheme, - set: applyTheme, - get: getCurrentTheme - }; - })(); - - // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/matrix-rain.js - (function() { - const canvas = document.getElementById("matrix-canvas"); - if (!canvas) return; - if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; - const ctx = canvas.getContext("2d"); - const CHARS = "\u30A2\u30A4\u30A6\u30A8\u30AA\u30AB\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D2\u30D5\u30D8\u30DB\u30DE\u30DF\u30E0\u30E1\u30E2\u30E4\u30E6\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EF\u30F2\u30F30123456789ABCDEF<>/\\|{}[]$#@!"; - const FS = 14; - let cols, drops, raf; - function init() { - canvas.width = canvas.offsetWidth; - canvas.height = canvas.offsetHeight; - cols = Math.floor(canvas.width / FS) + 1; - drops = Array.from({ length: cols }, () => Math.random() * -(canvas.height / FS)); - } - function tick() { - const light = document.documentElement.classList.contains("theme-light"); - ctx.fillStyle = light ? "rgba(240,244,248,0.07)" : "rgba(6,11,16,0.055)"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.font = `${FS}px "JetBrains Mono", monospace`; - for (let i = 0; i < cols; i++) { - const char = CHARS[Math.floor(Math.random() * CHARS.length)]; - ctx.fillStyle = Math.random() > 0.96 ? light ? "#008f5a" : "#00ff88" : light ? "#7c3aed" : "#a855f7"; - ctx.fillText(char, i * FS, drops[i] * FS); - if (drops[i] * FS > canvas.height && Math.random() > 0.975) { - drops[i] = Math.random() * -20; - } - drops[i] += 0.5; - } - raf = requestAnimationFrame(tick); - } - window.addEventListener("theme-changed", function() { - }, { passive: true }); - init(); - window.addEventListener("resize", () => { - cancelAnimationFrame(raf); - init(); - tick(); - }, { passive: true }); - document.addEventListener("visibilitychange", () => { - if (document.hidden) { - cancelAnimationFrame(raf); - } else { - tick(); - } - }); - tick(); - window.MatrixRain = { init, tick }; - })(); - - // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/progress-bar.js - (function() { - const progressBar = document.querySelector(".reading-progress"); - if (!progressBar) return; - const mainContent = document.querySelector("main"); - if (!mainContent) return; - function updateProgress() { - const windowHeight = window.innerHeight; - const docHeight = document.documentElement.scrollHeight - windowHeight; - const scrolled = window.scrollY; - const percent = docHeight > 0 ? scrolled / docHeight * 100 : 0; - progressBar.style.width = percent + "%"; - } - const contentHeight = mainContent.offsetHeight; - if (contentHeight > window.innerHeight * 1.5) { - document.body.classList.add("scrollable"); - } - let ticking = false; - window.addEventListener("scroll", function() { - if (!ticking) { - requestAnimationFrame(updateProgress); - ticking = true; - setTimeout(() => { - ticking = false; - }, 100); - } - }, { passive: true }); - updateProgress(); - })(); - - // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/copy-code.js - (function() { - const codeBlocks = document.querySelectorAll("pre, .highlight"); - codeBlocks.forEach((block) => { - const btn = document.createElement("button"); - btn.className = "code-copy-btn"; - btn.textContent = "copy"; - btn.type = "button"; - btn.setAttribute("aria-label", "Copy code"); - const code = block.querySelector("code"); - const text = code ? code.textContent : block.textContent; - btn.addEventListener("click", async function() { - try { - await navigator.clipboard.writeText(text); - const originalText = btn.textContent; - btn.textContent = "copied!"; - btn.classList.add("copied"); - setTimeout(() => { - btn.textContent = originalText; - btn.classList.remove("copied"); - }, 2e3); - } catch (err) { - console.error("Failed to copy:", err); - btn.textContent = "error"; - } - }); - block.style.position = "relative"; - block.appendChild(btn); - }); - })(); -})(); -//# sourceMappingURL=main.js.map diff --git a/public/js/main.js.map b/public/js/main.js.map deleted file mode 100644 index 5e4682a..0000000 --- a/public/js/main.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/js/theme-toggle.js","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/js/matrix-rain.js","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/js/progress-bar.js","file:///home/danix/Programming/GIT/danix2-hugo-theme/assets/js/copy-code.js"],"sourcesContent":["// theme-toggle.js\n(function() {\n const STORAGE_KEY = 'danix-theme';\n const DARK_CLASS = 'theme-dark';\n const LIGHT_CLASS = 'theme-light';\n\n // Initialize theme on page load\n function init() {\n const saved = localStorage.getItem(STORAGE_KEY);\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n const isDark = saved === null ? prefersDark : saved === 'dark';\n\n applyTheme(isDark ? 'dark' : 'light');\n }\n\n // Apply theme to document\n function applyTheme(theme) {\n const html = document.documentElement;\n\n html.classList.remove(DARK_CLASS, LIGHT_CLASS);\n\n if (theme === 'dark') {\n html.classList.remove(LIGHT_CLASS);\n localStorage.setItem(STORAGE_KEY, 'dark');\n } else {\n html.classList.add(LIGHT_CLASS);\n localStorage.setItem(STORAGE_KEY, 'light');\n }\n }\n\n // Get current theme\n function getCurrentTheme() {\n return document.documentElement.classList.contains(LIGHT_CLASS) ? 'light' : 'dark';\n }\n\n // Toggle theme\n function toggleTheme() {\n const current = getCurrentTheme();\n const next = current === 'dark' ? 'light' : 'dark';\n applyTheme(next);\n\n // Dispatch custom event for other scripts to listen\n window.dispatchEvent(new CustomEvent('theme-changed', { detail: { theme: next } }));\n }\n\n // Setup toggle button\n function setupToggleButton() {\n const btn = document.getElementById('theme-toggle-btn');\n if (btn) {\n btn.addEventListener('click', toggleTheme);\n updateToggleButtonLabel();\n\n // Listen for theme changes to update button label\n window.addEventListener('theme-changed', updateToggleButtonLabel);\n }\n }\n\n function updateToggleButtonLabel() {\n const btn = document.getElementById('theme-toggle-btn');\n if (btn) {\n const current = getCurrentTheme();\n btn.textContent = current === 'dark' ? '☀️ light' : '🌙 dark';\n }\n }\n\n // Initialize on DOMContentLoaded\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', function() {\n init();\n setupToggleButton();\n });\n } else {\n init();\n setupToggleButton();\n }\n\n // Expose to global scope for testing\n window.ThemeToggle = {\n toggle: toggleTheme,\n set: applyTheme,\n get: getCurrentTheme,\n };\n})();\n","// matrix-rain.js\n(function () {\n const canvas = document.getElementById('matrix-canvas');\n if (!canvas) return;\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;\n\n const ctx = canvas.getContext('2d');\n const CHARS = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789ABCDEF\u003c\u003e/\\\\|{}[]$#@!';\n const FS = 14; // font size / column width in px\n let cols, drops, raf;\n\n function init() {\n canvas.width = canvas.offsetWidth;\n canvas.height = canvas.offsetHeight;\n cols = Math.floor(canvas.width / FS) + 1;\n drops = Array.from({ length: cols }, () =\u003e Math.random() * -(canvas.height / FS));\n }\n\n function tick() {\n const light = document.documentElement.classList.contains('theme-light');\n // Fade trail: near-transparent fill each frame\n ctx.fillStyle = light ? 'rgba(240,244,248,0.07)' : 'rgba(6,11,16,0.055)';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.font = `${FS}px \"JetBrains Mono\", monospace`;\n\n for (let i = 0; i \u003c cols; i++) {\n const char = CHARS[Math.floor(Math.random() * CHARS.length)];\n // 4% chance of bright \"head\" char, otherwise use accent color\n ctx.fillStyle = Math.random() \u003e 0.96\n ? (light ? '#008f5a' : '#00ff88') // bright green head\n : (light ? '#7c3aed' : '#a855f7'); // purple trail\n ctx.fillText(char, i * FS, drops[i] * FS);\n\n if (drops[i] * FS \u003e canvas.height \u0026\u0026 Math.random() \u003e 0.975) {\n drops[i] = Math.random() * -20; // reset column randomly\n }\n drops[i] += 0.5; // slow fall speed\n }\n raf = requestAnimationFrame(tick);\n }\n\n // Listen for theme changes and reinit\n window.addEventListener('theme-changed', function() {\n // Matrix rain auto-colors based on theme-light class\n }, { passive: true });\n\n init();\n window.addEventListener('resize', () =\u003e {\n cancelAnimationFrame(raf);\n init();\n tick();\n }, { passive: true });\n\n document.addEventListener('visibilitychange', () =\u003e {\n if (document.hidden) {\n cancelAnimationFrame(raf);\n } else {\n tick();\n }\n });\n\n tick();\n\n window.MatrixRain = { init, tick };\n})();\n","// progress-bar.js\n(function() {\n const progressBar = document.querySelector('.reading-progress');\n if (!progressBar) return;\n\n // Only enable on pages with substantial content\n const mainContent = document.querySelector('main');\n if (!mainContent) return;\n\n function updateProgress() {\n // Calculate scroll percentage\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight - windowHeight;\n const scrolled = window.scrollY;\n const percent = docHeight \u003e 0 ? (scrolled / docHeight) * 100 : 0;\n\n progressBar.style.width = percent + '%';\n }\n\n // Mark body as scrollable if there's significant content\n const contentHeight = mainContent.offsetHeight;\n if (contentHeight \u003e window.innerHeight * 1.5) {\n document.body.classList.add('scrollable');\n }\n\n // Use requestAnimationFrame for smooth updates\n let ticking = false;\n window.addEventListener('scroll', function() {\n if (!ticking) {\n requestAnimationFrame(updateProgress);\n ticking = true;\n setTimeout(() =\u003e { ticking = false; }, 100);\n }\n }, { passive: true });\n\n // Initial update\n updateProgress();\n})();\n","// copy-code.js\n(function() {\n // Add copy button to all code blocks\n const codeBlocks = document.querySelectorAll('pre, .highlight');\n\n codeBlocks.forEach(block =\u003e {\n // Create copy button\n const btn = document.createElement('button');\n btn.className = 'code-copy-btn';\n btn.textContent = 'copy';\n btn.type = 'button';\n btn.setAttribute('aria-label', 'Copy code');\n\n // Get code text\n const code = block.querySelector('code');\n const text = code ? code.textContent : block.textContent;\n\n // Copy on click\n btn.addEventListener('click', async function() {\n try {\n await navigator.clipboard.writeText(text);\n\n // Show feedback\n const originalText = btn.textContent;\n btn.textContent = 'copied!';\n btn.classList.add('copied');\n\n setTimeout(() =\u003e {\n btn.textContent = originalText;\n btn.classList.remove('copied');\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n btn.textContent = 'error';\n }\n });\n\n // Add button to block\n block.style.position = 'relative';\n block.appendChild(btn);\n });\n})();\n"],"mappings":"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","names":[]}
\ No newline at end of file diff --git a/public/posts/index.html b/public/posts/index.html deleted file mode 100644 index 47d0691..0000000 --- a/public/posts/index.html +++ /dev/null @@ -1,82 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Posts | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <div class="container"> - <h1>Posts</h1> - - - <p>Tempor est exercitation ad qui pariatur quis adipisicing aliquip nisi ea consequat ipsum occaecat. Nostrud consequat ullamco laboris fugiat esse esse adipisicing velit laborum ipsum incididunt ut enim. Dolor pariatur nulla quis fugiat dolore excepteur. Aliquip ad quis aliqua enim do consequat.</p> - - - </div> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/posts/post-1/index.html b/public/posts/post-1/index.html deleted file mode 100644 index 129968f..0000000 --- a/public/posts/post-1/index.html +++ /dev/null @@ -1,89 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Post 1 | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <article class="page-page"> - <div class="container-narrow"> - <h1>Post 1</h1> - <div class="post-card-meta" style="margin-bottom: 2rem;"> - <span>Jan 15, 2023</span> - - </div> - - <div class="post-content"> - <p>Tempor proident minim aliquip reprehenderit dolor et ad anim Lorem duis sint eiusmod. Labore ut ea duis dolor. Incididunt consectetur proident qui occaecat incididunt do nisi Lorem. Tempor do laborum elit laboris excepteur eiusmod do. Eiusmod nisi excepteur ut amet pariatur adipisicing Lorem.</p> -<p>Occaecat nulla excepteur dolore excepteur duis eiusmod ullamco officia anim in voluptate ea occaecat officia. Cillum sint esse velit ea officia minim fugiat. Elit ea esse id aliquip pariatur cupidatat id duis minim incididunt ea ea. Anim ut duis sunt nisi. Culpa cillum sit voluptate voluptate eiusmod dolor. Enim nisi Lorem ipsum irure est excepteur voluptate eu in enim nisi. Nostrud ipsum Lorem anim sint labore consequat do.</p> - - </div> - </div> - </article> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/posts/post-2/index.html b/public/posts/post-2/index.html deleted file mode 100644 index 9a56e90..0000000 --- a/public/posts/post-2/index.html +++ /dev/null @@ -1,89 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Post 2 | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <article class="page-page"> - <div class="container-narrow"> - <h1>Post 2</h1> - <div class="post-card-meta" style="margin-bottom: 2rem;"> - <span>Feb 15, 2023</span> - - </div> - - <div class="post-content"> - <p>Anim eiusmod irure incididunt sint cupidatat. Incididunt irure irure irure nisi ipsum do ut quis fugiat consectetur proident cupidatat incididunt cillum. Dolore voluptate occaecat qui mollit laborum ullamco et. Ipsum laboris officia anim laboris culpa eiusmod ex magna ex cupidatat anim ipsum aute. Mollit aliquip occaecat qui sunt velit ut cupidatat reprehenderit enim sunt laborum. Velit veniam in officia nulla adipisicing ut duis officia.</p> -<p>Exercitation voluptate irure in irure tempor mollit Lorem nostrud ad officia. Velit id fugiat occaecat do tempor. Sit officia Lorem aliquip eu deserunt consectetur. Aute proident deserunt in nulla aliquip dolore ipsum Lorem ut cupidatat consectetur sit sint laborum. Esse cupidatat sit sint sunt tempor exercitation deserunt. Labore dolor duis laborum est do nisi ut veniam dolor et nostrud nostrud.</p> - - </div> - </div> - </article> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/posts/post-3/bryce-canyon.jpg b/public/posts/post-3/bryce-canyon.jpg Binary files differdeleted file mode 100644 index 9a923be..0000000 --- a/public/posts/post-3/bryce-canyon.jpg +++ /dev/null diff --git a/public/posts/post-3/index.html b/public/posts/post-3/index.html deleted file mode 100644 index 7322f06..0000000 --- a/public/posts/post-3/index.html +++ /dev/null @@ -1,90 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Post 3 | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <article class="page-page"> - <div class="container-narrow"> - <h1>Post 3</h1> - <div class="post-card-meta" style="margin-bottom: 2rem;"> - <span>Mar 15, 2023</span> - - </div> - - <div class="post-content"> - <p>Occaecat aliqua consequat laborum ut ex aute aliqua culpa quis irure esse magna dolore quis. Proident fugiat labore eu laboris officia Lorem enim. Ipsum occaecat cillum ut tempor id sint aliqua incididunt nisi incididunt reprehenderit. Voluptate ad minim sint est aute aliquip esse occaecat tempor officia qui sunt. Aute ex ipsum id ut in est velit est laborum incididunt. Aliqua qui id do esse sunt eiusmod id deserunt eu nostrud aute sit ipsum. Deserunt esse cillum Lorem non magna adipisicing mollit amet consequat.</p> -<p><img src="bryce-canyon.jpg" alt="Bryce Canyon National Park"></p> -<p>Sit excepteur do velit veniam mollit in nostrud laboris incididunt ea. Amet eu cillum ut reprehenderit culpa aliquip labore laborum amet sit sit duis. Laborum id proident nostrud dolore laborum reprehenderit quis mollit nulla amet veniam officia id id. Aliquip in deserunt qui magna duis qui pariatur officia sunt deserunt.</p> - - </div> - </div> - </article> - - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/sitemap.xml b/public/sitemap.xml deleted file mode 100644 index a8f827f..0000000 --- a/public/sitemap.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" - xmlns:xhtml="http://www.w3.org/1999/xhtml"> - <url> - <loc>http://localhost:1313/is/</loc> - <lastmod>2026-01-01T00:00:00+00:00</lastmod> - </url><url> - <loc>http://localhost:1313/articles/</loc> - <lastmod>2026-01-01T00:00:00+00:00</lastmod> - </url><url> - <loc>http://localhost:1313/is/here/</loc> - <lastmod>2026-01-01T00:00:00+00:00</lastmod> - </url><url> - <loc>http://localhost:1313/</loc> - <lastmod>2026-01-01T00:00:00+00:00</lastmod> - </url><url> - <loc>http://localhost:1313/tags/blue/</loc> - <lastmod>2023-03-15T11:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/tags/green/</loc> - <lastmod>2023-03-15T11:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/posts/post-3/</loc> - <lastmod>2023-03-15T11:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/tags/red/</loc> - <lastmod>2023-03-15T11:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/tags/</loc> - <lastmod>2023-03-15T11:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/posts/post-2/</loc> - <lastmod>2023-02-15T10:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/posts/post-1/</loc> - <lastmod>2023-01-15T09:00:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/posts/</loc> - <lastmod>2023-01-01T08:30:00-07:00</lastmod> - </url><url> - <loc>http://localhost:1313/categories/</loc> - </url> -</urlset> diff --git a/public/tags/blue/index.html b/public/tags/blue/index.html deleted file mode 100644 index 8ed343b..0000000 --- a/public/tags/blue/index.html +++ /dev/null @@ -1,77 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Blue | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <h1>Blue</h1> - - - <h2><a href="/posts/post-3/">Post 3</a></h2> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/tags/blue/index.xml b/public/tags/blue/index.xml deleted file mode 100644 index aa9747f..0000000 --- a/public/tags/blue/index.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Blue on danilo m.</title> - <link>http://localhost:1313/tags/blue/</link> - <description>Recent content in Blue on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <lastBuildDate>Wed, 15 Mar 2023 11:00:00 -0700</lastBuildDate> - <atom:link href="http://localhost:1313/tags/blue/index.xml" rel="self" type="application/rss+xml" /> - <item> - <title>Post 3</title> - <link>http://localhost:1313/posts/post-3/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-3/</guid> - <description><p>Occaecat aliqua consequat laborum ut ex aute aliqua culpa quis irure esse magna dolore quis. Proident fugiat labore eu laboris officia Lorem enim. Ipsum occaecat cillum ut tempor id sint aliqua incididunt nisi incididunt reprehenderit. Voluptate ad minim sint est aute aliquip esse occaecat tempor officia qui sunt. Aute ex ipsum id ut in est velit est laborum incididunt. Aliqua qui id do esse sunt eiusmod id deserunt eu nostrud aute sit ipsum. Deserunt esse cillum Lorem non magna adipisicing mollit amet consequat.</p></description> - </item> - </channel> -</rss> diff --git a/public/tags/green/index.html b/public/tags/green/index.html deleted file mode 100644 index 025cdee..0000000 --- a/public/tags/green/index.html +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Green | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <h1>Green</h1> - - - <h2><a href="/posts/post-3/">Post 3</a></h2> - - <h2><a href="/posts/post-2/">Post 2</a></h2> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/tags/green/index.xml b/public/tags/green/index.xml deleted file mode 100644 index 2f9098a..0000000 --- a/public/tags/green/index.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Green on danilo m.</title> - <link>http://localhost:1313/tags/green/</link> - <description>Recent content in Green on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <lastBuildDate>Wed, 15 Mar 2023 11:00:00 -0700</lastBuildDate> - <atom:link href="http://localhost:1313/tags/green/index.xml" rel="self" type="application/rss+xml" /> - <item> - <title>Post 3</title> - <link>http://localhost:1313/posts/post-3/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-3/</guid> - <description><p>Occaecat aliqua consequat laborum ut ex aute aliqua culpa quis irure esse magna dolore quis. Proident fugiat labore eu laboris officia Lorem enim. Ipsum occaecat cillum ut tempor id sint aliqua incididunt nisi incididunt reprehenderit. Voluptate ad minim sint est aute aliquip esse occaecat tempor officia qui sunt. Aute ex ipsum id ut in est velit est laborum incididunt. Aliqua qui id do esse sunt eiusmod id deserunt eu nostrud aute sit ipsum. Deserunt esse cillum Lorem non magna adipisicing mollit amet consequat.</p></description> - </item> - <item> - <title>Post 2</title> - <link>http://localhost:1313/posts/post-2/</link> - <pubDate>Wed, 15 Feb 2023 10:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-2/</guid> - <description><p>Anim eiusmod irure incididunt sint cupidatat. Incididunt irure irure irure nisi ipsum do ut quis fugiat consectetur proident cupidatat incididunt cillum. Dolore voluptate occaecat qui mollit laborum ullamco et. Ipsum laboris officia anim laboris culpa eiusmod ex magna ex cupidatat anim ipsum aute. Mollit aliquip occaecat qui sunt velit ut cupidatat reprehenderit enim sunt laborum. Velit veniam in officia nulla adipisicing ut duis officia.</p>
<p>Exercitation voluptate irure in irure tempor mollit Lorem nostrud ad officia. Velit id fugiat occaecat do tempor. Sit officia Lorem aliquip eu deserunt consectetur. Aute proident deserunt in nulla aliquip dolore ipsum Lorem ut cupidatat consectetur sit sint laborum. Esse cupidatat sit sint sunt tempor exercitation deserunt. Labore dolor duis laborum est do nisi ut veniam dolor et nostrud nostrud.</p></description> - </item> - </channel> -</rss> diff --git a/public/tags/index.html b/public/tags/index.html deleted file mode 100644 index ce1a253..0000000 --- a/public/tags/index.html +++ /dev/null @@ -1,81 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Tags | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <h1>Tags</h1> - - - <h2><a href="/tags/blue/">Blue</a></h2> - - <h2><a href="/tags/green/">Green</a></h2> - - <h2><a href="/tags/red/">Red</a></h2> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/tags/index.xml b/public/tags/index.xml deleted file mode 100644 index 3a78b22..0000000 --- a/public/tags/index.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Tags on danilo m.</title> - <link>http://localhost:1313/tags/</link> - <description>Recent content in Tags on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <lastBuildDate>Wed, 15 Mar 2023 11:00:00 -0700</lastBuildDate> - <atom:link href="http://localhost:1313/tags/index.xml" rel="self" type="application/rss+xml" /> - <item> - <title>Blue</title> - <link>http://localhost:1313/tags/blue/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/tags/blue/</guid> - <description></description> - </item> - <item> - <title>Green</title> - <link>http://localhost:1313/tags/green/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/tags/green/</guid> - <description></description> - </item> - <item> - <title>Red</title> - <link>http://localhost:1313/tags/red/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/tags/red/</guid> - <description></description> - </item> - </channel> -</rss> diff --git a/public/tags/red/index.html b/public/tags/red/index.html deleted file mode 100644 index 7617dd6..0000000 --- a/public/tags/red/index.html +++ /dev/null @@ -1,81 +0,0 @@ -<!DOCTYPE html> -<html lang="en-US" dir="ltr"> -<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script> - <meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<meta name="description" content="Writing about IT, life, and the things that matter."> -<meta name="theme-color" content="#060b10"> -<title>Red | danilo m.</title> - - - <link rel="stylesheet" href="/css/main.css"> - - - <script src="/js/main.js"></script> - - -</head> -<body> - <div class="reading-progress"></div> - <header><div class="header-container"> - <a href="/" class="site-title">Danilo M.</a> - <div class="header-controls"> - <nav> - <ul> - - <li> - <a href="/articles/" > - articles - </a> - </li> - - <li> - <a href="/is/" > - about - </a> - </li> - - <li> - <a href="/is/here/" > - contact - </a> - </li> - - </ul> - </nav> - <button id="theme-toggle-btn" class="theme-toggle" aria-label="Toggle theme">🌙 dark</button> - </div> -</div> -</header> - <main> - <h1>Red</h1> - - - <h2><a href="/posts/post-3/">Post 3</a></h2> - - <h2><a href="/posts/post-2/">Post 2</a></h2> - - <h2><a href="/posts/post-1/">Post 1</a></h2> - -</main> - <footer><div class="footer-container"> - <div class="footer-content"> - <div class="footer-copyright"> - © 2026 Danilo M.. All rights reserved. - </div> - <nav> - <ul class="footer-nav"> - - <li><a href="/articles/">articles</a></li> - - <li><a href="/is/">about</a></li> - - <li><a href="/is/here/">contact</a></li> - - </ul> - </nav> - </div> -</div> -</footer> -</body> -</html> diff --git a/public/tags/red/index.xml b/public/tags/red/index.xml deleted file mode 100644 index 84e6c56..0000000 --- a/public/tags/red/index.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Red on danilo m.</title> - <link>http://localhost:1313/tags/red/</link> - <description>Recent content in Red on danilo m.</description> - <generator>Hugo</generator> - <language>en-US</language> - <lastBuildDate>Wed, 15 Mar 2023 11:00:00 -0700</lastBuildDate> - <atom:link href="http://localhost:1313/tags/red/index.xml" rel="self" type="application/rss+xml" /> - <item> - <title>Post 3</title> - <link>http://localhost:1313/posts/post-3/</link> - <pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-3/</guid> - <description><p>Occaecat aliqua consequat laborum ut ex aute aliqua culpa quis irure esse magna dolore quis. Proident fugiat labore eu laboris officia Lorem enim. Ipsum occaecat cillum ut tempor id sint aliqua incididunt nisi incididunt reprehenderit. Voluptate ad minim sint est aute aliquip esse occaecat tempor officia qui sunt. Aute ex ipsum id ut in est velit est laborum incididunt. Aliqua qui id do esse sunt eiusmod id deserunt eu nostrud aute sit ipsum. Deserunt esse cillum Lorem non magna adipisicing mollit amet consequat.</p></description> - </item> - <item> - <title>Post 2</title> - <link>http://localhost:1313/posts/post-2/</link> - <pubDate>Wed, 15 Feb 2023 10:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-2/</guid> - <description><p>Anim eiusmod irure incididunt sint cupidatat. Incididunt irure irure irure nisi ipsum do ut quis fugiat consectetur proident cupidatat incididunt cillum. Dolore voluptate occaecat qui mollit laborum ullamco et. Ipsum laboris officia anim laboris culpa eiusmod ex magna ex cupidatat anim ipsum aute. Mollit aliquip occaecat qui sunt velit ut cupidatat reprehenderit enim sunt laborum. Velit veniam in officia nulla adipisicing ut duis officia.</p>
<p>Exercitation voluptate irure in irure tempor mollit Lorem nostrud ad officia. Velit id fugiat occaecat do tempor. Sit officia Lorem aliquip eu deserunt consectetur. Aute proident deserunt in nulla aliquip dolore ipsum Lorem ut cupidatat consectetur sit sint laborum. Esse cupidatat sit sint sunt tempor exercitation deserunt. Labore dolor duis laborum est do nisi ut veniam dolor et nostrud nostrud.</p></description> - </item> - <item> - <title>Post 1</title> - <link>http://localhost:1313/posts/post-1/</link> - <pubDate>Sun, 15 Jan 2023 09:00:00 -0700</pubDate> - <guid>http://localhost:1313/posts/post-1/</guid> - <description><p>Tempor proident minim aliquip reprehenderit dolor et ad anim Lorem duis sint eiusmod. Labore ut ea duis dolor. Incididunt consectetur proident qui occaecat incididunt do nisi Lorem. Tempor do laborum elit laboris excepteur eiusmod do. Eiusmod nisi excepteur ut amet pariatur adipisicing Lorem.</p>
<p>Occaecat nulla excepteur dolore excepteur duis eiusmod ullamco officia anim in voluptate ea occaecat officia. Cillum sint esse velit ea officia minim fugiat. Elit ea esse id aliquip pariatur cupidatat id duis minim incididunt ea ea. Anim ut duis sunt nisi. Culpa cillum sit voluptate voluptate eiusmod dolor. Enim nisi Lorem ipsum irure est excepteur voluptate eu in enim nisi. Nostrud ipsum Lorem anim sint labore consequat do.</p></description> - </item> - </channel> -</rss> |
