lazyBoy/docs/hero.html

152 lines
6.6 KiB
HTML
Raw Normal View History

<!doctype html>
2026-09-06 14:09:17 +00:00
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>LazyBoy hero</title>
<style>
@font-face {
font-family: Huninn;
font-weight: 400;
src: url("../apps/web/node_modules/@fontsource/huninn/files/huninn-latin-400-normal.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F;
}
@font-face {
font-family: Huninn;
font-weight: 400;
src: url("../apps/web/node_modules/@fontsource/huninn/files/huninn-latin-ext-400-normal.woff2") format("woff2");
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1EFF;
}
@font-face {
font-family: Huninn;
font-weight: 400;
src: url("../apps/web/node_modules/@fontsource/huninn/files/huninn-chinese-traditional-400-normal.woff2") format("woff2");
unicode-range: U+4E00-9FFF, U+3400-4DBF, U+F900-FAFF, U+3000-303F, U+FF00-FFEF;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
width: 1280px;
2026-09-09 07:32:46 +00:00
height: 760px;
overflow: hidden;
background: #f3f3f5;
color: #161618;
font-family: Huninn, "jf open 粉圓", "PingFang TC", sans-serif;
}
2026-09-09 07:32:46 +00:00
.page { width: 1280px; height: 760px; padding: 30px 48px 0; }
.top { display: flex; align-items: center; justify-content: space-between; height: 36px; }
.brand { display: flex; align-items: center; gap: 10px; font-size: 20px; letter-spacing: .02em; }
.brand svg { width: 26px; height: 26px; }
.pill {
2026-09-09 07:32:46 +00:00
display: inline-flex; align-items: center; gap: 8px; height: 28px; padding: 0 12px;
border: 1px solid #e4e4e8; border-radius: 999px; background: #fff; color: #5c5c64; font-size: 12px;
}
2026-09-09 07:32:46 +00:00
.pill b { color: #0f766e; font-weight: 400; }
.copy { text-align: center; margin: 20px auto 18px; max-width: 820px; }
h1 { margin: 0; font-size: 40px; font-weight: 400; letter-spacing: .01em; line-height: 1.15; }
.lead { margin: 10px 0 0; color: #6b6b73; font-size: 15px; line-height: 1.55; }
.window {
2026-09-09 07:32:46 +00:00
width: 1184px; height: 554px; margin: 0 auto;
border-radius: 16px 16px 0 0; overflow: hidden; background: #0d0d0e;
box-shadow: 0 24px 70px rgba(16, 16, 20, .28), 0 0 0 1px rgba(0,0,0,.08);
2026-09-09 07:32:46 +00:00
display: grid; grid-template-rows: 34px 1fr;
}
.chrome {
2026-09-09 07:32:46 +00:00
display: flex; align-items: center; gap: 7px; padding: 0 14px;
background: #161618; border-bottom: 1px solid #202023;
}
.dot { width: 10px; height: 10px; border-radius: 50%; }
.dot.r { background: #ff5f57; }
.dot.y { background: #febc2e; }
.dot.g { background: #28c840; }
2026-09-09 07:32:46 +00:00
/* Real pixels: docs/hero/*.png comes from scripts/capture-hero.mjs. */
/* 1184x520 matches the capture ratio (1480x650), so nothing is cropped. */
.shot { position: relative; width: 1184px; height: 520px; overflow: hidden; }
.shot img { position: absolute; display: block; }
</style>
</head>
<body>
<div class="page">
<div class="top">
<div class="brand">
2026-09-09 07:32:46 +00:00
<svg viewBox="0 0 64 64" aria-hidden="true">
<path fill="#3ec5a8" d="M33 5c11.5 1 24 11 23 26-1 14-11 27-25 28S6 47 7 31 21 4 33 5z"/>
<ellipse cx="25.5" cy="29" rx="4.2" ry="5" fill="#1b1b22"/>
<ellipse cx="40.5" cy="29" rx="4.2" ry="5" fill="#1b1b22"/>
<circle cx="26.8" cy="27.2" r="1.3" fill="#f3f3f6"/>
<circle cx="41.8" cy="27.2" r="1.3" fill="#f3f3f6"/>
</svg>
LazyBoy
</div>
2026-09-09 07:55:39 +00:00
<div class="pill"><b id="pill-strong"></b> <span id="pill-rest"></span></div>
</div>
<div class="copy">
2026-09-09 07:55:39 +00:00
<h1 id="title"></h1>
<p class="lead" id="lead"></p>
</div>
<div class="window">
<div class="chrome"><i class="dot r"></i><i class="dot y"></i><i class="dot g"></i></div>
2026-09-09 07:32:46 +00:00
<div class="shot"></div>
</div>
</div>
2026-09-09 07:32:46 +00:00
<script>
2026-09-09 07:55:39 +00:00
// One banner per README language: the frame copy and the screenshot are
// captured in the same language, so the English README never shows a
// Chinese screen and vice versa. ?lang=zh-TW|en.
const pages = {
en: {
pillStrong: 'Self-hosted',
pillRest: 'a Linux desktop per agent',
title: 'Give an agent a real computer',
lead: [
'Assign work by text, voice, or a quick demo, then watch its own Linux desktop do it.',
'Chats, memory, and desktops stay on your host. You choose the model.',
],
alt: 'LazyBoy group chat routing one message to a single agent, with that agent\'s live desktop on the right',
},
'zh-TW': {
pillStrong: '自架部署',
pillRest: '每個 Agent 一台 Linux 桌面',
title: '給 Agent 一台真正的電腦',
lead: [
'用文字、語音或一段示範交代任務,接著看它自己的 Linux 桌面動手做完。',
'對話、記憶與桌面都留在你的主機上,模型由你挑選。',
],
alt: 'LazyBoy 群組對話:訊息由其中一個 Agent 接手回覆,右側是它自己的即時桌面',
},
2026-09-09 07:32:46 +00:00
};
2026-09-09 07:55:39 +00:00
// Real captures only, from scripts/capture-hero.mjs. The group view is two
// layers: room-<lang>.png is shot with `--hide .side-card`, which blanks the
// desktop panel (an agent's browser holds whatever its owner left open), and
// desktop-<lang>.png drops a neutral one back in at the anchor that same
// capture prints. Captures are 2x shots of a 1480px viewport, so a
// capture-space number becomes hero-space by multiplying by 1184/1480 = 0.8.
const lang = new URLSearchParams(location.search).get('lang') || 'en';
const page = pages[lang] || pages.en;
const capture = lang === 'en' ? 'en' : 'zh';
const layers = [
{ src: `./hero/room-${capture}.png`, x: 0, y: 0, w: 1184, h: 520 },
{ src: `./hero/desktop-${capture}.png`, x: 832, y: 0, w: 352, h: 520 },
];
document.documentElement.lang = lang;
document.title = `LazyBoy hero (${lang})`;
document.getElementById('pill-strong').textContent = page.pillStrong;
document.getElementById('pill-rest').textContent = page.pillRest;
document.getElementById('title').textContent = page.title;
document.getElementById('lead').innerHTML = page.lead.join('<br/>');
document.querySelector('.shot').append(
...layers.map((layer) => {
const img = document.createElement('img');
img.src = layer.src;
img.alt = page.alt;
img.style.left = `${layer.x}px`;
img.style.top = `${layer.y}px`;
img.style.width = `${layer.w}px`;
img.style.height = `${layer.h}px`;
return img;
}),
);
2026-09-09 07:32:46 +00:00
</script>
</body>
</html>