diff --git a/package-lock.json b/package-lock.json index 526bcaf..1f2a7ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,10 +22,12 @@ "react-scripts": "5.0.1", "styled-components": "^6.1.11", "three": "^0.165.0", + "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, "devDependencies": { "@types/styled-components": "^5.1.34", + "@types/three": "^0.165.0", "typescript": "^4.9.5" } }, @@ -3989,6 +3991,13 @@ "node": ">=10.13.0" } }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.2", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.2.tgz", + "integrity": "sha512-kMCNaZCJugWI86xiEHaY338CU5JpD0B97p1j1IKNn/Zto8PgACjQx0UxbHjmOcLl/dDOBnItwD07KmCs75pxtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -4563,6 +4572,13 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/styled-components": { "version": "5.1.34", "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", @@ -4588,11 +4604,32 @@ "@types/jest": "*" } }, + "node_modules/@types/three": { + "version": "0.165.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.165.0.tgz", + "integrity": "sha512-AJK8JZAFNBF0kBXiAIl5pggYlzAGGA8geVYQXAcPCEDRbyA+oEjkpUBcJJrtNz6IiALwzGexFJGZG2yV3WsYBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tweenjs/tween.js": "~23.1.1", + "@types/stats.js": "*", + "@types/webxr": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, + "node_modules/@types/webxr": { + "version": "0.5.18", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.18.tgz", + "integrity": "sha512-EM8P5wtYMPUlFbDgKfNoPc5PyhgZvwXz0Wf9gYBfJOpTI8AtPzoLJlvw/D9TmIW/LPLTmwMxWI0axBs3hjLSLg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -8455,6 +8492,13 @@ "bser": "2.1.1" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -12672,6 +12716,13 @@ "node": ">= 8" } }, + "node_modules/meshoptimizer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", + "dev": true, + "license": "MIT" + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", diff --git a/package.json b/package.json index db86eb5..ce89b51 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "react-scripts": "5.0.1", "styled-components": "^6.1.11", "three": "^0.165.0", + "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, "scripts": { @@ -45,6 +46,7 @@ }, "devDependencies": { "@types/styled-components": "^5.1.34", + "@types/three": "^0.165.0", "typescript": "^4.9.5" } } diff --git a/src/App.tsx b/src/App.tsx index e113e98..42b3167 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,13 +2,22 @@ import React from "react"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import MainPage from "./pages/MainPage"; import ThemeRecs from "./pages/ThemeRecs"; +import ThemeRecsQuestions from "./pages/ThemeRecsQuestions"; +import ThemeRecsResult from "./pages/ThemeRecsResult"; +import Navbar from "./components/Navbar"; const App: React.FC = () => { return ( + - - + } /> + } /> + } + /> + } /> ); diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index aaa2c8c..7438a57 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Container } from "../styles/NavbarStyled"; +import { Container, NavLink } from "../styles/NavbarStyled"; import logo from "../image/bangpro_logo.png"; import { BsChatSquareHeartFill } from "react-icons/bs"; import { BsCollectionFill } from "react-icons/bs"; @@ -11,25 +11,34 @@ const Navbar = () => {
logo
+
-
-
- + +
+
+ +
+

테마 추천

-

테마 추천

-
-
-
- + + + +
+
+ +
+

테마 정보

-

테마 정보

-
-
-
- + + + +
+
+ +
+

마이페이지

-

마이페이지

-
+
); diff --git a/src/components/RoomTheme.tsx b/src/components/RoomTheme.tsx new file mode 100644 index 0000000..a34585b --- /dev/null +++ b/src/components/RoomTheme.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { Theme } from "../styles/RoomThemeStyled"; + +const RoomTheme = () => { + return ( + +
+

방탈출 테마 이름

+
+
+

매장 정보

+
+
+
+

#난이도

+

#장르

+
+
+

예약 사이트

+
+
+
+ ); +}; + +export default RoomTheme; diff --git a/src/index.css b/src/index.css index 95b2997..d8a4846 100644 --- a/src/index.css +++ b/src/index.css @@ -12,3 +12,7 @@ code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; } + +p { + margin: 0; +} diff --git a/src/index.tsx b/src/index.tsx index dac7f10..1264558 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,7 +3,6 @@ import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; -import Navbar from "./components/Navbar"; const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement @@ -12,7 +11,6 @@ const root = ReactDOM.createRoot( root.render( // strictMode에서는 두번 렌더링 될 수 있으나, 프로덕션빌드 모드에서는 그렇지 않을것 - ); diff --git a/src/pages/Cube.tsx b/src/pages/Cube.tsx new file mode 100644 index 0000000..c341d30 --- /dev/null +++ b/src/pages/Cube.tsx @@ -0,0 +1,142 @@ +import React, { useEffect, useRef, useState } from "react"; +import * as THREE from "three"; + +const Cube = () => { + const mountRef = useRef(null); + const [mouseX, setMouseX] = useState(0); + const [mouseY, setMouseY] = useState(0); + const [isDragging, setIsDragging] = useState(false); + const [previousMouseX, setPreviousMouseX] = useState(0); + const [previousMouseY, setPreviousMouseY] = useState(0); + const [initialRotation, setInitialRotation] = useState( + null + ); + const [initialZoom, setInitialZoom] = useState(5); // 초기 줌 값을 상태로 관리 + + useEffect(() => { + const mount = mountRef.current; + + // Scene, Camera, Renderer 생성 + const scene = new THREE.Scene(); + scene.background = null; // 배경을 투명하게 설정 + + const camera = new THREE.PerspectiveCamera( + 70, + mount!.clientWidth / mount!.clientHeight, + 0.1, + 1000 + ); + const renderer = new THREE.WebGLRenderer({ alpha: true }); // alpha 속성을 true로 설정 + renderer.setSize(mount!.clientWidth, mount!.clientHeight); + mount!.appendChild(renderer.domElement); + + // 조명 + const directionLight = new THREE.DirectionalLight(0xffffff, 1.5); + directionLight.position.set(-0.7, 1, 5); + scene.add(directionLight); + + // 큐브 생성 (색상 변경) + const geometry = new THREE.BoxGeometry(2, 2, 2); + const material = new THREE.MeshPhysicalMaterial({ + color: 0x03ff8d, + metalness: 1, + roughness: 0.5, + transparent: true, + opacity: 0.9, + reflectivity: 0.9, + }); + const cube = new THREE.Mesh(geometry, material); + scene.add(cube); + + camera.position.z = initialZoom; // 초기 줌 값 설정 + + // 마우스 이벤트 리스너 + const onMouseDown = (event: MouseEvent) => { + setIsDragging(true); + setPreviousMouseX(event.clientX); + setPreviousMouseY(event.clientY); + setInitialRotation(cube.rotation.clone()); // 클릭 시점의 회전 상태 저장 + setInitialZoom(camera.position.z); // 클릭 시점의 줌 값 저장 + }; + + const onMouseMove = (event: MouseEvent) => { + if (isDragging) { + const deltaX = event.clientX - previousMouseX; + const deltaY = event.clientY - previousMouseY; + + if (initialRotation) { + cube.rotation.y = initialRotation.y + deltaX * 0.005; + cube.rotation.x = initialRotation.x + deltaY * 0.005; + } + + setPreviousMouseX(event.clientX); + setPreviousMouseY(event.clientY); + } + }; + + const onMouseUp = () => { + setIsDragging(false); + }; + + const onWheel = (event: WheelEvent) => { + const delta = event.deltaY * 0.01; + + camera.position.z -= delta; + + // Limiting camera zoom + if (camera.position.z < 4) { + camera.position.z = 4; + } else if (camera.position.z > 15) { + camera.position.z = 15; + } + }; + + window.addEventListener("mousedown", onMouseDown); + window.addEventListener("mousemove", onMouseMove); + window.addEventListener("mouseup", onMouseUp); + window.addEventListener("wheel", onWheel); + + if (previousMouseX > 0 || previousMouseY > 0) { + cube.rotation.x -= previousMouseX; + cube.rotation.y -= previousMouseY; + } + + // 반응형 처리 + const onWindowResize = () => { + if (mount) { + camera.aspect = mount.clientWidth / mount.clientHeight; + camera.updateProjectionMatrix(); + renderer.setSize(mount.clientWidth, mount.clientHeight); + } + }; + window.addEventListener("resize", onWindowResize); + + // 애니메이션 루프 + const animate = () => { + requestAnimationFrame(animate); + + // 기본 회전 + if (!isDragging) { + cube.rotation.x += 0.005; + cube.rotation.y += 0.005; + } + + renderer.render(scene, camera); + }; + animate(); + + // 클린업 함수 + return () => { + mount!.removeChild(renderer.domElement); + window.removeEventListener("mousedown", onMouseDown); + window.removeEventListener("mousemove", onMouseMove); + window.removeEventListener("mouseup", onMouseUp); + window.removeEventListener("wheel", onWheel); + window.removeEventListener("resize", onWindowResize); + }; + }, [isDragging, initialRotation, initialZoom]); + + return
; +}; + +export default Cube; diff --git a/src/pages/ThemeRecs.tsx b/src/pages/ThemeRecs.tsx index 11dd954..d44cd02 100644 --- a/src/pages/ThemeRecs.tsx +++ b/src/pages/ThemeRecs.tsx @@ -1,10 +1,28 @@ import React from "react"; +import Cube from "./Cube"; +import { Container, StyledLink } from "../styles/ThemeRecsStyled"; +import { IoIosArrowForward } from "react-icons/io"; const ThemeRecs = () => { return ( - <> -

ThemeRecs

- + +
+
당신을 위한 방,
+
방탈출 맞춤 추천
+
+
+ +
+ +
+

시작하기

+
+ +
+
+
+
); }; + export default ThemeRecs; diff --git a/src/pages/ThemeRecsQuestions.tsx b/src/pages/ThemeRecsQuestions.tsx new file mode 100644 index 0000000..f515357 --- /dev/null +++ b/src/pages/ThemeRecsQuestions.tsx @@ -0,0 +1,136 @@ +import React, { useEffect, useState } from "react"; +import Cube from "./Cube"; +import { + Container, + StartBtn, + Select, + StyledLink, +} from "../styles/ThemeRecsQuestionsStyled"; +import { IoIosArrowForward } from "react-icons/io"; + +const ThemeRecsQuestions = () => { + const [isVisible, setIsVisible] = useState(false); + + const handleScroll = () => { + const bottom = + window.innerHeight + window.scrollY >= + document.documentElement.scrollHeight - 10; // Slight buffer to ensure visibility + setIsVisible(bottom); + }; + + useEffect(() => { + window.addEventListener("scroll", handleScroll); + return () => { + window.removeEventListener("scroll", handleScroll); + }; + }, []); + + return ( + <> + +
+
당신을 위한 방,
+
어느 지역을 원하시나요?
+
+ + + + + + + + + + +
+
+
+ +
+
+ +
+ +
+
+
당신을 위한 방,
+
어떤 장르를 원하시나요?
+
+ + + + + + +
+
+
+ +
+
당신을 위한 방,
+
어떤 난이도를 원하시나요?
+
+ + + +
+
+ +
+ +
+
+ + + +
+

추천 받기

+
+ +
+
+
+
+ + ); +}; + +export default ThemeRecsQuestions; diff --git a/src/pages/ThemeRecsResult.tsx b/src/pages/ThemeRecsResult.tsx new file mode 100644 index 0000000..888b9ff --- /dev/null +++ b/src/pages/ThemeRecsResult.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import { Container, StartBtn } from "../styles/ThemeRecsResultStyled"; +import { IoIosArrowForward } from "react-icons/io"; +import RoomTheme from "../components/RoomTheme"; + +const ThemeRecsResult = () => { + return ( + +
+
방프로가 추천하는
+
당신을 위한 방,
+
+ +
+ + + +
+ + +
+

홈으로

+
+ +
+
+
+
+ ); +}; + +export default ThemeRecsResult; diff --git a/src/styles/NavbarStyled.tsx b/src/styles/NavbarStyled.tsx index 9de6225..e03ecd7 100644 --- a/src/styles/NavbarStyled.tsx +++ b/src/styles/NavbarStyled.tsx @@ -13,7 +13,7 @@ export const Container = styled.div` justify-content: space-between; background-color: #080101; - box-shadow: 0px 4px 50px rgba(255, 255, 255, 0.2); + box-shadow: 0px 4px 50px rgba(45, 45, 45, 0.126); color: #3b3b3b; .logoBox { @@ -32,35 +32,35 @@ export const Container = styled.div` justify-content: space-between; align-items: center; } +`; - .navBox > div { - display: flex; - justify-content: center; - align-items: center; - } +export const NavLink = styled(Link)` + text-decoration: none; - .navBox > div > div { + .nav { display: flex; justify-content: center; align-items: center; + transition: all 0.3s ease-in-out; + } + + .nav > div { font-size: 1.4rem; margin-right: 0.7rem; } - .navBox > div:hover { + .nav:hover { cursor: pointer; color: white; + transform: scale(1.05); } -`; -export const StyledLink = styled(Link)` - text-decoration: none; &:focus, - &:hover, &:visited, &:link, &:active { text-decoration: none; + color: #3b3b3b; } `; diff --git a/src/styles/RoomThemeStyled.tsx b/src/styles/RoomThemeStyled.tsx new file mode 100644 index 0000000..ea8f397 --- /dev/null +++ b/src/styles/RoomThemeStyled.tsx @@ -0,0 +1,68 @@ +import styled from "styled-components"; +import { Link } from "react-router-dom"; + +export const Theme = styled.div` + width: 20vw; + height: 20vh; + padding: 1rem 2rem; + margin: 0 1.5rem; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + + background-color: #080101; + color: white; + border-radius: 1rem; + filter: drop-shadow(0px 0px 7px #03ff8d); + + .titleBox > p { + font-size: 1.7rem; + border-left: 5px solid #03ff8d; + padding-left: 0.5rem; + font-weight: bold; + } + + .addressBox > p { + margin-top: 1rem; + font-size: 1.2rem; + } + + .cardFooter { + width: inherit; + margin-top: 1.5rem; + + display: flex; + justify-content: space-between; + } + + .hashtagBox { + display: flex; + } + + .hashtagBox > p { + margin-right: 1rem; + } + + .linkBtn { + padding: 0.2rem 1rem; + border-radius: 1rem; + background-color: #03ff8d; + color: #080101; + + cursor: pointer; + } +`; + +export const StyledLink = styled(Link)` + text-decoration: none; + + &:focus, + &:hover, + &:visited, + &:link, + &:active { + text-decoration: none; + } +`; diff --git a/src/styles/ThemeRecsQuestionsStyled.tsx b/src/styles/ThemeRecsQuestionsStyled.tsx new file mode 100644 index 0000000..4b936e1 --- /dev/null +++ b/src/styles/ThemeRecsQuestionsStyled.tsx @@ -0,0 +1,128 @@ +import styled from "styled-components"; +import { Link } from "react-router-dom"; + +export const Container = styled.div` + width: 100vw; + height: 90vh; + /* margin: 0; */ + /* margin-top: 10vh; */ + background: radial-gradient(50% 50% at 50% 50%, #3b3b3b 0%, #080101 100%); + + display: flex; + + .textBox { + /* width: 60vw; */ + height: inherit; + padding: 0 10vw; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + } + + .subTitle { + color: white; + font-size: 2.1rem; + } + + .title { + margin-top: 1rem; + color: white; + font-size: 3.7rem; + font-weight: bold; + } + .cubeBox { + width: 40vw; + height: inherit; + } + + .selectBox { + width: 43vw; + margin-top: 2rem; + flex-wrap: wrap; + + display: flex; + } +`; + +export const StartBtn = styled.div<{ isVisible: boolean }>` + // 화면 맨 끝에 도착해야만 보이게 + transition: opacity 0.7s ease-in-out; + opacity: ${(props) => (props.isVisible ? 1 : 0)}; + transform: ${(props) => + props.isVisible ? "translateY(0)" : "translateY(20px)"}; + visibility: ${(props) => (props.isVisible ? "visible" : "hidden")}; + + .startBtn { + position: fixed; + bottom: 10vh; + right: 10vw; + + display: flex; + justify-content: center; + align-items: center; + + height: 2rem; + padding: 0.7rem 2rem; + + border-radius: 1rem; + border: 3px solid white; + + color: white; + background-color: #080101; + cursor: pointer; + filter: drop-shadow(0px 0px 10px #ffffff62); + transition: 0.2s all ease-in-out; + } + + .startBtn:hover { + filter: drop-shadow(0px 0px 10px #ffffff); + } + + .start { + font-size: 1.5rem; + margin-right: 0.3rem; + } + + .icon { + width: 1.5rem; + font-size: 2rem; + display: flex; + justify-content: flex-end; + align-items: center; + } +`; + +export const Select = styled.div` + margin-top: 1rem; + margin-right: 1rem; + padding: 0.5rem 1.3rem; + font-size: 1.2rem; + color: white; + border-radius: 1rem; + border: 1px solid white; + + &:hover { + cursor: pointer; + background-color: rgba(255, 255, 255, 0.2); + border-color: #ccc; + } + + &:active { + background-color: rgba(255, 255, 255, 0.2); + border-color: #ccc; + } +`; + +export const StyledLink = styled(Link)` + text-decoration: none; + + &:focus, + &:hover, + &:visited, + &:link, + &:active { + text-decoration: none; + } +`; diff --git a/src/styles/ThemeRecsResultStyled.tsx b/src/styles/ThemeRecsResultStyled.tsx new file mode 100644 index 0000000..f2c76af --- /dev/null +++ b/src/styles/ThemeRecsResultStyled.tsx @@ -0,0 +1,135 @@ +import styled from "styled-components"; +import { Link } from "react-router-dom"; + +export const Container = styled.div` + width: 100vw; + height: 90vh; + background: radial-gradient(50% 50% at 50% 50%, #3b3b3b 0%, #080101 100%); + + display: flex; + flex-direction: column; + + .textBox { + width: 80vw; + height: 40vh; + padding: 0 10vw; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + } + + .subTitle { + color: white; + font-size: 2.1rem; + } + + .title { + margin-top: 1rem; + color: white; + font-size: 3.7rem; + font-weight: bold; + } + .cubeBox { + width: 40vw; + height: inherit; + } + + .selectBox { + width: 43vw; + margin-top: 2rem; + flex-wrap: wrap; + + display: flex; + } + + .resultBox { + width: 100vw; + height: 50vh; + + display: flex; + justify-content: center; + } +`; + +export const StartBtn = styled.div<{ isVisible: boolean }>` + // 화면 맨 끝에 도착해야만 보이게 + transition: opacity 0.7s ease-in-out; + opacity: ${(props) => (props.isVisible ? 1 : 0)}; + transform: ${(props) => + props.isVisible ? "translateY(0)" : "translateY(20px)"}; + visibility: ${(props) => (props.isVisible ? "visible" : "hidden")}; + + .startBtn { + position: fixed; + bottom: 10vh; + right: 10vw; + + display: flex; + justify-content: center; + align-items: center; + + height: 2rem; + padding: 0.7rem 2rem; + + border-radius: 1rem; + border: 3px solid white; + + color: white; + background-color: #080101; + cursor: pointer; + filter: drop-shadow(0px 0px 10px #ffffff62); + transition: 0.2s all ease-in-out; + } + + .startBtn:hover { + filter: drop-shadow(0px 0px 10px #ffffff); + } + + .start { + font-size: 1.5rem; + margin-right: 0.3rem; + } + + .icon { + width: 1.5rem; + font-size: 2rem; + display: flex; + justify-content: flex-end; + align-items: center; + } +`; + +export const Select = styled.div` + margin-top: 1rem; + margin-right: 1rem; + padding: 0.5rem 1.3rem; + font-size: 1.2rem; + color: white; + border-radius: 1rem; + border: 1px solid white; + + &:hover { + cursor: pointer; + background-color: rgba(255, 255, 255, 0.2); + border-color: #ccc; + } + + &:active { + background-color: rgba(255, 255, 255, 0.2); + border-color: #ccc; + } +`; + +export const StyledLink = styled(Link)` + text-decoration: none; + + &:focus, + &:hover, + &:visited, + &:link, + &:active { + text-decoration: none; + } +`; diff --git a/src/styles/ThemeRecsStyled.tsx b/src/styles/ThemeRecsStyled.tsx new file mode 100644 index 0000000..9e1b315 --- /dev/null +++ b/src/styles/ThemeRecsStyled.tsx @@ -0,0 +1,90 @@ +import styled from "styled-components"; +import { Link } from "react-router-dom"; + +export const Container = styled.div` + width: 100vw; + height: 90vh; + /* margin: 0; */ + margin-top: 10vh; + background: radial-gradient(50% 50% at 50% 50%, #3b3b3b 0%, #080101 100%); + + display: flex; + + .textBox { + width: 40vw; + height: inherit; + padding: 0 10vw; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + } + + .subTitle { + color: white; + font-size: 2.3rem; + } + + .title { + margin-top: 1rem; + color: white; + font-size: 3.8rem; + font-weight: bold; + } + .cubeBox { + width: 50vw; + height: inherit; + } + + .startBtn { + position: absolute; + bottom: 10vh; + right: 10vw; + + display: flex; + justify-content: center; + align-items: center; + + height: 2rem; + padding: 0.7rem 2rem; + + border-radius: 1rem; + border: 3px solid white; + + color: white; + background-color: #080101; + cursor: pointer; + filter: drop-shadow(0px 0px 10px #ffffff62); + transition: 0.2s all ease-in-out; + } + + .startBtn:hover { + filter: drop-shadow(0px 0px 10px #ffffff); + } + + .start { + font-size: 1.5rem; + margin-right: 0.3rem; + } + + .icon { + width: 1.5rem; + font-size: 2rem; + display: flex; + justify-content: flex-end; + align-items: center; + } +`; + +export const StyledLink = styled(Link)` + text-decoration: none; + + &:focus, + &:hover, + &:visited, + &:link, + &:active { + text-decoration: none; + } +`;