收紧世界模拟器能力与壳提示,对齐新的落盘合同和呈现分工。

让选题填写与游玩投影读到一致的规格口径。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-07 23:49:34 +08:00
co-authored by Cursor
parent ff5c77bfb1
commit cf6cb68429
22 changed files with 623 additions and 462 deletions
@@ -23,7 +23,7 @@ id: alongside
## note
```note
不替换:正文和结构同屏。窄屏改为上下。选项在最下,直接可见。结构用创作时固定的绘图器,游玩灌入拓扑。
不替换:外壳铺满宿主宽度;正文和结构同屏。窄屏改为上下。选项在最下,直接可见。结构用创作时固定的绘图器,游玩灌入拓扑。
可替换:两栏谁更宽、抬头文字、结构块的短名、配色和字体。本局没有结构时改用阅读或正文为主。
```
@@ -32,19 +32,19 @@ id: alongside
```sample
html:
<div id="app">
<p id="heading"></p>
<p id="heading" data-block="heading"></p>
<div class="pair">
<article id="body"></article>
<article id="body" data-block="body"></article>
<section id="structure">
<div id="graph"></div>
<div id="graph" data-block="structure"></div>
</section>
</div>
<ol id="options"></ol>
<ol id="options" data-block="options"></ol>
</div>
css:
:root { color: #1c1915; background: #f7f3ea; }
#app { max-width: 56rem; margin: 0 auto; padding: 1.25rem; font: 16px/1.6 "Palatino Linotype", "Songti SC", serif; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1.25rem; font: 16px/1.6 "Palatino Linotype", "Songti SC", serif; }
.pair { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: 1rem; }
#structure { border: 1px solid #d5cbb8; border-radius: 6px; padding: 0.8rem; background: #fffdf8; }
#graph { min-height: 8rem; }
@@ -54,17 +54,8 @@ css:
js:
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putText("heading", blocks.heading);
putText("body", blocks.body);
putGraph("graph", blocks.structure);
putList("options", blocks.options);
});
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
}
function putGraph(id, value) {
var el = document.getElementById(id);
if (!el) return;
@@ -110,15 +101,4 @@ function putGraph(id, value) {
});
el.appendChild(svg);
}
function putList(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (!Array.isArray(value) || !value.length) { el.remove(); return; }
value.forEach(function (line) {
var li = document.createElement("li");
li.textContent = String(line);
el.appendChild(li);
});
}
```
@@ -25,7 +25,7 @@ id: data-cards
## note
```note
不替换:数据区在抬头下一直展开。正文在其下较宽的一栏,篇幅仍是数百字。窄栏在较窄的一栏。选项在两栏之下,直接可见。窄屏时宽栏在上。
不替换:外壳铺满宿主宽度;数据区在抬头下一直展开。正文在其下较宽的一栏,篇幅仍是数百字。窄栏在较窄的一栏。选项在两栏之下,直接可见。窄屏时宽栏在上。
可替换:数据项的名称、条数和当前值,窄栏的标题和条目,配色和字体。本局没有窄栏时删掉窄栏,正文占回整宽。
```
@@ -34,21 +34,21 @@ id: data-cards
```sample
html:
<div id="app">
<p id="heading"></p>
<p id="heading" data-block="heading"></p>
<div id="cards"></div>
<div class="pair">
<article id="body"></article>
<article id="body" data-block="body"></article>
<aside class="side">
<p id="side-title"></p>
<p id="side-title" data-block="side_title"></p>
<div id="side"></div>
</aside>
</div>
<ol id="options"></ol>
<ol id="options" data-block="options"></ol>
</div>
css:
:root { color: #1c2420; background: #d5ddd4; }
#app { max-width: 52rem; margin: 0 auto; padding: 1rem; font: 15px/1.75 "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1rem; font: 15px/1.75 "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
#heading { margin: 0 0 0.6rem; font-size: 13px; }
#cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.45rem; margin-bottom: 0.75rem; }
#cards.stack { grid-template-columns: 1fr; }
@@ -66,19 +66,9 @@ css:
js:
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putText("heading", blocks.heading);
putText("side-title", blocks.side_title);
putText("body", blocks.body);
putCards("cards", blocks.cards);
putLines("side", blocks.side);
putList("options", blocks.options);
});
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
}
function putCards(id, value) {
var el = document.getElementById(id);
if (!el) return;
@@ -111,15 +101,4 @@ function putLines(id, value) {
el.appendChild(p);
});
}
function putList(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (!Array.isArray(value) || !value.length) { el.remove(); return; }
value.forEach(function (line) {
var li = document.createElement("li");
li.textContent = String(line);
el.appendChild(li);
});
}
```
@@ -14,7 +14,7 @@ id: dual-text
可加: 短文、结构、数据、抬头、文字选项
摆放:
抬头: 最上的一行短内容
正文: 占满阅读宽度,按数百字来写
正文: 占满宿主阅读面;行长可限在正文柱,按数百字来写
短文、结构: 标签或折叠,点开才看。标签用短显示名
数据: 若有,默认可收起
文字选项: 始终直接可见,不放进标签或折叠
@@ -24,8 +24,8 @@ id: dual-text
## note
```note
不替换:正文占满阅读宽度。其余块收在标签或折叠里,默认不展开。选项在这些控件之外,直接可见。
可替换:标签和折叠的短名、收起块里的文字、配色和字体。本局没有的块删掉。数据要一直展开时改用数据常驻。
不替换:外壳铺满宿主宽度;正文是主阅读面。其余块收在标签或折叠里,默认不展开。选项在这些控件之外,直接可见。
可替换:标签和折叠的短名、收起块里的文字、配色和字体、正文柱行长上限。本局没有的块删掉。数据要一直展开时改用数据常驻。
```
## sample
@@ -33,47 +33,26 @@ id: dual-text
```sample
html:
<div id="app">
<p id="heading"></p>
<article id="body"></article>
<p id="heading" data-block="heading"></p>
<article id="body" data-block="body"></article>
<details>
<summary id="vignette-title"></summary>
<div id="vignette"></div>
<summary id="vignette-title" data-block="vignette_title"></summary>
<div id="vignette" data-block="vignette"></div>
</details>
<ol id="options"></ol>
<ol id="options" data-block="options"></ol>
</div>
css:
:root { color: #1c1915; background: #f7f3ea; }
#app { max-width: 40rem; margin: 0 auto; padding: 1.25rem; font: 17px/1.75 "Palatino Linotype", "Songti SC", serif; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1.25rem; font: 17px/1.75 "Palatino Linotype", "Songti SC", serif; }
#heading, #body, details, #options { max-width: 40rem; margin-inline: auto; }
#heading { margin: 0 0 0.8rem; font-size: 0.95rem; }
#vignette { font-size: 0.92rem; margin-top: 0.6rem; }
#options { margin: 0.8rem 0 0; padding-left: 1.2rem; }
#options { margin: 0.8rem auto 0; padding-left: 1.2rem; }
summary { cursor: pointer; }
js:
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putText("heading", blocks.heading);
putText("body", blocks.body);
putText("vignette-title", blocks.vignette_title);
putText("vignette", blocks.vignette);
putList("options", blocks.options);
present.onData(function () {
/* 文本区由程序按 data-block 灌数;折叠开合是浏览器原生行为 */
});
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
}
function putList(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (!Array.isArray(value) || !value.length) { el.remove(); return; }
value.forEach(function (line) {
var li = document.createElement("li");
li.textContent = String(line);
el.appendChild(li);
});
}
```
@@ -23,8 +23,8 @@ id: paged
## note
```note
不替换:同时只显示一页。页用一行标签切换。抬头在标签之外。
可替换:每个标签的短名、页内文字和数据项、配色和字体。本局未启用的页不建标签。
不替换:外壳铺满宿主宽度;同时只显示一页。页用一行标签切换。抬头在标签之外。
可替换:每个标签的短名、页内文字和数据项、配色和字体、页内正文柱行长上限。本局未启用的页不建标签。
```
## sample
@@ -32,14 +32,15 @@ id: paged
```sample
html:
<div id="app">
<p id="heading"></p>
<p id="heading" data-block="heading"></p>
<div id="tabs"></div>
<div id="page"></div>
<div id="page" data-block="page"></div>
</div>
css:
:root { color: #1c1915; background: #f7f3ea; }
#app { max-width: 44rem; margin: 0 auto; padding: 1.25rem; font: 16px/1.65 "Segoe UI", "Source Han Sans SC", sans-serif; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1.25rem; font: 16px/1.65 "Segoe UI", "Source Han Sans SC", sans-serif; }
#heading, #tabs, #page { max-width: 44rem; margin-inline: auto; }
#tabs { display: flex; gap: 0.4rem; margin-bottom: 0.9rem; }
#tabs button { border: 0; border-bottom: 2px solid transparent; background: transparent; padding: 0.35rem 0.6rem; font: inherit; color: inherit; }
#tabs button[aria-current="true"] { border-bottom-color: #8a5a2b; }
@@ -49,7 +50,6 @@ var pages = [];
var current = 0;
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putText("heading", blocks.heading);
pages = Array.isArray(blocks.pages) ? blocks.pages : [];
current = 0;
drawTabs();
@@ -73,12 +73,7 @@ function drawTabs() {
}
function drawPage() {
var el = document.getElementById("page");
el.textContent = pages[current] ? pages[current].text : "";
}
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
var text = pages[current] ? pages[current].text : "";
el.innerHTML = text ? present.markdown(String(text)) : "";
}
```
@@ -13,7 +13,7 @@ id: piece
主区: 一份成稿
可加窄带: 文字选项
摆放:
成稿: 居中。内部小节在创作时按范例重写
成稿: 外壳铺满宿主;成稿正文柱可限行长并水平居中
文字选项: 成稿之后,始终直接可见
未启用的区不留空位。
```
@@ -21,8 +21,8 @@ id: piece
## note
```note
不替换:一份成稿容器居中。选项在容器之后,直接可见。
可替换:容器内部的标记、分段、配色和字体。按本局这一份成品重写内部。样本内部与本局不同时整段替换,保留容器和选项的前后关系。
不替换:外壳铺满宿主宽度;一份成稿容器。选项在容器之后,直接可见。
可替换:容器内部的标记、分段、配色和字体、成稿柱行长上限。按本局这一份成品重写内部。样本内部与本局不同时整段替换,保留容器和选项的前后关系。
```
## sample
@@ -30,37 +30,19 @@ id: piece
```sample
html:
<div id="app">
<article id="piece"></article>
<ol id="options"></ol>
<article id="piece" data-block="piece"></article>
<ol id="options" data-block="options"></ol>
</div>
css:
:root { color: #1c1916; background: #ebe6dc; }
#app { max-width: 34rem; margin: 0 auto; padding: 1.6rem 1.25rem 2rem; font: 16px/1.65 "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
#piece { margin: 0; }
#options { margin: 1rem 0 0; padding-left: 1.15rem; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1.6rem 1.25rem 2rem; font: 16px/1.65 "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
#piece, #options { max-width: 34rem; margin-inline: auto; }
#piece { margin: 0 auto; }
#options { margin: 1rem auto 0; padding-left: 1.15rem; }
js:
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putText("piece", blocks.piece);
putList("options", blocks.options);
present.onData(function () {
/* 成稿与选项由程序按 data-block 灌数 */
});
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
}
function putList(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (!Array.isArray(value) || !value.length) { el.remove(); return; }
value.forEach(function (line) {
var li = document.createElement("li");
li.textContent = String(line);
el.appendChild(li);
});
}
```
@@ -14,7 +14,7 @@ id: reading
可加窄带: 抬头、文字选项
摆放:
抬头: 正文之前的一行短内容
正文: 阅读柱,占主要宽度
正文: 阅读柱;外壳铺满宿主,行长可限在正文柱
文字选项: 正文之后,始终直接可见,不放进标签或折叠。不显示「文字选项」这个区名
未启用的区不留空位。
```
@@ -22,8 +22,8 @@ id: reading
## note
```note
不替换:单栏阅读柱。抬头在正文前,独占一行。选项在正文后,直接可见。
可替换:抬头文字、正文文字、配色和字体。本局没有抬头时删掉抬头。
不替换:外壳铺满宿主宽度;单栏阅读柱。抬头在正文前,独占一行。选项在正文后,直接可见。
可替换:抬头文字、正文文字、配色和字体、正文柱行长上限。本局没有抬头时删掉抬头。
```
## sample
@@ -31,53 +31,21 @@ id: reading
```sample
html:
<div id="app">
<p id="heading"></p>
<article id="body"></article>
<ol id="options"></ol>
<p id="heading" data-block="heading"></p>
<article id="body" data-block="body"></article>
<ol id="options" data-block="options"></ol>
</div>
css:
:root { color: #1c1915; background: #f7f3ea; }
#app { max-width: 38rem; margin: 0 auto; padding: 1.5rem 1.25rem 2.5rem; font: 17px/1.75 "Palatino Linotype", "Songti SC", serif; }
#app { width: 100%; box-sizing: border-box; margin: 0; padding: 1.5rem 1.25rem 2.5rem; font: 17px/1.75 "Palatino Linotype", "Songti SC", serif; }
#heading, #body, #options { max-width: 38rem; margin-inline: auto; }
#heading { margin: 0 0 0.85rem; font-size: 0.95rem; letter-spacing: 0.04em; }
#body { font-size: 1.05rem; }
#options { margin: 1.25rem 0 0; padding-left: 1.2rem; }
#options { margin: 1.25rem auto 0; padding-left: 1.2rem; }
js:
present.onData(function (data) {
var blocks = (data && data.blocks) || {};
putHeading("heading", blocks.heading);
putText("body", blocks.body);
putList("options", blocks.options);
present.onData(function () {
/* 正文/抬头/选项由程序按 data-block 灌数;本地交互再写这里 */
});
function putHeading(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (value == null || value === "") { el.remove(); return; }
if (typeof value === "string") { el.textContent = value; return; }
Object.keys(value).forEach(function (key) {
var item = document.createElement("span");
item.textContent = key + " " + String(value[key]);
item.style.marginRight = "1rem";
el.appendChild(item);
});
}
function putText(id, value) {
var el = document.getElementById(id);
if (!el) return;
if (value == null || value === "") { el.remove(); return; }
el.textContent = String(value);
}
function putList(id, value) {
var el = document.getElementById(id);
if (!el) return;
el.replaceChildren();
if (!Array.isArray(value) || !value.length) { el.remove(); return; }
value.forEach(function (line) {
var li = document.createElement("li");
li.textContent = String(line);
el.appendChild(li);
});
}
```