Configure board deployment and backend proxy
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 65d91830-ed68-4c91-99dc-b18d3b4d3d35 implementation handoff
|
||||
|
||||
This archive is the source of truth for turning the design into production code. Start from `index.html`, then preserve the visual system, responsive behavior, and interactions found in the exported files.
|
||||
|
||||
## Implementation target
|
||||
- Build production UI from the exported design, not a loose reinterpretation.
|
||||
- Preserve typography scale, spacing rhythm, color tokens, border radii, shadows, motion timing, and component states.
|
||||
- Replace static placeholders only when the target app has real data or functional equivalents.
|
||||
- Keep generated product UI free of OpenDesign chrome, preview labels, or design-process annotations.
|
||||
- Treat this handoff as a visual contract: if implementation choices conflict, match the exported pixels and behavior first, then refactor internals.
|
||||
|
||||
## Source map
|
||||
- Primary entry: `index.html`
|
||||
- HTML screens detected: 3
|
||||
- Stylesheets detected: 0
|
||||
- Script/component files detected: 0
|
||||
- Supporting assets detected: 1
|
||||
|
||||
## Responsive contract
|
||||
Validate the implementation across this 2025–2026 viewport matrix:
|
||||
- Mobile compact: 360×800
|
||||
- Mobile standard: 390×844
|
||||
- Mobile large: 430×932
|
||||
- Foldable / small tablet: 600×960
|
||||
- Tablet portrait: 820×1180
|
||||
- Tablet landscape: 1024×768
|
||||
- Laptop: 1366×768
|
||||
- Desktop: 1440×900
|
||||
- Wide desktop: 1920×1080
|
||||
|
||||
For responsive web exports, treat these as a modern breakpoint system for one adaptive web experience, not three fixed screenshots. Do not split responsive web into unrelated native app screens unless the project explicitly includes native targets. Use semantic layout thresholds, fluid `clamp()` type/spacing, and container queries where component width matters more than viewport width. Preserve any CSS media queries, container queries, fluid `clamp()` scales, and layout changes already present in the exported files.
|
||||
|
||||
## Design fidelity contract
|
||||
- Extract reusable tokens before writing components: background, surface, foreground, muted text, border, accent, radius, shadow, spacing, type scale, and motion duration/easing.
|
||||
- Map product screens, in-app modules/components, optional landing page, and optional OS widget surfaces before coding. Keep these surfaces separate in the target architecture.
|
||||
- Match layout geometry: max-widths, gutters, grid columns, card proportions, sticky/fixed elements, and viewport-specific navigation.
|
||||
- Preserve real copy, labels, and data shown in the export. Do not replace specific text with generic marketing filler.
|
||||
- Preserve interactive affordances: hover, focus, pressed, disabled, loading, validation, copy/share, tab/accordion, modal/sheet, and keyboard states where present.
|
||||
- Preserve accessibility semantics when converting: headings stay hierarchical, controls remain buttons/links/inputs, focus states stay visible.
|
||||
- Do not keep prototype-only annotations, frame labels, or OpenDesign chrome in the production UI.
|
||||
|
||||
## CJX-ready UX contract
|
||||
- Use `DESIGN-MANIFEST.json` as the machine-readable map for screens, app modules, OS widgets, landing pages, tokens, interactions, and viewport checks.
|
||||
- Screen-file-first: when multiple user-facing surfaces exist, implement each HTML screen as its own route/file. Treat `index.html` as a launcher/overview when the manifest marks it that way, not as a combined final UI.
|
||||
- If `landing.html`, app screens, platform screens, or OS widget files exist, preserve those boundaries in the target app instead of merging them into one page.
|
||||
- A single self-contained `index.html` is acceptable only when the export truly contains one user-facing screen and its CSS/JS are structured enough to extract tokens, components, states, and behavior.
|
||||
- If separate `css/` or `js/` files exist, treat them as source of truth for token/component/interactions before porting to React, Vue, SwiftUI, Compose, or another target stack.
|
||||
- In-app modules/components are product UI blocks inside the app. OS widgets are home-screen/lock-screen/quick-access surfaces outside the app. Do not merge those concepts.
|
||||
|
||||
## Color and brand contract
|
||||
- Use the exported design tokens and product/domain context as the color source of truth.
|
||||
- Do not introduce warm beige / cream / peach / pink / orange-brown background washes unless they are already explicit brand/reference colors in the export.
|
||||
- No obvious token stylesheet was detected; sample colors from the entry file and convert them into named tokens before coding.
|
||||
|
||||
## Implementation sequence for AI coding tools
|
||||
1. Open `index.html` and `DESIGN-MANIFEST.json`; identify every screen file, launcher/overview file, app module, and interaction before coding.
|
||||
2. If multiple HTML screens exist, map them to separate routes/surfaces first; do not merge `landing.html`, product app screens, platform screens, or OS widgets into one route.
|
||||
3. Extract a token table from CSS/root styles and inline styles before building framework components.
|
||||
4. Build product screens and domain-specific in-app modules from largest layout regions down to controls; avoid starting with isolated atoms that lose spatial intent.
|
||||
5. Port responsive behavior across the modern viewport matrix and test each semantic breakpoint before cleanup.
|
||||
6. Port interactions and states, then replace static placeholders only with real app data or functional equivalents.
|
||||
7. Keep optional landing page and OS widget surfaces as separate surfaces if present.
|
||||
8. Compare final screenshots against the export at 360×800, 390×844, 430×932, 820×1180, 1024×768, 1366×768, 1440×900, and 1920×1080 before declaring done.
|
||||
|
||||
## Entry points
|
||||
- `control.html`
|
||||
- `index.html`
|
||||
- `screen.html`
|
||||
|
||||
## Styles
|
||||
- None detected
|
||||
|
||||
## Scripts/components
|
||||
- None detected
|
||||
|
||||
## Assets and supporting files
|
||||
- `drawing-2026-09-12T12-48-14-971Z.png`
|
||||
|
||||
## Coding checklist for AI tools
|
||||
1. Inspect `index.html` and `DESIGN-MANIFEST.json` first and identify reusable components before coding.
|
||||
2. Implement each user-facing screen file as its own route/surface; keep launcher, landing, app, platform, and OS widget files separate.
|
||||
3. Extract design tokens into the target stack: colors, type scale, spacing, radius, shadows, and motion.
|
||||
4. Implement layout with real 2025–2026 responsive breakpoints, fluid type/spacing, and container-query-aware component behavior; test with no horizontal overflow.
|
||||
5. Preserve interactive controls, hover/focus/pressed states, form behavior, validation, and copy actions where present.
|
||||
6. Implement domain-specific in-app modules with real states; do not flatten them into generic cards.
|
||||
7. Keep landing page, product screens, and OS widget/quick-access surfaces separate when present.
|
||||
8. Confirm the production result visually matches the exported design before refactoring internals.
|
||||
9. Reject implementation shortcuts that flatten the design into generic cards, generic gradients, placeholder stats, or framework-default typography.
|
||||
10. If a detail is ambiguous, keep the exported HTML/CSS/JS behavior rather than inventing a new pattern.
|
||||
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"schema": "open-design.design-manifest.v1",
|
||||
"title": "65d91830-ed68-4c91-99dc-b18d3b4d3d35",
|
||||
"entryFile": "index.html",
|
||||
"sourceFiles": {
|
||||
"all": [
|
||||
"control.html",
|
||||
"drawing-2026-09-12T12-48-14-971Z.png",
|
||||
"index.html",
|
||||
"screen.html"
|
||||
],
|
||||
"html": [
|
||||
"control.html",
|
||||
"index.html",
|
||||
"screen.html"
|
||||
],
|
||||
"css": [],
|
||||
"scriptsAndComponents": [],
|
||||
"assets": [
|
||||
"drawing-2026-09-12T12-48-14-971Z.png"
|
||||
]
|
||||
},
|
||||
"screens": [
|
||||
{
|
||||
"file": "control.html",
|
||||
"role": "screen",
|
||||
"implementationNote": "Preserve visual hierarchy, responsive behavior, and interactive states from this screen."
|
||||
},
|
||||
{
|
||||
"file": "index.html",
|
||||
"role": "launcher-overview",
|
||||
"implementationNote": "Use this as the navigation/overview entry only; implement each linked screen file as its own route/surface."
|
||||
},
|
||||
{
|
||||
"file": "screen.html",
|
||||
"role": "product-screen",
|
||||
"implementationNote": "Preserve visual hierarchy, responsive behavior, and interactive states from this screen."
|
||||
}
|
||||
],
|
||||
"screenFilePolicy": {
|
||||
"mode": "screen-file-first",
|
||||
"entryFileRole": "launcher-overview",
|
||||
"rules": [
|
||||
"Each distinct user-facing screen or surface must be delivered and implemented as its own file/route.",
|
||||
"If a landing page is present or requested, keep it in landing.html and do not merge it into the product app screen.",
|
||||
"When multiple HTML screens exist, index.html is a launcher/overview only; it must not be treated as the combined final UI.",
|
||||
"Keep product app screens, landing pages, platform screens, and OS widget surfaces separate in production code."
|
||||
]
|
||||
},
|
||||
"appModules": [
|
||||
"Identify domain-specific in-app modules from the exported UI; do not reduce them to generic cards.",
|
||||
"For each major module, implement purpose, default/loading/empty/error/success states, and responsive behavior.",
|
||||
"Keep app modules separate from OS home-screen widgets in the production component model."
|
||||
],
|
||||
"osWidgets": [
|
||||
"If the export includes home-screen, lock-screen, Live Activity, tablet glance, or Android widget surfaces, implement them as platform quick-access surfaces outside the app UI.",
|
||||
"If none are present, do not invent OS widgets unless the product requirements request them."
|
||||
],
|
||||
"landingPage": {
|
||||
"detection": "Inspect files and screen names for a marketing/landing page surface. If present, keep it separate from product app screens.",
|
||||
"requiredSections": [
|
||||
"hero",
|
||||
"value props",
|
||||
"product proof/screenshots",
|
||||
"feature proof",
|
||||
"CTA"
|
||||
]
|
||||
},
|
||||
"tokens": {
|
||||
"source": [
|
||||
"index.html"
|
||||
],
|
||||
"required": [
|
||||
"background",
|
||||
"surface",
|
||||
"foreground",
|
||||
"muted text",
|
||||
"border",
|
||||
"accent",
|
||||
"radius",
|
||||
"shadow",
|
||||
"spacing",
|
||||
"type scale",
|
||||
"motion"
|
||||
],
|
||||
"note": "Extract/freeze tokens before framework implementation so coding tools do not substitute default theme colors or typography."
|
||||
},
|
||||
"interactions": {
|
||||
"source": [
|
||||
"index.html"
|
||||
],
|
||||
"requiredStates": [
|
||||
"default",
|
||||
"hover",
|
||||
"focus",
|
||||
"active",
|
||||
"disabled",
|
||||
"loading",
|
||||
"empty",
|
||||
"error",
|
||||
"success"
|
||||
],
|
||||
"requiredBehaviors": [
|
||||
"forms/validation where present",
|
||||
"tabs/filters where present",
|
||||
"dialogs/sheets/drawers where present",
|
||||
"copy/generate/share actions where present",
|
||||
"player or quick controls where present"
|
||||
],
|
||||
"note": "If the prototype is static, derive missing behavior from visible controls and document it before coding."
|
||||
},
|
||||
"responsiveViewports": [
|
||||
{
|
||||
"name": "mobile-compact",
|
||||
"width": 360,
|
||||
"height": 800,
|
||||
"category": "mobile",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "mobile-standard",
|
||||
"width": 390,
|
||||
"height": 844,
|
||||
"category": "mobile",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "mobile-large",
|
||||
"width": 430,
|
||||
"height": 932,
|
||||
"category": "mobile",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "foldable-small-tablet",
|
||||
"width": 600,
|
||||
"height": 960,
|
||||
"category": "foldable-tablet",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "tablet-portrait",
|
||||
"width": 820,
|
||||
"height": 1180,
|
||||
"category": "tablet",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "tablet-landscape",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"category": "tablet",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "laptop",
|
||||
"width": 1366,
|
||||
"height": 768,
|
||||
"category": "desktop",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "desktop",
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"category": "desktop",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
},
|
||||
{
|
||||
"name": "wide",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"category": "wide",
|
||||
"mustAvoidHorizontalScroll": true
|
||||
}
|
||||
],
|
||||
"implementationChecklist": [
|
||||
"Open entryFile first and map screens, modules, tokens, and interactions.",
|
||||
"Extract tokens before writing framework components.",
|
||||
"Implement app-specific modules with real states instead of generic card grids.",
|
||||
"Preserve or rebuild JS interactions for meaningful UX actions.",
|
||||
"Validate screenshots at desktop/tablet/mobile viewports with no horizontal overflow.",
|
||||
"Keep landing pages, in-app modules, and OS widgets as separate implementation surfaces."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<title>遥控器 · 找到你自己</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg:#ffffff; --surface:#f6f6f3; --surface-warm:#e5e5e0;
|
||||
--fg:#211922; --fg-2:#000000; --muted:#62625b; --meta:#91918c;
|
||||
--border-soft:#e0e0d9; --accent:#e60023; --success:#103c25;
|
||||
--font-body:"Pin Sans",-apple-system,system-ui,Arial,sans-serif;
|
||||
--text-xs:12px; --text-sm:14px; --text-base:16px; --text-xl:22px; --text-2xl:28px;
|
||||
--leading-body:1.4; --tracking-display:-0.02em;
|
||||
--space-2:8px; --space-3:12px; --space-4:16px; --space-6:24px; --space-8:32px; --space-12:48px;
|
||||
--radius-md:16px; --radius-pill:9999px;
|
||||
--focus-ring:0 0 0 3px rgba(67,94,229,.35);
|
||||
}
|
||||
*,*::before,*::after { box-sizing:border-box; }
|
||||
html,body { margin:0;padding:0;height:100%; }
|
||||
body { background:var(--bg);color:var(--fg);font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-body); }
|
||||
.scroll { min-height:100dvh;display:grid;justify-items:center;padding:48px 16px 32px; }
|
||||
.box { width:min(440px,100%);margin-top:6vh;display:grid;gap:16px;align-content:start; }
|
||||
.eyebrow { font-size:var(--text-xs);font-weight:700;letter-spacing:.14em;color:var(--meta);margin:0; }
|
||||
h1 { margin:0;font-size:var(--text-2xl);letter-spacing:var(--tracking-display); }
|
||||
.lede { margin:0;color:var(--muted); }
|
||||
.field { display:grid;gap:8px;margin-top:24px; }
|
||||
.field label { font-size:var(--text-sm);font-weight:700; }
|
||||
.fake-input { border:1px solid var(--meta);border-radius:var(--radius-md);background:var(--bg);color:var(--meta);padding:12px 15px;min-height:48px;display:flex;align-items:center; }
|
||||
.main-btn { background:var(--accent);color:#000;border-radius:var(--radius-md);padding:14px 20px;font-weight:700;font-size:var(--text-sm);text-align:center; }
|
||||
.foot { font-size:var(--text-xs);color:var(--meta);text-align:center;margin:0; }
|
||||
.success { text-align:center;padding:32px 0;display:grid;gap:12px;justify-items:center;border-top:1px solid var(--border-soft); }
|
||||
.mark { width:64px;height:64px;border-radius:var(--radius-pill);background:var(--surface-warm);color:var(--success);display:grid;place-items:center;font-size:28px;font-weight:700; }
|
||||
.success h2 { margin:0;font-size:var(--text-xl); }
|
||||
.success p { margin:0;color:var(--muted);font-size:var(--text-sm); }
|
||||
.static-note { font-size:var(--text-xs);color:var(--meta);text-align:center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="scroll" aria-label="遥控器静态设计">
|
||||
<div class="box">
|
||||
<p class="eyebrow">LIVE · 现场互动</p>
|
||||
<h1>找到你自己</h1>
|
||||
<p class="lede">输入名字,它会出现在大屏幕上。</p>
|
||||
<div class="field">
|
||||
<label>你的名字</label>
|
||||
<div class="fake-input">输入你的名字</div>
|
||||
</div>
|
||||
<div class="main-btn">在大屏上找到我</div>
|
||||
<div class="success" aria-label="成功状态示意">
|
||||
<div class="mark">✓</div>
|
||||
<h2>找到了 · 抬头看看大屏</h2>
|
||||
<p>几秒后大屏会恢复完整词云 · 再找一个名字</p>
|
||||
</div>
|
||||
<p class="foot">请留意现场大屏</p>
|
||||
<p class="static-note">静态设计示意 · 不可交互</p>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
@@ -0,0 +1,126 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<title>个人查找 · 词云</title>
|
||||
<style>
|
||||
@layer od-layout {
|
||||
:where(.od-stack,.od-row) > :where(*) { min-width: 0; }
|
||||
.od-stack { display:flex;flex-direction:column;gap:var(--od-gap,8px); }
|
||||
.od-row { display:flex;align-items:center;gap:var(--od-gap,8px); }
|
||||
.od-nowrap { white-space:nowrap; }
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
:root {
|
||||
--bg:#ffffff; --surface:#f6f6f3; --surface-warm:#e5e5e0;
|
||||
--fg:#211922; --fg-2:#000000; --muted:#62625b; --meta:#91918c;
|
||||
--border:#c8c8c1; --border-soft:#e0e0d9;
|
||||
--accent:#e60023;
|
||||
--font-body:"Pin Sans",-apple-system,system-ui,"Segoe UI",Roboto,Arial,sans-serif;
|
||||
--font-art:"Pin Sans",-apple-system,"PingFang SC","Hiragino Sans GB","Noto Sans SC","Microsoft YaHei",system-ui,sans-serif;
|
||||
--text-xs:12px; --text-sm:14px; --text-base:16px; --text-lg:18px; --text-2xl:28px;
|
||||
--leading-body:1.4; --tracking-display:-0.02em;
|
||||
--space-2:8px; --space-3:12px; --space-4:16px; --space-6:24px;
|
||||
--radius-md:16px; --radius-pill:9999px;
|
||||
--elev-raised:0 4px 16px rgba(33,25,34,0.06);
|
||||
}
|
||||
*,*::before,*::after { box-sizing:border-box; }
|
||||
html,body { margin:0;padding:0;height:100%; }
|
||||
body { background:var(--bg);color:var(--fg);font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-body); }
|
||||
.page { height:100dvh;position:relative;overflow:hidden; }
|
||||
.cloud { position:absolute;inset:0; }
|
||||
.cloud span { position:absolute;transform:translate(-50%,-50%);white-space:nowrap;font-family:var(--font-art);color:var(--fg); }
|
||||
.t1 { font-size:15px;opacity:.55;font-weight:500; }
|
||||
.t2 { font-size:22px;opacity:.7;font-weight:600; }
|
||||
.t3 { font-size:34px;opacity:.85;font-weight:700; }
|
||||
.t4 { font-size:52px;opacity:.94;font-weight:700;letter-spacing:var(--tracking-display); }
|
||||
.eye { position:absolute;left:16px;top:max(16px,env(safe-area-inset-top));font-size:var(--text-xs);letter-spacing:.14em;color:var(--meta);font-weight:700;margin:0;z-index:3; }
|
||||
.art-title { position:absolute;left:50%;top:max(44px,calc(env(safe-area-inset-top) + 36px));transform:translateX(-50%);text-align:center;pointer-events:none;margin:0;max-width:min(88vw,640px);z-index:2;width:max-content; }
|
||||
.art-title h1 { margin:0;font-size:clamp(22px,6vw,32px);font-weight:700;letter-spacing:var(--tracking-display);line-height:1.2;text-wrap:balance; }
|
||||
.art-title p { margin:6px 0 0;font-size:var(--text-xs);letter-spacing:.2em;color:var(--meta);font-weight:700;white-space:nowrap; }
|
||||
.art-title::after { content:"";display:block;width:32px;height:2px;background:var(--accent);border-radius:2px;margin:10px auto 0;opacity:.9; }
|
||||
.dock-wrap { position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:center;padding:0 16px calc(16px + env(safe-area-inset-bottom)); }
|
||||
.dock { width:min(520px,100%);background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--radius-md);box-shadow:var(--elev-raised);padding:12px;display:grid;gap:8px; }
|
||||
.row { display:flex;gap:8px; }
|
||||
.fake-input { flex:1;border:1px solid var(--meta);border-radius:var(--radius-md);background:var(--bg);color:var(--meta);padding:12px 15px;font-size:var(--text-base); }
|
||||
.fake-btn { background:var(--accent);color:#000;border-radius:var(--radius-md);padding:12px 20px;font-weight:700;font-size:var(--text-sm);display:grid;place-items:center; }
|
||||
.found { background:var(--bg);border:1px dashed var(--border);border-radius:var(--radius-md);padding:10px 12px; }
|
||||
.found strong { display:block;font-size:var(--text-base); }
|
||||
.found small { color:var(--muted);font-size:var(--text-sm); }
|
||||
.found-row { display:flex;gap:8px;align-items:center;margin-top:8px; }
|
||||
.ghost-btn { background:var(--surface-warm);color:var(--fg-2);border-radius:var(--radius-md);padding:10px 16px;font-size:var(--text-sm);font-weight:700; }
|
||||
.dock-note { font-size:var(--text-xs);color:var(--meta);text-align:center;margin:0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page" aria-label="个人查找静态设计">
|
||||
<p class="eye">LIVE ARCHIVE · 2026</p>
|
||||
<div class="art-title">
|
||||
<h1>2026 毕业典礼 · 全体名单</h1>
|
||||
<p>CLASS OF 2026 · WORD CLOUD</p>
|
||||
</div>
|
||||
<div class="cloud" aria-hidden="true">
|
||||
<span class="t4" style="left:50%;top:44%">王小明</span>
|
||||
<span class="t3" style="left:32%;top:30%">林嘉怡</span>
|
||||
<span class="t3" style="left:68%;top:30%">Sophia</span>
|
||||
<span class="t3" style="left:24%;top:58%">李欣</span>
|
||||
<span class="t3" style="left:76%;top:60%">Kevin</span>
|
||||
<span class="t3" style="left:50%;top:66%">陈晨</span>
|
||||
<span class="t2" style="left:38%;top:52%">Alex</span>
|
||||
<span class="t2" style="left:62%;top:52%">Lily</span>
|
||||
<span class="t2" style="left:44%;top:24%">张雨</span>
|
||||
<span class="t2" style="left:58%;top:76%">Daniel</span>
|
||||
<span class="t2" style="left:18%;top:40%">赵天宇</span>
|
||||
<span class="t2" style="left:82%;top:42%">Emma</span>
|
||||
<span class="t2" style="left:30%;top:76%">苏晚晴</span>
|
||||
<span class="t2" style="left:70%;top:78%">周子墨</span>
|
||||
<span class="t2" style="left:50%;top:14%">Olivia</span>
|
||||
<span class="t2" style="left:50%;top:88%">沈知遥</span>
|
||||
<span class="t1" style="left:14%;top:66%">王梓涵</span>
|
||||
<span class="t1" style="left:86%;top:66%">李雨桐</span>
|
||||
<span class="t1" style="left:22%;top:22%">张浩然</span>
|
||||
<span class="t1" style="left:78%;top:20%">刘亦菲</span>
|
||||
<span class="t1" style="left:12%;top:52%">陈子豪</span>
|
||||
<span class="t1" style="left:88%;top:52%">杨晨曦</span>
|
||||
<span class="t1" style="left:36%;top:84%">黄俊杰</span>
|
||||
<span class="t1" style="left:64%;top:84%">吴思远</span>
|
||||
<span class="t1" style="left:26%;top:44%">徐若瑄</span>
|
||||
<span class="t1" style="left:74%;top:46%">孙浩宇</span>
|
||||
<span class="t1" style="left:42%;top:38%">马晓彤</span>
|
||||
<span class="t1" style="left:58%;top:38%">朱子睿</span>
|
||||
<span class="t1" style="left:34%;top:64%">胡文轩</span>
|
||||
<span class="t1" style="left:66%;top:64%">郭美玲</span>
|
||||
<span class="t1" style="left:46%;top:58%">何佳怡</span>
|
||||
<span class="t1" style="left:55%;top:59%">罗子涵</span>
|
||||
<span class="t1" style="left:20%;top:82%">James</span>
|
||||
<span class="t1" style="left:80%;top:82%">Mary</span>
|
||||
<span class="t1" style="left:16%;top:30%">John</span>
|
||||
<span class="t1" style="left:84%;top:30%">Grace</span>
|
||||
<span class="t1" style="left:40%;top:10%">Noah</span>
|
||||
<span class="t1" style="left:60%;top:10%">Mia</span>
|
||||
<span class="t1" style="left:50%;top:94%">艾</span>
|
||||
<span class="t2" style="left:68%;top:14%">Alexandrina</span>
|
||||
<span class="t2" style="left:30%;top:90%">欧阳雨桐溪</span>
|
||||
</div>
|
||||
<div class="dock-wrap">
|
||||
<div class="dock">
|
||||
<div class="row">
|
||||
<div class="fake-input">输入你的名字</div>
|
||||
<div class="fake-btn">查找</div>
|
||||
</div>
|
||||
<div class="found">
|
||||
<strong>找到你了 · 王小明</strong>
|
||||
<small>你在这里 · 静态示意,不可点击</small>
|
||||
<div class="found-row">
|
||||
<span class="ghost-btn">查看全图</span>
|
||||
<small>找到 2 处 · 1 / 2</small>
|
||||
</div>
|
||||
</div>
|
||||
<p class="dock-note">静态设计示意 · 不可交互</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,98 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>大屏展示 · 词云</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg:#ffffff; --surface:#f6f6f3; --surface-warm:#e5e5e0;
|
||||
--fg:#211922; --fg-2:#000000; --muted:#62625b; --meta:#91918c;
|
||||
--border-soft:#e0e0d9; --accent:#e60023;
|
||||
--font-body:"Pin Sans",-apple-system,system-ui,Arial,sans-serif;
|
||||
--font-art:"Pin Sans",-apple-system,"PingFang SC","Noto Sans SC","Microsoft YaHei",system-ui,sans-serif;
|
||||
--text-xs:12px; --text-sm:14px; --text-lg:18px;
|
||||
--radius-md:16px; --radius-sm:12px;
|
||||
--elev-raised:0 4px 16px rgba(33,25,34,0.06);
|
||||
}
|
||||
*,*::before,*::after { box-sizing:border-box; }
|
||||
html,body { margin:0;padding:0;height:100%; }
|
||||
body { background:var(--bg);color:var(--fg);font-family:var(--font-body); }
|
||||
.page { height:100dvh;position:relative;overflow:hidden; }
|
||||
.cloud { position:absolute;inset:0; }
|
||||
.cloud span { position:absolute;transform:translate(-50%,-50%);white-space:nowrap;font-family:var(--font-art);color:var(--fg); }
|
||||
.t1 { font-size:18px;opacity:.55;font-weight:500; }
|
||||
.t2 { font-size:28px;opacity:.7;font-weight:600; }
|
||||
.t3 { font-size:44px;opacity:.85;font-weight:700; }
|
||||
.t4 { font-size:72px;opacity:.94;font-weight:700; }
|
||||
.eye { position:absolute;left:48px;top:48px;font-size:var(--text-xs);letter-spacing:.14em;color:var(--meta);font-weight:700;margin:0;z-index:3; }
|
||||
.art-title { position:absolute;left:50%;top:48px;transform:translateX(-50%);text-align:center;pointer-events:none;margin:0;max-width:min(80vw,900px);z-index:2;width:max-content; }
|
||||
.art-title h1 { margin:0;font-size:clamp(38px,4.2vw,62px);font-weight:700;letter-spacing:-0.02em;line-height:1.1;text-wrap:balance; }
|
||||
.art-title p { margin:10px 0 0;font-size:var(--text-sm);letter-spacing:.24em;color:var(--meta);font-weight:700;white-space:nowrap; }
|
||||
.art-title::after { content:"";display:block;width:48px;height:3px;background:var(--accent);border-radius:3px;margin:14px auto 0;opacity:.9; }
|
||||
.cloud { position:absolute;inset:0;z-index:1; }
|
||||
.caption { position:absolute;left:48px;bottom:48px;margin:0;font-size:var(--text-sm);letter-spacing:.12em;color:var(--meta); }
|
||||
.qr { position:absolute;right:48px;bottom:48px;background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--radius-md);box-shadow:var(--elev-raised);padding:16px;display:flex;gap:16px;align-items:center;max-width:360px; }
|
||||
.qr-code { width:168px;height:168px;flex:none;background:#fff;border-radius:var(--radius-sm);display:grid;grid-template-columns:repeat(9,1fr);grid-template-rows:repeat(9,1fr);gap:1px;padding:10px;border:1px solid var(--border-soft); }
|
||||
.qr-code i { background:#fff;display:block; }
|
||||
.qr-code i.b { background:var(--fg); }
|
||||
.qr h2 { margin:0 0 4px;font-size:var(--text-lg); }
|
||||
.qr p { margin:0;font-size:var(--text-sm);color:var(--muted); }
|
||||
.screen-note { position:absolute;left:48px;top:76px;font-size:var(--text-xs);color:var(--meta); }
|
||||
@media (max-width:760px) {
|
||||
.eye { left:16px;top:16px; }
|
||||
.caption { display:none; }
|
||||
.screen-note { left:16px;top:40px; }
|
||||
.qr { right:16px;left:16px;bottom:16px;max-width:none; }
|
||||
.qr-code { width:120px;height:120px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page" aria-label="大屏展示静态设计">
|
||||
<p class="eye">LIVE ARCHIVE · 2026</p>
|
||||
<div class="art-title">
|
||||
<h1>2026 毕业典礼 · 全体名单</h1>
|
||||
<p>CLASS OF 2026 · WORD CLOUD</p>
|
||||
</div>
|
||||
<p class="screen-note">静态设计示意 · 不可交互</p>
|
||||
<div class="cloud" aria-hidden="true">
|
||||
<span class="t4" style="left:50%;top:44%">王小明</span>
|
||||
<span class="t3" style="left:32%;top:28%">林嘉怡</span>
|
||||
<span class="t3" style="left:68%;top:28%">Sophia</span>
|
||||
<span class="t3" style="left:24%;top:56%">李欣</span>
|
||||
<span class="t3" style="left:76%;top:58%">Kevin</span>
|
||||
<span class="t3" style="left:50%;top:66%">陈晨</span>
|
||||
<span class="t2" style="left:38%;top:50%">Alex</span>
|
||||
<span class="t2" style="left:62%;top:50%">Lily</span>
|
||||
<span class="t2" style="left:44%;top:20%">张雨</span>
|
||||
<span class="t2" style="left:58%;top:78%">Daniel</span>
|
||||
<span class="t2" style="left:16%;top:40%">赵天宇</span>
|
||||
<span class="t2" style="left:84%;top:42%">Emma</span>
|
||||
<span class="t2" style="left:30%;top:78%">苏晚晴</span>
|
||||
<span class="t2" style="left:70%;top:80%">周子墨</span>
|
||||
<span class="t1" style="left:14%;top:64%">王梓涵</span>
|
||||
<span class="t1" style="left:86%;top:64%">李雨桐</span>
|
||||
<span class="t1" style="left:22%;top:20%">张浩然</span>
|
||||
<span class="t1" style="left:78%;top:18%">刘亦菲</span>
|
||||
<span class="t1" style="left:36%;top:84%">黄俊杰</span>
|
||||
<span class="t1" style="left:64%;top:84%">吴思远</span>
|
||||
<span class="t1" style="left:42%;top:36%">马晓彤</span>
|
||||
<span class="t1" style="left:58%;top:36%">朱子睿</span>
|
||||
<span class="t1" style="left:20%;top:82%">James</span>
|
||||
<span class="t1" style="left:80%;top:82%">Mary</span>
|
||||
<span class="t1" style="left:50%;top:12%">Olivia</span>
|
||||
<span class="t1" style="left:50%;top:90%">沈知遥</span>
|
||||
</div>
|
||||
<p class="caption">THIS WALL IS MADE OF EVERYONE HERE</p>
|
||||
<aside class="qr" aria-label="扫码互动静态示意">
|
||||
<div class="qr-code" aria-hidden="true"><i class="b"></i><i class="b"></i><i class="b"></i><i></i><i class="b"></i><i></i><i class="b"></i><i class="b"></i><i class="b"></i><i class="b"></i><i></i><i></i><i></i><i></i><i class="b"></i><i></i><i></i><i class="b"></i><i class="b"></i><i></i><i class="b"></i><i></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i></i><i></i><i></i><i></i><i class="b"></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i></i><i class="b"></i><i class="b"></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i class="b"></i><i></i><i class="b"></i><i></i><i></i><i></i><i></i><i class="b"></i><i></i><i></i><i class="b"></i><i></i><i class="b"></i><i class="b"></i><i class="b"></i><i></i><i></i><i class="b"></i></div>
|
||||
<div>
|
||||
<h2>找到你的名字</h2>
|
||||
<p>扫码输入名字</p>
|
||||
<p>静态占位 · 不可扫码</p>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user