# Oracle Redwood 设计系统

## Oracle Redwood 设计系统界面预览

编辑数量、检查验证结果、排序和筛选，同时保留有效的草稿。

## Oracle Redwood 设计系统设计参考

基础公开声明来自指定版本的 JET 19.0.0 Redwood 样式表。工作表的原创行为与布局已另行标明；基础参考中不包含私有变量和后续反色覆盖。

### Redwood 基础语义用途

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --oj-core-text-color-primary | rgb(var(--oj-palette-neutral-rgb-190)) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-core-text-color-secondary | rgba(var(--oj-palette-neutral-rgb-190), .70) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-core-text-color-disabled | rgba(var(--oj-palette-neutral-rgb-190), .4) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-core-bg-color-content | rgb(var(--oj-palette-neutral-rgb-0)) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-body-bg-color | rgb(var(--oj-palette-neutral-rgb-10)) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-core-divider-color | rgba(var(--oj-palette-neutral-rgb-190),.12) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
| --oj-core-focus-border-color | rgb(var(--oj-palette-neutral-rgb-190)) | 来自 JET 19 Redwood 的首个/基础声明。反色和密度选择器可能会覆盖这些值；不要将所有声明简化为仅查找最后一个值。 |
### 工作表使用的调色板值

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --oj-palette-neutral-rgb-0 | 255, 255, 255 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-neutral-rgb-10 | 251, 249, 248 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-neutral-rgb-20 | 245, 244, 242 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-neutral-rgb-190 | 22, 21, 19 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-brand-rgb-120 | 0, 104, 140 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-info-rgb-20 | 237, 246, 249 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-danger-rgb-120 | 179, 49, 31 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-success-rgb-20 | 235, 248, 222 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
| --oj-palette-success-rgb-140 | 53, 86, 23 | 原始 RGB 通道值会在 rgb() 或 rgba() 中使用，单独使用时并不是完整的 CSS 色值。 |
### 间距与形状

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --oj-core-spacing-1x | .25rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-2x | .5rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-3x | .75rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-4x | 1rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-5x | 1.25rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-6x | 1.5rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-7x | 1.75rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-8x | 2rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-9x | 2.25rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-10x | 2.5rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-11x | 2.75rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-spacing-12x | 3rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-border-radius-sm | 2px | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-border-radius-md | .25rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-border-radius-lg | .375rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
| --oj-core-border-radius-xl | .5rem | 已发布的基础比例。工作表的原生 HTML 控件使用其中选定的值，但不代表具备 JET 组件行为。 |
### 正文字体排版与控件尺寸

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --oj-typography-body-xs-font-size | 0.75rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-typography-body-sm-font-size | 0.859rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-typography-body-md-font-size | 1rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-typography-body-lg-font-size | 1.125rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-typography-body-xl-font-size | 1.25rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-typography-body-md-line-height | 1.25 | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-button-height | 2.75rem | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
| --oj-button-border-radius | var(--oj-core-border-radius-md) | 基础主题声明。原始示例使用 Arial 作为回退字体，其表格和内容布局属于应用代码。 |
### 公共样式边界

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Global theme overrides | :root declarations after JET CSS | 覆盖根级公共变量会影响所有使用方。 |
| Instance styling | A class scoped to the target component | 如果只有一个原生组件需要更改，请限定公共变量的作用范围。 |
| Redwood base | Tracks Oracle visual changes | 如果目标是匹配 Oracle 的外观，可选择此方案；升级可能会改变继承的值。 |
| Stable base | Alternative for a distinct custom theme | 不要将其描述为与 Redwood 完全相同，也不要假设所有反色或缩放功能都一致。 |
| Private variables | --oj-private-* excluded | 示例构建公共参考时没有依赖私有实现钩子。 |
## Oracle Redwood 设计系统完整指南

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

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

## Oracle Redwood 设计系统与 JET 版本边界

### 准确说明实现层

> Redwood 的范围不止一个可下载的组件库。本指南使用 Oracle JET 19.0.0 随附的公共 CSS 基础样式，作为可具体查阅的参考。预览是一个原创的 HTML/CSS 库存审查工作表，使用这些值；它不会实例化 oj-table、oj-input-number 或任何其他 JET 原生自定义元素。这里明确说明运行时，避免读者将视觉基础样式误认为完整的 Oracle 应用 SDK。

- 参考来源：Oracle JET 19 Redwood CSS。

- 预览运行时：原创的原生浏览器 HTML/CSS/JavaScript。

- 数据和验证规则：原创的本地示例。

### 将 Oracle 应用采用与其他活动区分开

在 Oracle SaaS 产品中采用 Redwood、配置 JET 应用，以及借用公共主题作为参考，是不同的活动。此示例不会更改租户、连接库存记录或执行产品迁移。完整的本地文档适合用于研究视觉规则和状态模型；实际的 JET 应用则应遵循对应版本的框架设置指南和原生组件文档。

## Oracle Redwood 设计系统语义角色与调色板值

### 正确解析基础声明

参考资料从固定版本的样式表中提取每个公共变量的首个（基础）声明。后续的反色或密度作用域可能会重新定义相同名称。因此，简单地提取最后一个匹配项，会把反色前景色误标为默认的浅色文本颜色。本指南明确限定基础作用域，并将 --oj-private-* 钩子排除在发布的参考内容之外。

### 区分原始通道值与颜色值

--oj-palette-brand-rgb-120 等调色板变量包含三个 RGB 通道，而语义角色会用 rgb() 或 rgba() 包裹这些通道。原始操作按钮通过 rgb() 使用品牌色通道，文本使用 core-text-color-primary，卡片表面使用 core-bg-color-content。即使通道数字看起来合理，直接将原始通道字符串复制到 background-color 中仍会导致 CSS 无效。

## Oracle Redwood 设计系统间距、字体与密度

### 采用具体的基础样式比例

公共 core-spacing 序列从 1x 到 12x，以 4px 为步进。小、中、大和特大边框角色各不相同，按钮高度则是单独的组件变量。工作表在适用处采用这些实际值，并将 32px 标题、响应式表格转换和 1120px 外层宽度标明为原创的布局决策。

### 不要混用特定密度的值

在此固定版本的样式表中，基础 body-md 字号为 1rem，行高为 1.25；后续选择器可能会呈现按比例缩放的像素值。本指南记录的是基础值，并不意味着 Redwood 的所有场景都必须使用同一个计算字号。浏览器示例使用 Arial 回退字体，并未声称已加载 Oracle Sans。原生 JET 应用应结合所选密度、主题和平台进行测试。

## Oracle Redwood 受 Oracle Redwood 设计系统启发的工作表结构

### 让数据和操作一目了然

每个原创行项目都列出一种工作室用品、说明其计量单位、将当前库存与最低库存进行比较，并提供数量输入框。审查状态标签会重复显示该项目是否计入本地草稿。摘要统计整个草稿中的单位总数，包括被筛选条件隐藏的行。这些都是虚构的示例记录，不代表库存证据或采购建议。

### 排序时保持行标识稳定

应用按项目 ID 而非表格位置存储数量。因此，按名称排序或恢复原始顺序后，编辑内容仍会保留。“低于最低库存”筛选只会更改可见项目集合。若使用与已渲染行顺序绑定的位置数组，排序后可能会将某个项目的数量分配给另一个项目；所提供的代码明确避免了这一问题。

## Oracle Redwood 受 Oracle Redwood 设计系统启发的数量验证

### 拒绝超出所述本地规则的值

原始数量输入框只接受 0 到 99 的整数。输入为空、负数、小数或超出范围时，会显示行内错误并禁用审查操作。草稿模型会保留最后一个有效数量，直到有效编辑替换它。可见错误会清楚说明这一差异，无效值不会计入审查总数。

### 说明何时会丢弃无效编辑

更改筛选或排序时，系统会根据最后有效的草稿值重新生成可见行，因此未完成的无效编辑会被丢弃。这是本地示例有意设定的边界，并非 JET 原生验证保证。生产环境中的可编辑表格也可以选择在切换视图时保留无效草稿，或阻止页面跳转；这些行为必须在各自的状态模型中进行设计和测试。

## Oracle Redwood 受 Oracle Redwood 设计系统启发的审查与重置

### 说明这是本地审查，而非提交订单

“审查此草稿”会生成易读的单位数和相关项目数，并明确说明没有发送订单。示例允许审查单位数为零且有效的草稿，因为它没有臆造强制采购规则。编辑数量会清除之前的审查消息，避免草稿更改后仍显示过期的确认信息。

### 提供可预测的恢复方式

重置数量会恢复最初建议的补货量，并清除审核提示。当前筛选和排序会保留，随后根据重置后的数据重新绘制这些行。这样无需重新加载页面，也能清楚看到恢复结果。此示例不使用存储或后端服务，因此重新加载页面也会恢复初始本地数据。

## Oracle Redwood 设计系统：Oracle Redwood 风格的响应式表格

### 在窄屏上保留信息层级

宽屏布局采用表格形式，包含列标题和作为行标题的商品名称。宽度低于 650px 时，表格行会变为易读的信息块，每个数据单元格都会在数值前显示标签。输入框不会超出可用宽度，商品描述也会与商品名称保持关联。此处展示的是原始应用 CSS 的布局转换，并非声称 oj-table 具备相同的响应式行为。

### 测试编辑和筛选状态

浏览器检查会先输入无效数量并更正，再对商品排序、筛选低于最低库存的项目，并在测量布局前检查汇总数量。检查了从 1440px 到 280px 的四种屏幕宽度。这些测试覆盖实际内容和状态变化，而不只是确认空表格容器存在。

## Oracle Redwood 设计系统完整参考实现

### 运行提供的完整文档

HTML 示例包含所需的公共令牌声明、原始样式、示例记录和所有事件处理程序。将其保存为 index.html 并提供该目录即可运行；无需补充导入，也没有外部运行时调用。参考值固定为 JET 19.0.0，但本地实现无需安装 JET JavaScript 软件包即可运行。

1. 将提供的完整文档保存为 index.html。

2. 通过本地 HTTP 服务提供该文件夹。

3. 测试无效数量及其更正。

4. 对同一份草稿进行排序和筛选，然后检查并重置。

### 通过各自的配置方式使用原生 JET 组件

对于原生应用，请安装匹配的 Oracle JET 软件包并按照其框架配置指南操作，然后使用对应版本的 oj-* 组件契约和公共样式变量。不要将 oj-* 标签粘贴到此独立实现中，并假定它会自动初始化。链接的样式概览区分了根级主题设置和组件范围内的覆盖样式，并说明何时更适合以 Redwood 或 Stable 为基础。

## Oracle Redwood 设计系统组件示例

### index.html — 完整的原始工作表

完整的公共令牌子集、响应式 HTML、验证、稳定的行状态，以及仅限本地的审核和重置行为。

```
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Studio supplies worksheet</title><style>:root{--oj-palette-danger-rgb-10:255, 248, 247;--oj-palette-danger-rgb-20:255, 241, 239;--oj-palette-danger-rgb-30:255, 235, 232;--oj-palette-danger-rgb-40:255, 217, 211;--oj-palette-danger-rgb-50:255, 193, 184;--oj-palette-danger-rgb-60:255, 157, 144;--oj-palette-danger-rgb-70:255, 134, 117;--oj-palette-danger-rgb-80:254, 104, 84;--oj-palette-danger-rgb-90:236, 79, 58;--oj-palette-danger-rgb-100:214, 59, 37;--oj-palette-danger-rgb-110:195, 53, 34;--oj-palette-danger-rgb-120:179, 49, 31;--oj-palette-danger-rgb-130:170, 34, 34;--oj-palette-danger-rgb-140:143, 39, 25;--oj-palette-danger-rgb-150:124, 34, 22;--oj-palette-danger-rgb-160:102, 28, 18;--oj-palette-danger-rgb-170:86, 24, 15;--oj-palette-warning-rgb-10:254, 249, 242;--oj-palette-warning-rgb-20:253, 242, 229;--oj-palette-warning-rgb-30:252, 237, 220;--oj-palette-warning-rgb-40:249, 221, 188;--oj-palette-warning-rgb-50:246, 199, 146;--oj-palette-warning-rgb-60:240, 169, 87;--oj-palette-warning-rgb-70:235, 150, 50;--oj-palette-warning-rgb-80:225, 128, 18;--oj-palette-warning-rgb-90:198, 113, 14;--oj-palette-warning-rgb-100:172, 99, 12;--oj-palette-warning-rgb-110:156, 89, 11;--oj-palette-warning-rgb-120:143, 82, 10;--oj-palette-warning-rgb-130:129, 73, 9;--oj-palette-warning-rgb-140:114, 65, 8;--oj-palette-warning-rgb-150:99, 56, 7;--oj-palette-warning-rgb-160:81, 47, 6;--oj-palette-warning-rgb-170:69, 39, 5;--oj-palette-success-rgb-10:244, 252, 235;--oj-palette-success-rgb-20:235, 248, 222;--oj-palette-success-rgb-30:228, 245, 211;--oj-palette-success-rgb-40:207, 235, 179;--oj-palette-success-rgb-50:177, 221, 136;--oj-palette-success-rgb-60:138, 201, 79;--oj-palette-success-rgb-70:125, 186, 69;--oj-palette-success-rgb-80:111, 169, 57;--oj-palette-success-rgb-90:94, 148, 43;--oj-palette-success-rgb-100:80, 130, 35;--oj-palette-success-rgb-110:73, 118, 32;--oj-palette-success-rgb-120:67, 107, 29;--oj-palette-success-rgb-130:60, 96, 26;--oj-palette-success-rgb-140:53, 86, 23;--oj-palette-success-rgb-150:46, 73, 20;--oj-palette-success-rgb-160:38, 61, 16;--oj-palette-success-rgb-170:31, 51, 14;--oj-palette-info-rgb-10:246, 250, 252;--oj-palette-info-rgb-20:237, 246, 249;--oj-palette-info-rgb-30:228, 241, 247;--oj-palette-info-rgb-40:208, 229, 238;--oj-palette-info-rgb-50:180, 213, 225;--oj-palette-info-rgb-60:143, 191, 208;--oj-palette-info-rgb-70:121, 177, 198;--oj-palette-info-rgb-80:95, 162, 186;--oj-palette-info-rgb-90:65, 144, 172;--oj-palette-info-rgb-100:34, 126, 158;--oj-palette-info-rgb-110:14, 114, 151;--oj-palette-info-rgb-120:0, 104, 140;--oj-palette-info-rgb-130:2, 94, 126;--oj-palette-info-rgb-140:4, 83, 111;--oj-palette-info-rgb-150:6, 72, 95;--oj-palette-info-rgb-160:6, 60, 78;--oj-palette-info-rgb-170:5, 50, 66;--oj-palette-brand-rgb-10:246, 250, 252;--oj-palette-brand-rgb-20:237, 246, 249;--oj-palette-brand-rgb-30:228, 241, 247;--oj-palette-brand-rgb-40:208, 229, 238;--oj-palette-brand-rgb-50:180, 213, 225;--oj-palette-brand-rgb-60:143, 191, 208;--oj-palette-brand-rgb-70:121, 177, 198;--oj-palette-brand-rgb-80:95, 162, 186;--oj-palette-brand-rgb-90:65, 144, 172;--oj-palette-brand-rgb-100:34, 126, 158;--oj-palette-brand-rgb-110:14, 114, 151;--oj-palette-brand-rgb-120:0, 104, 140;--oj-palette-brand-rgb-130:2, 94, 126;--oj-palette-brand-rgb-140:4, 83, 111;--oj-palette-brand-rgb-150:6, 72, 95;--oj-palette-brand-rgb-160:6, 60, 78;--oj-palette-brand-rgb-170:5, 50, 66;--oj-palette-neutral-rgb-0:255, 255, 255;--oj-palette-neutral-rgb-10:251, 249, 248;--oj-palette-neutral-rgb-20:245, 244, 242;--oj-palette-neutral-rgb-30:241, 239, 237;--oj-palette-neutral-rgb-40:228, 225, 221;--oj-palette-neutral-rgb-50:212, 207, 202;--oj-palette-neutral-rgb-60:188, 182, 177;--oj-palette-neutral-rgb-70:174, 168, 162;--oj-palette-neutral-rgb-80:158, 152, 146;--oj-palette-neutral-rgb-90:139, 133, 128;--oj-palette-neutral-rgb-100:123, 117, 112;--oj-palette-neutral-rgb-110:111, 105, 100;--oj-palette-neutral-rgb-120:101, 95, 91;--oj-palette-neutral-rgb-130:92, 86, 81;--oj-palette-neutral-rgb-140:81, 76, 71;--oj-palette-neutral-rgb-150:71, 66, 62;--oj-palette-neutral-rgb-160:58, 54, 50;--oj-palette-neutral-rgb-170:49, 45, 42;--oj-palette-neutral-rgb-180:32, 30, 28;--oj-palette-neutral-rgb-190:22, 21, 19;--oj-palette-neutral-rgb-200:00, 00, 00;--oj-palette-dvt-rgb-1:36, 93, 99;--oj-palette-dvt-rgb-2:215, 121, 15;--oj-palette-dvt-rgb-3:49, 160, 156;--oj-palette-dvt-rgb-4:78, 65, 55;--oj-palette-dvt-rgb-5:105, 158, 97;--oj-palette-dvt-rgb-6:180, 114, 130;--oj-palette-dvt-rgb-7:131, 64, 30;--oj-palette-dvt-rgb-8:158, 127, 204;--oj-palette-dvt-rgb-9:168, 142, 0;--oj-palette-dvt-rgb-10:88, 49, 110;--oj-palette-dvt-rgb-11:89, 153, 181;--oj-palette-dvt-rgb-12:49, 122, 69;--oj-core-text-color-primary:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-text-color-secondary:rgba(var(--oj-palette-neutral-rgb-190), .70);--oj-core-text-color-disabled:rgba(var(--oj-palette-neutral-rgb-190), .4);--oj-core-text-color-brand:rgb(var(--oj-palette-brand-rgb-110));--oj-core-text-color-danger:rgb(var(--oj-palette-danger-rgb-120));--oj-core-text-color-warning:rgb(var(--oj-palette-warning-rgb-120));--oj-core-text-color-success:rgb(var(--oj-palette-success-rgb-120));--oj-core-bg-color-content:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-bg-color-hover:rgba(var(--oj-palette-neutral-rgb-190), .08);--oj-core-bg-color-active:rgba(var(--oj-palette-neutral-rgb-190), .16);--oj-core-bg-color-selected:rgb(var(--oj-palette-brand-rgb-30));--oj-core-border-color-selected:rgb(var(--oj-palette-brand-rgb-100));--oj-core-border-color-enabled:rgba(var(--oj-palette-neutral-rgb-190), 0.5);--oj-core-color-disabled-1:rgba(var(--oj-palette-neutral-rgb-190), 0.04);--oj-core-color-disabled-2:rgba(var(--oj-palette-neutral-rgb-190),.20);--oj-core-icon-size-lg:1.5rem;--oj-core-icon-size-sm:1rem;--oj-core-divider-color:rgba(var(--oj-palette-neutral-rgb-190),.12);--oj-core-divider-margin:0.5rem;--oj-core-neutral-1:rgb(var(--oj-palette-neutral-rgb-100));--oj-core-neutral-2:rgb(var(--oj-palette-neutral-rgb-110));--oj-core-neutral-3:rgb(var(--oj-palette-neutral-rgb-120));--oj-core-neutral-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-neutral-secondary-1:rgba(var(--oj-palette-neutral-rgb-190), 0.08);--oj-core-neutral-secondary-2:rgb(var(--oj-palette-neutral-rgb-20));--oj-core-neutral-secondary-3:rgb(var(--oj-palette-neutral-rgb-10));--oj-core-neutral-secondary-contrast:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-brand-1:rgb(var(--oj-palette-brand-rgb-100));--oj-core-brand-2:rgb(var(--oj-palette-brand-rgb-110));--oj-core-brand-3:rgb(var(--oj-palette-brand-rgb-120));--oj-core-brand-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-danger-1:rgb(var(--oj-palette-danger-rgb-120));--oj-core-danger-2:rgb(var(--oj-palette-danger-rgb-110));--oj-core-danger-3:rgb(var(--oj-palette-danger-rgb-120));--oj-core-danger-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-danger-secondary-1:rgba(var(--oj-palette-danger-rgb-60), 0.4);--oj-core-danger-secondary-2:rgb(var(--oj-palette-danger-rgb-20));--oj-core-danger-secondary-3:rgb(var(--oj-palette-danger-rgb-10));--oj-core-danger-secondary-contrast:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-warning-1:rgb(var(--oj-palette-warning-rgb-120));--oj-core-warning-2:rgb(var(--oj-palette-warning-rgb-110));--oj-core-warning-3:rgb(var(--oj-palette-warning-rgb-120));--oj-core-warning-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-warning-secondary-1:rgba(var(--oj-palette-warning-rgb-60), 0.4);--oj-core-warning-secondary-2:rgb(var(--oj-palette-warning-rgb-20));--oj-core-warning-secondary-3:rgb(var(--oj-palette-warning-rgb-10));--oj-core-warning-secondary-contrast:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-success-1:rgb(var(--oj-palette-success-rgb-120));--oj-core-success-2:rgb(var(--oj-palette-success-rgb-110));--oj-core-success-3:rgb(var(--oj-palette-success-rgb-120));--oj-core-success-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-success-secondary-1:rgba(var(--oj-palette-success-rgb-60), 0.4);--oj-core-success-secondary-2:rgb(var(--oj-palette-success-rgb-20));--oj-core-success-secondary-3:rgb(var(--oj-palette-success-rgb-10));--oj-core-success-secondary-contrast:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-info-1:rgb(var(--oj-palette-info-rgb-120));--oj-core-info-2:rgb(var(--oj-palette-info-rgb-110));--oj-core-info-3:rgb(var(--oj-palette-info-rgb-120));--oj-core-info-contrast:rgb(var(--oj-palette-neutral-rgb-0));--oj-core-info-secondary-1:rgba(var(--oj-palette-info-rgb-60), 0.4);--oj-core-info-secondary-2:rgb(var(--oj-palette-info-rgb-20));--oj-core-info-secondary-3:rgb(var(--oj-palette-info-rgb-10));--oj-core-info-secondary-contrast:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-focus-border-color:rgb(var(--oj-palette-neutral-rgb-190));--oj-core-cursor-clickable:pointer;--oj-core-drag-drop-color-1:rgb(var(--oj-palette-brand-rgb-40));--oj-core-drag-drop-color-2:rgb(var(--oj-palette-brand-rgb-100));--oj-core-drag-drop-line-color:rgb(var(--oj-palette-brand-rgb-100));--oj-core-touch-target-min-size:2.25rem;--oj-core-box-shadow-rgb:var(--oj-palette-neutral-rgb-200);--oj-core-box-shadow-xs:0px 1px 4px 0px rgba(var(--oj-core-box-shadow-rgb),.12);--oj-core-box-shadow-sm:0px 4px 8px 0px rgba(var(--oj-core-box-shadow-rgb),.16);--oj-core-box-shadow-md:0px 6px 12px 0px rgba(var(--oj-core-box-shadow-rgb),.2);--oj-core-box-shadow-lg:0px 8px 16px 0px rgba(var(--oj-core-box-shadow-rgb),0.24);--oj-core-box-shadow-xl:0px 12px 20px 0px rgba(var(--oj-core-box-shadow-rgb),0.28);--oj-core-dropdown-box-shadow:var(--oj-core-box-shadow-sm);--oj-core-scrim-color:rgba(var(--oj-palette-neutral-rgb-190), .4);--oj-core-spacing-1x:.25rem;--oj-core-spacing-2x:.5rem;--oj-core-spacing-3x:.75rem;--oj-core-spacing-4x:1rem;--oj-core-spacing-5x:1.25rem;--oj-core-spacing-6x:1.5rem;--oj-core-spacing-7x:1.75rem;--oj-core-spacing-8x:2rem;--oj-core-spacing-9x:2.25rem;--oj-core-spacing-10x:2.5rem;--oj-core-spacing-11x:2.75rem;--oj-core-spacing-12x:3rem;--oj-core-border-radius-sm:2px;--oj-core-border-radius-md:.25rem;--oj-core-border-radius-lg:.375rem;--oj-core-border-radius-xl:.5rem;--oj-core-z-index-popup:1000;--oj-core-z-index-dialog:1050;--oj-core-z-index-messages:2000;--oj-typography-heading-2xl-font-size:2.5rem;--oj-typography-heading-2xl-font-weight:800;--oj-typography-heading-2xl-line-height:1.3;--oj-typography-heading-xl-font-size:2.25rem;--oj-typography-heading-xl-font-weight:800;--oj-typography-heading-xl-line-height:1.222;--oj-typography-heading-lg-font-size:2rem;--oj-typography-heading-lg-font-weight:800;--oj-typography-heading-lg-line-height:1.25;--oj-typography-heading-md-font-size:1.75rem;--oj-typography-heading-md-font-weight:800;--oj-typography-heading-md-line-height:1.2857;--oj-typography-heading-sm-font-size:1.5rem;--oj-typography-heading-sm-font-weight:800;--oj-typography-heading-sm-line-height:1.3333;--oj-typography-heading-xs-font-size:1.25rem;--oj-typography-heading-xs-font-weight:800;--oj-typography-heading-xs-line-height:1.4;--oj-typography-subheading-2xl-font-size:2.25rem;--oj-typography-subheading-2xl-font-weight:bold;--oj-typography-subheading-2xl-line-height:1.2222;--oj-typography-subheading-xl-font-size:2rem;--oj-typography-subheading-xl-font-weight:bold;--oj-typography-subheading-xl-line-height:1.25;--oj-typography-subheading-lg-font-size:1.75rem;--oj-typography-subheading-lg-font-weight:bold;--oj-typography-subheading-lg-line-height:1.2857;--oj-typography-subheading-md-font-size:1.5rem;--oj-typography-subheading-md-font-weight:bold;--oj-typography-subheading-md-line-height:1.3333;--oj-typography-subheading-sm-font-size:1.25rem;--oj-typography-subheading-sm-font-weight:bold;--oj-typography-subheading-sm-line-height:1.4;--oj-typography-subheading-xs-font-size:1rem;--oj-typography-subheading-xs-font-weight:bold;--oj-typography-subheading-xs-line-height:1.5;--oj-typography-body-xl-font-size:1.25rem;--oj-typography-body-xl-line-height:1.4;--oj-typography-body-lg-font-size:1.125rem;--oj-typography-body-lg-line-height:1.3333;--oj-typography-body-md-font-size:1rem;--oj-typography-body-md-line-height:1.25;--oj-typography-body-sm-font-size:0.859rem;--oj-typography-body-sm-line-height:1.2;--oj-typography-body-xs-font-size:0.75rem;--oj-typography-body-xs-line-height:1.3333;--oj-typography-body-2xs-font-size:0.625rem;--oj-typography-body-2xs-line-height:1.2;--oj-body-bg-color:rgb(var(--oj-palette-neutral-rgb-10));--oj-button-height:2.75rem;--oj-button-border-radius:var(--oj-core-border-radius-md);}*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;font-size:16px;color:var(--oj-core-text-color-primary);background:var(--oj-body-bg-color)}main{max-width:1120px;padding:32px;margin:auto}header{display:flex;justify-content:space-between;gap:24px;align-items:flex-start;flex-wrap:wrap}h1{font-size:32px;line-height:1.2;margin:12px 0 24px}.eyebrow{font-size:12px;letter-spacing:.08em;font-weight:700}.scope{font-size:14px;line-height:1.6;max-width:78ch;color:var(--oj-core-text-color-secondary)}.count{padding:16px 24px;border:1px solid var(--oj-core-divider-color);border-radius:var(--oj-core-border-radius-lg);background:var(--oj-core-bg-color-content);min-width:140px}.count strong{display:block;font-size:32px}.toolbar{display:flex;gap:24px;align-items:center;flex-wrap:wrap;margin:24px 0}button,select,input{font:inherit}button{min-height:var(--oj-button-height);padding:8px 16px;border:1px solid var(--oj-core-divider-color);border-radius:var(--oj-button-border-radius);background:var(--oj-core-bg-color-content);color:var(--oj-core-text-color-primary);cursor:pointer}button.primary{background:rgb(var(--oj-palette-brand-rgb-120));color:white;border-color:transparent}button:disabled{opacity:.5;cursor:default}select{min-height:44px;border:1px solid var(--oj-core-divider-color);border-radius:4px;padding:8px;background:white;max-width:100%}.table-wrap{overflow:auto;background:var(--oj-core-bg-color-content);border:1px solid var(--oj-core-divider-color);border-radius:var(--oj-core-border-radius-lg)}table{width:100%;border-collapse:collapse;table-layout:fixed}th,td{text-align:left;padding:20px 24px;vertical-align:top;border-bottom:1px solid var(--oj-core-divider-color)}thead th{font-size:13px;background:rgb(var(--oj-palette-neutral-rgb-20))}th:first-child{width:36%}tbody tr:last-child td,tbody tr:last-child th{border-bottom:0}td p,th p{font-size:13px;color:var(--oj-core-text-color-secondary);font-weight:400;margin:8px 0;line-height:1.5}input{width:88px;max-width:100%;padding:8px;border:1px solid var(--oj-core-divider-color);border-radius:4px;background:white;min-height:44px}.note{margin:24px 0;padding:24px;background:rgb(var(--oj-palette-info-rgb-20));border-left:4px solid rgb(var(--oj-palette-brand-rgb-120));line-height:1.6}.actions{display:flex;gap:16px;flex-wrap:wrap}.error{color:rgb(var(--oj-palette-danger-rgb-120));font-size:13px;line-height:1.5}.status{font-size:13px;padding:4px 8px;border-radius:4px;background:rgb(var(--oj-palette-neutral-rgb-20));display:inline-block}.status.ready{background:rgb(var(--oj-palette-success-rgb-20));color:rgb(var(--oj-palette-success-rgb-140))}:focus-visible{outline:2px solid var(--oj-core-focus-border-color);outline-offset:3px}[hidden]{display:none!important}@media(max-width:650px){main{padding:16px}table,tbody,tr,td,th{display:block}table{table-layout:auto}thead{display:none}th:first-child{width:auto}tbody tr{padding:16px;border-bottom:1px solid var(--oj-core-divider-color)}tbody tr:last-child{border-bottom:0}td,th{padding:8px;border:0!important}td:before{content:attr(data-label);display:block;font-size:12px;font-weight:700;margin-bottom:8px}.toolbar label{display:flex;flex-wrap:wrap;gap:8px}}
</style></head><body><main><header><div><p class="eyebrow">REDWOOD FOUNDATIONS / ORIGINAL WORKSHEET</p><h1>Prepare the studio supplies</h1><p class="scope">An original stock-review worksheet using public Oracle JET 19 Redwood variables. This is plain HTML/CSS and JavaScript, not a native JET component runtime or an Oracle inventory service. Arial is an explicit font fallback.</p></div><div class="count"><strong id="total">0</strong>units in the local draft</div></header><div class="toolbar"><label for="filter">Show <select id="filter"><option value="all">All sample items</option><option value="low">Below minimum stock</option></select></label><button id="sort">Sort by item name</button></div><div class="table-wrap"><table><thead><tr><th scope="col">Item</th><th scope="col">On hand / minimum</th><th scope="col">Add to draft</th><th scope="col">Review state</th></tr></thead><tbody id="rows"></tbody></table></div><p id="empty" hidden>No items match this view. <button id="show-all">Show all items</button></p><p class="note">Change a quantity to build a local replenishment draft. A draft may contain zero units. Nothing is ordered, approved or sent from this example.</p><div class="actions"><button class="primary" id="keep">Review this draft</button><button id="reset">Reset quantities</button></div><p id="message" role="status"></p></main><script>const initial=[{id:'paper',name:'Sketch paper',detail:'A4 recycled sheets',stock:18,min:30},{id:'markers',name:'Fine-tip markers',detail:'Black ink / single pens',stock:12,min:10},{id:'clips',name:'Binder clips',detail:'Medium / single clips',stock:6,min:20}];let amounts={paper:12,markers:0,clips:14},ascending=false;const tbody=document.querySelector('#rows');function visible(){let a=initial.filter(x=>document.querySelector('#filter').value!=='low'||x.stock<x.min);return ascending?[...a].sort((a,b)=>a.name.localeCompare(b.name)):a;}function count(){let inputs=[...document.querySelectorAll('input')];let bad=inputs.some(x=>!x.checkValidity()||x.value==='');document.querySelector('#keep').disabled=bad;document.querySelector('#total').textContent=Object.values(amounts).reduce((a,b)=>a+b,0);return bad;}function render(){tbody.innerHTML=visible().map(x=>`<tr><th scope="row">${x.name}<p>${x.detail}</p></th><td data-label="On hand / minimum">${x.stock} / ${x.min}<p>${x.stock<x.min?'Below minimum':'Above minimum'}</p></td><td data-label="Add to draft"><input id="qty-${x.id}" aria-label="Quantity for ${x.name}" type="number" min="0" max="99" step="1" value="${amounts[x.id]}" data-id="${x.id}"><p class="error" hidden>Use a whole number from 0 to 99.</p></td><td data-label="Review state"><span class="status ${amounts[x.id]?'ready':''}">${amounts[x.id]?'In draft':'No addition'}</span></td></tr>`).join('');tbody.querySelectorAll('input').forEach(input=>input.addEventListener('input',()=>{let valid=input.checkValidity()&&input.value!=='';input.setAttribute('aria-invalid',String(!valid));input.nextElementSibling.hidden=valid;document.querySelector('#message').textContent='';if(valid){amounts[input.dataset.id]=Number(input.value);const status=input.closest('tr').querySelector('.status');status.textContent=Number(input.value)?'In draft':'No addition';status.classList.toggle('ready',Number(input.value)>0)}count()}));document.querySelector('#empty').hidden=visible().length>0;count()}document.querySelector('#filter').addEventListener('change',render);document.querySelector('#sort').addEventListener('click',e=>{ascending=!ascending;e.currentTarget.textContent=ascending?'Use original order':'Sort by item name';render()});document.querySelector('#show-all').addEventListener('click',()=>{document.querySelector('#filter').value='all';render()});document.querySelector('#keep').addEventListener('click',()=>{if(!count())document.querySelector('#message').textContent='Reviewed '+Object.values(amounts).reduce((a,b)=>a+b,0)+' units across '+Object.values(amounts).filter(x=>x>0).length+' items in this local draft. No order was sent.'});document.querySelector('#reset').addEventListener('click',()=>{amounts={paper:12,markers:0,clips:14};document.querySelector('#message').textContent='';render()});render();</script></body></html>
```

代码参考

- 这并非 oj-table 或 oj-input-number。

- 未连接 Oracle 应用、库存服务或订单接口。

## Oracle Redwood 设计系统 Agent 设置

### 实现起点

运行原始独立实现。采用原生 JET 是另一种框架配置方式，相关说明见链接中的官方文档。

```
# Save the complete supplied document as index.html.
python3 -m http.server 8000
# Open http://localhost:8000/
```

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

```
使用经验证的 JET 19 公共基础变量，实现提供的原始 Redwood 风格库存审核工作表。保留 RGB 通道语法、以商品 ID 为键的有效数量状态、验证边界、排序和筛选状态，以及仅限本地的审核和重置行为。不要将此浏览器实现描述为原生 JET 或 Oracle 服务。
```

## Oracle Redwood 设计系统来源与范围

采用 Oracle JET 19 公共 Redwood 变量的 OpenDesign 实现。预览使用纯 HTML/CSS/JavaScript，并非原生 JET 组件或 Oracle 库存服务。明确指定 Arial 作为备用字体。

- JET 样式概览 公共变量的作用范围、Redwood 与 Stable 的区别，以及主题边界。

- 固定版本的 Redwood CSS 参考实现和示例中实际使用的基础值。

- Oracle JET 文档 原生框架配置和开发背景。

- 采用 Redwood Oracle 应用采用方案的独立背景说明。

## Oracle Redwood 设计系统相关资源

### Orange OUDS Web

通过完整的响应式对比研究，查看 Orange OUDS 1.4 的实际语义设计令牌、主题软件包和原生 Offcanvas 行为。

### Palantir Blueprint

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

### Pega Bolt

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


- [实现参考](https://docs.oracle.com/en/middleware/developer-tools/jet/19/reference-styling/CssVariablesOverview.html)
- [来源](https://cdn.jsdelivr.net/npm/@oracle/oraclejet@19.0.0/dist/css/redwood/oj-redwood.css)
- [来源](https://docs.oracle.com/en/middleware/developer-tools/jet/19/reference-styling/CssVariablesOverview.html)
- [代码参考](https://cdn.jsdelivr.net/npm/@oracle/oraclejet@19.0.0/dist/css/redwood/oj-redwood.css)
- [JET 样式概览 公共变量的作用范围、Redwood 与 Stable 的区别，以及主题边界。](https://docs.oracle.com/en/middleware/developer-tools/jet/19/reference-styling/CssVariablesOverview.html)
- [固定版本的 Redwood CSS 参考实现和示例中实际使用的基础值。](https://cdn.jsdelivr.net/npm/@oracle/oraclejet@19.0.0/dist/css/redwood/oj-redwood.css)
- [Oracle JET 文档 原生框架配置和开发背景。](https://docs.oracle.com/en/middleware/developer-tools/jet/19/develop/index.html)
- [采用 Redwood Oracle 应用采用方案的独立背景说明。](https://docs.oracle.com/en/cloud/saas/readiness/redwood-adoption/)
