feat: restore mentor page to final day/night spec

Rebuild the mentor workspace per the approved final design (day.png/night.png):
- mentorView gets a dedicated full-width immersive shell (independent 56px
  top bar with page title slot + theme mode text, hidden module-nav/market
  tape/overview/status bar) scoped to body[data-active-view=mentorView].
- Assistant messages become borderless body text with name/time above; only
  user messages use a blue bubble; keep loading/error/streaming caret states.
- 4 quick topics stay visible with history; composer restored to a framed
  ~94px card with bottom-left shortcut hint and bottom-right send button.
- Directory tools merged into one row (search + filter menu + sort); the
  filter menu still offers all/A/B/C; list selected state is an inset rounded
  fill; contact rows are borderless 75px items.
- Chat header always shows pin/note/profile/clear; pin reuses /api/mentors/
  preferences; theme toggle stays the single #themeToggle.
- Night tokens match the spec including the two distinct blues (#316FEF link,
  #5B8DEF quote/selected icon). Mobile (<768) stacks panels with no horizontal
  overflow; 1024+ follows the desktop spec.
- Update stale test baselines (300px sidebar, 94px composer, hint presence,
  night bubble color, centered disclaimer) and regenerate the architecture
  inventory.

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
MS-01-Codex
2026-08-18 11:54:57 +08:00
co-authored by multica-agent
parent d95bcb523a
commit d239519299
12 changed files with 1118 additions and 465 deletions
+12 -7
View File
@@ -280,13 +280,18 @@ class FrontendContractTests(unittest.TestCase):
self.assertNotIn('context.fillStyle = "#6c7983";', chart)
def test_dark_mentor_tokens_and_sentiment_bottom_clearance_are_defined(self):
self.assertIn(":root[data-theme=\"dark\"] #mentorView {", self.mentor_styles)
self.assertIn("--mentor-ink: var(--text-primary);", self.mentor_styles)
self.assertIn("--mentor-sub: var(--text-secondary);", self.mentor_styles)
self.assertIn(":root[data-theme=\"dark\"] #mentorView .mentor-message {", self.mentor_styles)
self.assertIn("border-color: var(--line-soft);", self.mentor_styles)
self.assertIn("background: var(--surface-subtle);", self.mentor_styles)
self.assertIn("box-shadow: none;", self.mentor_styles)
self.assertIn(":root[data-theme=\"dark\"] #mentorView.workspace-view {", self.mentor_styles)
self.assertIn("--qp-bg-chat: #232529;", self.mentor_styles)
self.assertIn("--qp-bg-bubble-self: #35598C;", self.mentor_styles)
self.assertIn("--qp-bg-selected: #2B3B58;", self.mentor_styles)
self.assertIn("--qp-link: #316FEF;", self.mentor_styles)
self.assertIn("--qp-accent-soft: #5B8DEF;", self.mentor_styles)
self.assertIn("--mentor-directory-width: 300px;", self.tokens)
self.assertIn("--mentor-composer-min-height: 94px;", self.tokens)
self.assertIn("#mentorView .mentor-message.user .mentor-message-content {", self.mentor_styles)
self.assertIn("background: var(--qp-bg-bubble-self);", self.mentor_styles)
self.assertIn("#mentorView .mentor-quick-prompts button {", self.mentor_styles)
self.assertIn("#mentorView .mentor-composer-hint {", self.mentor_styles)
self.assertIn("#sentimentCycleView .sentiment-history-frame {", self.sentiment_styles)
self.assertIn("margin-bottom: var(--card-gap);", self.sentiment_styles)
self.assertIn("padding-bottom: var(--card-gap);", self.sentiment_styles)