Skip to content

Commit a2165ae

Browse files
committed
feat(website): add brew copy button and interactive mockup outline
1 parent 5f7634c commit a2165ae

3 files changed

Lines changed: 143 additions & 66 deletions

File tree

website/css/site.css

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ nav a:hover { color: var(--text); }
253253
.mockup-body {
254254
display: flex;
255255
background: var(--bg);
256-
min-height: 340px;
256+
height: 380px;
257257
}
258258

259259
.mockup-sidebar {
@@ -276,7 +276,12 @@ nav a:hover { color: var(--text); }
276276
font-size: 13px;
277277
color: var(--text-muted);
278278
padding: 4px 16px;
279-
cursor: default;
279+
cursor: pointer;
280+
transition: color 0.15s;
281+
}
282+
283+
.mockup-outline-item:hover {
284+
color: var(--text);
280285
}
281286

282287
.mockup-outline-item[data-level="2"] {
@@ -296,7 +301,9 @@ nav a:hover { color: var(--text); }
296301
line-height: 1.65;
297302
color: var(--text);
298303
padding: 28px 32px;
299-
overflow: hidden;
304+
overflow-y: auto;
305+
scroll-behavior: smooth;
306+
scrollbar-width: none;
300307
}
301308

302309
.mockup-content.markdown-body h1 {
@@ -590,17 +597,40 @@ html.dark .code-string { color: #7ee787; }
590597
font-size: 0.8rem !important;
591598
}
592599

600+
.brew-block {
601+
display: flex;
602+
align-items: center;
603+
background: var(--code-bg);
604+
border-radius: 6px;
605+
overflow: hidden;
606+
}
607+
593608
.brew-cmd {
594-
display: block;
609+
flex: 1;
595610
font-size: 0.75rem;
596-
background: var(--code-bg);
597611
padding: 8px 12px;
598-
border-radius: 6px;
599612
color: var(--text-muted);
600613
word-break: break-all;
601614
user-select: all;
602615
}
603616

617+
.brew-copy {
618+
flex-shrink: 0;
619+
background: none;
620+
border: none;
621+
padding: 8px 10px;
622+
cursor: pointer;
623+
color: var(--text-muted);
624+
display: flex;
625+
align-items: center;
626+
transition: color 0.15s;
627+
}
628+
629+
.brew-copy:hover { color: var(--text); }
630+
.brew-copy .icon-check { display: none; }
631+
.brew-copy.copied .icon-copy { display: none; }
632+
.brew-copy.copied .icon-check { display: block; color: #28c840; }
633+
604634
/* === Footer === */
605635

606636
footer {
@@ -659,7 +689,7 @@ footer {
659689

660690
.mockup-wrapper { padding: 0 16px; }
661691
.mockup-sidebar { display: none; }
662-
.mockup-body { min-height: auto; }
692+
.mockup-body { height: auto; max-height: 300px; }
663693

664694
.feature-split {
665695
flex-direction: column !important;

website/index.html

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<nav>
1818
<a href="#features">Features</a>
1919
<a href="#download">Download</a>
20-
<a href="https://github.com/Devitools/arandu" target="_blank" rel="noopener">GitHub</a>
20+
<a href="https://github.com/devitools/arandu" target="_blank" rel="noopener">GitHub</a>
2121
<button id="theme-toggle" title="Toggle theme" aria-label="Toggle theme">
2222
<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor">
2323
<path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm0 1v12A6 6 0 1 1 8 2z"/>
@@ -38,7 +38,7 @@ <h1>A beautiful way to<br>read Markdown.</h1>
3838
<a id="cta-download" href="#download" class="btn btn-primary">
3939
Download for <span id="cta-os">your OS</span>
4040
</a>
41-
<a href="https://github.com/Devitools/arandu" class="btn btn-secondary" target="_blank" rel="noopener">
41+
<a href="https://github.com/devitools/arandu" class="btn btn-secondary" target="_blank" rel="noopener">
4242
View on GitHub
4343
</a>
4444
</div>
@@ -54,18 +54,23 @@ <h1>A beautiful way to<br>read Markdown.</h1>
5454
<div class="mockup-body">
5555
<div class="mockup-sidebar">
5656
<div class="mockup-sidebar-header">OUTLINE</div>
57-
<div class="mockup-outline-item active" data-level="1">Getting Started</div>
58-
<div class="mockup-outline-item" data-level="2">Installation</div>
59-
<div class="mockup-outline-item" data-level="2">Usage</div>
60-
<div class="mockup-outline-item" data-level="1">Features</div>
61-
<div class="mockup-outline-item" data-level="2">Syntax Highlighting</div>
62-
<div class="mockup-outline-item" data-level="2">Live Reload</div>
57+
<div class="mockup-outline-item active" data-level="1" data-target="mock-getting-started">Getting Started</div>
58+
<div class="mockup-outline-item" data-level="2" data-target="mock-installation">Installation</div>
59+
<div class="mockup-outline-item" data-level="2" data-target="mock-usage">Usage</div>
60+
<div class="mockup-outline-item" data-level="1" data-target="mock-features">Features</div>
61+
<div class="mockup-outline-item" data-level="2" data-target="mock-syntax">Syntax Highlighting</div>
62+
<div class="mockup-outline-item" data-level="2" data-target="mock-reload">Live Reload</div>
6363
</div>
6464
<div class="mockup-content markdown-body">
65-
<h1>Getting Started</h1>
65+
<h1 id="mock-getting-started">Getting Started</h1>
6666
<p>Arandu is a minimal Markdown viewer that renders your files with beautiful typography, syntax highlighting, and a live-updating preview.</p>
67-
<pre><code>arandu README.md</code></pre>
68-
<h2>Features</h2>
67+
<h2 id="mock-installation">Installation</h2>
68+
<pre><code>brew install --cask devitools/arandu/arandu</code></pre>
69+
<h2 id="mock-usage">Usage</h2>
70+
<pre><code>arandu README.md
71+
arandu doc1.md doc2.md
72+
arandu *.md</code></pre>
73+
<h2 id="mock-features">Features</h2>
6974
<table>
7075
<thead>
7176
<tr><th>Feature</th><th>Description</th></tr>
@@ -76,6 +81,13 @@ <h2>Features</h2>
7681
<tr><td>Live Reload</td><td>Auto-refresh on file save</td></tr>
7782
</tbody>
7883
</table>
84+
<h2 id="mock-syntax">Syntax Highlighting</h2>
85+
<p>Code blocks are highlighted automatically with support for over 190 languages.</p>
86+
<pre><code><span class="code-keyword">function</span> <span class="code-function">greet</span>(<span class="code-param">name</span>) {
87+
console.<span class="code-function">log</span>(<span class="code-string">`Hello, ${name}!`</span>);
88+
}</code></pre>
89+
<h2 id="mock-reload">Live Reload</h2>
90+
<p>Arandu watches your file for changes and refreshes the preview instantly when you save from any editor.</p>
7991
</div>
8092
</div>
8193
</div>
@@ -184,9 +196,15 @@ <h2>Download</h2>
184196
</svg>
185197
<h3>macOS</h3>
186198
<p>Tauri app</p>
187-
<a href="https://github.com/Devitools/arandu/releases/latest" class="btn btn-primary">Download DMG</a>
199+
<a href="https://github.com/devitools/arandu/releases/latest" class="btn btn-primary">Download DMG</a>
188200
<p class="brew-hint">or install with Homebrew:</p>
189-
<code class="brew-cmd">brew install --cask devitools/arandu/arandu</code>
201+
<div class="brew-block">
202+
<code class="brew-cmd">brew install --cask devitools/arandu/arandu</code>
203+
<button class="brew-copy" title="Copy to clipboard" onclick="navigator.clipboard.writeText('brew install --cask devitools/arandu/arandu');this.classList.add('copied');setTimeout(()=>this.classList.remove('copied'),1500)">
204+
<svg class="icon-copy" width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25z"/><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25z"/></svg>
205+
<svg class="icon-check" width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/></svg>
206+
</button>
207+
</div>
190208
</div>
191209
<div class="download-card fade-in" data-os="linux">
192210
<svg class="os-icon" viewBox="0 0 24 24" fill="currentColor">
@@ -195,8 +213,8 @@ <h3>macOS</h3>
195213
<h3>Linux</h3>
196214
<p>Tauri app</p>
197215
<div class="download-links">
198-
<a href="https://github.com/Devitools/arandu/releases/latest" class="btn btn-primary">AppImage</a>
199-
<a href="https://github.com/Devitools/arandu/releases/latest" class="btn btn-secondary">.deb</a>
216+
<a href="https://github.com/devitools/arandu/releases/latest" class="btn btn-primary">AppImage</a>
217+
<a href="https://github.com/devitools/arandu/releases/latest" class="btn btn-secondary">.deb</a>
200218
</div>
201219
</div>
202220
<div class="download-card fade-in" data-os="windows">
@@ -205,16 +223,16 @@ <h3>Linux</h3>
205223
</svg>
206224
<h3>Windows</h3>
207225
<p>Tauri app</p>
208-
<a href="https://github.com/Devitools/arandu/releases/latest" class="btn btn-primary">Download .exe</a>
226+
<a href="https://github.com/devitools/arandu/releases/latest" class="btn btn-primary">Download .exe</a>
209227
</div>
210228
</div>
211229
</div>
212230
</section>
213231

214232
<footer>
215233
<div class="container footer-inner">
216-
<span>&copy; 2026 Devitools</span>
217-
<a href="https://github.com/Devitools/arandu" target="_blank" rel="noopener">GitHub</a>
234+
<span>&copy; 2026 devitools</span>
235+
<a href="https://github.com/devitools/arandu" target="_blank" rel="noopener">GitHub</a>
218236
</div>
219237
</footer>
220238

website/js/site.js

Lines changed: 70 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,86 @@
11
(function () {
2-
var ua = navigator.userAgent.toLowerCase();
3-
var os = "macos";
4-
if (ua.includes("win")) os = "windows";
5-
else if (ua.includes("linux")) os = "linux";
6-
7-
var osLabel = { macos: "macOS", linux: "Linux", windows: "Windows" };
8-
var ctaOs = document.getElementById("cta-os");
9-
if (ctaOs) ctaOs.textContent = osLabel[os];
10-
11-
document.querySelectorAll(".download-card").forEach(function (card) {
12-
if (card.dataset.os === os) card.classList.add("highlighted");
13-
});
14-
15-
var themes = ["system", "light", "dark"];
16-
var current = localStorage.getItem("arandu-site-theme") || "system";
17-
18-
function applyTheme(theme) {
19-
current = theme;
20-
localStorage.setItem("arandu-site-theme", theme);
21-
document.documentElement.classList.remove("light", "dark");
22-
if (theme !== "system") document.documentElement.classList.add(theme);
2+
var ua = navigator.userAgent.toLowerCase()
3+
var os = 'macos'
4+
if (ua.includes('win')) os = 'windows'
5+
else if (ua.includes('linux')) os = 'linux'
6+
7+
var osLabel = { macos: 'macOS', linux: 'Linux', windows: 'Windows' }
8+
var ctaOs = document.getElementById('cta-os')
9+
if (ctaOs) ctaOs.textContent = osLabel[os]
10+
11+
document.querySelectorAll('.download-card').forEach(function (card) {
12+
if (card.dataset.os === os) card.classList.add('highlighted')
13+
})
14+
15+
var themes = ['system', 'light', 'dark']
16+
var current = localStorage.getItem('arandu-site-theme') || 'system'
17+
18+
function applyTheme (theme) {
19+
current = theme
20+
localStorage.setItem('arandu-site-theme', theme)
21+
document.documentElement.classList.remove('light', 'dark')
22+
if (theme !== 'system') document.documentElement.classList.add(theme)
2323
}
2424

25-
var toggle = document.getElementById("theme-toggle");
25+
var toggle = document.getElementById('theme-toggle')
2626
if (toggle) {
27-
toggle.addEventListener("click", function () {
28-
var idx = themes.indexOf(current);
29-
applyTheme(themes[(idx + 1) % themes.length]);
30-
});
27+
toggle.addEventListener('click', function () {
28+
var idx = themes.indexOf(current)
29+
applyTheme(themes[(idx + 1) % themes.length])
30+
})
3131
}
3232

33-
applyTheme(current);
33+
applyTheme(current)
3434

3535
var observer = new IntersectionObserver(function (entries) {
3636
entries.forEach(function (entry) {
3737
if (entry.isIntersecting) {
38-
entry.target.classList.add("visible");
39-
observer.unobserve(entry.target);
38+
entry.target.classList.add('visible')
39+
observer.unobserve(entry.target)
4040
}
41-
});
42-
}, { threshold: 0.1 });
41+
})
42+
}, { threshold: 0.1 })
4343

44-
document.querySelectorAll(".fade-in").forEach(function (el) {
45-
observer.observe(el);
46-
});
44+
document.querySelectorAll('.fade-in').forEach(function (el) {
45+
observer.observe(el)
46+
})
4747

4848
document.querySelectorAll('a[href^="#"]').forEach(function (a) {
49-
a.addEventListener("click", function (e) {
50-
var target = document.querySelector(a.getAttribute("href"));
49+
a.addEventListener('click', function (e) {
50+
var target = document.querySelector(a.getAttribute('href'))
5151
if (target) {
52-
e.preventDefault();
53-
target.scrollIntoView({ behavior: "smooth" });
52+
e.preventDefault()
53+
target.scrollIntoView({ behavior: 'smooth' })
5454
}
55-
});
56-
});
57-
})();
55+
})
56+
})
57+
58+
var outlineItems = document.querySelectorAll('.mockup-outline-item[data-target]')
59+
var mockupContent = document.querySelector('.mockup-content.markdown-body')
60+
61+
if (outlineItems.length && mockupContent) {
62+
outlineItems.forEach(function (item) {
63+
item.addEventListener('click', function () {
64+
var target = document.getElementById(item.dataset.target)
65+
if (!target) return
66+
target.scrollIntoView({ behavior: 'smooth', block: 'start' })
67+
outlineItems.forEach(function (el) { el.classList.remove('active') })
68+
item.classList.add('active')
69+
})
70+
})
71+
72+
mockupContent.addEventListener('scroll', function () {
73+
var headings = mockupContent.querySelectorAll('h1[id], h2[id]')
74+
var scrollTop = mockupContent.scrollTop
75+
var active = headings[0]
76+
headings.forEach(function (h) {
77+
if (h.offsetTop - mockupContent.offsetTop <= scrollTop + 10) active = h
78+
})
79+
if (active) {
80+
outlineItems.forEach(function (el) {
81+
el.classList.toggle('active', el.dataset.target === active.id)
82+
})
83+
}
84+
})
85+
}
86+
})()

0 commit comments

Comments
 (0)