统一界面上的ip形象标识
新增陶泥儿产品 IP 公共图片资产 左上角品牌标识和绑定页品牌块统一展示该形象 更新产品基线、创作主页方案和共享决策记录
This commit is contained in:
@@ -16,6 +16,14 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-23 陶泥儿产品 IP 形象统一为陶罐探出橙色耳朵形象
|
||||
|
||||
- 背景:平台左上角“陶泥儿”品牌旁产品形象曾分散使用创作主页旧小陶偶、运行态 logo 或局部欢迎图,后续提到产品 IP / 产品形象容易产生歧义。
|
||||
- 决策:产品 IP / 产品形象统一定义为 `public/branding/taonier-product-ip.png`,即陶罐中探出的橙色耳朵形象。公共品牌组件 `RpgEntryBrandLogo` 默认展示该图;后续左上角品牌区和产品形象说明默认引用该资产,专题玩法若有独立运行态素材需在对应文档单独说明。
|
||||
- 影响范围:平台左上角品牌区、绑定手机号页品牌块、创作主页工作台 chrome、公共品牌资产常量和产品基线文档。
|
||||
- 验证方式:运行品牌标识、绑定手机号页和平台首页相关前端测试,确认品牌图 `src` 为 `/branding/taonier-product-ip.png`;执行 `npm run check:encoding` 和 `git diff --check`。
|
||||
- 关联文档:`docs/【项目基线】当前产品与工程约束-2026-05-15.md`、`docs/【玩法创作】创作主页与项目入口改版计划-2026-06-18.md`。
|
||||
|
||||
## 2026-06-22 创作主页精选只展示项目内画布生成资源
|
||||
|
||||
- 背景:`/creation` 的 `陶泥儿精选` 曾从账号级素材库读取,并在素材为空时用公开作品图片补充,导致新创作页出现不属于任何当前图片画布项目的素材。
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# Genarrative 项目共享概览
|
||||
|
||||
更新时间:`2026-06-12`
|
||||
更新时间:`2026-06-23`
|
||||
|
||||
## 一句话定位
|
||||
|
||||
Genarrative / 陶泥儿是一个 AI 原生互动内容与小游戏平台,把 AI 创作、作品草稿、公开分发、运行态、用户账号、钱包任务、后台管理和小程序外壳收在同一套工程中。
|
||||
|
||||
产品 IP / 产品形象统一为 `public/branding/taonier-product-ip.png`:陶罐中探出的橙色耳朵形象。后续提到“产品 IP”“产品形象”或左上角品牌旁形象时默认指该资产。
|
||||
|
||||
## 当前主要能力
|
||||
|
||||
- RPG / 自定义世界创作与运行时。
|
||||
|
||||
@@ -149,7 +149,7 @@ Tab:
|
||||
- 桌面端复用现有平台壳层,保留上方栏和左侧导航栏。
|
||||
- 主页整体采用浅色布局,避免外站品牌文案。
|
||||
- 视觉排版参考陶土质感创作工具工作台:首屏标题居中、主按钮与社区按钮使用大号圆角胶囊尺寸,九大创作工具以 3 列大卡片展示,卡片左侧保留大号陶土感图标区域,右侧展示原有标题与描述;桌面平台一级页的顶部栏和左侧导航统一压平成单层工作台 chrome,避免外框套内框;桌面端页面结构必须先分为“左侧完整栏 / 右侧内容区”,左侧完整栏同时包含顶部品牌 Logo 和下方导航页签,右侧内容区再拆为顶部搜索、钱包、账号栏与下方主屏,不能用顶部栏的第一列假装左侧品牌区;左侧栏采用紧凑但保留图标和文字的导航胶囊,顶部搜索栏、泥点入口和账号入口都保持精简宽度,提升推荐、发现、我的、创作主页和项目页的工具感与精致度;只调整样式与布局,不改文案、搜索、登录、导航、项目创建、社区弹层、最近项目、精选素材 Tab 或数据读取逻辑。
|
||||
- 背景、顶部品牌小陶偶、左侧导航、按钮和九大创作工具图标使用 `gpt-image-2` / image2 生成资源,统一保存在 `public/creation-home/`;资源只作为装饰图标或背景纹理接入,不包含图内文字,不替换或隐藏现有 UI 文案和交互。
|
||||
- 背景、左侧导航、按钮和九大创作工具图标使用 `gpt-image-2` / image2 生成资源,统一保存在 `public/creation-home/`;资源只作为装饰图标或背景纹理接入,不包含图内文字,不替换或隐藏现有 UI 文案和交互。顶部品牌旁产品形象统一使用 `public/branding/taonier-product-ip.png`,不再使用创作主页旧小陶偶作为左上角品牌形象。
|
||||
- 社群入口复用现有玩家社区弹层,点击后必须停留在 `/creation`。
|
||||
- 不在 UI 中放规则说明、实现说明或“暂不实装”提示。
|
||||
- 未登录时不渲染最近项目区;需要创建项目时走登录弹窗和登录后重试。
|
||||
|
||||
@@ -20,6 +20,7 @@ Genarrative / 陶泥儿是一个 AI 原生互动内容与小游戏平台。当
|
||||
- 消费单位:泥点。
|
||||
- 公开账号标识:陶泥号。
|
||||
- 创作侧称谓:陶泥儿主。
|
||||
- 产品 IP / 产品形象:统一指 `public/branding/taonier-product-ip.png`,即陶罐中探出的橙色耳朵形象;后续左上角品牌区、产品形象引用和品牌视觉说明默认使用该形象,除非专题玩法明确要求独立运行态素材。
|
||||
|
||||
不要把旧“百梦”等历史命名重新写入新 UI 或新文档。
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
@@ -15,7 +15,7 @@
|
||||
},
|
||||
{
|
||||
"file": "/creation-home/brand-mascot.png",
|
||||
"subject": "陶泥儿品牌小陶偶头像",
|
||||
"subject": "创作主页旧装饰头像,不作为产品 IP 形象",
|
||||
"bytes": 265352
|
||||
},
|
||||
{
|
||||
@@ -114,4 +114,4 @@
|
||||
"bytes": 280555
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ test('绑定手机号表单复用平台输入和字段标题', async () => {
|
||||
expect(screen.getByText('当前登录身份:微信旅人').className).toContain(
|
||||
'platform-subpanel',
|
||||
);
|
||||
expect(
|
||||
document
|
||||
.querySelector('.selection-hero-brand__image')
|
||||
?.getAttribute('src'),
|
||||
).toBe('/branding/taonier-product-ip.png');
|
||||
|
||||
await user.type(phoneInput, '13800000000');
|
||||
await user.type(codeInput, '123456');
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
|
||||
import type { PlatformTheme } from '../../../packages/shared/src/contracts/runtime';
|
||||
import type { AuthCaptchaChallenge, AuthUser } from '../../services/authService';
|
||||
import { BRAND_ASSETS } from '../../uiAssets';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
@@ -67,7 +68,16 @@ export function BindPhoneScreen({
|
||||
<div className="platform-auth-card grid w-full max-w-4xl overflow-hidden rounded-[28px] md:grid-cols-[1.05fr_0.95fr]">
|
||||
<div className="border-b border-[var(--platform-subpanel-border)] bg-[linear-gradient(135deg,rgba(204,117,76,0.18),rgba(240,203,169,0.16))] px-6 py-8 md:border-b-0 md:border-r md:px-10 md:py-12">
|
||||
<div className="selection-hero-brand selection-hero-brand--left">
|
||||
<div className="selection-hero-brand__title">陶泥儿</div>
|
||||
<div className="selection-hero-brand__lockup">
|
||||
<img
|
||||
src={BRAND_ASSETS.taonierProductIp}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
draggable={false}
|
||||
className="selection-hero-brand__image"
|
||||
/>
|
||||
<div className="selection-hero-brand__title">陶泥儿</div>
|
||||
</div>
|
||||
<div className="selection-hero-brand__subtitle">视觉叙事 RPG</div>
|
||||
</div>
|
||||
<p className="mt-8 text-[11px] font-semibold tracking-[0.32em] text-[var(--platform-cool-text)]">
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { RpgEntryBrandLogo } from './RpgEntryBrandLogo';
|
||||
|
||||
test('陶泥儿品牌标识展示统一产品形象', () => {
|
||||
const { container } = render(<RpgEntryBrandLogo />);
|
||||
|
||||
expect(
|
||||
screen.getByRole('img', { name: '陶泥儿 GENARRATIVE' }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
container
|
||||
.querySelector('.platform-brand-logo__image')
|
||||
?.getAttribute('src'),
|
||||
).toBe('/branding/taonier-product-ip.png');
|
||||
});
|
||||
|
||||
test('装饰模式不暴露额外品牌朗读入口', () => {
|
||||
render(<RpgEntryBrandLogo decorative />);
|
||||
|
||||
expect(screen.queryByRole('img')).toBeNull();
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
import { BRAND_ASSETS } from '../../uiAssets';
|
||||
|
||||
export interface RpgEntryBrandLogoProps {
|
||||
className?: string;
|
||||
decorative?: boolean;
|
||||
@@ -18,10 +20,19 @@ export function RpgEntryBrandLogo({
|
||||
aria-hidden={decorative || undefined}
|
||||
aria-label={decorative ? undefined : '陶泥儿 GENARRATIVE'}
|
||||
>
|
||||
<span className="platform-brand-logo__title">
|
||||
陶泥<span className="platform-brand-logo__title-suffix">儿</span>
|
||||
<img
|
||||
src={BRAND_ASSETS.taonierProductIp}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
draggable={false}
|
||||
className="platform-brand-logo__image"
|
||||
/>
|
||||
<span className="platform-brand-logo__copy">
|
||||
<span className="platform-brand-logo__title">
|
||||
陶泥<span className="platform-brand-logo__title-suffix">儿</span>
|
||||
</span>
|
||||
<span className="platform-brand-logo__subtitle">GENARRATIVE</span>
|
||||
</span>
|
||||
<span className="platform-brand-logo__subtitle">GENARRATIVE</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3834,6 +3834,11 @@ test('desktop recommend page reuses compact workbench chrome', () => {
|
||||
expect(leftbar).toBeTruthy();
|
||||
expect(topbar).toBeTruthy();
|
||||
expect(leftbar?.querySelector('.creation-home-brand-lockup')).toBeTruthy();
|
||||
expect(
|
||||
leftbar
|
||||
?.querySelector('.platform-brand-logo__image')
|
||||
?.getAttribute('src'),
|
||||
).toBe('/branding/taonier-product-ip.png');
|
||||
expect(topbar?.querySelector('.creation-home-brand-lockup')).toBeNull();
|
||||
expect(
|
||||
within(leftbar as HTMLElement).getByRole('button', { name: '推荐' }),
|
||||
|
||||
@@ -331,7 +331,6 @@ const CREATION_HOME_NAV_ICON_SRC: Record<PlatformNavTab, string> = {
|
||||
profile: '/creation-home/nav-profile.png',
|
||||
};
|
||||
const CREATION_HOME_TOPBAR_ASSETS = {
|
||||
brandMascot: '/creation-home/brand-mascot.png',
|
||||
search: '/creation-home/topbar-search.png',
|
||||
wallet: '/creation-home/topbar-wallet.png',
|
||||
} as const;
|
||||
@@ -4926,13 +4925,6 @@ export function RpgEntryHomeView({
|
||||
) : null;
|
||||
const desktopBrandLockup: ReactNode = (
|
||||
<span className="creation-home-brand-lockup shrink-0">
|
||||
<img
|
||||
src={CREATION_HOME_TOPBAR_ASSETS.brandMascot}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
draggable={false}
|
||||
className="creation-home-brand-lockup__art"
|
||||
/>
|
||||
<RpgEntryBrandLogo className="shrink-0" decorative />
|
||||
</span>
|
||||
);
|
||||
|
||||
+42
-11
@@ -888,6 +888,20 @@ html[data-mobile-keyboard-open='true'] #root {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.selection-hero-brand__lockup {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.82rem;
|
||||
}
|
||||
|
||||
.selection-hero-brand__image {
|
||||
width: clamp(3rem, 10vw, 4.4rem);
|
||||
height: clamp(3rem, 10vw, 4.4rem);
|
||||
flex: 0 0 auto;
|
||||
object-fit: contain;
|
||||
filter: drop-shadow(0 0.55rem 0.58rem rgba(0, 0, 0, 0.28));
|
||||
}
|
||||
|
||||
.selection-hero-brand__title {
|
||||
font-family: 'Noto Serif SC', 'Georgia', serif !important;
|
||||
font-size: clamp(3rem, 10vw, 4.6rem);
|
||||
@@ -1485,10 +1499,25 @@ html[data-mobile-keyboard-open='true'] #root {
|
||||
.platform-brand-logo {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.platform-brand-logo__image {
|
||||
width: clamp(2.1rem, 6vw, 2.95rem);
|
||||
height: clamp(2.1rem, 6vw, 2.95rem);
|
||||
flex: 0 0 auto;
|
||||
object-fit: contain;
|
||||
filter: drop-shadow(0 0.24rem 0.28rem rgba(112, 62, 32, 0.18));
|
||||
}
|
||||
|
||||
.platform-brand-logo__copy {
|
||||
display: inline-flex;
|
||||
min-width: 0;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.18rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.platform-brand-logo__title,
|
||||
@@ -11700,7 +11729,6 @@ button.image-canvas-editor__reference-chip:disabled {
|
||||
gap: 0.7rem;
|
||||
}
|
||||
|
||||
.creation-home-brand-lockup__art,
|
||||
.creation-home-nav-art,
|
||||
.creation-home-topbar-art {
|
||||
display: none;
|
||||
@@ -11774,21 +11802,15 @@ button.image-canvas-editor__reference-chip:disabled {
|
||||
|
||||
.platform-desktop-shell--workbench .creation-home-brand-lockup {
|
||||
align-self: flex-start;
|
||||
gap: 0.42rem;
|
||||
min-height: 3.28rem;
|
||||
padding-left: 0.28rem;
|
||||
}
|
||||
|
||||
.platform-desktop-shell--workbench .creation-home-brand-lockup__art {
|
||||
display: block;
|
||||
width: 2.58rem;
|
||||
height: 2.58rem;
|
||||
.platform-desktop-shell--workbench .platform-brand-logo__image {
|
||||
width: 2.82rem;
|
||||
height: 2.82rem;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 999px;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
filter: drop-shadow(0 0.36rem 0.34rem rgba(112, 62, 32, 0.18));
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
.platform-desktop-shell--workbench .platform-brand-logo__title {
|
||||
@@ -14204,6 +14226,15 @@ button {
|
||||
gap: 0.6rem;
|
||||
}
|
||||
|
||||
.selection-hero-brand__lockup {
|
||||
gap: 0.58rem;
|
||||
}
|
||||
|
||||
.selection-hero-brand__image {
|
||||
width: 2.85rem;
|
||||
height: 2.85rem;
|
||||
}
|
||||
|
||||
.selection-hero-brand__title {
|
||||
letter-spacing: 0.16em;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export const CUSTOM_WORLD_THEME_ICONS = {
|
||||
|
||||
export const BRAND_ASSETS = {
|
||||
kuranGamesLogo: '/branding/kuran-games-logo.svg',
|
||||
taonierProductIp: '/branding/taonier-product-ip.png',
|
||||
} as const;
|
||||
|
||||
export const UI_CHROME = {
|
||||
|
||||
Reference in New Issue
Block a user