mirror of
https://github.com/stackblitz/bolt.new
synced 2025-02-05 20:46:43 +00:00
Merge pull request #282 from thecodacus/ui-background-rays
feat(styling): added ray effects for the UI as decorative elements
This commit is contained in:
commit
225042bf5f
@ -18,82 +18,6 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.RayContainer {
|
||||
--gradient-opacity: 0.85;
|
||||
--ray-gradient: radial-gradient(rgba(83, 196, 255, var(--gradient-opacity)) 0%, rgba(43, 166, 255, 0) 100%);
|
||||
transition: opacity 0.25s linear;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.LightRayOne {
|
||||
width: 480px;
|
||||
height: 680px;
|
||||
transform: rotate(80deg);
|
||||
top: -540px;
|
||||
left: 250px;
|
||||
filter: blur(110px);
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
background: var(--ray-gradient);
|
||||
}
|
||||
|
||||
.LightRayTwo {
|
||||
width: 110px;
|
||||
height: 400px;
|
||||
transform: rotate(-20deg);
|
||||
top: -280px;
|
||||
left: 350px;
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0.6;
|
||||
filter: blur(60px);
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
background: var(--ray-gradient);
|
||||
}
|
||||
|
||||
.LightRayThree {
|
||||
width: 400px;
|
||||
height: 370px;
|
||||
top: -350px;
|
||||
left: 200px;
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0.6;
|
||||
filter: blur(21px);
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
background: var(--ray-gradient);
|
||||
}
|
||||
|
||||
.LightRayFour {
|
||||
position: absolute;
|
||||
width: 330px;
|
||||
height: 370px;
|
||||
top: -330px;
|
||||
left: 50px;
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0.5;
|
||||
filter: blur(21px);
|
||||
border-radius: 100%;
|
||||
background: var(--ray-gradient);
|
||||
}
|
||||
|
||||
.LightRayFive {
|
||||
position: absolute;
|
||||
width: 110px;
|
||||
height: 400px;
|
||||
transform: rotate(-40deg);
|
||||
top: -280px;
|
||||
left: -10px;
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0.8;
|
||||
filter: blur(60px);
|
||||
border-radius: 100%;
|
||||
background: var(--ray-gradient);
|
||||
}
|
||||
|
||||
.PromptEffectContainer {
|
||||
--prompt-container-offset: 50px;
|
||||
--prompt-line-stroke-width: 1px;
|
||||
|
@ -291,19 +291,9 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
const baseChat = (
|
||||
<div
|
||||
ref={ref}
|
||||
className={classNames(
|
||||
styles.BaseChat,
|
||||
'relative flex flex-col lg:flex-row h-full w-full overflow-hidden bg-bolt-elements-background-depth-1',
|
||||
)}
|
||||
className={classNames(styles.BaseChat, 'relative flex h-full w-full overflow-hidden')}
|
||||
data-chat-visible={showChat}
|
||||
>
|
||||
<div className={classNames(styles.RayContainer)}>
|
||||
<div className={classNames(styles.LightRayOne)}></div>
|
||||
<div className={classNames(styles.LightRayTwo)}></div>
|
||||
<div className={classNames(styles.LightRayThree)}></div>
|
||||
<div className={classNames(styles.LightRayFour)}></div>
|
||||
<div className={classNames(styles.LightRayFive)}></div>
|
||||
</div>
|
||||
<ClientOnly>{() => <Menu />}</ClientOnly>
|
||||
<div ref={scrollRef} className="flex flex-col lg:flex-row overflow-y-auto w-full h-full">
|
||||
<div className={classNames(styles.Chat, 'flex flex-col flex-grow lg:min-w-[var(--chat-min-width)] h-full')}>
|
||||
@ -353,15 +343,15 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="rotate(-45)"
|
||||
>
|
||||
<stop offset="0%" stopColor="#1488fc" stopOpacity="0%"></stop>
|
||||
<stop offset="40%" stopColor="#1488fc" stopOpacity="80%"></stop>
|
||||
<stop offset="50%" stopColor="#1488fc" stopOpacity="80%"></stop>
|
||||
<stop offset="100%" stopColor="#1488fc" stopOpacity="0%"></stop>
|
||||
<stop offset="0%" stopColor="#b44aff" stopOpacity="0%"></stop>
|
||||
<stop offset="40%" stopColor="#b44aff" stopOpacity="80%"></stop>
|
||||
<stop offset="50%" stopColor="#b44aff" stopOpacity="80%"></stop>
|
||||
<stop offset="100%" stopColor="#b44aff" stopOpacity="0%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient id="shine-gradient">
|
||||
<stop offset="0%" stopColor="white" stopOpacity="0%"></stop>
|
||||
<stop offset="40%" stopColor="#8adaff" stopOpacity="80%"></stop>
|
||||
<stop offset="50%" stopColor="#8adaff" stopOpacity="80%"></stop>
|
||||
<stop offset="40%" stopColor="#ffffff" stopOpacity="80%"></stop>
|
||||
<stop offset="50%" stopColor="#ffffff" stopOpacity="80%"></stop>
|
||||
<stop offset="100%" stopColor="white" stopOpacity="0%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
@ -10,13 +10,10 @@ export function Header() {
|
||||
|
||||
return (
|
||||
<header
|
||||
className={classNames(
|
||||
'flex items-center bg-bolt-elements-background-depth-1 p-5 border-b h-[var(--header-height)]',
|
||||
{
|
||||
'border-transparent': !chat.started,
|
||||
'border-bolt-elements-borderColor': chat.started,
|
||||
},
|
||||
)}
|
||||
className={classNames('flex items-center p-5 border-b h-[var(--header-height)]', {
|
||||
'border-transparent': !chat.started,
|
||||
'border-bolt-elements-borderColor': chat.started,
|
||||
})}
|
||||
>
|
||||
<div className="flex items-center gap-2 z-logo text-bolt-elements-textPrimary cursor-pointer">
|
||||
<div className="i-ph:sidebar-simple-duotone text-xl" />
|
||||
|
18
app/components/ui/BackgroundRays/index.tsx
Normal file
18
app/components/ui/BackgroundRays/index.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const BackgroundRays = () => {
|
||||
return (
|
||||
<div className={`${styles.rayContainer} `}>
|
||||
<div className={`${styles.lightRay} ${styles.ray1}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray2}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray3}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray4}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray5}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray6}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray7}`}></div>
|
||||
<div className={`${styles.lightRay} ${styles.ray8}`}></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BackgroundRays;
|
246
app/components/ui/BackgroundRays/styles.module.scss
Normal file
246
app/components/ui/BackgroundRays/styles.module.scss
Normal file
@ -0,0 +1,246 @@
|
||||
.rayContainer {
|
||||
// Theme-specific colors
|
||||
--ray-color-primary: color-mix(in srgb, var(--primary-color), transparent 30%);
|
||||
--ray-color-secondary: color-mix(in srgb, var(--secondary-color), transparent 30%);
|
||||
--ray-color-accent: color-mix(in srgb, var(--accent-color), transparent 30%);
|
||||
|
||||
// Theme-specific gradients
|
||||
--ray-gradient-primary: radial-gradient(var(--ray-color-primary) 0%, transparent 70%);
|
||||
--ray-gradient-secondary: radial-gradient(var(--ray-color-secondary) 0%, transparent 70%);
|
||||
--ray-gradient-accent: radial-gradient(var(--ray-color-accent) 0%, transparent 70%);
|
||||
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 1.5s ease-out;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
// background-color: transparent;
|
||||
|
||||
:global(html[data-theme='dark']) & {
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
:global(html[data-theme='light']) & {
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
}
|
||||
|
||||
.lightRay {
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
|
||||
:global(html[data-theme='dark']) & {
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
:global(html[data-theme='light']) & {
|
||||
mix-blend-mode: multiply;
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.ray1 {
|
||||
width: 600px;
|
||||
height: 800px;
|
||||
background: var(--ray-gradient-primary);
|
||||
transform: rotate(65deg);
|
||||
top: -500px;
|
||||
left: -100px;
|
||||
filter: blur(80px);
|
||||
opacity: 0.6;
|
||||
animation: float1 15s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray2 {
|
||||
width: 400px;
|
||||
height: 600px;
|
||||
background: var(--ray-gradient-secondary);
|
||||
transform: rotate(-30deg);
|
||||
top: -300px;
|
||||
left: 200px;
|
||||
filter: blur(60px);
|
||||
opacity: 0.6;
|
||||
animation: float2 18s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray3 {
|
||||
width: 500px;
|
||||
height: 400px;
|
||||
background: var(--ray-gradient-accent);
|
||||
top: -320px;
|
||||
left: 500px;
|
||||
filter: blur(65px);
|
||||
opacity: 0.5;
|
||||
animation: float3 20s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray4 {
|
||||
width: 400px;
|
||||
height: 450px;
|
||||
background: var(--ray-gradient-secondary);
|
||||
top: -350px;
|
||||
left: 800px;
|
||||
filter: blur(55px);
|
||||
opacity: 0.55;
|
||||
animation: float4 17s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray5 {
|
||||
width: 350px;
|
||||
height: 500px;
|
||||
background: var(--ray-gradient-primary);
|
||||
transform: rotate(-45deg);
|
||||
top: -250px;
|
||||
left: 1000px;
|
||||
filter: blur(45px);
|
||||
opacity: 0.6;
|
||||
animation: float5 16s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray6 {
|
||||
width: 300px;
|
||||
height: 700px;
|
||||
background: var(--ray-gradient-accent);
|
||||
transform: rotate(75deg);
|
||||
top: -400px;
|
||||
left: 600px;
|
||||
filter: blur(75px);
|
||||
opacity: 0.45;
|
||||
animation: float6 19s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray7 {
|
||||
width: 450px;
|
||||
height: 600px;
|
||||
background: var(--ray-gradient-primary);
|
||||
transform: rotate(45deg);
|
||||
top: -450px;
|
||||
left: 350px;
|
||||
filter: blur(65px);
|
||||
opacity: 0.55;
|
||||
animation: float7 21s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.ray8 {
|
||||
width: 380px;
|
||||
height: 550px;
|
||||
background: var(--ray-gradient-secondary);
|
||||
transform: rotate(-60deg);
|
||||
top: -380px;
|
||||
left: 750px;
|
||||
filter: blur(58px);
|
||||
opacity: 0.6;
|
||||
animation: float8 14s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes float1 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(65deg) translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(70deg) translate(30px, 20px);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(60deg) translate(-20px, 40px);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(68deg) translate(-40px, 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float2 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(-30deg) scale(1);
|
||||
}
|
||||
33% {
|
||||
transform: rotate(-25deg) scale(1.1);
|
||||
}
|
||||
66% {
|
||||
transform: rotate(-35deg) scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float3 {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: translate(40px, 20px) rotate(5deg);
|
||||
}
|
||||
75% {
|
||||
transform: translate(-30px, 40px) rotate(-5deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float4 {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.15) rotate(10deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float5 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(-45deg) translate(0, 0);
|
||||
}
|
||||
33% {
|
||||
transform: rotate(-40deg) translate(25px, -20px);
|
||||
}
|
||||
66% {
|
||||
transform: rotate(-50deg) translate(-25px, 20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float6 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(75deg) scale(1);
|
||||
filter: blur(75px);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(85deg) scale(1.1);
|
||||
filter: blur(65px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float7 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(45deg) translate(0, 0);
|
||||
opacity: 0.55;
|
||||
}
|
||||
50% {
|
||||
transform: rotate(40deg) translate(-30px, 30px);
|
||||
opacity: 0.65;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float8 {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(-60deg) scale(1);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(-55deg) scale(1.05);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-65deg) scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import { ClientOnly } from 'remix-utils/client-only';
|
||||
import { BaseChat } from '~/components/chat/BaseChat';
|
||||
import { Chat } from '~/components/chat/Chat.client';
|
||||
import { Header } from '~/components/header/Header';
|
||||
import BackgroundRays from '~/components/ui/BackgroundRays';
|
||||
|
||||
export const meta: MetaFunction = () => {
|
||||
return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];
|
||||
@ -12,7 +13,8 @@ export const loader = () => json({});
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<div className="flex flex-col h-full w-full">
|
||||
<div className="flex flex-col h-full w-full bg-bolt-elements-background-depth-1">
|
||||
<BackgroundRays />
|
||||
<Header />
|
||||
<ClientOnly fallback={<BaseChat />}>{() => <Chat />}</ClientOnly>
|
||||
</div>
|
||||
|
@ -12,3 +12,13 @@ body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:root {
|
||||
--gradient-opacity: 0.8;
|
||||
--primary-color: rgba(158, 117, 240, var(--gradient-opacity));
|
||||
--secondary-color: rgba(138, 43, 226, var(--gradient-opacity));
|
||||
--accent-color: rgba(128, 59, 239, var(--gradient-opacity));
|
||||
// --primary-color: rgba(147, 112, 219, var(--gradient-opacity));
|
||||
// --secondary-color: rgba(138, 43, 226, var(--gradient-opacity));
|
||||
// --accent-color: rgba(180, 170, 220, var(--gradient-opacity));
|
||||
}
|
||||
|
@ -35,17 +35,17 @@ const BASE_COLORS = {
|
||||
950: '#0A0A0A',
|
||||
},
|
||||
accent: {
|
||||
50: '#EEF9FF',
|
||||
100: '#D8F1FF',
|
||||
200: '#BAE7FF',
|
||||
300: '#8ADAFF',
|
||||
400: '#53C4FF',
|
||||
500: '#2BA6FF',
|
||||
600: '#1488FC',
|
||||
700: '#0D6FE8',
|
||||
800: '#1259BB',
|
||||
900: '#154E93',
|
||||
950: '#122F59',
|
||||
50: '#F8F5FF',
|
||||
100: '#F0EBFF',
|
||||
200: '#E1D6FF',
|
||||
300: '#CEBEFF',
|
||||
400: '#B69EFF',
|
||||
500: '#9C7DFF',
|
||||
600: '#8A5FFF',
|
||||
700: '#7645E8',
|
||||
800: '#6234BB',
|
||||
900: '#502D93',
|
||||
950: '#2D1959',
|
||||
},
|
||||
green: {
|
||||
50: '#F0FDF4',
|
||||
|
Loading…
Reference in New Issue
Block a user