Reduce Dream QA hero copy

#41
by ADJCJH - opened
dream_customs/ui/app.py CHANGED
@@ -686,6 +686,8 @@ def _hero_html(language: str = DEFAULT_LANGUAGE, status: str = "record") -> str:
686
  if index < active_step:
687
  line_classes.append("is-complete")
688
  step_html.append(f'<i class="{" ".join(line_classes)}" aria-hidden="true"></i>')
 
 
689
  return f"""
690
  <header class="dc-hero">
691
  <div class="dc-hero-top">
@@ -699,7 +701,7 @@ def _hero_html(language: str = DEFAULT_LANGUAGE, status: str = "record") -> str:
699
  </div>
700
  <div class="dc-sun-mark" aria-hidden="true"></div>
701
  </div>
702
- <p class="dc-hero-body">{copy['hero_body']}</p>
703
  <div class="dc-hero-ribbon" aria-label="{escape(copy['hero_badge'])}">
704
  <span>{escape(copy['hero_badge'])}</span>
705
  <small>{escape(copy['hero_mobile_note'])}</small>
 
686
  if index < active_step:
687
  line_classes.append("is-complete")
688
  step_html.append(f'<i class="{" ".join(line_classes)}" aria-hidden="true"></i>')
689
+ hero_body = copy.get("hero_body", "").strip()
690
+ hero_body_html = f"<p class=\"dc-hero-body\">{escape(hero_body)}</p>" if hero_body else ""
691
  return f"""
692
  <header class="dc-hero">
693
  <div class="dc-hero-top">
 
701
  </div>
702
  <div class="dc-sun-mark" aria-hidden="true"></div>
703
  </div>
704
+ {hero_body_html}
705
  <div class="dc-hero-ribbon" aria-label="{escape(copy['hero_badge'])}">
706
  <span>{escape(copy['hero_badge'])}</span>
707
  <small>{escape(copy['hero_mobile_note'])}</small>
dream_customs/ui/copy.py CHANGED
@@ -9,11 +9,11 @@ APP_COPY = {
9
  "en": {
10
  "title": "Dream QA",
11
  "hero_kicker": "Dream QA / The Morning Question Desk",
12
- "hero_title": "What did the dream leave you asking?",
13
- "subtitle": "Record the dream, answer one gentle question, and leave with a grounded Morning Ticket.",
14
- "hero_body": "A small-model dream desk for the first few minutes after waking. It gathers concrete details, asks before interpreting, and writes one note for today.",
15
- "hero_badge": "Text + image + voice intake",
16
- "hero_mobile_note": "Made for the half-awake minute",
17
  "brand_subtitle": "Dream Customs",
18
  "steps": ["Record", "One Question", "Today Tip"],
19
  "notice_record": "Write one dream fragment, then use a demo chip if you want the 90-second judge path.",
@@ -80,11 +80,11 @@ APP_COPY = {
80
  "zh": {
81
  "title": "梦境问答台",
82
  "hero_kicker": "梦境问答台 / 清晨问讯室",
83
- "hero_title": "这个梦,醒来后把什么问题留给了你?",
84
- "subtitle": "记录梦境回答一个温和追问,最后拿到一张贴着梦境细节的清晨小票。",
85
- "hero_body": "一个适合刚醒来几分钟使用的小模型问讯台:先捡起具体细节,再问一个好问题,最后只给今天的一张小纸条。",
86
- "hero_badge": "文字 + 图片 + 语音统一入口",
87
- "hero_mobile_note": "适合半醒时的一分钟",
88
  "brand_subtitle": "Dream Customs",
89
  "steps": ["记录", "一个追问", "清晨小票"],
90
  "notice_record": "写一个梦境片段;想走 90 秒演示路径,也可以直接点示例 chip。",
 
9
  "en": {
10
  "title": "Dream QA",
11
  "hero_kicker": "Dream QA / The Morning Question Desk",
12
+ "hero_title": "What did the dream ask?",
13
+ "subtitle": "One fragment. One gentle question. One Morning Ticket.",
14
+ "hero_body": "",
15
+ "hero_badge": "Text · image · voice",
16
+ "hero_mobile_note": "Half-awake friendly",
17
  "brand_subtitle": "Dream Customs",
18
  "steps": ["Record", "One Question", "Today Tip"],
19
  "notice_record": "Write one dream fragment, then use a demo chip if you want the 90-second judge path.",
 
80
  "zh": {
81
  "title": "梦境问答台",
82
  "hero_kicker": "梦境问答台 / 清晨问讯室",
83
+ "hero_title": "这个梦在问什么?",
84
+ "subtitle": "一个片段,一个追问,一张清晨小票。",
85
+ "hero_body": "",
86
+ "hero_badge": "文字 · 图片 · 语音",
87
+ "hero_mobile_note": "适合半醒时使用",
88
  "brand_subtitle": "Dream Customs",
89
  "steps": ["记录", "一个追问", "清晨小票"],
90
  "notice_record": "写一个梦境片段;想走 90 秒演示路径,也可以直接点示例 chip。",
dream_customs/ui/styles.py CHANGED
@@ -3125,23 +3125,37 @@ button.secondary {
3125
  """
3126
 
3127
  CSS += """
3128
- /* Hero proportion fix: make the desk invitation feel calm, not like a giant poster. */
3129
  .dc-hero {
3130
  align-content: center;
 
3131
  background:
3132
  radial-gradient(circle at 74% 37%, rgba(255, 253, 248, 0.54) 0 16%, rgba(255, 253, 248, 0.88) 33%, rgba(255, 253, 248, 0.98) 62%),
3133
  linear-gradient(180deg, rgba(246, 251, 246, 0.96), rgba(255, 250, 240, 0.99)),
3134
  url("https://images.unsplash.com/photo-1494438639946-1ebd1d20bf85?auto=format&fit=crop&w=1600&q=80") 74% 43% / cover !important;
3135
- gap: clamp(12px, 2vw, 18px);
3136
- min-height: clamp(420px, 50vh, 560px);
3137
  overflow: hidden;
3138
- padding: clamp(24px, 4vw, 46px) clamp(18px, 5vw, 70px) clamp(30px, 4.8vw, 54px);
 
3139
  }
3140
 
3141
  .dc-hero-top {
 
3142
  grid-template-columns: 44px minmax(0, 1fr) 44px;
3143
  }
3144
 
 
 
 
 
 
 
 
 
 
 
 
3145
  .dc-menu-mark {
3146
  opacity: 0.78;
3147
  }
@@ -3158,19 +3172,23 @@ CSS += """
3158
  }
3159
 
3160
  .dc-hero h1 {
3161
- font-size: clamp(2.35rem, 5.4vw, 4.85rem) !important;
3162
- line-height: 1.03;
3163
  margin-left: auto;
3164
  margin-right: auto;
3165
- max-width: 1080px;
 
3166
  text-wrap: balance;
3167
  }
3168
 
3169
  .dc-brand-subtitle {
3170
  color: #6f7f8b;
3171
- font-size: clamp(1rem, 1.8vw, 1.34rem);
3172
  line-height: 1.45;
3173
- max-width: 780px;
 
 
 
3174
  text-wrap: balance;
3175
  }
3176
 
@@ -3183,6 +3201,7 @@ CSS += """
3183
  }
3184
 
3185
  .dc-hero-ribbon {
 
3186
  background: rgba(255, 253, 248, 0.62);
3187
  border-color: rgba(95, 143, 104, 0.2);
3188
  border-radius: 999px;
@@ -3214,7 +3233,8 @@ CSS += """
3214
  }
3215
 
3216
  .dc-stepper {
3217
- margin-top: clamp(18px, 3.2vw, 34px);
 
3218
  max-width: 680px;
3219
  }
3220
 
@@ -3235,12 +3255,12 @@ CSS += """
3235
 
3236
  @media (max-width: 900px) {
3237
  .dc-hero {
3238
- min-height: 470px;
3239
  padding: 24px 22px 32px;
3240
  }
3241
 
3242
  .dc-hero h1 {
3243
- font-size: clamp(2.25rem, 10vw, 3.65rem) !important;
3244
  }
3245
 
3246
  .dc-brand-subtitle,
@@ -3251,7 +3271,7 @@ CSS += """
3251
 
3252
  @media (max-width: 640px) {
3253
  .dc-hero {
3254
- min-height: 520px;
3255
  }
3256
 
3257
  .dc-hero-top {
 
3125
  """
3126
 
3127
  CSS += """
3128
+ /* Hero proportion fix: make the desk invitation feel calm, centered, and brief. */
3129
  .dc-hero {
3130
  align-content: center;
3131
+ justify-items: center;
3132
  background:
3133
  radial-gradient(circle at 74% 37%, rgba(255, 253, 248, 0.54) 0 16%, rgba(255, 253, 248, 0.88) 33%, rgba(255, 253, 248, 0.98) 62%),
3134
  linear-gradient(180deg, rgba(246, 251, 246, 0.96), rgba(255, 250, 240, 0.99)),
3135
  url("https://images.unsplash.com/photo-1494438639946-1ebd1d20bf85?auto=format&fit=crop&w=1600&q=80") 74% 43% / cover !important;
3136
+ gap: clamp(10px, 1.8vw, 16px);
3137
+ min-height: clamp(360px, 44vh, 500px);
3138
  overflow: hidden;
3139
+ padding: clamp(22px, 3.6vw, 40px) clamp(18px, 5vw, 70px) clamp(26px, 4.2vw, 48px);
3140
+ text-align: center;
3141
  }
3142
 
3143
  .dc-hero-top {
3144
+ justify-self: stretch;
3145
  grid-template-columns: 44px minmax(0, 1fr) 44px;
3146
  }
3147
 
3148
+ .dc-brand-lockup {
3149
+ justify-content: center;
3150
+ text-align: center;
3151
+ }
3152
+
3153
+ .dc-brand-lockup > div {
3154
+ display: grid;
3155
+ justify-items: center;
3156
+ max-width: min(100%, 900px);
3157
+ }
3158
+
3159
  .dc-menu-mark {
3160
  opacity: 0.78;
3161
  }
 
3172
  }
3173
 
3174
  .dc-hero h1 {
3175
+ font-size: clamp(2.45rem, 5.2vw, 4.35rem) !important;
3176
+ line-height: 1.01;
3177
  margin-left: auto;
3178
  margin-right: auto;
3179
+ max-width: 820px;
3180
+ text-align: center;
3181
  text-wrap: balance;
3182
  }
3183
 
3184
  .dc-brand-subtitle {
3185
  color: #6f7f8b;
3186
+ font-size: clamp(1rem, 1.55vw, 1.2rem);
3187
  line-height: 1.45;
3188
+ margin-left: auto;
3189
+ margin-right: auto;
3190
+ max-width: 560px;
3191
+ text-align: center;
3192
  text-wrap: balance;
3193
  }
3194
 
 
3201
  }
3202
 
3203
  .dc-hero-ribbon {
3204
+ justify-self: center;
3205
  background: rgba(255, 253, 248, 0.62);
3206
  border-color: rgba(95, 143, 104, 0.2);
3207
  border-radius: 999px;
 
3233
  }
3234
 
3235
  .dc-stepper {
3236
+ justify-self: center;
3237
+ margin-top: clamp(14px, 2.4vw, 26px);
3238
  max-width: 680px;
3239
  }
3240
 
 
3255
 
3256
  @media (max-width: 900px) {
3257
  .dc-hero {
3258
+ min-height: 430px;
3259
  padding: 24px 22px 32px;
3260
  }
3261
 
3262
  .dc-hero h1 {
3263
+ font-size: clamp(2.15rem, 9.4vw, 3.45rem) !important;
3264
  }
3265
 
3266
  .dc-brand-subtitle,
 
3271
 
3272
  @media (max-width: 640px) {
3273
  .dc-hero {
3274
+ min-height: 460px;
3275
  }
3276
 
3277
  .dc-hero-top {
tests/test_ui_actions.py CHANGED
@@ -101,10 +101,12 @@ def test_hero_subtitle_explains_app_instead_of_legacy_name():
101
  hero_html = ui_app._hero_html()
102
 
103
  assert "The Morning Question Desk" in hero_html
104
- assert "What did the dream leave you asking?" in hero_html
105
- assert "grounded Morning Ticket" in hero_html
106
  assert "dc-hero-ribbon" in hero_html
107
- assert "Text + image + voice intake" in hero_html
 
 
108
  assert "Dream Customs" not in hero_html
109
 
110
 
 
101
  hero_html = ui_app._hero_html()
102
 
103
  assert "The Morning Question Desk" in hero_html
104
+ assert "What did the dream ask?" in hero_html
105
+ assert "One fragment. One gentle question. One Morning Ticket." in hero_html
106
  assert "dc-hero-ribbon" in hero_html
107
+ assert "Text · image · voice" in hero_html
108
+ assert "A small-model dream desk" not in hero_html
109
+ assert "dc-hero-body" not in hero_html
110
  assert "Dream Customs" not in hero_html
111
 
112