Files
Genarrative/packages/shared/src/components/styles.css
T
kdletters e072c66ce9
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
修复 AGC 模板库筛选与卡片状态的表现缺陷
- 模板库筛选区改用共享筛选条与标签 chip:选中为实心品牌填充 + 反白文字,未选为浅底描边
- 未选中悬停不再借用品牌色(品牌色专属已选中),状态阶梯固定为静止 / 悬停 / 按下 / 选中
- 新增 getPlatformCategoryChipClassName 收敛筛选 chip 类名口径,模板库、资源画布、参考图弹窗与平台 Web 端共用
- PlatformSegmentedTabs 增加 accent 选中口径,与筛选 chip 共用 --platform-chip-* 语义色
- 修复卡片文字区按 grid auto 行排版导致的标题 / 简介 / 标签被裁:行高契约拆为分项常量,文字区固定 174
- 修复忙状态下动作行塞入第三个元素导致的按钮文案换行顶出卡片:忙状态写在触发它的按钮上
- 修复经典滚动条占宽导致的卡片区横向滚动条:按竖滚动条预留列宽后再算列宽行高
- 焦点环由 15% 透明度改为实心色并用 outline 绘制,选中项聚焦不再被状态投影盖掉
- 封面加载失败改为隐藏图片留中性底色,不再出现浏览器裂图图标
- 补充状态对比度、行高契约、滚动条预留、封面兜底与忙状态文案的回归测试
- 同步技术方案、踩坑记录与决策记录的口径
2026-09-23 16:51:15 +08:00

1544 lines
39 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Shared token CSS for the shadcn-owned UI source. Hosts only need to import
* this file and theme.css; no application layout, business selector, or
* Tailwind preset is pulled into the consuming app.
*/
.genarrative-ui {
--genarrative-ui-focus-ring: var(
--platform-input-focus-ring,
rgba(204, 117, 76, 0.24)
);
color: var(--platform-text-strong, #3d1f10);
font-family: var(
--platform-font-family,
Inter,
'Noto Sans CJK SC',
'PingFang SC',
system-ui,
sans-serif
);
}
.genarrative-ui *,
.genarrative-ui *::before,
.genarrative-ui *::after {
box-sizing: border-box;
}
.genarrative-ui-label {
display: inline-flex;
align-items: center;
gap: 0.35rem;
color: var(--platform-text-strong, #3d1f10);
font-size: 0.8125rem;
font-weight: 700;
line-height: 1.25;
cursor: pointer;
}
.genarrative-ui-checkbox {
display: inline-grid;
width: 1.125rem;
height: 1.125rem;
flex: 0 0 auto;
place-items: center;
appearance: none;
border: 1px solid var(--platform-neutral-border, rgba(226, 203, 184, 0.88));
border-radius: 0.35rem;
background: var(--platform-button-secondary-fill, rgba(255, 253, 250, 0.88));
color: var(--platform-button-primary-text, #fffaf5);
cursor: pointer;
transition:
background-color 160ms ease,
border-color 160ms ease,
box-shadow 160ms ease,
transform 160ms ease;
}
.genarrative-ui-checkbox::after {
content: '✓';
font-size: 0.75rem;
font-weight: 900;
line-height: 1;
opacity: 0;
transform: scale(0.7);
transition:
opacity 120ms ease,
transform 120ms ease;
}
.genarrative-ui-checkbox:checked {
border-color: var(--platform-button-primary-border, rgba(182, 98, 63, 0.32));
background: var(--platform-button-primary-fill, #c7653d);
}
.genarrative-ui-checkbox:checked::after {
opacity: 1;
transform: scale(1);
}
.genarrative-ui-checkbox:hover:not(:disabled) {
transform: translateY(-1px);
}
.genarrative-ui-checkbox:active:not(:disabled) {
transform: translateY(1px);
}
.genarrative-ui-checkbox:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--genarrative-ui-focus-ring);
}
.genarrative-ui-checkbox:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.genarrative-ui-skeleton {
min-height: 1rem;
border-radius: 0.55rem;
background: linear-gradient(
100deg,
rgba(226, 203, 184, 0.42) 20%,
rgba(255, 253, 250, 0.92) 40%,
rgba(226, 203, 184, 0.42) 60%
);
background-size: 200% 100%;
animation: genarrative-ui-skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes genarrative-ui-skeleton-shimmer {
to {
background-position: -200% 0;
}
}
.genarrative-ui-table__container {
width: 100%;
overflow-x: auto;
border: 1px solid var(--platform-subpanel-border, rgba(226, 203, 184, 0.88));
border-radius: 0.9rem;
background: var(--platform-subpanel-fill, rgba(255, 253, 250, 0.72));
}
.genarrative-ui-table {
width: 100%;
border-collapse: collapse;
color: var(--platform-text-strong, #3d1f10);
font-size: 0.8125rem;
text-align: left;
}
.genarrative-ui-table__head,
.genarrative-ui-table__cell {
padding: 0.7rem 0.85rem;
white-space: nowrap;
}
.genarrative-ui-table__header {
background: rgba(226, 203, 184, 0.2);
color: var(--platform-text-soft, #755a49);
font-size: 0.72rem;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.genarrative-ui-table__row + .genarrative-ui-table__row {
border-top: 1px solid var(--platform-line-soft, rgba(226, 203, 184, 0.72));
}
.genarrative-ui-table__body .genarrative-ui-table__row:hover {
background: rgba(255, 255, 255, 0.58);
}
.genarrative-ui-table__caption {
padding: 0.7rem 0.85rem;
color: var(--platform-text-soft, #755a49);
font-size: 0.75rem;
text-align: left;
}
.genarrative-ui-button,
.genarrative-ui-icon-button,
.genarrative-ui-tabs__item,
.genarrative-ui-switch {
font: inherit;
}
.genarrative-ui-button {
display: inline-flex;
min-height: 2.5rem;
align-items: center;
justify-content: center;
gap: 0.5rem;
border: 1px solid transparent;
border-radius: 0.75rem;
padding: 0 1rem;
font-weight: 700;
line-height: 1;
cursor: pointer;
transition:
transform 160ms ease,
box-shadow 160ms ease,
background-color 160ms ease,
border-color 160ms ease,
color 160ms ease,
opacity 160ms ease;
}
.genarrative-ui-button--sm {
min-height: 2.125rem;
border-radius: 0.625rem;
padding-inline: 0.75rem;
font-size: 0.8125rem;
}
.genarrative-ui-button--md {
min-height: 2.5rem;
font-size: 0.875rem;
}
.genarrative-ui-button--lg {
min-height: 2.875rem;
border-radius: 0.875rem;
padding-inline: 1.25rem;
font-size: 0.9375rem;
}
.genarrative-ui-button--full-width {
width: 100%;
}
.genarrative-ui-button--pill {
border-radius: 999px;
}
.genarrative-ui-button--start {
justify-content: flex-start;
text-align: left;
}
.genarrative-ui-button--primary {
border-color: var(--platform-button-primary-border, rgba(182, 98, 63, 0.32));
background: var(--platform-button-primary-fill, #c7653d);
color: var(--platform-button-primary-text, #fffaf5);
box-shadow: var(
--platform-profile-action-shadow,
0 8px 18px rgba(182, 98, 63, 0.18)
);
}
.genarrative-ui-button--secondary {
border-color: var(--platform-surface-border, rgba(226, 203, 184, 0.88));
background: var(--platform-button-secondary-fill, rgba(255, 253, 250, 0.88));
color: var(--platform-button-secondary-text, #4b2412);
}
.genarrative-ui-button--ghost {
border-color: transparent;
background: transparent;
color: var(--platform-button-ghost-text, #755a49);
}
.genarrative-ui-button--danger {
border-color: var(--platform-button-danger-border, rgba(185, 75, 58, 0.24));
background: var(--platform-button-danger-fill, #fff0eb);
color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-button--tone-accent {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.3));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
color: var(--platform-warm-text, #b6623f);
}
.genarrative-ui-button--tone-accent-soft {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.22));
background: transparent;
color: var(--platform-accent, #c7653d);
}
.genarrative-ui-button:not(:disabled):hover,
.genarrative-ui-icon-button:not(:disabled):not([aria-disabled='true']):hover,
.genarrative-ui-tabs__item:not(:disabled):hover,
.genarrative-ui-switch:not(:disabled):hover {
transform: translateY(-1px);
}
.genarrative-ui-button:not(:disabled):active,
.genarrative-ui-icon-button:not(:disabled):not([aria-disabled='true']):active,
.genarrative-ui-tabs__item:not(:disabled):active,
.genarrative-ui-switch:not(:disabled):active {
transform: translateY(1px);
transition-duration: 80ms;
}
.genarrative-ui-button:not(:disabled):active {
filter: brightness(0.97);
box-shadow: inset 0 2px 4px rgba(50, 22, 8, 0.14);
}
.genarrative-ui-button--primary:not(:disabled):active {
filter: brightness(0.94);
box-shadow:
inset 0 2px 4px rgba(50, 22, 8, 0.2),
0 3px 8px rgba(182, 98, 63, 0.16);
}
.genarrative-ui-icon-button:not(:disabled):not([aria-disabled='true']):active {
background: var(--platform-icon-active-fill, rgba(238, 208, 183, 0.42));
box-shadow: inset 0 2px 4px rgba(50, 22, 8, 0.12);
}
.genarrative-ui-icon-button--quiet:not(:disabled):not(
[aria-disabled='true']
):active {
background: var(--platform-button-ghost-fill, rgba(255, 253, 250, 0.56));
}
.genarrative-ui-tabs__item:not(:disabled):active {
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
box-shadow: inset 0 2px 4px rgba(50, 22, 8, 0.1);
}
.genarrative-ui-switch:not(:disabled):active {
color: var(--platform-text-strong, #3d1f10);
}
.genarrative-ui-switch:not(:disabled):active .genarrative-ui-switch__track {
filter: brightness(0.94);
}
.genarrative-ui-button--primary:not(:disabled):hover {
filter: brightness(1.04);
box-shadow: 0 12px 24px rgba(182, 98, 63, 0.24);
}
.genarrative-ui-button:focus-visible,
.genarrative-ui-icon-button:focus-visible,
.genarrative-ui-tabs__item:focus-visible,
.genarrative-ui-switch:focus-visible,
.genarrative-ui-text-field__control:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--genarrative-ui-focus-ring);
}
/* Platform-prefixed adapters share these small chrome primitives with the
* web host. Keeping the selectors in the package means Tauri consumers do not
* need to import the website's large application stylesheet. */
.platform-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.55rem;
min-height: 2.9rem;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 1rem;
padding: 0.7rem 1rem;
font-size: 0.9375rem;
font-weight: 600;
transition:
transform 180ms ease,
border-color 180ms ease,
background-color 180ms ease,
color 180ms ease,
opacity 180ms ease,
box-shadow 180ms ease;
}
.platform-button:hover {
transform: translateY(-1px);
}
.platform-button:active {
transform: translateY(0);
}
.platform-button:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.platform-button--primary {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
box-shadow: 0 16px 34px rgba(182, 98, 63, 0.18);
}
.platform-button--secondary {
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
}
.platform-button--ghost {
background: var(--platform-button-ghost-fill);
color: var(--platform-button-ghost-text);
}
.platform-button--danger {
border-color: var(--platform-button-danger-border);
background: var(--platform-button-danger-fill);
color: var(--platform-button-danger-text);
}
.platform-icon-button {
display: inline-flex;
width: 2.5rem;
height: 2.5rem;
align-items: center;
justify-content: center;
border: 1px solid var(--platform-icon-border);
border-radius: 9999px;
background: var(--platform-icon-fill);
color: var(--platform-icon-text);
transition:
background-color 180ms ease,
border-color 180ms ease,
color 180ms ease,
transform 180ms ease;
}
.platform-icon-button:hover {
transform: translateY(-1px);
border-color: var(--platform-nav-active-border);
background: var(--platform-nav-active-fill);
color: var(--platform-text-strong);
}
.platform-subpanel {
border: 1px solid var(--platform-subpanel-border);
background: var(--platform-subpanel-fill);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.platform-primary-button {
border: 1px solid var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
box-shadow: var(--platform-profile-action-shadow);
transition:
transform 180ms ease,
filter 180ms ease,
opacity 180ms ease;
}
.platform-primary-button:hover:not(:disabled) {
transform: translateY(-1px);
filter: brightness(1.02);
}
.platform-progress-track {
border: 1px solid var(--platform-track-border);
background: var(--platform-track-fill);
}
/* Filter toolbar chrome is part of the shared platform surface so the
* canonical toolbar renders the same in the web app and standalone hosts. */
.platform-category-filter-row {
display: flex;
min-width: 0;
align-items: center;
gap: 0.65rem;
overflow: hidden;
border: 1px solid var(--platform-subpanel-border);
border-radius: 1.25rem;
background: var(--platform-subpanel-fill);
padding: 0.55rem 0.65rem;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.platform-category-filter-button,
.platform-category-sort-button,
.platform-category-chip {
cursor: pointer;
transition:
transform 160ms ease,
border-color 160ms ease,
background-color 160ms ease,
color 160ms ease,
box-shadow 160ms ease;
}
.platform-category-filter-button {
display: inline-flex;
position: relative;
min-height: 2.25rem;
flex: 0 0 auto;
align-items: center;
gap: 0.35rem;
border: 1px solid var(--platform-cool-border);
border-radius: 9999px;
background: var(--platform-cool-bg);
color: var(--platform-cool-text);
padding: 0 0.75rem;
font-size: 0.86rem;
font-weight: 900;
white-space: nowrap;
}
.platform-category-filter-button__count {
display: inline-flex;
min-width: 1.18rem;
height: 1.18rem;
align-items: center;
justify-content: center;
border-radius: 9999px;
background: var(--platform-warm-text);
color: var(--platform-button-primary-text);
padding: 0 0.28rem;
font-size: 0.72rem;
line-height: 1;
}
.platform-category-filter-divider {
width: 1px;
height: 1.85rem;
flex: 0 0 auto;
background: var(--platform-line-soft);
}
.platform-category-chip-scroll {
display: flex;
min-width: 0;
flex: 1 1 auto;
gap: 0.55rem;
overflow-x: auto;
padding-right: 0.1rem;
}
/* 横向滚动条按需隐藏:分段页签的 `layout="scroll"` 与标签排都靠它保持外观干净,
滚动能力本身不隐藏(内容仍可横向滚动,只是不画滚动条)。 */
.scrollbar-hide {
scrollbar-width: none;
-ms-overflow-style: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
/* 分段页签的**横滚**子项不得被压到内容宽度以下。中文标签(例如「角色与对象」需要一个
`1.5rem 内边距 + 4 个字`的宽度)在窄容器里一旦被压扁,标签虽然 `nowrap`,文字仍会
画出自己的盒子压到相邻项上——现场表现就是「后几项挤成一团、文字互相重叠」。
`min-width: max-content` 给每个子项一个「内容宽度」下限:放得下就照原样排,放不下
就由容器横向滚动兜底(`layout="scroll"` 的容器有 `overflow-x-auto`),任何情况下都不叠字。
这里**只作用于 scroll 布局**:grid 布局没有溢出容器,轨道是 `minmax(0, 1fr)`,
给子项加 `min-width: max-content` 只会让盒子宽过自己那条轨道、直接画到相邻格上,
正是本规则要防的重叠。grid 侧靠轨道等分 + 宿主的 `truncateLabels` 收口。 */
.platform-segmented-tabs--scroll > button {
min-width: max-content;
}
.platform-category-chip {
display: inline-flex;
min-height: 2.25rem;
flex: 0 0 auto;
align-items: center;
justify-content: center;
border: 1px solid var(--platform-subpanel-border);
border-radius: 0.78rem;
background: var(--platform-chip-idle-fill, rgba(255, 253, 250, 0.72));
color: var(--platform-text-base);
padding: 0 0.92rem;
font-size: 0.88rem;
font-weight: 800;
white-space: nowrap;
}
/* 状态阶梯(三个状态必须一眼分得开):
静止 = 浅底 + 中性描边;悬停 = 中性加描边 + 极淡暖底 + 常规文字(**不能**用品牌色,
否则一颗未选中的 chip 悬停起来就像已选中,等于把「选中」这个强状态用掉了);
按下 = 再压一层;选中 = 实心品牌填充 + 反白文字,是唯一的强状态。 */
.platform-category-chip:not(.platform-category-chip--active):hover {
border-color: var(--platform-surface-hover-border, rgba(204, 117, 76, 0.42));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
color: var(--platform-text-strong);
}
.platform-category-chip:not(.platform-category-chip--active):active {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.28));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
}
.platform-category-chip--active {
border-color: var(--platform-chip-active-border, #7d3719);
background: var(
--platform-chip-active-fill,
linear-gradient(135deg, #b3542f, #8f3f22)
);
color: var(--platform-chip-active-text, #fffaf5);
box-shadow: var(
--platform-chip-active-shadow,
0 6px 14px rgba(150, 71, 39, 0.24)
);
}
/* chip 里的计数(标签命中数量):次要信息,比标签文字轻一档;
选中态跟着标签文字一起变白,不参与不透明度衰减,避免落在 AA 以下。 */
.platform-category-chip__count {
font-size: 0.72rem;
font-weight: 600;
color: var(--platform-text-soft);
}
.platform-category-chip--active .platform-category-chip__count {
color: inherit;
}
/* 分段页签的「实心选中」项:与筛选 chip 共用同一组语义色,
避免两处各写一套「选中长什么样」。 */
.platform-segmented-tabs__item--solid {
border-color: var(--platform-chip-active-border, #7d3719);
background: var(
--platform-chip-active-fill,
linear-gradient(135deg, #b3542f, #8f3f22)
);
color: var(--platform-chip-active-text, #fffaf5);
box-shadow: var(
--platform-chip-active-shadow,
0 6px 14px rgba(150, 71, 39, 0.24)
);
}
.platform-category-sort-button {
display: inline-flex;
width: fit-content;
min-height: 1.75rem;
align-items: center;
gap: 0.2rem;
border: 0;
background: transparent;
color: var(--platform-text-soft);
padding: 0 0.2rem;
font-size: 0.88rem;
font-weight: 800;
}
.platform-category-filter-button:hover,
.platform-category-chip:hover,
.platform-category-sort-button:hover {
transform: translateY(-1px);
filter: brightness(1.03);
}
.platform-category-filter-button:active,
.platform-category-chip:active,
.platform-category-sort-button:active {
transform: translateY(1px);
filter: brightness(0.96);
transition-duration: 80ms;
}
.platform-category-filter-button:focus-visible,
.platform-category-chip:focus-visible,
.platform-category-sort-button:focus-visible {
/* 焦点环用 outline 而不是 box-shadow:选中态自己带 box-shadow(实心 chip 的投影),
用 box-shadow 画环会被状态投影覆盖,选中的 chip 就完全没有焦点提示。outline 不参与
box-shadow 的层叠,也不会撑开布局(offset 2px 落在元素外),选中态自己的投影照旧。 */
outline: 2px solid var(--platform-input-focus-ring);
outline-offset: 2px;
}
.platform-navigable-list-item {
cursor: pointer;
border-radius: 0.9rem;
transition:
transform 160ms ease,
background-color 160ms ease,
box-shadow 160ms ease,
opacity 160ms ease;
}
.platform-navigable-list-item:hover:not(:disabled) {
background: var(--platform-button-ghost-fill);
}
.platform-navigable-list-item:active:not(:disabled) {
transform: translateY(1px);
box-shadow: inset 0 2px 4px rgba(50, 22, 8, 0.1);
transition-duration: 80ms;
}
.platform-navigable-list-item:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.platform-navigable-list-item:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
@media (max-width: 480px) {
.platform-category-filter-row {
border-radius: 1rem;
gap: 0.5rem;
padding: 0.46rem 0.5rem;
}
.platform-category-filter-button {
min-height: 2.05rem;
padding-inline: 0.62rem;
font-size: 0.8rem;
}
.platform-category-chip {
min-height: 2.05rem;
border-radius: 0.68rem;
padding-inline: 0.78rem;
font-size: 0.8rem;
}
}
.genarrative-ui-button:disabled,
.genarrative-ui-icon-button:disabled,
.genarrative-ui-icon-button[aria-disabled='true'],
.genarrative-ui-tabs__item:disabled,
.genarrative-ui-switch:disabled {
cursor: not-allowed;
opacity: 0.52;
}
.genarrative-ui-spinner {
display: inline-block;
width: 1em;
height: 1em;
flex: 0 0 auto;
border: 2px solid currentColor;
border-right-color: transparent;
border-radius: 50%;
animation: genarrative-ui-spin 700ms linear infinite;
}
@keyframes genarrative-ui-spin {
to {
transform: rotate(360deg);
}
}
.genarrative-ui-icon-button {
display: inline-grid;
flex: 0 0 auto;
place-items: center;
border: 1px solid var(--platform-icon-border, rgba(226, 203, 184, 0.72));
border-radius: 0.75rem;
background: var(--platform-icon-fill, rgba(255, 253, 250, 0.86));
color: var(--platform-icon-text, #7b5c49);
cursor: pointer;
transition:
transform 160ms ease,
background-color 160ms ease,
color 160ms ease,
opacity 160ms ease;
}
.genarrative-ui-icon-button--sm {
width: 2rem;
height: 2rem;
font-size: 1.1rem;
}
.genarrative-ui-icon-button--md {
width: 2.5rem;
height: 2.5rem;
font-size: 1.2rem;
}
.genarrative-ui-icon-button--lg {
width: 3rem;
height: 3rem;
font-size: 1.35rem;
}
.genarrative-ui-icon-button--quiet {
border-color: transparent;
background: transparent;
}
.genarrative-ui-icon-button--danger {
border-color: var(--platform-button-danger-border, rgba(185, 75, 58, 0.24));
background: var(--platform-button-danger-fill, #fff0eb);
color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-icon-button--surface-floating {
border-color: rgba(255, 255, 255, 0.8);
background: rgba(255, 255, 255, 0.94);
color: var(--platform-text-strong, #3d1f10);
box-shadow: 0 0.35rem 1rem rgba(50, 22, 8, 0.12);
backdrop-filter: blur(8px);
}
.genarrative-ui-icon-button--surface-dark-mini {
border-color: rgba(255, 255, 255, 0.16);
background: rgba(0, 0, 0, 0.55);
color: #fff;
}
.genarrative-ui-icon-button--surface-dark-mini:not(:disabled):hover {
background: rgba(0, 0, 0, 0.7);
}
.genarrative-ui-visually-hidden {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
clip-path: inset(50%);
white-space: nowrap;
}
.genarrative-ui-text-field {
display: grid;
min-width: 0;
gap: 0.45rem;
color: var(--platform-text-base, #6f5848);
font-size: 0.875rem;
font-weight: 650;
}
.genarrative-ui-text-field__label {
color: var(--platform-text-strong, #3d1f10);
font-weight: 750;
}
.genarrative-ui-text-field__control-wrap {
position: relative;
display: flex;
min-width: 0;
align-items: center;
}
.genarrative-ui-text-field__control {
display: block;
width: 100%;
min-width: 0;
border: 1px solid var(--platform-subpanel-border, rgba(226, 203, 184, 0.82));
border-radius: 0.75rem;
background: var(--platform-input-fill, rgba(255, 253, 250, 0.94));
color: var(--platform-text-strong, #3d1f10);
font: inherit;
font-weight: 500;
line-height: 1.4;
transition:
border-color 160ms ease,
background-color 160ms ease,
box-shadow 160ms ease;
}
.genarrative-ui-text-field__control--sm {
min-height: 2.125rem;
padding: 0.5rem 0.75rem;
font-size: 0.8125rem;
}
.genarrative-ui-text-field__control--md {
min-height: 2.5rem;
padding: 0.625rem 0.875rem;
font-size: 0.875rem;
}
.genarrative-ui-text-field__control--lg {
min-height: 2.875rem;
padding: 0.75rem 1rem;
font-size: 0.9375rem;
}
textarea.genarrative-ui-text-field__control {
min-height: 7rem;
resize: vertical;
}
.genarrative-ui-text-field__control:focus {
border-color: var(--platform-surface-hover-border, rgba(204, 117, 76, 0.52));
background: var(--platform-input-fill-focus, #fff);
}
.genarrative-ui-text-field__control--error {
border-color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-text-field__slot {
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--platform-text-soft, #988476);
}
.genarrative-ui-text-field__control-wrap
> .genarrative-ui-text-field__slot:first-child {
margin-right: -2rem;
z-index: 1;
width: 2rem;
pointer-events: none;
}
.genarrative-ui-text-field__control-wrap
> .genarrative-ui-text-field__slot:last-child {
margin-left: -2rem;
z-index: 1;
width: 2rem;
pointer-events: none;
}
.genarrative-ui-text-field__control-wrap
> .genarrative-ui-text-field__slot:first-child
~ .genarrative-ui-text-field__control {
padding-left: 2.25rem;
}
.genarrative-ui-text-field__hint,
.genarrative-ui-text-field__error {
font-size: 0.75rem;
font-weight: 550;
}
.genarrative-ui-text-field__hint {
color: var(--platform-text-soft, #988476);
}
.genarrative-ui-text-field__error {
color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-subpanel {
border: 1px solid var(--platform-subpanel-border, rgba(226, 203, 184, 0.82));
border-radius: 1rem;
background: var(--platform-subpanel-fill, rgba(255, 254, 252, 0.94));
color: var(--platform-text-base, #6f5848);
}
.genarrative-ui-subpanel--soft {
background: var(--platform-panel-fill-soft, rgba(255, 254, 252, 0.9));
}
.genarrative-ui-subpanel--contrast {
border-color: var(--platform-surface-border, rgba(226, 203, 184, 0.82));
background: var(--platform-panel-fill, #fff);
}
.genarrative-ui-subpanel--padding-sm {
padding: 0.75rem;
}
.genarrative-ui-subpanel--padding-md {
padding: 1rem;
}
.genarrative-ui-subpanel--padding-lg {
padding: 1.25rem;
}
.genarrative-ui-subpanel--padding-none {
padding: 0;
}
.genarrative-ui-subpanel__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
margin-bottom: 0.875rem;
}
.genarrative-ui-subpanel__title {
min-width: 0;
margin: 0;
color: var(--platform-text-strong, #3d1f10);
font-size: 0.9375rem;
font-weight: 800;
}
.genarrative-ui-subpanel__actions {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.genarrative-ui-modal__backdrop {
position: fixed;
z-index: 1000;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
background: var(--platform-overlay-fill, rgba(21, 12, 7, 0.48));
backdrop-filter: blur(10px);
}
.genarrative-ui-modal__panel {
display: flex;
width: min(100%, 38rem);
max-height: min(90vh, 50rem);
flex-direction: column;
overflow: auto;
border: 1px solid var(--platform-modal-border, rgba(255, 255, 255, 0.58));
border-radius: 1.25rem;
background: var(--platform-modal-fill, #fff);
color: var(--platform-text-strong, #3d1f10);
box-shadow: 0 24px 72px rgba(50, 22, 8, 0.24);
}
.genarrative-ui-modal__panel--sm {
width: min(100%, 26rem);
}
.genarrative-ui-modal__panel--lg {
width: min(100%, 54rem);
}
.genarrative-ui-modal__header,
.genarrative-ui-modal__footer {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
padding: 1rem 1.25rem;
}
.genarrative-ui-modal__header {
border-bottom: 1px solid var(--platform-line-soft, rgba(226, 203, 184, 0.72));
}
.genarrative-ui-modal__footer {
align-items: center;
border-top: 1px solid var(--platform-line-soft, rgba(226, 203, 184, 0.72));
}
.genarrative-ui-modal__title {
margin: 0;
color: var(--platform-text-strong, #3d1f10);
font-size: 1.05rem;
font-weight: 850;
}
.genarrative-ui-modal__description {
margin: 0.35rem 0 0;
color: var(--platform-text-soft, #988476);
font-size: 0.8rem;
}
.genarrative-ui-modal__body {
min-height: 0;
padding: 1.25rem;
overflow: auto;
}
/*
* 平台弹窗外壳:共享弹窗组件(网页端 `src/components/common/UnifiedModal`、
* `PlatformMudPointConfirmDialog` 等)产出的宿主类。
*
* 这三条原先只写在网页端整站样式表 `src/index.css`。AGC 是独立宿主,只引入本文件与
* `theme.css`,不引入那张整站样式表,于是弹窗面板拿到 `platform-modal-shell` 却没有任何
* `background` / `border` / `box-shadow` 声明,面板变透明、背后画布直接透出来(AGC
* 「选择替换素材」弹窗即此例)。放在这里,凡是引入本文件的宿主就一起命中;写进任一宿主的
* 业务样式里都会变成下一份平行拷贝。
*
* 依赖 `theme.css` 的 token,由祖先的 `.platform-theme--light` / `.platform-theme--dark`
* 提供:弹窗 portal 到 `document.body` 时主题类必须挂在遮罩上(`UnifiedModal.portalTheme`)。
*/
.platform-modal-shell {
border: 1px solid var(--platform-modal-border);
background: var(--platform-modal-fill);
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.16);
}
.platform-modal-backdrop {
background: var(--platform-overlay-fill);
color: var(--platform-text-strong);
backdrop-filter: blur(12px);
}
.platform-overlay {
background: var(--platform-overlay-fill);
}
/*
* 参考图 / 替换素材选择组件的**非模态浮层**形态(`nonModal`)。
*
* 与上面的 `platform-modal-shell` 同一处理由:一个组件两种外壳,壳样式放在这里,凡是引入本文件
* 的宿主一起命中;写进任一宿主的业务样式就会变成平行拷贝。落差只有外壳——底色 / 边框 / 阴影 /
* 头部 / 滚动区 + 一列动作条,**不铺遮罩、不抢焦点**,宿主画布保持可点(AGC 的「替换素材」用它
* 在画布上点选目标素材)。锚定位置由宿主给(AGC 是画布右上角),这里不写 `position`。
*
* 依赖 `theme.css` 的 token,由最近的主题祖先提供(AGC 的锚点容器自带
* `.platform-theme--light`)。
*/
.image-canvas-editor__project-asset-picker--floating {
display: flex;
width: min(22rem, 34vw);
max-height: min(30rem, 70vh);
flex-direction: column;
overflow: hidden;
border: 1px solid var(--platform-modal-border);
border-radius: 0.75rem;
background: var(--platform-modal-fill);
box-shadow: var(--platform-panel-shadow);
color: var(--platform-text-strong);
backdrop-filter: blur(10px);
}
.image-canvas-editor__project-asset-picker-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
border-bottom: 1px solid var(--platform-line-soft);
padding: 0.68rem 0.78rem;
}
.image-canvas-editor__project-asset-picker-header strong {
font-size: 0.82rem;
font-weight: 850;
}
.image-canvas-editor__project-asset-picker-scroll {
min-height: 0;
flex: 1 1 auto;
overflow-y: auto;
overscroll-behavior: contain;
padding: 0.75rem 0.8rem;
scrollbar-width: thin;
}
.image-canvas-editor__project-asset-picker-actions {
display: flex;
align-items: center;
gap: 0.45rem;
border-top: 1px solid var(--platform-line-soft);
padding: 0.6rem 0.7rem;
}
.genarrative-ui-empty-state {
display: grid;
min-height: 10rem;
place-items: center;
align-content: center;
gap: 0.5rem;
border: 1px dashed var(--platform-subpanel-border, rgba(226, 203, 184, 0.82));
border-radius: 1rem;
padding: 1.5rem;
text-align: center;
color: var(--platform-text-soft, #988476);
}
.genarrative-ui-empty-state__icon {
display: grid;
width: 2.5rem;
height: 2.5rem;
place-items: center;
border-radius: 50%;
background: var(--platform-neutral-bg, rgba(255, 253, 250, 0.7));
color: var(--platform-accent, #c7653d);
}
.genarrative-ui-empty-state h2,
.genarrative-ui-empty-state p {
margin: 0;
}
.genarrative-ui-empty-state h2 {
color: var(--platform-text-strong, #3d1f10);
font-size: 0.95rem;
}
.genarrative-ui-empty-state p {
max-width: 34rem;
font-size: 0.8rem;
}
.genarrative-ui-empty-state__action {
margin-top: 0.35rem;
}
.genarrative-ui-status {
display: flex;
align-items: flex-start;
gap: 0.625rem;
border: 1px solid var(--platform-subpanel-border, rgba(226, 203, 184, 0.82));
border-radius: 0.75rem;
padding: 0.75rem 0.875rem;
color: var(--platform-text-base, #6f5848);
font-size: 0.8125rem;
line-height: 1.45;
}
.genarrative-ui-status__icon {
display: inline-flex;
flex: 0 0 auto;
color: currentColor;
}
.genarrative-ui-status--neutral {
background: var(--platform-neutral-bg, rgba(255, 253, 250, 0.7));
}
.genarrative-ui-status--info {
border-color: var(--platform-cool-border, rgba(199, 117, 76, 0.24));
background: var(--platform-cool-bg, rgba(238, 208, 183, 0.26));
color: var(--platform-cool-text, #b76038);
}
.genarrative-ui-status--success {
border-color: var(--platform-success-border, rgba(73, 144, 96, 0.24));
background: var(--platform-success-bg, rgba(237, 248, 239, 0.92));
color: var(--platform-success-text, #2f7b46);
}
.genarrative-ui-status--warning {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.28));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
color: var(--platform-warm-text, #b6623f);
}
.genarrative-ui-status--error {
border-color: var(--platform-button-danger-border, rgba(185, 75, 58, 0.22));
background: var(--platform-button-danger-fill, #ffede5);
color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-badge {
display: inline-flex;
align-items: center;
gap: 0.3rem;
border: 1px solid var(--platform-neutral-border, rgba(226, 203, 184, 0.44));
border-radius: 999px;
font-weight: 750;
line-height: 1;
white-space: nowrap;
}
.genarrative-ui-badge--sm {
min-height: 1.5rem;
padding: 0.25rem 0.55rem;
font-size: 0.6875rem;
}
.genarrative-ui-badge--md {
min-height: 1.875rem;
padding: 0.35rem 0.7rem;
font-size: 0.8125rem;
}
.genarrative-ui-badge--neutral {
background: var(--platform-neutral-bg, rgba(255, 253, 250, 0.7));
color: var(--platform-neutral-text, #7b6150);
}
.genarrative-ui-badge--accent {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.28));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
color: var(--platform-warm-text, #b6623f);
}
.genarrative-ui-badge--success {
border-color: var(--platform-success-border, rgba(73, 144, 96, 0.24));
background: var(--platform-success-bg, rgba(237, 248, 239, 0.92));
color: var(--platform-success-text, #2f7b46);
}
.genarrative-ui-badge--warning {
border-color: var(--platform-warm-border, rgba(204, 117, 76, 0.28));
background: var(--platform-warm-bg, rgba(234, 204, 179, 0.32));
color: var(--platform-warm-text, #b6623f);
}
.genarrative-ui-badge--danger {
border-color: var(--platform-button-danger-border, rgba(185, 75, 58, 0.22));
background: var(--platform-button-danger-fill, #ffede5);
color: var(--platform-button-danger-text, #a6402f);
}
.genarrative-ui-badge--info {
border-color: var(--platform-cool-border, rgba(199, 117, 76, 0.24));
background: var(--platform-cool-bg, rgba(238, 208, 183, 0.26));
color: var(--platform-cool-text, #b76038);
}
.genarrative-ui-progress {
display: grid;
gap: 0.45rem;
}
.genarrative-ui-progress__track {
position: relative;
height: 0.5rem;
overflow: hidden;
border-radius: 999px;
background: var(--platform-track-fill, rgba(255, 253, 250, 0.9));
}
.genarrative-ui-progress__fill {
display: block;
height: 100%;
border-radius: inherit;
background: var(--platform-button-primary-fill, #c7653d);
transition: width 220ms ease;
}
.genarrative-ui-progress__track--indeterminate .genarrative-ui-progress__fill {
width: 42%;
animation: genarrative-ui-progress 1.2s ease-in-out infinite;
}
@keyframes genarrative-ui-progress {
from {
transform: translateX(-110%);
}
to {
transform: translateX(260%);
}
}
.genarrative-ui-progress__label {
color: var(--platform-text-soft, #988476);
font-size: 0.75rem;
}
.genarrative-ui-tabs {
display: flex;
min-width: 0;
gap: 0.25rem;
overflow-x: auto;
border: 1px solid var(--platform-subpanel-border, rgba(226, 203, 184, 0.82));
border-radius: 0.875rem;
padding: 0.25rem;
background: var(--platform-neutral-bg, rgba(255, 253, 250, 0.7));
}
.genarrative-ui-tabs__item {
min-height: 2.125rem;
flex: 1 0 auto;
border: 0;
border-radius: 0.625rem;
background: transparent;
padding: 0 0.875rem;
color: var(--platform-text-base, #6f5848);
font-size: 0.8125rem;
font-weight: 700;
cursor: pointer;
transition:
transform 160ms ease,
background-color 160ms ease,
color 160ms ease,
opacity 160ms ease;
}
.genarrative-ui-tabs__item--active {
background: var(--platform-panel-fill, #fff);
color: var(--platform-text-strong, #3d1f10);
box-shadow: 0 2px 8px rgba(112, 57, 30, 0.1);
}
.genarrative-ui-switch {
display: inline-flex;
align-items: center;
gap: 0.625rem;
border: 0;
background: transparent;
padding: 0;
color: var(--platform-text-base, #6f5848);
font-size: 0.875rem;
font-weight: 650;
cursor: pointer;
text-align: left;
transition:
transform 160ms ease,
opacity 160ms ease;
}
.genarrative-ui-switch__track {
position: relative;
display: inline-flex;
width: 2.75rem;
height: 1.625rem;
align-items: center;
border-radius: 999px;
background: var(--platform-neutral-border, rgba(226, 203, 184, 0.7));
padding: 0.1875rem;
transition: background-color 160ms ease;
}
.genarrative-ui-switch__thumb {
display: block;
width: 1.25rem;
height: 1.25rem;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 4px rgba(50, 22, 8, 0.2);
transition: transform 160ms ease;
}
.genarrative-ui-switch--checked .genarrative-ui-switch__track {
background: var(
--platform-button-primary-solid,
var(--platform-accent, #c7653d)
);
}
.genarrative-ui-switch--checked .genarrative-ui-switch__thumb {
transform: translateX(1.125rem);
}
.genarrative-ui-divider {
height: 1px;
border: 0;
background: var(--platform-line-soft, rgba(226, 203, 184, 0.72));
}
@media (prefers-reduced-motion: reduce) {
.genarrative-ui-button,
.genarrative-ui-icon-button,
.genarrative-ui-tabs__item,
.genarrative-ui-switch,
.genarrative-ui-progress__fill,
.genarrative-ui-spinner,
.genarrative-ui-skeleton {
transition: none;
animation: none;
}
}
@media (max-width: 480px) {
.genarrative-ui-modal__backdrop {
align-items: flex-end;
padding: 0;
}
.genarrative-ui-modal__panel,
.genarrative-ui-modal__panel--sm,
.genarrative-ui-modal__panel--lg {
width: 100%;
max-height: 92vh;
border-radius: 1.25rem 1.25rem 0 0;
}
}
/* 画布卡片角标:缩放由宿主传入,两个入口保持一致的视觉尺寸。 */
.shared-canvas-card-corners {
position: absolute;
top: 6px;
right: 6px;
z-index: 3;
display: flex;
align-items: center;
gap: 4px;
max-width: calc(100% - 12px);
transform: scale(
var(
--image-canvas-editor-inverse-scale,
var(--genarrative-image-canvas-inverse-scale, 1)
)
);
transform-origin: top right;
}
.shared-canvas-card-kind {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 4px 8px;
border: 1px solid rgb(255 255 255 / 72%);
border-radius: 999px;
background: rgb(199 101 61 / 92%);
color: #fff;
font-size: 11px;
font-weight: 850;
line-height: 1;
}
.shared-canvas-card-kind[role='button'] {
cursor: pointer;
}
.shared-canvas-card-info {
display: grid;
flex: 0 0 22px;
width: 22px;
height: 22px;
place-items: center;
border: 1px solid rgb(255 255 255 / 42%);
border-radius: 50%;
background: rgb(199 101 61 / 92%);
color: #fff;
cursor: pointer;
}
.shared-canvas-card-info:hover,
.shared-canvas-card-kind[role='button']:hover {
background: #b95d3a;
}
.shared-canvas-card-corners [role='button']:focus-visible {
outline: 2px solid #fff;
outline-offset: 2px;
}
.shared-overflow-trigger {
flex: none;
display: inline-flex;
align-items: center;
gap: 5px;
min-height: 30px;
padding: 0 10px;
border: 0;
border-radius: 6px;
background: transparent;
color: inherit;
font-size: 12px;
font-weight: 700;
white-space: nowrap;
cursor: pointer;
}
.shared-overflow-trigger:hover,
.shared-overflow-trigger[aria-expanded='true'] {
background: #f4e7df;
}
.shared-overflow-panel {
position: fixed;
z-index: 1500;
display: flex;
flex-direction: column;
gap: 3px;
width: 200px;
max-width: calc(100vw - 16px);
overflow-y: auto;
overscroll-behavior: contain;
padding: 6px;
border: 1px solid #e7d5c8;
border-radius: 9px;
background: #fff;
color: #4b3026;
box-shadow: 0 10px 28px rgb(52 30 22 / 18%);
}
.shared-overflow-panel > button {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 8px;
flex: 0 0 auto;
width: 100%;
min-height: 34px;
padding: 6px 10px;
border: 0;
border-radius: 5px;
background: transparent;
color: inherit;
font-size: 12px;
text-align: left;
cursor: pointer;
}
.shared-overflow-panel > button:hover,
.shared-overflow-panel > button:focus-visible {
background: #f4e7df;
}
.shared-overflow-panel > button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.shared-overflow-panel
> button.genarrative-image-canvas__chrome-button:not(
.genarrative-image-canvas__chrome-button--with-label
)::after {
content: attr(aria-label);
}