diff options
| -rw-r--r-- | docs/example-viewer.html | 263 | ||||
| -rw-r--r-- | docs/examples.html | 140 |
2 files changed, 399 insertions, 4 deletions
diff --git a/docs/example-viewer.html b/docs/example-viewer.html index dd51e95..0417c30 100644 --- a/docs/example-viewer.html +++ b/docs/example-viewer.html @@ -31,6 +31,117 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-x: hidden; + background-image: + linear-gradient( + to right, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to right, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ); + background-size: + 40px 40px, + 40px 40px, + 20px 20px, + 20px 20px; + background-position: + calc(50% - 480px + 20px) 0, + calc(50% - 480px) 0, + calc(50% - 480px + 10px) 0, + calc(50% - 480px + 10px) 0; + } + + /* Dashed side lines along the viewer edges */ + html::before, + html::after { + content: ""; + position: fixed; + top: 0; + bottom: 0; + width: 1px; + background: repeating-linear-gradient( + to bottom, + rgba(212, 168, 75, 0.25) 0, + rgba(212, 168, 75, 0.25) 4px, + transparent 4px, + transparent 9px + ); + z-index: 49; + pointer-events: none; + } + + html::before { + left: max(0px, calc(50% - 480px)); + } + + html::after { + right: max(0px, calc(50% - 480px)); + } + + /* Cursor glow dot */ + .cursor-dot { + position: fixed; + pointer-events: none; + border-radius: 50%; + width: 400px; + height: 400px; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.06) 0%, + rgba(212, 168, 75, 0.02) 45%, + transparent 70% + ); + transform: translate(-50%, -50%); + z-index: 10000; + opacity: 0; + transition: + opacity 0.3s ease, + left 0.12s ease-out, + top 0.12s ease-out; + } + + /* Ink drop effect */ + .ink-drop { + position: fixed; + pointer-events: none; + border-radius: 50%; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.15) 0%, + rgba(196, 57, 49, 0.06) 50%, + transparent 100% + ); + width: 0; + height: 0; + transform: translate(-50%, -50%); + animation: inkSpread 0.9s ease-out forwards; + z-index: 9999; + } + + @keyframes inkSpread { + 0% { + width: 0; + height: 0; + opacity: 1; + } + 100% { + width: 500px; + height: 500px; + opacity: 0; + } } a { color: #d4a84b; @@ -83,6 +194,24 @@ color: #d4a84b; } + nav .nav-links .btn-nav { + display: inline-block; + padding: 0.35rem 1rem; + border: 1px solid #d4a84b; + border-radius: 20px; + color: #d4a84b; + font-weight: 600; + font-size: 0.85rem; + transition: + background 0.2s, + color 0.2s; + } + + nav .nav-links .btn-nav:hover { + background: #d4a84b; + color: #1a1410; + } + .viewer { margin-top: 4rem; padding: 1.5rem; @@ -184,6 +313,45 @@ font-variant-ligatures: inherit; } + /* Line numbers + hover highlight */ + .code-frame pre { + position: relative; + } + + .code-frame pre code { + counter-reset: line; + } + + .code-frame pre code .line { + display: block; + counter-increment: line; + } + + .code-frame pre code .line::before { + content: counter(line); + display: inline-block; + width: 2.5ch; + margin-right: 3ch; + text-align: right; + color: #6a5a4a; + user-select: none; + } + + .code-line-highlight { + position: absolute; + left: 0; + right: 0; + height: 28px; + background: rgba(255, 255, 255, 0.1); + border-left: 2px solid rgba(255, 255, 255, 0.45); + pointer-events: none; + opacity: 0; + transition: + opacity 0.15s ease, + top 0.08s ease; + z-index: 3; + } + .doc-box { background: #241c16; border: 1px solid #3a2e24; @@ -226,6 +394,13 @@ color: #e8ddd0; } + /* Markdown code blocks: drop the hljs theme's fg/bg, keep the pre styling */ + .doc-box pre code.hljs { + background: transparent !important; + color: #c0b0a0; + padding: 0 !important; + } + .loading { text-align: center; padding: 4rem 1rem; @@ -282,6 +457,12 @@ target="_blank" >GitHub</a > + <a + href="https://crates.io/crates/mingling" + target="_blank" + class="btn-nav" + >cargo add mingling</a + > </div> </nav> @@ -325,6 +506,33 @@ </p> </footer> + <script> + // Persistent glow dot following the mouse + var cursorDot = document.createElement("div"); + cursorDot.className = "cursor-dot"; + document.body.appendChild(cursorDot); + + document.addEventListener("mousemove", function (e) { + cursorDot.style.left = e.clientX + "px"; + cursorDot.style.top = e.clientY + "px"; + if (cursorDot.style.opacity !== "1") { + cursorDot.style.opacity = "1"; + } + }); + + // Ink drop ripple on click + document.addEventListener("click", function (e) { + var drop = document.createElement("div"); + drop.className = "ink-drop"; + drop.style.left = e.clientX + "px"; + drop.style.top = e.clientY + "px"; + document.body.appendChild(drop); + setTimeout(function () { + drop.remove(); + }, 1000); + }); + </script> + <script src="scripts/highlight/highlight.min.js"></script> <script src="scripts/highlight/rust.min.js"></script> <script src="scripts/highlight/bash.min.js"></script> @@ -390,10 +598,18 @@ i++; } i++; // skip closing ``` - var codeText = escapeHtml(codeLines.join("\n")); + var rawCode = codeLines.join("\n"); + var highlighted; + if (lang && hljs.getLanguage(lang)) { + highlighted = hljs.highlight(rawCode, { + language: lang, + }).value; + } else { + highlighted = escapeHtml(rawCode); + } html += - "<pre style=\"background:#1a1410;border:1px solid #3a2e24;border-radius:2px;padding:0.75rem;margin:0.5rem 0;overflow-x:auto;font-size:0.8rem;line-height:1.5;font-family:'JetBrains Mono','Noto Serif SC',monospace;font-variant-ligatures:contextual\"><code>" + - codeText + + "<pre style=\"background:#1a1410;border:1px solid #3a2e24;border-radius:2px;padding:0.75rem;margin:0.5rem 0;overflow-x:auto;font-size:0.8rem;line-height:1.5;font-family:'JetBrains Mono','Noto Serif SC',monospace;font-variant-ligatures:contextual\"><code class=\"hljs\">" + + highlighted + "</code></pre>"; continue; } @@ -594,6 +810,18 @@ delete codeContent.dataset.highlighted; hljs.highlightElement(codeContent); + // Wrap each line with a .line span for numbering + codeContent.innerHTML = codeContent.innerHTML + .split("\n") + .map(function (line) { + return ( + '<span class="line">' + + line + + "</span>" + ); + }) + .join(""); + tabsEl .querySelectorAll("button") .forEach(function (b) { @@ -627,6 +855,35 @@ tabsEl.appendChild(btn); }); + // Line highlight on hover + (function () { + var pre = codePre; + var code = codeContent; + var hl = document.createElement("div"); + hl.className = "code-line-highlight"; + pre.appendChild(hl); + + var lineHeight = parseFloat( + getComputedStyle(code).lineHeight, + ); + + pre.addEventListener("mousemove", function (e) { + var rect = pre.getBoundingClientRect(); + var y = e.clientY - rect.top; + var index = Math.floor(y / lineHeight); + var lineCount = code.innerText.split("\n").length; + if (index < 0) index = 0; + if (index >= lineCount) index = lineCount - 1; + hl.style.top = index * lineHeight + "px"; + hl.style.height = lineHeight + "px"; + hl.style.opacity = "1"; + }); + + pre.addEventListener("mouseleave", function () { + hl.style.opacity = "0"; + }); + })(); + // Load first file if (files.length > 0) loadFile(files[0]); } diff --git a/docs/examples.html b/docs/examples.html index a200000..9d2ae8c 100644 --- a/docs/examples.html +++ b/docs/examples.html @@ -33,6 +33,37 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-x: hidden; + background-image: + linear-gradient( + to right, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to right, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ); + background-size: + 40px 40px, + 40px 40px, + 20px 20px, + 20px 20px; + background-position: + calc(50% - 550px + 20px) 0, + calc(50% - 550px) 0, + calc(50% - 550px + 10px) 0, + calc(50% - 550px + 10px) 0; } a { @@ -55,6 +86,86 @@ padding: 0 1.5rem; } + /* Dashed side lines along the container edges */ + html::before, + html::after { + content: ""; + position: fixed; + top: 0; + bottom: 0; + width: 1px; + background: repeating-linear-gradient( + to bottom, + rgba(212, 168, 75, 0.25) 0, + rgba(212, 168, 75, 0.25) 4px, + transparent 4px, + transparent 9px + ); + z-index: 49; + pointer-events: none; + } + + html::before { + left: max(0px, calc(50% - 550px)); + } + + html::after { + right: max(0px, calc(50% - 550px)); + } + + /* Cursor glow dot */ + .cursor-dot { + position: fixed; + pointer-events: none; + border-radius: 50%; + width: 400px; + height: 400px; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.06) 0%, + rgba(212, 168, 75, 0.02) 45%, + transparent 70% + ); + transform: translate(-50%, -50%); + z-index: 10000; + opacity: 0; + transition: + opacity 0.3s ease, + left 0.12s ease-out, + top 0.12s ease-out; + } + + /* Ink drop effect */ + .ink-drop { + position: fixed; + pointer-events: none; + border-radius: 50%; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.15) 0%, + rgba(196, 57, 49, 0.06) 50%, + transparent 100% + ); + width: 0; + height: 0; + transform: translate(-50%, -50%); + animation: inkSpread 0.9s ease-out forwards; + z-index: 9999; + } + + @keyframes inkSpread { + 0% { + width: 0; + height: 0; + opacity: 1; + } + 100% { + width: 500px; + height: 500px; + opacity: 0; + } + } + /* ── Nav ── */ nav { position: fixed; @@ -107,7 +218,7 @@ display: inline-block; padding: 0.35rem 1rem; border: 1px solid #d4a84b; - border-radius: 2px; + border-radius: 20px; color: #d4a84b; font-weight: 600; font-size: 0.85rem; @@ -486,5 +597,32 @@ .replace(/"/g, """); } </script> + + <script> + // Persistent glow dot following the mouse + var cursorDot = document.createElement("div"); + cursorDot.className = "cursor-dot"; + document.body.appendChild(cursorDot); + + document.addEventListener("mousemove", function (e) { + cursorDot.style.left = e.clientX + "px"; + cursorDot.style.top = e.clientY + "px"; + if (cursorDot.style.opacity !== "1") { + cursorDot.style.opacity = "1"; + } + }); + + // Ink drop ripple on click + document.addEventListener("click", function (e) { + var drop = document.createElement("div"); + drop.className = "ink-drop"; + drop.style.left = e.clientX + "px"; + drop.style.top = e.clientY + "px"; + document.body.appendChild(drop); + setTimeout(function () { + drop.remove(); + }, 1000); + }); + </script> </body> </html> |
