Spaces:
Running
Running
/* Import Tailwind base, components, and utilities */ | |
/* @tailwind base; */ | |
/* @tailwind components; */ | |
/* @tailwind utilities; */ | |
/* | |
اگر TailwindCSS را به صورت PostCSS plugin نصب کردهاید، | |
نیازی به ایمپورت مستقیم فایلهای بالا نیست و فقط باید فایل اصلی CSS خود را ایمپورت کنید. | |
اگر از CDN استفاده میکنید، این بخش را نادیده بگیرید و مطمئن شوید CDN در public/index.html شما هست. | |
برای سادگی، فرض میکنیم Tailwind به درستی در پروژه تنظیم شده است. | |
*/ | |
/* CSS variables and base styles from your HTML */ | |
:root { | |
--radius: 0.625rem; /* 10px */ | |
--radius-md: 0.5rem; /* 8px */ | |
--background: oklch(1 0 0); | |
--foreground: oklch(0.145 0 0); | |
--popover: oklch(1 0 0); | |
--popover-foreground: oklch(0.145 0 0); | |
--border: oklch(0.922 0 0); | |
/* Gemini variables (optional, if you want to theme them) */ | |
--Neutral-5: var(--background); | |
--Neutral-30: var(--border); | |
--Blue-500: #3b82f6; /* Example blue */ | |
--Red-500: #ef4444; /* Example red */ | |
} | |
.dark { | |
--background: oklch(0.145 0 0); | |
--foreground: oklch(0.985 0 0); | |
--popover: oklch(0.205 0 0); | |
--popover-foreground: oklch(0.985 0 0); | |
--border: oklch(1 0 0 / 10%); | |
--Neutral-5: var(--background); | |
--Neutral-30: var(--border); | |
--Blue-500: #60a5fa; /* Lighter blue for dark mode */ | |
--Red-500: #f87171; /* Lighter red for dark mode */ | |
} | |
@layer base { | |
* { | |
/* @apply border-border outline-ring/50; */ /* Tailwind directive */ | |
/* For non-Tailwind setup, define border-border if needed */ | |
border-color: var(--border); | |
} | |
body { | |
/* @apply bg-background text-foreground; */ /* Tailwind directive */ | |
background-color: var(--background); | |
color: var(--foreground); | |
overflow-x: hidden; | |
font-family: sans-serif; /* Add a default font */ | |
} | |
} | |
/* Notification Popover Wrapper & Content - Converted from Tailwind classes */ | |
.notification-popover-wrapper { | |
position: fixed; | |
top: 1rem; | |
left: 50%; | |
transform: translateX(-50%); | |
z-index: 100; | |
width: calc(100% - 2rem); | |
max-width: 28rem; | |
display: flex; | |
justify-content: center; | |
pointer-events: none; | |
} | |
.popover-content { | |
width: 100%; | |
border-radius: var(--radius-md, 0.5rem); | |
border-width: 1px; | |
border-color: var(--border); | |
background-color: var(--popover); | |
color: var(--popover-foreground); | |
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); | |
outline: none; | |
transition: opacity 0.3s ease-out, transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55); | |
opacity: 0; | |
transform: translateY(-100%) scale(0.9); | |
pointer-events: none; | |
} | |
.popover-content.open { | |
opacity: 1; | |
transform: translateY(0) scale(1); | |
pointer-events: auto; | |
} | |
.notification-popover-text-content { | |
background-color: #eff6ff; /* bg-blue-50 */ | |
font-size: 0.875rem; | |
line-height: 1.5rem; | |
direction: rtl; | |
padding: 1rem; | |
border-radius: var(--radius-md, 0.5rem); | |
color: oklch(0.145 0 0); | |
} | |
.dark .notification-popover-text-content { | |
background-color: oklch(0.25 0.05 230); | |
color: oklch(0.95 0.01 230); | |
} | |
/* Header controls - Converted from Tailwind classes */ | |
.header-controls { | |
display: flex; | |
padding: 1rem; | |
justify-content: space-between; | |
align-items: center; | |
width: 100%; | |
position: absolute; | |
top: 0; | |
left: 0; | |
z-index: 10; | |
} | |
.header-button { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
padding: 0.5rem; | |
border-radius: var(--radius-lg, 0.625rem); | |
background-color: #e5e7eb; /* bg-gray-200 */ | |
cursor: pointer; | |
transition: background-color 0.2s; | |
border: none; /* Reset button border */ | |
} | |
.header-button:hover { | |
background-color: #d1d5db; /* bg-gray-300 */ | |
} | |
.header-button svg { | |
opacity: 0.7; | |
stroke: #374151; /* gray-700 */ | |
width: 24px; | |
height: 24px; | |
} | |
.dark .header-button { | |
background-color: oklch(0.28 0 0); | |
} | |
.dark .header-button:hover { | |
background-color: oklch(0.35 0 0); | |
} | |
.dark .header-button svg { | |
opacity: 0.8; | |
stroke: oklch(0.85 0 0); | |
} | |
/* Footer controls styles, to be used by ControlTray.tsx */ | |
.footer-controls { | |
width: 100%; | |
display: flex; | |
gap: 1rem; | |
position: absolute; | |
bottom: 0; | |
padding: 2rem 3rem; | |
align-items: center; | |
box-sizing: border-box; /* Add box-sizing */ | |
} | |
.footer-controls.layout-default { | |
justify-content: space-between; | |
} | |
.footer-controls.layout-with-small-logo { | |
justify-content: space-around; | |
} | |
.control-button { | |
height: 80px; | |
width: 80px; | |
border-radius: 9999px; | |
padding: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
border-width: 1px; | |
border-color: var(--border); | |
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06); | |
cursor: pointer; | |
transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; | |
} | |
.control-button:hover { | |
transform: scale(1.05); | |
box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05); | |
} | |
.cam-button-color { background-color: #E0ECFF; } | |
.mic-button-color { background-color: #fecdd3; } | |
.dark .cam-button-color { background-color: #223355; } | |
.dark .mic-button-color { background-color: #5C2129; } | |
/* Styles for the switch camera button (used in ControlTray.tsx) */ | |
.switch-camera-button-container { | |
position: absolute; | |
bottom: calc(100% + 0.65rem); | |
left: 50%; | |
z-index: 5; | |
opacity: 0; | |
transform: translateY(15px) scale(0.7) translateX(-50%); | |
pointer-events: none; | |
transition: opacity 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55), transform 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55); | |
transform-origin: center bottom; | |
} | |
.switch-camera-button-container.visible { | |
opacity: 1; | |
transform: translateY(0) scale(1) translateX(-50%); | |
pointer-events: auto; | |
} | |
.switch-camera-button-content { | |
width: 48px; | |
height: 48px; | |
background-color: var(--background); | |
border: 1px solid var(--border); | |
border-radius: 9999px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
box-shadow: 0 5px 10px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08); | |
cursor: pointer; | |
transform-origin: center; | |
transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; | |
} | |
.switch-camera-button-content:hover { | |
transform: scale(1.12) rotate(-6deg); | |
} | |
.switch-camera-button-content:active { | |
transform: scale(1.03) rotate(0deg); | |
} | |
.switch-camera-button-content svg { | |
width: 22px; | |
height: 22px; | |
stroke: var(--foreground); | |
transition: transform 0.3s ease-in-out; | |
} | |
.switch-camera-button-content:hover svg { | |
transform: rotate(360deg); | |
} | |
/* Styles for the mic button pulse (from original control-tray.scss) */ | |
@property --volume { | |
syntax: "<length>"; | |
inherit: false; | |
initial-value: 0px; | |
} | |
.mic-button-wrapper .control-button { /* Target the control-button specifically for mic */ | |
position: relative; | |
/* background-color: var(--Red-500); */ /* This is already set by .mic-button-color */ | |
z-index: 1; | |
color: black; /* Or var(--foreground) if it fits better */ | |
transition: all 0.2s ease-in; | |
} | |
.mic-button-wrapper .control-button:focus { | |
/* border: 2px solid var(--Neutral-20); Using var(--border) is better */ | |
outline: 2px solid var(--Red-500); /* Keep red outline for mic */ | |
} | |
/* .mic-button-wrapper .control-button:hover { | |
background-color: var(--Red-400); No, keep original hover from .control-button | |
} */ | |
.mic-button-wrapper .control-button.active:before { /* only show pulse when active (mic on) */ | |
position: absolute; | |
z-index: -1; | |
top: calc(var(--volume) * -1); | |
left: calc(var(--volume) * -1); | |
display: block; | |
content: ""; | |
opacity: 0.35; | |
background-color: var(--Red-500); | |
width: calc(100% + var(--volume) * 2); | |
height: calc(100% + var(--volume) * 2); | |
border-radius: calc(var(--radius-md) + var(--volume)); /* Adjust radius with volume */ | |
transition: all 0.02s ease-in-out; | |
} | |
.app-container { | |
width: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
min-height: 90vh; /* md:min-h-screen */ | |
} | |
@media (min-width: 768px) { | |
.app-container { | |
min-height: 100vh; | |
} | |
} | |
.main-content-wrapper { | |
max-width: 48rem; /* max-w-3xl */ | |
width: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
height: 100%; | |
position: relative; | |
} | |
.media-toggle-area { | |
width: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
height: 90vh; /* or 100% of its container if nested differently */ | |
background-color: var(--background); | |
top: 0; | |
left: 0; | |
position: relative; /* Or absolute if it's layered */ | |
} | |
.video-feed { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
object-fit: cover; | |
transform: scaleX(-1); /* Mirror effect */ | |
} | |
.large-logo-container, .small-logo-container { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
.large-logo-container { | |
width: 100%; | |
height: 100%; | |
position: absolute; | |
top: 0; | |
left: 0; | |
} | |
/* Add class for body when modal is open to prevent scrolling */ | |
.body-no-scroll { | |
overflow: hidden; | |
} | |
/* Gemini Original App class, if needed for Altair or SidePanel */ | |
.App { | |
/* display: flex; // This might conflict with new layout */ | |
/* flex-direction: column; // This might conflict */ | |
height: 100vh; | |
width: 100vw; | |
overflow: hidden; /* Prevent main app scroll if not desired */ | |
background-color: var(--background); /* Ensure background consistency */ | |
} | |
.streaming-console { | |
display: flex; | |
flex-grow: 1; | |
overflow: hidden; /* If SidePanel or Altair have their own scroll */ | |
} | |
main { | |
flex-grow: 1; | |
display: flex; | |
flex-direction: column; | |
position: relative; /* For positioning Altair and video */ | |
overflow: hidden; | |
} | |
.main-app-area { | |
flex-grow: 1; | |
position: relative; | |
} | |
/* Ensure Altair is visible if used */ | |
/* .altair-chat { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: 5; // Example, adjust as needed | |
background: rgba(255,255,255,0.8); // Example for visibility | |
} */ |