完整手機 composition playground
證明四條 root stack、清單與 fill reader 可以接成一條手機操作路徑;它不是 design system,也不代表 OPEN 配置已採用。
這裡直接展示 App Shell、股票清單與滑動判讀,以及它們的主要狀態。完整手機、Shell 與判讀預覽可操作;純狀態樣本會清楚標示,不會假裝有尚未決定的控制邏輯。
Source of truth 是 tokens.css、utilities.css、各 domain CSS/JS 與 COMPONENTS.md;本頁只從它們 live render,不是第二份真相。
載入順序:tokens → utilities → domain。五層 metadata 仍是 Foundations、Components、Patterns、Compositions、Decision Status;人類閱讀順序依 D15 改為總覽 → 元件與狀態 → Patterns → Foundations → Decision Status。
不用先讀 class 或契約:先操作完整手機,再從三張代表樣本辨認 Shell、清單與判讀。
證明四條 root stack、清單與 fill reader 可以接成一條手機操作路徑;它不是 design system,也不代表 OPEN 配置已採用。
固定 App 外框、四格 bottom nav 與每條 root 各自的 stack。
D4。DOM、狀態與 token 依賴見同卡契約;實際樣式由 shell.css 與 tokens.css 提供。
用同一個股票列承接今日、自選、市場與編輯/批次狀態。
把判讀內容放進唯一縱向 scroller,讓卡片吸附與 progress 對應。
先用眼睛比較 selected/unselected,再到 live preview 操作四條獨立 stack。
四格 root 導覽的高頻狀態;個股從 root push 進去,不額外佔一格。
D4。必要 DOM 與 token 依賴由 shell_nav contract 與 shell.css 定義;本卡沒有重抄 token 值。
從實際 preview-shell.html 渲染,可切換 root tab、push、back,並觀察 depth 與狀態保留。
完整 row-level class、用途、狀態/變體、token 依賴與 contract 深連結保留在 DOM;人類預設不必閱讀。
| class | 用途 | 狀態/變體 | token 依賴 | 完整契約 |
|---|---|---|---|---|
.lila-shell | 固定 App 外框與四列版位 | 內嵌/全高 | --shell-*、surface、radius、z | §5 |
.shell-statusbar | status chrome 與 safe top | mark+系統 icon | --statusbar-height、space、text/bg | §5 |
.shell-header | root/push 共用 header | root/depth;文字/骨架 title | header、divider、shadow、z、space | §5 |
.shell-header-back | pop 目前 stack | .is-root/active | space、radius、accent、motion | §5 |
.shell-header-title | root 名或次層骨架 title | 文字/.is-placeholder | type、skeleton、radius | §5 |
.shell-depth / .shell-depth-dot | stack 深度指示 | current/previous;JS 動態數量 | space、border、accent | §5 |
.shell-content | root viewport 與 clipping 邊界 | 預設 | surface、--z-base | §5 |
.shell-root | 單一 root tab 的獨立 stack | active/hidden;四個固定 root | 無額外視覺 token | §5 |
.shell-stack | 同 root 的 page 疊層 | 預設 | surface | §5 |
.shell-stack-page | 可 push/back 的 page 層 | active/under/preparing/exiting;root/骨架 title | motion、surface、z | §5+fill 追加 |
.shell-page-scroll | 預設模式的唯一縱向 scroller | default/fill 時不捲 | 無額外視覺 token | fill §2 |
.shell-slot | 內容 domain 唯一 mount seam | empty/mounted;edge-to-edge | min-size;fill 時確定高度 | §6 |
.shell-nav | 四格 root nav 與 safe bottom | 固定四格 | nav size、safe、divider、shadow、z | §3 |
.shell-tab | 單一 root tab | selected/unselected/pressed/focus;badge | text、accent、radius、type、motion | §3 |
.shell-tab-icon | tab icon 容器 | selected/unselected;SVG | space、radius、accent | §5 |
.shell-tab-label | tab 固定文字 | selected/unselected;四個固定 label | type、weight | §3 |
.shell-tab-badge | 無數字通知圓點 | hidden/visible | space、bg、accent、radius | §3 |
.shell-placeholder-page | preview 骨架頁;runtime 可替換 | root/detail | space | §5 |
.shell-skeleton-line | 文字資訊骨架 | default/short | skeleton、space、radius | §5 |
.shell-skeleton-block | 大型資訊區骨架 | default | skeleton、space、radius | §5 |
.shell-skeleton-card | 卡片/清單資訊骨架 | 可含 line/icon | skeleton、surface、border、shadow、space | §5 |
.shell-skeleton-icon | 圖像資訊骨架 | default | skeleton、space、radius | §5 |
.shell-skeleton-group | 多個骨架的排列容器 | default | space | §5 |
.shell-placeholder-action | preview 的 push 觸發控制 | default/pressed/focus;不同深度入口 | surface、border、text、space、motion | §5 |
.shell-preview-* | Shell preview 展示外框,非 runtime | demo/state gallery | shell size、surface、border、shadow、space | §5 |
資訊位維持骨架;用外部 anatomy 標籤說明 identity/quote/action/reason,不填假價格或假理由。
同一列只替換 leading 與 action;清單可以表達狀態,但不在 catalog 補上業務 controller。
從實際 preview-lists.html 渲染 feed、股票列、自選編輯態、市場分段與個人入口。
完整 row-level 索引仍在 DOM,預設收合;每列的必要 class、狀態、變體與 token 依賴沒有刪除。
| class | 用途 | 狀態/變體 | token 依賴 | 完整契約 |
|---|---|---|---|---|
.list-stack | 四條 root 的清單層根容器 | default;flush 由 content 控制 | bg、text、font | §6 |
.list-stack__content | 清單內容 padding 與 section gap | default/--flush | space | §6 |
.list-section | 通用內容分組 | default | space | §6 |
.stock-list | 一般股票列集合 | default/外層 aria busy | space | §6 |
.feed-list | Feed 分組與卡片集合 | default/aria busy | space | §6 |
.list-section-header | 分組標題、meta、右側動作 | copy/meta/action 可省略 | text、space | §6 |
.filter-strip | 水平捲動 chip 容器 | default | space | §6 |
.filter-chip | Feed 篩選 | selected/unselected/disabled | accent、border、radius、type、space、motion | §6 |
.segmented-control | 市場分類切換 | selected/unselected;三欄 | surface、border、radius、space、shadow | §6 |
.stock-row | 股票列共同外殼 | pressed/selected/disabled/loading;up/down/flat/card/compact/draggable | surface、divider、border、radius、space、motion | §3 |
.stock-row__primary | 進入個股的主點擊區 | active/focus;button/anchor | text、space、focus、motion | §3 |
.stock-row__identity | 股票識別插槽 | default/loading | text、mono、space | §3 |
.stock-row__quote | 價格/漲跌插槽 | up/down/flat/loading | text、mono、up/down/flat、space | §3 |
.stock-row__sparkline | 迷你走勢插槽 | skeleton | skeleton、radius、space | §3 |
.stock-row__leading | 編輯/選取前置控制槽 | empty/populated;drag/select | space | §3 |
.stock-row__action | 右側動作槽 | empty/populated;watch/delete/chevron | space | §3 |
.row-action | 加入自選或通用右側動作 | pressed/watchlisted/unwatchlisted | accent、text、radius、space | §6 |
.drag-handle | 自選排序控制 | idle/active | text、radius、space | §6 |
.selection-control | 批次選取控制 | selected/unselected | accent、inverse、border、radius | §6 |
.delete-control | 自選刪除入口 | idle/focus | surface、text、radius、space | §6 |
.feed-card | 今日重點卡外殼 | default | surface、border、radius、shadow | §6 |
.reason-slot | Feed 推薦理由承載位 | skeleton/populated;本輪只 skeleton | surface、divider、text、radius、space | §6 |
.empty-state | Feed/自選/市場空狀態 | mark/CTA 可省略 | surface、border、radius、text、space | §6 |
.list-edit-toolbar | 自選正常/編輯模式切換列 | normal/editing | surface、border、radius、space | §6 |
.batch-bar | 自選批次摘要與動作 | none-selected/selected | surface、border、radius、space | §6 |
.text-action | toolbar/empty-state 文字動作 | default/focus;filled | accent、inverse、type、radius、space | §6 |
.destination-list | 非股票目的地集合 | default | surface、border、radius | §6 |
.destination-row | 「我的」等入口列 | active/focus | text、divider、space | §6 |
.profile-shell | 「我的」空殼 | default | space | §6 |
.profile-shell__placeholder | 未定設定區骨架 | skeleton | surface、border、radius、space | §6 |
.skeleton-line | 文字/數字骨架 | long/medium/short/number | skeleton、radius、space、width tokens | §5 |
.skeleton-text-group | 一致的多行骨架排版 | two-line/numeric | skeleton、space | §5 |
.skeleton-block--sparkline | 迷你走勢骨架 | default | skeleton | §5 |
Ready/Loading/Empty 並排。判讀要教哪一段、K 線位置與判讀層 nav 都保持 OPEN。
把正常閱讀與系統狀態分開呈現;狀態層覆蓋 viewport,但不替 OPEN 的資訊內容填答案。
從實際 preview-read.html 渲染;可上下滑卡片、點 progress 跳段,並切換 ready/loading/empty。
D8。preview 可操作不等於真實瀏覽器已於本輪驗證,也不代表 O1/O7/O9 已決定。
完整 class、必要 DOM、狀態/變體、token 依賴與契約深連結保留在收合內容。
| class | 用途 | 狀態/變體 | token 依賴 | 完整契約 |
|---|---|---|---|---|
.read-swipe | reader 根節點與狀態邊界 | ready/loading/empty;first/middle/last;任意卡數 | surface、z、space、motion | §6 |
.read-swipe__progress | 目前段落與直接跳段 | normal/root-state disabled;自動段數 | space、color、z-header | §6 |
.read-swipe__segment | 單一段落跳轉 hit target | pending/complete/current/focus/active | accent、motion | §6 |
.read-swipe__viewport | 唯一縱向 scroller 與手勢面 | ready/inert/focus;touch/wheel/keyboard | surface、focus、motion | §5 |
.read-card | 一個判讀 lens/步驟 | active/inert;內容長短可變 | space、border、surface | §6 |
.read-card__content | 卡內資訊分區容器 | 靜態;K 線/metrics/block 可組合 | space、shell width | §6 |
.read-card__* skeleton primitives | 卡內可替換資訊骨架 | skeleton;line/metric/block | skeleton、space、radius、border | §6 |
.read-kline | 唯一具體圖形:假資料 K 線 | up/down/flat candle | up/down/flat、divider、surface、space | §4 |
.read-swipe__state[data-read-loading] | blocking loading layer | visible/hidden;spinner+骨架 | surface、skeleton、motion、z | §6 |
.read-swipe__state[data-read-empty] | blocking empty layer | visible/hidden | surface、skeleton、z | §6 |
Pattern 由多個 component 與狀態/事件接縫組成;先看關係圖,需要實作時才展開最小 HTML。
把一個 root page 掛進 shell 的 stack host,預設由 shell page scroll 負責垂直捲動。
<section class="shell-stack-root" data-shell-root="today">
<article class="shell-stack-page is-active" data-shell-page>
<header class="shell-header" data-shell-header>...</header>
<div class="shell-page-scroll" data-shell-scroll>
<main class="shell-slot" data-shell-slot>...</main>
</div>
</article>
</section>一般頁由 shell 捲;需要內部唯一 scroller 的頁面用 fill,取得確定高度與 min-height: 0。
D11。
<article class="shell-stack-page" data-shell-page data-shell-scroll-mode="fill">
<header class="shell-header" data-shell-header>...</header>
<div class="shell-page-scroll" data-shell-scroll>
<main class="shell-slot" data-shell-slot>
<section class="read-swipe" data-read-swipe>...</section>
</main>
</div>
</article>股票列只發起導覽;shell push 一個 fill page,reader 自己管理縱向 scroll。
<article class="stock-row">
<button class="stock-row__primary" type="button" data-phone-push>...</button>
</article>
<template data-reader-page>
<article class="shell-stack-page" data-shell-page data-shell-scroll-mode="fill">
<div class="shell-page-scroll" data-shell-scroll>
<main class="shell-slot" data-shell-slot>
<section class="read-swipe" data-read-swipe>...</section>
</main>
</div>
</article>
</template>Feed 載入用骨架列;沒有內容時用 empty-state,不填選股、推薦或原因。
<section class="feed-list" aria-busy="true">
<article class="stock-row stock-row--loading">...</article>
</section>
<section class="empty-state">
<span class="empty-state__mark"></span>
<span class="skeleton-line"></span>
</section>自選清單在相同股票列上切換拖曳/刪除與選取/批次操作,但業務 controller 仍未定。
<div class="list-edit-toolbar">...</div>
<article class="stock-row stock-row--draggable">
<span class="stock-row__leading">...</span>
<span class="stock-row__primary">...</span>
<span class="stock-row__action">...</span>
</article>
<div class="batch-bar">...</div>樣本直接引用 var(--token);頁面載入後的文字值由 getComputedStyle 讀取目前 CSS,不在 HTML 複製 token 值。
O5。值的唯一來源是 tokens.css;本頁只以 var() 渲染並以 getComputedStyle 顯示 resolved value。
tokens.css → utilities.css → domain CSS(shell.css / lists.css / read.css)
本頁只直接載入 tokens 與 utilities;domain specimen 由既有 preview iframe 載入,避免 catalog 另抄 domain CSS。
將游標移入卡片可看目前 duration/easing;讀值仍直接來自 token。
.visually-hidden
跨 domain 的輔助技術隱藏工具。下一行在視覺上隱藏,但仍留在 accessibility tree。
utilities.css 已由 catalog 直接載入<span class="visually-hidden">輔助技術文字</span>
唯一來源是 DECISIONS.md 的 D13「目前的狀態盤點」;本頁不重新判斷。
若完整 pattern 沒有狀態標籤,未拍板的版位、K 線位置與互動會被完整度默默升格成產品決策。O1 到 O9 是刻意留白,不是待辦事項。特別是 nav 四格與「個股不佔格」為 Approved(D4);K 線目前只在判讀卡、清單迷你走勢為骨架的配置仍是 OPEN(O9)。