Files
pwa/src/styles/globals.css
T
ar.badieiandCursor c6243caa35 Add read-only Noya admin panel with assignments and UX polish.
Ship admin auth, user overview, assessments, chats, assignment filters/export, security hardening, and a separate desktop admin shell with clearer assessment answers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-21 08:00:24 +03:30

1175 lines
29 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
/* Light is the product default — calm off-white wellness palette */
--background: 210 40% 98%; /* #F8FAFC */
--foreground: 222 47% 11%;
--card: 0 0% 100%;
--card-foreground: 222 47% 11%;
--popover: 0 0% 100%;
--popover-foreground: 222 47% 11%;
--primary: 199 89% 48%; /* logo blue */
--primary-foreground: 0 0% 100%;
--secondary: 210 40% 96%;
--secondary-foreground: 222 47% 11%;
--muted: 210 40% 96%;
--muted-foreground: 215 25% 32%;
--accent: 176 70% 42%; /* logo teal/green */
--accent-foreground: 0 0% 100%;
--destructive: 0 72% 45%;
--destructive-foreground: 0 0% 100%;
--border: 214 32% 90%;
--input: 214 32% 91%;
--ring: 176 70% 42%;
--radius: 1rem;
/* Brand from mainlogo.png — teal-green → azure blue */
--logo-teal: #26d4ca;
--logo-blue: #00a8e8;
--neon-blue: #00a8e8;
--neon-cyan: #26d4ca;
--neon-teal: #26d4ca;
--neon-emerald: #10b981;
--navy-deep: #0f172a;
--navy: #1e293b;
--glass-bg: rgba(255, 255, 255, 0.55);
--glass-bg-strong: rgba(255, 255, 255, 0.72);
--body-text: #334155;
--glow-blue: 0 0 16px rgba(0, 168, 232, 0.35);
--glow-teal: 0 0 16px rgba(38, 212, 202, 0.4);
--glow-border: 0 0 12px rgba(38, 212, 202, 0.25);
--gradient-neon: linear-gradient(135deg, #26d4ca 0%, #14c4db 48%, #00a8e8 100%);
--chat-bg: #f8fafc;
--bubble-user-bg: #00a8e8;
--bubble-ai-bg: #ffffff;
--bubble-ai-border: #e2e8f0;
--theme-transition: background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease,
box-shadow 0.35s ease;
}
.light {
--background: 210 40% 98%;
--foreground: 222 47% 11%;
--card: 0 0% 100%;
--card-foreground: 222 47% 11%;
--popover: 0 0% 100%;
--popover-foreground: 222 47% 11%;
--primary: 199 89% 48%;
--primary-foreground: 0 0% 100%;
--secondary: 210 40% 96%;
--secondary-foreground: 222 47% 11%;
--muted: 210 40% 96%;
--muted-foreground: 215 25% 32%;
--accent: 176 70% 42%;
--accent-foreground: 0 0% 100%;
--destructive: 0 72% 45%;
--destructive-foreground: 0 0% 100%;
--border: 214 32% 90%;
--input: 214 32% 91%;
--ring: 176 70% 42%;
--logo-teal: #26d4ca;
--logo-blue: #00a8e8;
--neon-blue: #00a8e8;
--neon-cyan: #0d9488;
--neon-teal: #0f766e;
--glass-bg: rgba(255, 255, 255, 0.55);
--glass-bg-strong: rgba(255, 255, 255, 0.72);
--body-text: #334155;
--glow-blue: 0 2px 8px rgba(0, 168, 232, 0.18);
--glow-teal: 0 2px 8px rgba(38, 212, 202, 0.16);
--glow-border: none;
--gradient-neon: linear-gradient(135deg, #26d4ca 0%, #14c4db 48%, #00a8e8 100%);
--chat-bg: #f8fafc;
--bubble-user-bg: #00a8e8;
--bubble-ai-bg: #ffffff;
--bubble-ai-border: #e2e8f0;
}
/* Keep .dark as alias of product dark tokens */
.dark {
--background: 222 47% 11%; /* #0F172A */
--foreground: 210 40% 98%;
--card: 217 33% 17%;
--card-foreground: 210 40% 98%;
--popover: 217 33% 14%;
--popover-foreground: 210 40% 98%;
--primary: 193 100% 45%; /* logo blue #00A8E8 */
--primary-foreground: 0 0% 100%;
--secondary: 217 33% 17%;
--secondary-foreground: 210 40% 96%;
--muted: 217 33% 17%;
--muted-foreground: 215 20% 72%;
--accent: 176 70% 49%; /* logo teal #26D4CA */
--accent-foreground: 222 47% 11%;
--destructive: 0 72% 42%;
--destructive-foreground: 0 0% 100%;
--border: 215 25% 27%;
--input: 217 33% 16%;
--ring: 176 70% 49%;
--logo-teal: #26d4ca;
--logo-blue: #00a8e8;
--neon-blue: #00a8e8;
--neon-cyan: #26d4ca;
--neon-teal: #26d4ca;
--glass-bg: rgba(30, 41, 59, 0.52);
--glass-bg-strong: rgba(30, 41, 59, 0.72);
--body-text: #e2e8f0;
--glow-blue: 0 0 18px rgba(0, 168, 232, 0.45), 0 0 36px rgba(0, 168, 232, 0.2);
--glow-teal: 0 0 18px rgba(38, 212, 202, 0.5), 0 0 36px rgba(38, 212, 202, 0.22);
--glow-border: 0 0 14px rgba(38, 212, 202, 0.35), 0 0 28px rgba(0, 168, 232, 0.2);
--gradient-neon: linear-gradient(135deg, #26d4ca 0%, #14c4db 48%, #00a8e8 100%);
--chat-bg: #0f172a;
--bubble-user-bg: #00a8e8;
--bubble-ai-bg: #334155;
--bubble-ai-border: rgba(51, 65, 85, 0.85);
}
}
@font-face {
font-family: 'IRANSansX';
src: url('/fonts/iransansx/IRANSansX-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'IRANSansX';
src: url('/fonts/iransansx/IRANSansX-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'IRANSansX';
src: url('/fonts/iransansx/IRANSansX-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@layer base {
* {
border-color: hsl(var(--border) / 0.45);
}
html {
color-scheme: light;
height: 100%;
width: 100%;
max-width: 100%;
overflow: hidden;
overflow-x: hidden;
overscroll-behavior: none;
}
@supports (height: 100svh) {
html {
height: 100svh;
}
}
html.dark {
color-scheme: dark;
}
html.light {
color-scheme: light;
}
body,
#root {
height: 100%;
width: 100%;
max-width: 100%;
overflow: hidden;
overflow-x: hidden;
overscroll-behavior: none;
}
#root {
display: flex;
flex-direction: column;
min-height: 0;
}
body {
@apply text-foreground antialiased;
font-family: 'IRANSansX', 'Tahoma', system-ui, sans-serif;
background-color: #f1f5f9;
margin: 0;
transition: var(--theme-transition);
}
html.dark body {
background-color: #0f172a;
}
/* Smooth theme toggling across surfaces */
html,
.app-mobile-shell,
.app-header,
.glass-panel,
.glass-panel-strong,
.glass-panel-chat,
.composer-glass,
.bubble-user,
.bubble-ai,
.progress-neon,
.progress-neon-fill {
transition: var(--theme-transition);
}
h1,
h2,
h3,
h4 {
color: hsl(var(--foreground));
letter-spacing: -0.01em;
}
p,
label,
span,
li {
color: inherit;
}
}
@layer components {
/* Desktop stage: soft wellness ambience */
.app-desktop-stage {
@apply relative flex w-full flex-1 justify-center overflow-hidden;
min-height: 0;
background-color: #0f172a;
background-image:
radial-gradient(ellipse 50% 40% at 16% 20%, rgba(14, 165, 233, 0.08), transparent 72%),
radial-gradient(ellipse 45% 36% at 84% 16%, rgba(20, 184, 166, 0.06), transparent 70%),
radial-gradient(ellipse 40% 30% at 72% 82%, rgba(51, 65, 85, 0.35), transparent 72%);
}
.app-desktop-stage::before,
.app-desktop-stage::after {
content: '';
pointer-events: none;
position: absolute;
border-radius: 9999px;
filter: blur(90px);
z-index: 0;
opacity: 0.4;
}
.app-desktop-stage::before {
width: min(40vw, 320px);
height: min(40vw, 320px);
top: -6%;
left: 10%;
background: rgba(14, 165, 233, 0.14);
}
.app-desktop-stage::after {
width: min(36vw, 280px);
height: min(36vw, 280px);
bottom: -4%;
right: 8%;
background: rgba(20, 184, 166, 0.1);
}
/* Front phone surface: calm opaque shell for readable content */
.app-mobile-shell {
@apply relative z-10 flex w-full max-w-[430px] flex-1 flex-col overflow-hidden;
min-height: 0;
max-width: min(100%, 430px);
padding-bottom: env(safe-area-inset-bottom, 0px);
background: #0f172a;
border: 1px solid rgb(51 65 85 / 0.55);
box-shadow:
0 1px 2px rgb(0 0 0 / 0.2),
0 20px 50px rgb(0 0 0 / 0.35);
scrollbar-width: none;
-ms-overflow-style: none;
}
.app-mobile-shell::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
}
@media (max-width: 430px) {
.app-mobile-shell {
border: none;
border-radius: 0;
box-shadow: none;
background: #0f172a;
}
html.light .app-mobile-shell {
background: #f8fafc;
}
}
html.light .app-desktop-stage {
background-color: #e2e8f0;
background-image:
radial-gradient(ellipse 50% 40% at 16% 20%, rgba(14, 165, 233, 0.1), transparent 72%),
radial-gradient(ellipse 45% 36% at 84% 16%, rgba(20, 184, 166, 0.08), transparent 70%),
radial-gradient(ellipse 55% 40% at 50% 108%, rgba(148, 163, 184, 0.2), transparent 65%);
}
html.light .app-desktop-stage::before {
background: rgba(14, 165, 233, 0.16);
opacity: 0.55;
}
html.light .app-desktop-stage::after {
background: rgba(20, 184, 166, 0.14);
opacity: 0.5;
}
html.light .app-mobile-shell {
background: #f8fafc;
border-color: rgb(226 232 240 / 0.95);
box-shadow:
0 1px 2px rgb(15 23 42 / 0.04),
0 20px 40px rgb(15 23 42 / 0.08);
}
.glass-panel {
@apply relative overflow-hidden rounded-2xl;
background: var(--glass-bg);
border: 1px solid rgb(255 255 255 / 0.45);
backdrop-filter: blur(24px) saturate(1.45);
-webkit-backdrop-filter: blur(24px) saturate(1.45);
box-shadow:
0 8px 32px rgb(15 23 42 / 0.08),
inset 0 1px 0 rgb(255 255 255 / 0.55);
}
.glass-panel::before {
content: '';
pointer-events: none;
position: absolute;
inset-inline: 0;
top: 0;
height: 7rem;
background: linear-gradient(
to bottom,
rgb(0 168 232 / 0.14),
rgb(38 212 202 / 0.05),
transparent
);
z-index: 0;
}
/* Legacy alias — prefer .glass-panel (same visual language as login / assessment) */
.glass-panel-chat {
@apply relative h-full min-h-0 overflow-hidden rounded-2xl;
background: var(--glass-bg);
border: 1px solid rgb(255 255 255 / 0.45);
backdrop-filter: blur(24px) saturate(1.45);
-webkit-backdrop-filter: blur(24px) saturate(1.45);
box-shadow:
0 8px 32px rgb(15 23 42 / 0.08),
inset 0 1px 0 rgb(255 255 255 / 0.55);
}
/* Chat composer — glass, aligned with login inputs */
.composer-glass {
@apply relative flex min-h-12 w-full items-end gap-2 rounded-2xl p-1.5;
background: var(--glass-bg);
border: 1px solid rgb(255 255 255 / 0.4);
backdrop-filter: blur(18px) saturate(1.35);
-webkit-backdrop-filter: blur(18px) saturate(1.35);
box-shadow:
0 4px 16px rgb(15 23 42 / 0.06),
inset 0 1px 0 rgb(255 255 255 / 0.45);
}
.composer-glass textarea.input-neon {
min-height: 48px;
padding-block: 0.75rem;
padding-inline: 0.75rem;
line-height: 1.5;
transition: height 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.composer-glass:focus-within {
border-color: rgb(38 212 202 / 0.55);
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.3),
0 4px 16px rgb(15 23 42 / 0.08),
inset 0 1px 0 rgb(255 255 255 / 0.5);
}
html.dark .composer-glass,
html.dark .composer-glass:focus-within {
background: var(--glass-bg);
border-color: rgb(255 255 255 / 0.12);
box-shadow:
0 4px 18px rgb(0 0 0 / 0.28),
inset 0 1px 0 rgb(255 255 255 / 0.08);
}
html.dark .composer-glass:focus-within {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.45),
0 4px 18px rgb(0 0 0 / 0.35),
0 0 14px rgb(38 212 202 / 0.3),
inset 0 1px 0 rgb(255 255 255 / 0.1);
}
html.light .composer-glass,
html.light .composer-glass:focus-within {
background: var(--glass-bg);
border-color: rgb(255 255 255 / 0.55);
}
html.light .composer-glass:focus-within {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.28),
0 4px 16px rgb(15 23 42 / 0.08),
0 0 8px rgb(38 212 202 / 0.14),
inset 0 1px 0 rgb(255 255 255 / 0.6);
}
.composer-glass .input-neon,
html.light .composer-glass .input-neon,
html.dark .composer-glass .input-neon {
background: transparent !important;
border: none !important;
color: hsl(var(--foreground));
box-shadow: none !important;
backdrop-filter: none;
}
.composer-glass .input-neon::placeholder,
html.light .composer-glass .input-neon::placeholder,
html.dark .composer-glass .input-neon::placeholder {
color: hsl(var(--muted-foreground) / 0.85);
}
.composer-glass .input-neon:focus-visible {
box-shadow: none !important;
}
.glass-panel-strong {
@apply relative overflow-hidden rounded-2xl;
background: var(--glass-bg-strong);
border: 1px solid rgb(255 255 255 / 0.4);
backdrop-filter: blur(20px) saturate(1.35);
-webkit-backdrop-filter: blur(20px) saturate(1.35);
box-shadow:
0 8px 28px rgb(15 23 42 / 0.1),
inset 0 1px 0 rgb(255 255 255 / 0.5);
}
.neon-border {
border: 1px solid rgb(226 232 240);
background: var(--glass-bg);
box-shadow: 0 1px 2px rgb(15 23 42 / 0.04);
}
html.light .glass-panel,
html.light .glass-panel-strong {
border-color: rgb(255 255 255 / 0.65);
box-shadow:
0 8px 28px rgb(15 23 42 / 0.07),
inset 0 1px 0 rgb(255 255 255 / 0.7);
}
html.dark .glass-panel,
html.dark .glass-panel-strong {
border-color: rgb(255 255 255 / 0.12);
box-shadow:
0 10px 32px rgb(0 0 0 / 0.35),
inset 0 1px 0 rgb(255 255 255 / 0.1);
}
html.dark .glass-panel::before {
background: linear-gradient(
to bottom,
rgb(0 168 232 / 0.18),
rgb(38 212 202 / 0.06),
transparent
);
}
html.dark .neon-border {
border-color: rgb(51 65 85 / 0.55);
background: var(--glass-bg);
}
.neon-glow {
box-shadow: var(--glow-blue);
}
.neon-glow-teal {
box-shadow: var(--glow-teal);
}
.btn-neon {
@apply relative inline-flex items-center justify-center rounded-xl px-4 py-2.5 text-sm font-semibold text-white transition-all duration-300;
background: var(--gradient-neon);
background-size: 160% 160%;
border: 1px solid transparent;
box-shadow: 0 2px 4px rgb(15 23 42 / 0.08), 0 2px 8px rgb(38 212 202 / 0.2);
}
.btn-neon:hover:not(:disabled) {
filter: brightness(1.05);
border-color: rgb(38 212 202 / 0.55);
box-shadow: 0 3px 8px rgb(15 23 42 / 0.1), 0 4px 12px rgb(38 212 202 / 0.28);
}
html.light .btn-neon {
box-shadow: 0 2px 4px rgb(15 23 42 / 0.06), 0 2px 8px rgb(38 212 202 / 0.16);
}
html.light .btn-neon:hover:not(:disabled) {
filter: brightness(1.04);
border-color: rgb(38 212 202 / 0.5);
box-shadow: 0 3px 8px rgb(15 23 42 / 0.08), 0 4px 12px rgb(38 212 202 / 0.22);
}
/* Dark mode: logo teal/blue neon glow */
html.dark .btn-neon {
box-shadow:
0 2px 6px rgb(0 0 0 / 0.35),
0 0 12px rgb(38 212 202 / 0.45),
0 0 28px rgb(0 168 232 / 0.25);
}
html.dark .btn-neon:hover:not(:disabled) {
filter: brightness(1.08);
border-color: #26d4ca;
box-shadow:
0 3px 10px rgb(0 0 0 / 0.4),
0 0 16px rgb(38 212 202 / 0.6),
0 0 36px rgb(0 168 232 / 0.32);
}
.btn-neon:focus,
.btn-neon:focus-visible {
outline: none;
border-width: 1px;
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.35),
0 3px 8px rgb(15 23 42 / 0.1),
0 0 10px rgb(38 212 202 / 0.22);
}
html.dark .btn-neon:focus,
html.dark .btn-neon:focus-visible {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.5),
0 3px 10px rgb(0 0 0 / 0.4),
0 0 14px rgb(38 212 202 / 0.45),
0 0 24px rgb(0 168 232 / 0.25);
}
.btn-glass {
@apply inline-flex items-center justify-center rounded-xl px-4 py-2.5 text-sm font-medium transition-all duration-300;
background: rgb(255 255 255 / 0.35);
border: 1px solid rgb(255 255 255 / 0.5);
color: var(--body-text);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
box-shadow:
0 2px 8px rgb(15 23 42 / 0.05),
inset 0 1px 0 rgb(255 255 255 / 0.5);
}
.btn-glass:hover:not(:disabled) {
border-color: rgb(38 212 202 / 0.5);
background: rgb(255 255 255 / 0.55);
color: hsl(var(--foreground));
box-shadow: 0 3px 10px rgb(15 23 42 / 0.07);
}
html.dark .btn-glass {
background: rgb(30 41 59 / 0.45);
border-color: rgb(255 255 255 / 0.14);
box-shadow:
0 2px 10px rgb(0 0 0 / 0.25),
inset 0 1px 0 rgb(255 255 255 / 0.08);
}
html.dark .btn-glass:hover:not(:disabled) {
border-color: #26d4ca;
background: rgb(51 65 85 / 0.55);
box-shadow:
0 3px 10px rgb(0 0 0 / 0.35),
0 0 12px rgb(38 212 202 / 0.28),
0 0 22px rgb(0 168 232 / 0.15);
}
html.light .btn-glass {
background: rgb(255 255 255 / 0.4);
border-color: rgb(255 255 255 / 0.6);
}
.btn-glass:focus,
.btn-glass:focus-visible {
outline: none;
border-width: 1px;
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.3),
0 3px 8px rgb(15 23 42 / 0.08),
0 0 8px rgb(38 212 202 / 0.16);
}
html.dark .btn-glass:focus,
html.dark .btn-glass:focus-visible {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.45),
0 3px 10px rgb(0 0 0 / 0.35),
0 0 12px rgb(38 212 202 / 0.35),
0 0 20px rgb(0 168 232 / 0.18);
}
.btn-danger-neon {
@apply inline-flex items-center justify-center rounded-xl px-4 py-2.5 text-sm font-medium transition-all duration-300;
background: rgba(127, 29, 29, 0.35);
border: 1px solid rgba(248, 113, 113, 0.45);
color: #fecaca;
box-shadow: 0 2px 4px rgb(0 0 0 / 0.2);
}
html.light .btn-danger-neon {
background: rgba(254, 226, 226, 0.9);
border-color: rgba(220, 38, 38, 0.35);
color: #b91c1c;
box-shadow: 0 2px 4px rgb(15 23 42 / 0.05);
}
.btn-danger-neon:hover:not(:disabled) {
border-color: rgba(248, 113, 113, 0.75);
box-shadow: 0 3px 8px rgb(0 0 0 / 0.25), 0 0 14px rgba(239, 68, 68, 0.3);
color: #fff;
}
html.light .btn-danger-neon:hover:not(:disabled) {
color: #991b1b;
background: rgba(254, 202, 202, 0.95);
box-shadow: 0 3px 8px rgb(15 23 42 / 0.08);
}
.btn-danger-neon:focus,
.btn-danger-neon:focus-visible {
outline: none;
border-width: 1px;
border-color: #f87171;
box-shadow:
0 0 0 1px rgb(248 113 113 / 0.4),
0 3px 8px rgb(15 23 42 / 0.1);
}
.input-neon {
@apply flex h-11 w-full items-center rounded-xl px-3 py-0 text-sm leading-relaxed transition-all duration-300;
background: rgb(255 255 255 / 0.45);
border: 1px solid rgb(255 255 255 / 0.5);
color: hsl(var(--foreground));
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
box-shadow:
0 2px 8px rgb(15 23 42 / 0.05),
inset 0 1px 0 rgb(255 255 255 / 0.55);
}
.input-neon::placeholder {
color: hsl(var(--muted-foreground) / 0.8);
}
html.dark .input-neon {
background: rgb(15 23 42 / 0.35);
border-color: rgb(255 255 255 / 0.12);
box-shadow:
0 2px 10px rgb(0 0 0 / 0.25),
inset 0 1px 0 rgb(255 255 255 / 0.08);
}
html.light .input-neon {
background: rgb(255 255 255 / 0.5);
border-color: rgb(255 255 255 / 0.65);
color: hsl(var(--foreground));
box-shadow:
0 2px 8px rgb(15 23 42 / 0.05),
inset 0 1px 0 rgb(255 255 255 / 0.7);
}
html.light .input-neon::placeholder {
color: hsl(var(--muted-foreground) / 0.8);
}
.input-neon:focus,
.input-neon:focus-visible {
outline: none;
border-width: 1px;
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.35),
0 3px 8px rgb(15 23 42 / 0.08),
0 0 10px rgb(38 212 202 / 0.2);
}
html.dark .input-neon:focus,
html.dark .input-neon:focus-visible {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.45),
0 3px 10px rgb(0 0 0 / 0.35),
0 0 14px rgb(38 212 202 / 0.4),
0 0 22px rgb(0 168 232 / 0.22);
}
html.light .input-neon:focus,
html.light .input-neon:focus-visible {
border-color: #26d4ca;
box-shadow:
0 0 0 1px rgb(38 212 202 / 0.28),
0 3px 8px rgb(15 23 42 / 0.08),
0 0 8px rgb(38 212 202 / 0.16);
}
.input-neon:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.progress-neon {
@apply relative h-2.5 w-full overflow-hidden rounded-full;
background: rgb(226 232 240 / 0.85);
border: 1px solid rgb(203 213 225 / 0.6);
}
html.light .progress-neon {
background: rgb(241 245 249);
border-color: rgb(226 232 240);
}
html.dark .progress-neon {
background: rgb(30 41 59);
border-color: rgb(51 65 85 / 0.7);
}
.progress-neon-fill {
@apply h-full rounded-full transition-all duration-500 ease-out;
background: linear-gradient(90deg, #26d4ca 0%, #00a8e8 100%);
box-shadow: none;
}
html.dark .progress-neon-fill {
background: linear-gradient(90deg, #26d4ca 0%, #00a8e8 100%);
box-shadow: 0 0 10px rgb(38 212 202 / 0.45);
}
.ambient-glow {
position: relative;
/* Pseudo glows extend past the box; clip X so mobile cannot pan sideways */
overflow-x: clip;
}
@supports not (overflow: clip) {
.ambient-glow {
overflow-x: hidden;
}
}
.ambient-glow::before {
content: '';
pointer-events: none;
position: absolute;
inset: -18% 0 auto;
height: 58%;
background:
radial-gradient(ellipse 70% 60% at 30% 40%, rgba(0, 168, 232, 0.22), transparent 70%),
radial-gradient(ellipse 60% 50% at 78% 30%, rgba(38, 212, 202, 0.18), transparent 68%);
z-index: 0;
}
.ambient-glow::after {
content: '';
pointer-events: none;
position: absolute;
inset: auto 0 -25%;
height: 45%;
background: radial-gradient(ellipse 65% 55% at 60% 70%, rgba(38, 212, 202, 0.12), transparent 72%);
z-index: 0;
}
.nav-dock {
@apply fixed z-50 mx-auto;
left: 0.75rem;
right: 0.75rem;
bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
max-width: 28rem;
margin-inline: auto;
background: rgba(10, 15, 29, 0.72);
border: 1px solid rgba(0, 210, 255, 0.32);
border-radius: 1.25rem;
backdrop-filter: blur(18px);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.45),
var(--glow-border);
}
.nav-item-active-dot {
@apply absolute -top-0.5 h-1.5 w-1.5 rounded-full;
background: var(--neon-cyan);
box-shadow: 0 0 10px var(--neon-cyan), 0 0 18px rgba(0, 210, 255, 0.6);
}
.avatar-glow {
@apply rounded-full;
padding: 2px;
background: var(--gradient-neon);
box-shadow: 0 0 18px rgba(0, 210, 255, 0.4);
}
.bubble-user {
@apply inline-flex w-fit flex-col rounded-2xl py-2.5 text-base leading-7;
/* Cap at 100% — calc(85% * 1.2) was 102% and caused mobile sideways scroll */
max-width: min(100%, calc(85% * 1.2));
padding-inline: calc(0.875rem * 1.2);
background: rgba(255, 255, 255, 0.28);
backdrop-filter: blur(18px) saturate(1.35);
-webkit-backdrop-filter: blur(18px) saturate(1.35);
border: 1px solid rgb(47 127 212 / 0.2);
color: hsl(var(--foreground));
box-shadow:
-4px 5px 10px rgba(47, 127, 212, 0.22),
0 1px 0 rgba(255, 255, 255, 0.35) inset;
}
html.light .bubble-user {
background: rgba(236, 246, 255, 0.55);
color: hsl(var(--foreground));
border-color: rgb(47 127 212 / 0.2);
box-shadow:
-4px 5px 10px rgba(47, 127, 212, 0.18),
0 1px 0 rgba(255, 255, 255, 0.7) inset;
}
html.dark .bubble-user {
background: rgba(40, 90, 150, 0.22);
border-color: rgb(59 158 255 / 0.2);
box-shadow:
-4px 5px 10px rgba(56, 140, 220, 0.22),
0 1px 0 rgba(255, 255, 255, 0.08) inset;
}
html.light .bubble-ai {
color: hsl(var(--foreground));
}
html.light .ai-thinking-bubble {
background: rgba(255, 255, 255, 0.28);
border: none;
box-shadow: 0 8px 24px rgba(47, 127, 212, 0.12);
}
/* Readable brand accents on light surfaces */
html.light .text-neon-cyan {
color: #0f766e;
}
html.light .text-neon-teal {
color: #0d9488;
}
html.light .text-neon-emerald {
color: #059669;
}
.bubble-ai {
@apply rounded-2xl px-1 py-1 text-base leading-7;
background: transparent;
border: none;
box-shadow: none;
color: hsl(var(--foreground));
}
.bubble-ai p,
.bubble-ai li,
.bubble-ai .chat-prose {
text-align: justify;
text-align-last: right;
text-justify: inter-word;
}
/* ChatGPT-like breathing room between blocks */
.bubble-ai > div {
@apply space-y-4;
}
.bubble-ai p + p {
margin-top: 0.35rem;
}
.bubble-ai h3 {
@apply mt-1 mb-0.5;
}
.bubble-user .chat-prose {
width: fit-content;
max-width: 100%;
text-align: right;
white-space: pre-wrap;
}
.bubble-ai strong {
font-weight: 600;
}
/* Digits stay readable under RTL justify without breaking line layout. */
.bubble-ai .chat-num,
.bubble-user .chat-num {
color: hsl(var(--foreground));
font-variant-numeric: tabular-nums;
letter-spacing: 0;
unicode-bidi: isolate;
white-space: nowrap;
}
.bubble-ai ol,
.bubble-ai ul {
list-style-position: outside;
padding-inline-start: 1.35rem;
margin-inline-end: 0.15rem;
}
/* Ordered lists keep source numbers (۱. ۲. ۳.) — no CSS auto-renumber padding */
.bubble-ai ol.list-none {
padding-inline-start: 0;
margin-inline-end: 0;
}
.bubble-ai li::marker {
color: hsl(var(--foreground));
font-weight: 600;
}
/* App chrome — sticky top bar */
.app-header {
position: sticky;
top: 0;
z-index: 50;
flex-shrink: 0;
padding-top: env(safe-area-inset-top, 0px);
background: rgb(248 250 252 / 0.85);
backdrop-filter: blur(16px) saturate(1.2);
-webkit-backdrop-filter: blur(16px) saturate(1.2);
border-bottom: 1px solid rgb(226 232 240 / 0.8);
box-shadow: none;
}
html.dark .app-header {
background: rgb(15 23 42 / 0.88);
border-bottom-color: rgb(51 65 85 / 0.55);
}
/* Scrollable route area below header */
.app-main {
@apply flex min-h-0 flex-1 flex-col overflow-hidden;
}
/* Auth screens without app header still respect the top inset */
.app-auth-screen {
padding-top: env(safe-area-inset-top, 0px);
}
.header-menu-panel {
@apply absolute left-0 z-[70] mt-2 w-56 origin-top-left overflow-hidden rounded-2xl p-1.5;
background: #ffffff;
border: 1px solid rgb(226 232 240);
box-shadow:
0 12px 32px rgb(15 23 42 / 0.18),
0 1px 2px rgb(15 23 42 / 0.06);
}
html.dark .header-menu-panel {
background: #1e293b;
border-color: rgb(51 65 85 / 0.9);
box-shadow:
0 12px 32px rgb(0 0 0 / 0.45),
0 1px 2px rgb(0 0 0 / 0.25);
}
.header-menu-identity {
@apply mb-1 border-b border-slate-200 px-3 py-2.5 dark:border-slate-700/60;
}
.header-menu-item {
@apply flex w-full items-center gap-2.5 rounded-xl px-3 py-2.5 text-sm text-body transition-colors duration-200;
}
.header-menu-item:hover,
.header-menu-item:focus-visible {
background: rgb(241 245 249);
color: hsl(var(--foreground));
outline: none;
}
html.dark .header-menu-item:hover,
html.dark .header-menu-item:focus-visible {
background: rgb(51 65 85 / 0.65);
color: #f8fafc;
}
.header-menu-item-danger {
@apply text-red-600;
}
.header-menu-item-danger:hover,
.header-menu-item-danger:focus-visible {
background: rgb(254 226 226 / 0.7);
color: #b91c1c;
}
html.dark .header-menu-item-danger {
color: #fca5a5;
}
html.dark .header-menu-item-danger:hover,
html.dark .header-menu-item-danger:focus-visible {
background: rgb(127 29 29 / 0.35);
color: #fecaca;
}
.ai-thinking-bubble {
@apply rounded-2xl;
background: rgba(255, 255, 255, 0.16);
border: none;
box-shadow: 0 8px 24px rgba(47, 127, 212, 0.12);
}
html.dark .ai-thinking-bubble {
background: rgba(12, 20, 36, 0.35);
}
.ai-thinking-dots {
display: inline-flex;
align-items: center;
gap: 5px;
}
.ai-thinking-dot {
width: 6px;
height: 6px;
border-radius: 9999px;
background: #26d4ca;
box-shadow: 0 0 8px rgba(38, 212, 202, 0.55);
animation: ai-dot-bounce 1.15s ease-in-out infinite;
}
html.dark .ai-thinking-dot {
box-shadow: 0 0 8px rgba(38, 212, 202, 0.75), 0 0 14px rgba(0, 168, 232, 0.4);
}
.ai-thinking-dot:nth-child(2) {
animation-delay: 0.16s;
background: #00a8e8;
}
.ai-thinking-dot:nth-child(3) {
animation-delay: 0.32s;
background: #26d4ca;
}
.ai-stream-cursor {
display: inline-block;
width: 2px;
height: 1.05em;
margin-inline-start: 3px;
vertical-align: text-bottom;
border-radius: 1px;
background: linear-gradient(180deg, #26d4ca 0%, #00a8e8 100%);
box-shadow: none;
animation: ai-cursor-blink 0.95s step-end infinite;
}
html.dark .ai-stream-cursor {
box-shadow:
0 0 8px rgba(38, 212, 202, 0.75),
0 0 14px rgba(0, 168, 232, 0.45);
}
@keyframes ai-dot-bounce {
0%,
80%,
100% {
transform: translateY(0);
opacity: 0.45;
}
40% {
transform: translateY(-4px);
opacity: 1;
}
}
@keyframes ai-cursor-blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
.page-with-dock {
padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
}
.text-body {
color: var(--body-text);
}
}
/* RTL Support */
[dir='rtl'] {
direction: rtl;
text-align: right;
}
[dir='ltr'] {
direction: ltr;
text-align: left;
}
/* Hide scrollbar tracks everywhere — scroll still works with mouse wheel & touch */
* {
scrollbar-width: none;
-ms-overflow-style: none;
}
*::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
background: transparent;
}
/* Respect reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}