# Orange OUDS Web 设计系统

## Orange OUDS Web 设计系统界面预览

查看每个原生抽屉，保存本地选择并切换外观。

## Orange OUDS Web 设计系统设计参考

固定版本的 @ouds/web-orange 和 @ouds/web-common 1.4.0 源码，并将原创布局决策单独标明。

### 浅色语义颜色角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --bs-color-action-enabled | #000 | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-action-selected | #f15e00 | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-action-hover | rgba(0, 0, 0, 0.68) | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-action-pressed | #f15e00 | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-bg-primary | #fff | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-bg-secondary | #f4f4f4 | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-border-default | rgba(0, 0, 0, 0.2) | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-always-black | #000 | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
| --bs-color-always-white | #fff | Orange 1.4 预设中的第一组（浅色）声明。深色外观通过 data-bs-theme 获取自身颜色值，不会将此表中的值直接用作颜色。 |
### 比例间距

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --bs-space-scaled-none | 0px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-3xsmall | 2px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-2xsmall | 4px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-xsmall | 8px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-small | 12px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-medium | 16px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-large | 24px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-xlarge | 32px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-2xlarge | 40px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
| --bs-space-scaled-3xlarge | 48px | 实际导出的间距比例。原创对比布局使用这些值来选择自身的 24px 间距。 |
### 字体角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --bs-font-sans-serif | "HelvNeueOrange", "Helvetica Neue", Helvetica, "SF Pro", Roboto, Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-size-display-large | 2.5rem | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-size-heading-large | 1.5rem | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-size-body-large | 1rem | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-size-body-medium | 0.875rem | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-size-body-small | 0.75rem | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-line-height-body-large | 1.5 | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
| --bs-font-line-height-body-medium | 1.4285714286 | 已发布的字体和字体声明。内嵌研究明确使用 Arial 作为备用字体，而非品牌字体 HelvNeueOrange 文件。 |
### Offcanvas 默认值

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --bs-offcanvas-zindex | 1045 | 原生组件默认值。原始抽屉将宽度设为 440px，而原生 max-width 规则会确保它不超出视口。 |
| --bs-offcanvas-width | 400px | 原生组件默认值。原始抽屉将宽度设为 440px，而原生 max-width 规则会确保它不超出视口。 |
| --bs-offcanvas-height | 30vh | 原生组件默认值。原始抽屉将宽度设为 440px，而原生 max-width 规则会确保它不超出视口。 |
| --bs-offcanvas-transition | transform 0.3s ease-in-out | 原生组件默认值。原始抽屉将宽度设为 440px，而原生 max-width 规则会确保它不超出视口。 |
### 原生抽屉与按钮约定

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Brand action | .btn.btn-brand | 这是实际的 Orange 变体；不要假设上游的 Bootstrap .btn-primary 含义相同。 |
| Default action | .btn.btn-default | 实际用于外观切换和清除本地选择的次要/默认样式。 |
| Open trigger | data-bs-toggle="offcanvas" / data-bs-target | 原生 data API 会从每个原始方案按钮打开共用抽屉。 |
| Content event | show.bs.offcanvas / event.relatedTarget | 在渲染抽屉内容前，从触发按钮读取所点击的方案。 |
| Close API | oudsWeb.Offcanvas.getInstance(element).hide() | 进行本地选择后，关闭现有的原生实例。 |
| Theme | data-bs-theme="light" or "dark" | 更改实际主题变量，而无需重新构建比较状态。 |
## Orange OUDS Web 设计系统完整指南

实用指南，介绍如何为真实界面选择、应用和评审此系统。

完整指导、实现起点和源代码链接。

## Orange OUDS Web 设计系统 Orange OUDS 软件包与主题结构

### 同时安装通用软件包与 Orange 软件包

> OUDS Web 1.4.0 将共享行为与品牌主题分开。此示例以相同版本安装 @ouds/web-common 和 @ouds/web-orange。Orange 软件包提供已编译的 CSS，通用软件包则提供打包好的浏览器端 JavaScript。根文档会导入这两个明确路径，因此读者不会只拿到软件包安装命令，却面对一个没有样式的静态页面。

- @ouds/web-orange 提供 Orange 主题 CSS。

- @ouds/web-common 提供共享的 JavaScript。

- 此示例中，两个软件包都固定使用 1.4.0 版本。

### 将 OUDS 视为独立的组件约定

OUDS 基于 Bootstrap，但这种渊源并不意味着所有上游类都能直接替换使用。此版本采用 btn-brand、btn-default 等命名变体。所提供的对比示例使用这些实际类和原生 Offcanvas data 属性。迁移时应同时对比标记和主题值，而不只是更换样式表 URL。

## Orange OUDS Web 设计系统 Orange OUDS 语义色彩与排版角色

### 使用已安装的语义变量

原始卡片使用 color-bg-primary 和 color-border-default。窄屏页眉强调色使用 color-action-selected，该变量在浅色声明中解析为 #f15e00。深色主题通过根元素上的 data-bs-theme 更改这些角色。因此，本指南记录带有作用范围的浅色值，并由运行时选择正确的外观，而不会把某个橙色色值描述成整个设计系统。

### 明确说明字体排版

软件包在字体栈中优先列出 HelvNeueOrange。这个本地嵌入式示例移除了未使用的 font-face 声明，并明确使用 Arial 作为后备字体。表格仍说明了实际发布的字体系列和正文角色。加载组件 CSS 并不能证明品牌字体已加载；采用该字体的项目需要妥善处理其字体资源。

## Orange OUDS Web 设计系统 Orange OUDS 比较卡片与内容

### 为比较内容设计清晰的决策结构

三张卡片展示虚构的数据用量、简短的用途说明和查看详情操作。每张卡片都包含完整文案，而不是占位行的截图。这些内容仅用于原创示例，并非 Orange 当前的产品、价格或合约。本设计练习也不展示价格，以免让人误以为这是可购买的优惠或结账流程。

### 保持重复卡片的基准布局一致

桌面布局采用三个等宽网格列和纵向弹性卡片，使查看详情操作对齐到底部。视口宽度达到 720px 时，布局会变为单列并采用自然高度。原生按钮类提供实际的操作状态；外围网格、24px 内边距和内容顺序，则是应用自身的设计决策，均可在所提供的 CSS 中看到。

## Orange OUDS Web 设计系统 Orange OUDS 原生 Offcanvas 组合

### 根据触发按钮填充抽屉内容

每个查看详情按钮都指向同一个 #details Offcanvas，并携带一个简短的 data-plan 索引。show.bs.offcanvas 事件会提供 relatedTarget，用它可以在抽屉显示前选出对应的原始标题、说明和功能列表。列表使用 textContent 和实际列表项构建，使数据与标记保持分离。抽屉标题通过 aria-labelledby 关联。

### 让原生运行时负责打开和关闭行为

data API 会处理打开、背景遮罩、Escape 键和焦点行为。进行本地选择后，处理程序会调用 oudsWeb.Offcanvas.getInstance(drawer).hide() 来关闭现有实例。它不会移除 CSS 类，却把焦点陷阱或背景遮罩留在页面上。测试会等待过渡完成后再检查焦点是否返回，因为异步关闭也是组件约定的一部分。

## Orange OUDS Web 设计系统 Orange OUDS 本地选择与恢复

### 准确描述实际发生的操作

“保留此本地选择”只会记录选中的虚构方案，并在卡片下方显示该选择。提示信息会明确说明没有提交订单。新选择会替换之前的选择；清除选择后，提示信息会隐藏，焦点则返回第一个查看详情按钮。任何信息都不会发送到账户、购物车或支付服务。

### 将外观与选择状态分开

浅色/深色操作会更改根元素的主题属性及其自身的操作标签，同时保留当前本地选择和三张卡片的内容。测试主题时，这种区分很有用：视觉变化不应悄然重置用户当前的比较状态。此示例在两种外观下都使用原生 CSS，只有外围布局由应用提供。

## Orange OUDS Web 设计系统 Orange OUDS 键盘操作与窄屏行为

### 明确命名关闭和查看详情操作

每张卡片的操作名称都包含方案名称，原生的仅图标关闭按钮则明确使用“关闭详情”无障碍标签。抽屉带有 tabindex 和带标签的标题，以便原生实现管理焦点。测试会打开 Explore 抽屉，按 Escape 键将其关闭，并确认焦点返回触发按钮，然后再移至另一张卡片。

### 确保抽屉不超出实际视口

应用将抽屉宽度设为 440px，但原生 Offcanvas 最大宽度规则会确保其适配较窄的视口。卡片会纵向堆叠，小屏幕下外边距也会缩小。示例在选择方案并切换外观后，分别于 280px、390px、平板和桌面宽度下进行了检查，而不只是检查初始状态。

## Orange OUDS Web 设计系统 Orange OUDS 完整静态集成

### 使用完整的三文件示例

将 orange-index.html 保存为 index.html，并将 orange.css 和 orange-app.js 放在同一目录。安装指定版本的两个程序包，然后启动目录服务。HTML包含原生资源路径、全部卡片内容、抽屉结构和应用脚本。无需 React 封装层、缺失的脚手架或虚构的 SDK，即可还原此浏览器界面。

1. 将提供的三个文件保存在同一目录中。

2. 安装配套的两个 OUDS 程序包。

3. 启动文件夹服务并检查每张卡片。

4. 测试 Escape 键、焦点返回、本地清除和两种外观。

### 代码和资源使用相同版本

如果更改版本，请一并验证按钮变体、data API 命名空间、事件名称和主题变量。不同版本的 CSS 和脚本可能乍看正常，直到交互时才显露不匹配。此处提供的版本是经过实际测试的参考，并不意味着任何未来的程序包组合都能表现一致。

## Orange OUDS Web 设计系统组件示例

### orange-index.html

完整标记，以及原生的 CSS/JavaScript 导入方式。

```
<!doctype html><html lang="en" data-bs-theme="light"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Bundle comparison study</title><link rel="stylesheet" href="./node_modules/@ouds/web-orange/dist/css/ouds-web.min.css"><link rel="stylesheet" href="./orange.css"></head><body><main><header><div><p>OUDS WEB / ORIGINAL COMPARISON STUDY</p><h1>Choose room for your day</h1><p class="scope">Three fictional mobile-data bundles for inspecting Orange-themed cards, buttons and a native detail drawer. These are not commercial offers.</p></div><button id="theme" class="btn btn-default" type="button">Use dark appearance</button></header><div class="plans"><article class="plan"><h2>Everyday</h2><p class="amount">8 GB</p><p>For messages, maps and occasional listening.</p><button class="btn btn-brand" data-plan="0" data-bs-toggle="offcanvas" data-bs-target="#details" aria-controls="details">Inspect Everyday</button></article><article class="plan"><h2>Explore</h2><p class="amount">25 GB</p><p>More room for podcasts and a longer journey.</p><button class="btn btn-brand" data-plan="1" data-bs-toggle="offcanvas" data-bs-target="#details" aria-controls="details">Inspect Explore</button></article><article class="plan"><h2>Create</h2><p class="amount">60 GB</p><p>A larger sample allowance for sharing on the move.</p><button class="btn btn-brand" data-plan="2" data-bs-toggle="offcanvas" data-bs-target="#details" aria-controls="details">Inspect Create</button></article></div><section id="selected" hidden><p role="status" id="selection-message"></p><button id="clear" class="btn btn-default">Clear local choice</button></section><p class="fine">OUDS Web 1.4.0 native CSS and Offcanvas runtime; original sample content and local selection. Arial fallback is used instead of Orange’s branded typeface.</p></main><aside class="offcanvas offcanvas-end" tabindex="-1" id="details" aria-labelledby="drawer-title"><div class="offcanvas-header"><h2 class="offcanvas-title" id="drawer-title">Bundle details</h2><button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close details"></button></div><div class="offcanvas-body"><p id="drawer-description"></p><ul id="features"></ul><p>No account is connected. Keeping a choice changes this preview only.</p><button id="choose" class="btn btn-brand">Keep this local choice</button></div></aside><script src="./node_modules/@ouds/web-common/dist/js/ouds-web.bundle.min.js"></script><script src="./orange-app.js"></script></body></html>
```

代码参考

- 将 orange-index.html 保存为 index.html；另外两个文件名保持不变。

### orange.css

原始响应式卡片布局，并明确指定字体回退方案。

```
*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif}main{max-width:1080px;margin:auto;padding:32px}header{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;flex-wrap:wrap;border-bottom:4px solid var(--bs-color-action-selected);padding-bottom:24px}h1{font-size:36px;line-height:1.15;margin:12px 0}.scope{font-size:14px;line-height:1.6;max-width:75ch}.plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-top:32px}.plan{display:flex;flex-direction:column;border:1px solid var(--bs-color-border-default);padding:24px;background:var(--bs-color-bg-primary)}.plan h2{font-size:24px}.amount{font-size:40px;font-weight:700;line-height:1.2;margin:24px 0}.plan p{line-height:1.6}.plan .btn{margin-top:auto}.fine{font-size:13px;line-height:1.6;margin-top:24px}.offcanvas{--bs-offcanvas-width:440px}.offcanvas-header,.offcanvas-body{padding:24px}.offcanvas-header{gap:16px}.offcanvas-title{font-size:24px}.offcanvas-body p,.offcanvas-body li{line-height:1.6}.offcanvas-body ul{padding-left:24px}.offcanvas-body li{margin:12px 0}#selected{padding:24px;border:1px solid var(--bs-color-border-default);margin-top:24px}#selected p{margin:0}#selected .btn{margin-top:16px}@media(max-width:720px){main{padding:16px}.plans{grid-template-columns:1fr}.plan{padding:24px}.amount{margin:16px 0}.plan .btn{margin-top:16px}}[hidden]{display:none!important}
```

代码参考

- 将 orange-index.html 保存为 index.html；另外两个文件名保持不变。

### orange-app.js

原生抽屉事件处理，以及本地选择和主题状态。

```
const plans=[["Everyday", "8 GB", "For messages, maps and occasional listening.", ["8 GB of fictional monthly data", "One original study profile", "No contract, order or payment"]], ["Explore", "25 GB", "More room for podcasts and a longer journey.", ["25 GB of fictional monthly data", "One original study profile", "No contract, order or payment"]], ["Create", "60 GB", "A larger sample allowance for sharing on the move.", ["60 GB of fictional monthly data", "One original study profile", "No contract, order or payment"]]];let current=0;const drawer=document.querySelector('#details');drawer.addEventListener('show.bs.offcanvas',event=>{current=Number(event.relatedTarget.dataset.plan);const[name,amount,description,features]=plans[current];document.querySelector('#drawer-title').textContent=name+' · '+amount;document.querySelector('#drawer-description').textContent=description;document.querySelector('#features').replaceChildren(...features.map(text=>{const li=document.createElement('li');li.textContent=text;return li}));});document.querySelector('#choose').addEventListener('click',()=>{document.querySelector('#selected').hidden=false;document.querySelector('#selection-message').textContent=plans[current][0]+' is your local preview choice. No order was placed.';oudsWeb.Offcanvas.getInstance(drawer).hide();});document.querySelector('#clear').addEventListener('click',()=>{document.querySelector('#selected').hidden=true;document.querySelector('[data-plan]').focus()});document.querySelector('#theme').addEventListener('click',e=>{let dark=document.documentElement.dataset.bsTheme!=='dark';document.documentElement.dataset.bsTheme=dark?'dark':'light';e.currentTarget.textContent=dark?'Use light appearance':'Use dark appearance'});
```

代码参考

- 将 orange-index.html 保存为 index.html；另外两个文件名保持不变。

## Orange OUDS Web 设计系统 Agent 设置

### 实现起点

打开 http://localhost:8000/。此示例使用已编译的原生资源，无需 Sass 构建。

```
npm init -y
npm install @ouds/web-common@1.4.0 @ouds/web-orange@1.4.0
# Save index.html, orange.css and orange-app.js from the supplied examples.
python3 -m http.server 8000
```

### 适用于你项目的提示词

```
实现完整的 OUDS Web 1.4 对比研究，使用匹配的 common/Orange 程序包、真实的 btn-brand 和 btn-default 变体、原生 Offcanvas 事件与 API、浅色/深色令牌解析，以及明确指定的 Arial 字体回退方案。所有套餐内容均须为虚构，选择仅保存在本地。
```

## Orange OUDS Web 设计系统来源与范围

使用实际的 OUDS Web CSS 和 Offcanvas 运行时，搭配原创的 OpenDesign 虚构套餐及本地选择。明确指定 Arial 字体回退方案；不代表任何商业优惠或订单。

- 安装 配套的 common 和主题程序包配置。

- Offcanvas 抽屉结构、事件和 API。

- 按钮 OUDS 专属变体和状态。

- JavaScript 运行时行为与集成边界。

## Orange OUDS Web 设计系统相关资源

### Palantir Blueprint

使用 Blueprint 构建密集的数据工作区：经验证的字体和意图令牌、可选择的数据集表、审核检查器，以及完整的 React 源码。

### Pega Bolt

探索 Bolt 的 Pega 品牌内容系统：流动排版、横向与纵向间距分开设置，以及用于编辑资源页面的 Twig 手风琴式组合布局。

### Porsche 设计系统

通过流动式间距、CSS 配色方案、Porsche Next 字体和双选项配置器，探索 Porsche Design System v4。参考内容包含真实的令牌表达式，以及完整的 Vite 入口文件，并采用当前的分段控件事件。


- [实现参考](https://web.unified-design-system.orange.com/orange/docs/1.4/components/offcanvas/)
- [来源](https://cdn.jsdelivr.net/npm/@ouds/web-orange@1.4.0/dist/css/ouds-web.css)
- [来源](https://web.unified-design-system.orange.com/orange/docs/1.4/components/offcanvas/)
- [代码参考](https://web.unified-design-system.orange.com/orange/docs/1.4/getting-started/introduction/)
- [安装 配套的 common 和主题程序包配置。](https://web.unified-design-system.orange.com/orange/docs/1.4/getting-started/download/)
- [Offcanvas 抽屉结构、事件和 API。](https://web.unified-design-system.orange.com/orange/docs/1.4/components/offcanvas/)
- [按钮 OUDS 专属变体和状态。](https://web.unified-design-system.orange.com/orange/docs/1.4/components/buttons/)
- [JavaScript 运行时行为与集成边界。](https://web.unified-design-system.orange.com/orange/docs/1.4/getting-started/javascript/)
