evOo-local/apps/web/src/styles.css
cynarAI dc1d28c670
fix(web): make the shell follow the light theme (#107)
The composer, the shell frame and sidebar, the right side panel and the
create-bot modal were hard-coded dark while the text on them follows the
theme, so in the light theme the typed draft, the sidebar rows and the
side panel forms rendered dark on dark.

- Composer: the island uses the card and foreground tokens; attach, stop
  and chips use border and foreground tokens, and send is the default
  primary button. The focus and shadow utilities on the bar are removed:
  .apple-island always overrode them, so they never rendered.
- Shell frame and page background use the background token. The frame's
  radial gradient never rendered under Tailwind v4 and is dropped.
- Sidebar: the panel uses the sidebar tokens on desktop too. The main
  conversation, roster, project and Heute rows share one token-based
  row style; muted text measures 4.4:1 on the light sidebar, so row
  times use a dimmed foreground instead.
- Side panel and create-bot modal use background, popover and overlay
  tokens. Settings helper texts and inactive tabs use the full muted
  color, which stays above 4.5:1 in light.
- Stage vignette, stage pill, ensemble and hero orb, and the transcript
  paths behind the call overlay use tokens.
- E2E: chat-contrast.spec.ts gains a shell test that measures the
  composer draft, sidebar rows, the new bot form and the bot settings
  form in both themes and captures screenshots.


Claude-Session: https://claude.ai/code/session_01SSVQGR4WU92LaddTP19GcQ

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-03 15:27:51 +02:00

363 lines
7.8 KiB
CSS

@import "tailwindcss";
@import "@rakazo/ui-web/styles.css";
@import "@fontsource-variable/inter/index.css";
@import "@fontsource-variable/geist/wght.css";
@source "../../packages/ui-web/src/**/*.{ts,tsx}";
@source "./src/**/*.{ts,tsx}";
html,
body,
#root {
height: 100%;
margin: 0;
background: var(--background);
color: var(--foreground);
font-family:
"Inter Variable", -apple-system, BlinkMacSystemFont, "SF Pro Display", "Geist Variable",
system-ui, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
/* 2026/2027 Apple & Gemini Luxury Glass & Tactile Utilities */
.apple-glass {
backdrop-filter: blur(28px) saturate(190%);
-webkit-backdrop-filter: blur(28px) saturate(190%);
background: rgba(13, 17, 24, 0.78);
border: 1px solid rgba(255, 255, 255, 0.09);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12),
0 20px 40px -15px rgba(0, 0, 0, 0.65);
}
.apple-island {
backdrop-filter: blur(36px) saturate(210%);
-webkit-backdrop-filter: blur(36px) saturate(210%);
background: color-mix(in srgb, var(--card) 88%, transparent);
border: 1px solid color-mix(in srgb, var(--foreground) 13%, transparent);
box-shadow:
0 18px 44px -8px rgba(0, 0, 0, 0.75),
inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
.apple-glass-card {
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
background: color-mix(in srgb, var(--card) 68%, transparent);
border: 1px solid var(--border);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 6px 24px rgba(0, 0, 0, 0.35);
}
.chat-bubble-user {
background: var(--chat-user);
border: 1px solid var(--border);
box-shadow:
0 8px 24px -4px rgba(0, 0, 0, 0.5),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.chat-bubble-bot {
background: color-mix(in srgb, var(--card) 72%, transparent);
border: 1px solid var(--border);
box-shadow:
0 10px 32px -4px rgba(0, 0, 0, 0.35),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
/* Shell layout utilities — token-backed, use instead of one-off pixel classes */
@layer components {
.rk-shell-section-label {
@apply text-ui-label font-bold tracking-wider uppercase text-muted-foreground/80;
}
.rk-shell-icon-btn {
@apply grid size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 transition-colors hover:bg-accent hover:text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring;
}
.rk-shell-meta {
@apply text-ui-body-sm text-muted-foreground;
}
.rk-shell-row-title {
@apply text-ui-body font-medium text-foreground;
}
}
/* Gemini-Grade Accessible Typography (Apple-like with Inter Variable).
Heading, code and quote colors come from the shared @rakazo/chat-ui markdown styles. */
.rk-chat-markdown {
font-size: var(--font-size-reading);
line-height: var(--line-height-reading);
color: var(--foreground);
letter-spacing: -0.011em;
font-weight: 400;
}
.rk-chat-markdown p {
margin: 1.2em 0;
line-height: 1.7;
}
.rk-chat-markdown pre {
border-radius: 16px;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.09),
0 12px 36px rgba(0, 0, 0, 0.55);
padding: 1.25em 1.5em;
font-size: 14.5px;
line-height: 1.65;
font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
.sidebar-roster-row[data-selected="true"],
.sidebar-roster-row:hover {
background-color: var(--accent);
}
.rk-chat-markdown code:not(pre code) {
font-weight: 500;
border-radius: 6px;
padding: 0.15em 0.4em;
font-size: 14.5px;
font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
}
.rk-chat-markdown h1 {
font-size: 1.75em;
font-weight: 700;
line-height: 1.3;
letter-spacing: -0.025em;
margin: 1.6em 0 0.6em;
}
.rk-chat-markdown h2 {
font-size: 1.45em;
font-weight: 600;
line-height: 1.35;
letter-spacing: -0.02em;
margin: 1.4em 0 0.5em;
}
.rk-chat-markdown h3 {
font-size: 1.25em;
font-weight: 600;
line-height: 1.4;
letter-spacing: -0.015em;
margin: 1.2em 0 0.4em;
}
.rk-chat-markdown ul,
.rk-chat-markdown ol {
margin: 1.1em 0;
padding-left: 1.6em;
}
.rk-chat-markdown li {
margin: 0.5em 0;
line-height: 1.7;
}
.rk-chat-markdown strong {
font-weight: 600;
}
.rk-chat-markdown blockquote {
padding-left: 1.2em;
margin: 1.3em 0;
font-style: normal;
border-radius: 0 8px 8px 0;
padding-top: 0.4em;
padding-bottom: 0.4em;
}
:root {
--spring-snappy: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--spring-smooth: cubic-bezier(0.16, 1, 0.3, 1);
--spring-press: cubic-bezier(0.4, 0, 0.2, 1);
}
.tactile-press {
transition:
transform 0.14s var(--spring-smooth),
box-shadow 0.14s ease,
background-color 0.14s ease;
}
.tactile-press:hover {
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.18);
}
.tactile-press:active {
transform: scale(0.965);
transition-duration: 0.06s;
}
/* Horizontal scrollbar hiding for prompt chips */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
.rk-scroll::-webkit-scrollbar {
width: 6px;
}
.rk-scroll {
scrollbar-color: var(--scrollbar) transparent;
scrollbar-width: thin;
}
.rk-scroll::-webkit-scrollbar-track {
background: transparent;
}
.rk-scroll::-webkit-scrollbar-thumb {
background: var(--scrollbar);
border-radius: 3px;
}
.rk-scroll::-webkit-scrollbar-thumb:hover {
background: var(--scrollbar-hover);
}
.app-drag {
-webkit-app-region: drag;
user-select: none;
}
.app-no-drag {
-webkit-app-region: no-drag;
}
@keyframes rkPulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.3;
}
}
@keyframes orbitalSpin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes blurInFade {
0% {
opacity: 0;
filter: blur(8px);
transform: translateY(6px);
}
100% {
opacity: 1;
filter: blur(0px);
transform: translateY(0);
}
}
.animate-blur-in {
animation: blurInFade 0.35s var(--spring-smooth) forwards;
}
/* Audio Waveform Equalizer Bars */
.wave-bar-1 {
animation: waveBarAnim 1.1s ease-in-out infinite alternate;
animation-delay: 0.05s;
}
.wave-bar-2 {
animation: waveBarAnim 0.85s ease-in-out infinite alternate;
animation-delay: 0.15s;
}
.wave-bar-3 {
animation: waveBarAnim 1.25s ease-in-out infinite alternate;
animation-delay: 0.25s;
}
.wave-bar-4 {
animation: waveBarAnim 0.75s ease-in-out infinite alternate;
animation-delay: 0.35s;
}
.wave-bar-5 {
animation: waveBarAnim 1.05s ease-in-out infinite alternate;
animation-delay: 0.1s;
}
.wave-bar-6 {
animation: waveBarAnim 0.95s ease-in-out infinite alternate;
animation-delay: 0.2s;
}
.wave-bar-7 {
animation: waveBarAnim 1.15s ease-in-out infinite alternate;
animation-delay: 0.3s;
}
@keyframes waveBarAnim {
0% {
transform: scaleY(0.25);
}
100% {
transform: scaleY(1);
}
}
/* Text stage bloom */
@keyframes voiceBloomDrift {
0%,
100% {
transform: scale(1) translate(0, 0);
opacity: 0.7;
}
50% {
transform: scale(1.14) translate(2%, -1.5%);
opacity: 0.95;
}
}
@keyframes onboarding-oo-pop {
0% {
transform: scale(0.92);
opacity: 0.75;
}
55% {
transform: scale(1.04);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes voicePrimaryPulse {
0%,
100% {
box-shadow:
0 0 28px rgba(34, 211, 238, 0.22),
inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
50% {
box-shadow:
0 0 36px rgba(34, 211, 238, 0.34),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
}
.voice-bloom-emerald {
animation: voiceBloomDrift 4.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
.voice-bloom-emerald {
animation: none !important;
}
}