Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/ui-behavior.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ Generated-image items show the app-server-saved image as a bounded thumbnail.
Selecting it opens the shared non-modal image viewer; encoded image data is
never displayed as generic activity text.

User messages use the canonical soft-violet identity surface. Final Codex
messages use the canonical soft-blue identity surface, while interim Codex
User messages use the canonical soft-blue identity surface. Final Codex
messages use the canonical soft-violet identity surface, while interim Codex
updates remain neutral and identify their phase in the header. Process cards
also remain neutral so they support rather than dominate the primary exchange.
Status text alone uses canonical semantic state colors.
Expand Down
24 changes: 14 additions & 10 deletions src/codex/middle/ConversationCards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,8 +981,10 @@ class ConversationCard::Impl final {
const bool waiting = prompt->state == PromptState::Queued ||
prompt->state == PromptState::InFlight;
const bool failed = prompt->state == PromptState::Failed;
const QString foreground = failed ? QStringLiteral("#982f3d")
: QStringLiteral("#53389e");
const QString foreground = waiting || transitioning
? QStringLiteral("#536b8f")
: failed ? QStringLiteral("#982f3d")
: QStringLiteral("#1d2633");
const QString style =
QStringLiteral("background:transparent;color:%1;").arg(foreground);
bool changed = false;
Expand Down Expand Up @@ -1089,11 +1091,13 @@ void ConversationCard::paintEvent(QPaintEvent *event) {
const bool transitioning = acceptedTransitionActive(*prompt, now);
const bool failed = prompt->state == PromptState::Failed;
const QColor background = waiting || transitioning
? QColor(QStringLiteral("#eee8fb"))
? QColor(QStringLiteral("#dbe7f8"))
: failed ? QColor(QStringLiteral("#fff0f2"))
: QColor(QStringLiteral("#f4f0ff"));
const QColor border = failed ? QColor(QStringLiteral("#efb8c0"))
: QColor(QStringLiteral("#d4c5f2"));
: QColor(QStringLiteral("#eaf2ff"));
const QColor border = waiting || transitioning
? QColor(QStringLiteral("#9eb9df"))
: failed ? QColor(QStringLiteral("#efb8c0"))
: QColor(QStringLiteral("#bfd3f9"));
painter.setBrush(background);
painter.setPen(QPen(border, 1.0));
painter.drawRoundedRect(bounds, 8.0, 8.0);
Expand All @@ -1113,9 +1117,9 @@ void ConversationCard::paintEvent(QPaintEvent *event) {
const qreal center = bounds.left() + position * bounds.width();
const qreal radius = std::max(28.0, bounds.width() * 0.24);
QLinearGradient sweep(center - radius, 0.0, center + radius, 0.0);
sweep.setColorAt(0.0, QColor(105, 65, 198, 0));
sweep.setColorAt(0.5, QColor(155, 128, 214, 105));
sweep.setColorAt(1.0, QColor(105, 65, 198, 0));
sweep.setColorAt(0.0, QColor(47, 111, 235, 0));
sweep.setColorAt(0.5, QColor(117, 160, 239, 105));
sweep.setColorAt(1.0, QColor(47, 111, 235, 0));
QPainterPath clip;
clip.addRoundedRect(bounds, 8.0, 8.0);
painter.save();
Expand All @@ -1124,7 +1128,7 @@ void ConversationCard::paintEvent(QPaintEvent *event) {
painter.restore();

painter.setBrush(Qt::NoBrush);
painter.setPen(QPen(QColor(QStringLiteral("#b49bdf")), 1.5));
painter.setPen(QPen(QColor(QStringLiteral("#79a0d7")), 1.5));
painter.drawRoundedRect(bounds, 8.0, 8.0);
}

Expand Down
8 changes: 4 additions & 4 deletions src/codex/ui/UiStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,10 @@ QString applicationStyleSheet() {
QFrame[kind="panel"] { background: #ffffff; }
QFrame[kind="raised"] { background: #ffffff; border: 1px solid #d7dee8; border-radius: 10px; }
QFrame[kind="raised"][tone="warning"] { background: #fff6df; border-color: #e5c77d; }
QFrame[messageRole="user"] { background: #f4f0ff; border: 1px solid #d4c5f2; border-radius: 8px; }
QFrame[messageRole="user"] QLabel[kind="title"] { color: #53389e; }
QFrame[messageRole="agent"][messagePhase="final"] { background: #eaf2ff; border: 1px solid #bfd3f9; border-radius: 8px; }
QFrame[messageRole="agent"][messagePhase="final"] QLabel[kind="title"] { color: #285fca; }
QFrame[messageRole="user"] { background: #eaf2ff; border: 1px solid #bfd3f9; border-radius: 8px; }
QFrame[messageRole="user"] QLabel[kind="title"] { color: #285fca; }
QFrame[messageRole="agent"][messagePhase="final"] { background: #f4f0ff; border: 1px solid #d4c5f2; border-radius: 8px; }
QFrame[messageRole="agent"][messagePhase="final"] QLabel[kind="title"] { color: #53389e; }
QFrame[messageRole="agent"][messagePhase="update"] { background: #ffffff; border: 1px solid #d7dee8; border-radius: 8px; }
QFrame[kind="summary"] { background: #f8fafc; border: 1px solid #d7dee8; border-radius: 7px; }
QFrame[kind="standardDivider"] { background: #d7dee8; border: none; }
Expand Down
20 changes: 10 additions & 10 deletions tests/codex/ConversationCardsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,15 @@ bool testMessageIdentityPalette() {
};
const bool result = expect(
titleColor(user) ==
QColor(QString::fromLatin1(codexui::UiStyle::purpleText)) &&
surfaceColor(user) ==
QColor(QString::fromLatin1(codexui::UiStyle::purpleSurface)) &&
QColor(QString::fromLatin1(codexui::UiStyle::blueHover)) &&
surfaceColor(user) == QColor(QStringLiteral("#eaf2ff")) &&
surfaceColor(update) ==
QColor(QString::fromLatin1(codexui::UiStyle::panel)) &&
titleColor(final) ==
QColor(QString::fromLatin1(codexui::UiStyle::blueHover)) &&
surfaceColor(final) == QColor(QStringLiteral("#eaf2ff")),
"You is violet, interim Codex is neutral, and final Codex is blue");
QColor(QString::fromLatin1(codexui::UiStyle::purpleText)) &&
surfaceColor(final) ==
QColor(QString::fromLatin1(codexui::UiStyle::purpleSurface)),
"You is blue, interim Codex is neutral, and final Codex is violet");
qApp->setStyleSheet(originalStyleSheet);
return result;
}
Expand Down Expand Up @@ -1560,13 +1560,13 @@ bool testPendingPromptAnimation() {
const QImage second = card.grab().toImage();
bool result =
expect(first != second,
"an unacknowledged prompt visibly animates its violet sweep");
"an unacknowledged prompt visibly animates its blue sweep");
result &= expect(
first.pixelColor(10, first.height() - 10).blue() >
first.pixelColor(10, first.height() - 10).green() &&
first.pixelColor(10, first.height() - 10).red() >
first.pixelColor(10, first.height() - 10).red() &&
first.pixelColor(10, first.height() - 10).blue() >
first.pixelColor(10, first.height() - 10).green(),
"the temporary You card stays in the violet identity family");
"the temporary You card stays in the blue identity family");

auto &accepted = std::get<LocalPromptData>(pending.payload);
accepted.state = PromptState::Accepted;
Expand Down
6 changes: 3 additions & 3 deletions ui-review/UX-DESIGN-DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ This document records the implemented CodexUI visual and interaction contract.
white-text contrast.
- Hover, focus, selection, disabled, warning, error, pending, and active states
remain visually distinct.
- User messages use the violet identity family. Final Codex narrative uses the
canonical blue identity family; interim Codex updates remain neutral and are
identified by their phase label. Commands, tool activity, files, and
- User messages use the blue identity family. Final Codex narrative uses the
more prominent violet identity family; interim Codex updates remain neutral
and are identified by their phase label. Commands, tool activity, files, and
collaboration activity also use neutral raised cards.
- Scrollbars use one compact application style across conversation, nested
output, State, Protocol, and Inspector surfaces.
Expand Down
10 changes: 5 additions & 5 deletions web/src/styles.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading