Skip to content

Commit ce1116f

Browse files
committed
feat: add macOS app quickstart
1 parent c940ea0 commit ce1116f

1 file changed

Lines changed: 191 additions & 4 deletions

File tree

src/pages/index.astro

Lines changed: 191 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,17 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
148148
<button class="mode-btn active" data-mode="oneliner">Just Works</button>
149149
<button class="mode-btn" data-mode="quick">npm install</button>
150150
<button class="mode-btn" data-mode="hackable">Hackable</button>
151+
<button class="mode-btn" data-mode="macos">macOS App</button>
151152
</div>
152153
<div class="pm-switch" id="pm-switch" style="display: none;">
153154
<button class="pm-btn active" data-pm="npm">npm</button>
154155
<button class="pm-btn" data-pm="pnpm">pnpm</button>
155156
</div>
156-
<div class="os-switch" id="os-switch">
157+
<div class="os-indicator" id="os-indicator">
158+
<span class="os-detected" id="os-detected">macOS/Linux</span>
159+
<button class="os-change-btn" id="os-change-btn">change</button>
160+
</div>
161+
<div class="os-switch" id="os-switch" style="display: none;">
157162
<button class="os-btn active" data-os="unix">macOS/Linux</button>
158163
<button class="os-btn" data-os="windows">Windows</button>
159164
</div>
@@ -217,6 +222,23 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
217222
</button>
218223
</div>
219224
</div>
225+
<div id="code-macos" class="code-content" style="display: none;">
226+
<div class="macos-app-content">
227+
<div class="macos-description">
228+
<span class="macos-tagline">Spinable local web server</span>
229+
<span class="macos-subtitle">No terminal needed — just download, open, and go.</span>
230+
</div>
231+
<a href="https://github.com/clawdbot/clawdbot/releases/latest" class="macos-download-btn" target="_blank" rel="noopener">
232+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
233+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
234+
<polyline points="7 10 12 15 17 10"/>
235+
<line x1="12" y1="15" x2="12" y2="3"/>
236+
</svg>
237+
Download for macOS
238+
</a>
239+
<span class="macos-meta">Requires macOS 14+ · Universal Binary</span>
240+
</div>
241+
</div>
220242
</div>
221243
<p class="quickstart-note">
222244
Works on macOS, Windows & Linux. The one-liner installs Node.js and everything else for you.
@@ -234,8 +256,14 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
234256
windows: 'iwr -useb https://clawd.bot/install.ps1 | iex'
235257
};
236258

259+
const osLabels = {
260+
unix: 'macOS/Linux',
261+
windows: 'Windows'
262+
};
263+
237264
let currentPm = 'npm';
238265
let currentMode = 'oneliner';
266+
let osPickerExpanded = false;
239267

240268
// Auto-detect OS
241269
const isWindows = navigator.platform.toLowerCase().includes('win') ||
@@ -247,9 +275,13 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
247275
const modeBtns = document.querySelectorAll('.mode-btn');
248276
const pmSwitch = document.getElementById('pm-switch');
249277
const osSwitch = document.getElementById('os-switch');
278+
const osIndicator = document.getElementById('os-indicator');
279+
const osDetected = document.getElementById('os-detected');
280+
const osChangeBtn = document.getElementById('os-change-btn');
250281
const codeOneliner = document.getElementById('code-oneliner');
251282
const codeQuick = document.getElementById('code-quick');
252283
const codeHackable = document.getElementById('code-hackable');
284+
const codeMacos = document.getElementById('code-macos');
253285

254286
function updateCommands() {
255287
// Update hackable mode commands
@@ -258,18 +290,31 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
258290
document.querySelectorAll('.pm-install').forEach(cmd => cmd.textContent = installCmds[currentPm]);
259291
// Update one-liner OS command
260292
document.querySelectorAll('.os-cmd').forEach(cmd => cmd.textContent = osCmds[currentOs]);
293+
// Update OS indicator text
294+
osDetected.textContent = osLabels[currentOs];
261295
}
262296

263297
function updateVisibility() {
264298
codeOneliner.style.display = currentMode === 'oneliner' ? 'block' : 'none';
265299
codeQuick.style.display = currentMode === 'quick' ? 'block' : 'none';
266300
codeHackable.style.display = currentMode === 'hackable' ? 'block' : 'none';
301+
codeMacos.style.display = currentMode === 'macos' ? 'block' : 'none';
267302

268-
// Show OS switch only for one-liner, PM switch for others
269-
osSwitch.style.display = currentMode === 'oneliner' ? 'flex' : 'none';
270-
pmSwitch.style.display = currentMode !== 'oneliner' ? 'flex' : 'none';
303+
// Show OS indicator for one-liner, PM switch for quick/hackable, nothing for macos
304+
const showOsControls = currentMode === 'oneliner';
305+
const showPmControls = currentMode === 'quick' || currentMode === 'hackable';
306+
307+
osIndicator.style.display = showOsControls && !osPickerExpanded ? 'flex' : 'none';
308+
osSwitch.style.display = showOsControls && osPickerExpanded ? 'flex' : 'none';
309+
pmSwitch.style.display = showPmControls ? 'flex' : 'none';
271310
}
272311

312+
// OS change toggle
313+
osChangeBtn.addEventListener('click', () => {
314+
osPickerExpanded = true;
315+
updateVisibility();
316+
});
317+
273318
pmBtns.forEach(btn => {
274319
btn.addEventListener('click', () => {
275320
currentPm = btn.dataset.pm;
@@ -284,7 +329,9 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
284329
currentOs = btn.dataset.os;
285330
osBtns.forEach(b => b.classList.remove('active'));
286331
btn.classList.add('active');
332+
osPickerExpanded = false; // Collapse after selection
287333
updateCommands();
334+
updateVisibility();
288335
});
289336
});
290337

@@ -293,6 +340,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
293340
currentMode = btn.dataset.mode;
294341
modeBtns.forEach(b => b.classList.remove('active'));
295342
btn.classList.add('active');
343+
osPickerExpanded = false; // Reset when switching modes
296344
updateVisibility();
297345
});
298346
});
@@ -1078,6 +1126,99 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
10781126
text-align: center;
10791127
}
10801128

1129+
/* OS Indicator */
1130+
.os-indicator {
1131+
display: flex;
1132+
align-items: center;
1133+
gap: 8px;
1134+
margin-left: auto;
1135+
font-family: var(--font-mono);
1136+
font-size: 0.75rem;
1137+
color: var(--text-muted);
1138+
}
1139+
1140+
.os-detected {
1141+
color: var(--text-secondary);
1142+
}
1143+
1144+
.os-change-btn {
1145+
background: none;
1146+
border: none;
1147+
color: var(--coral-bright);
1148+
font-family: var(--font-mono);
1149+
font-size: 0.7rem;
1150+
cursor: pointer;
1151+
padding: 2px 6px;
1152+
border-radius: 4px;
1153+
transition: all 0.15s ease;
1154+
}
1155+
1156+
.os-change-btn:hover {
1157+
background: rgba(255, 77, 77, 0.15);
1158+
color: var(--cyan-bright);
1159+
}
1160+
1161+
/* macOS App Download Section */
1162+
.macos-app-content {
1163+
display: flex;
1164+
flex-direction: column;
1165+
align-items: center;
1166+
gap: 16px;
1167+
padding: 24px 16px;
1168+
text-align: center;
1169+
}
1170+
1171+
.macos-description {
1172+
display: flex;
1173+
flex-direction: column;
1174+
gap: 4px;
1175+
}
1176+
1177+
.macos-tagline {
1178+
font-family: var(--font-display);
1179+
font-size: 1.1rem;
1180+
font-weight: 600;
1181+
color: var(--text-primary);
1182+
}
1183+
1184+
.macos-subtitle {
1185+
font-size: 0.9rem;
1186+
color: var(--text-muted);
1187+
}
1188+
1189+
.macos-download-btn {
1190+
display: inline-flex;
1191+
align-items: center;
1192+
gap: 10px;
1193+
padding: 14px 28px;
1194+
background: linear-gradient(135deg, var(--coral-bright) 0%, var(--coral-dark) 100%);
1195+
border: none;
1196+
border-radius: 12px;
1197+
color: white;
1198+
font-family: var(--font-display);
1199+
font-size: 1rem;
1200+
font-weight: 600;
1201+
text-decoration: none;
1202+
cursor: pointer;
1203+
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
1204+
box-shadow: 0 4px 20px rgba(255, 77, 77, 0.3);
1205+
}
1206+
1207+
.macos-download-btn:hover {
1208+
transform: translateY(-2px);
1209+
box-shadow: 0 8px 30px rgba(255, 77, 77, 0.4);
1210+
}
1211+
1212+
.macos-download-btn svg {
1213+
width: 20px;
1214+
height: 20px;
1215+
}
1216+
1217+
.macos-meta {
1218+
font-size: 0.8rem;
1219+
color: var(--text-muted);
1220+
}
1221+
10811222
/* Footer */
10821223
.footer {
10831224
margin-top: auto;
@@ -1281,5 +1422,51 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
12811422
.testimonial-quote {
12821423
font-size: 0.85rem;
12831424
}
1425+
1426+
/* Quick Start mobile layout */
1427+
.code-header {
1428+
flex-wrap: wrap;
1429+
gap: 8px;
1430+
}
1431+
1432+
.mode-switch {
1433+
order: 1;
1434+
width: 100%;
1435+
justify-content: center;
1436+
margin-top: 8px;
1437+
}
1438+
1439+
.code-dot {
1440+
order: 0;
1441+
}
1442+
1443+
.code-dot:nth-child(1) { order: 0; }
1444+
.code-dot:nth-child(2) { order: 0; }
1445+
.code-dot:nth-child(3) { order: 0; }
1446+
1447+
.os-indicator,
1448+
.os-switch,
1449+
.pm-switch {
1450+
order: 2;
1451+
width: 100%;
1452+
justify-content: center;
1453+
margin-left: 0;
1454+
}
1455+
1456+
.mode-btn {
1457+
padding: 6px 8px;
1458+
font-size: 0.65rem;
1459+
}
1460+
1461+
.os-btn,
1462+
.pm-btn {
1463+
padding: 4px 8px;
1464+
font-size: 0.65rem;
1465+
}
1466+
1467+
.macos-download-btn {
1468+
padding: 12px 20px;
1469+
font-size: 0.9rem;
1470+
}
12841471
}
12851472
</style>

0 commit comments

Comments
 (0)