diff --git a/packages/client/src/app/App.scss b/packages/client/src/app/App.scss deleted file mode 100644 index b1aa12f..0000000 --- a/packages/client/src/app/App.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import '../scss/vars.scss'; - -.app-layout { - background-image: $img_default-background; - height: 100%; -} diff --git a/packages/client/src/app/App.tsx b/packages/client/src/app/App.tsx index 0ce1e32..dae0732 100644 --- a/packages/client/src/app/App.tsx +++ b/packages/client/src/app/App.tsx @@ -1,10 +1,7 @@ -// import { useEffect } from 'react' - -import '@/app/App.scss' -import AuthLayout from '@/layouts/auth-layout' -import PrivateLayout from '@/layouts/private-layout' -import PublicLayout from '@/layouts/public-layout' -import RootLayout from '@/layouts/root-layout' +import AuthLayout from '@/layouts/AuthLayout/AuthLayout' +import PrivateLayout from '@/layouts/PrivateLayout/PrivateLayout' +import PublicLayout from '@/layouts/PublicLayout/PublicLayout' +import RootLayout from '@/layouts/RootLayout/RootLayout' import { Error } from '@/pages/Error/Error' import { Forum } from '@/pages/Forum/Forum' import { Game } from '@/pages/Game/Game' @@ -84,23 +81,7 @@ const routerConfig = createBrowserRouter([ ]) function App() { - // useEffect(() => { - // const fetchServerData = async () => { - // const url = `http://localhost:${__SERVER_PORT__}` - // const response = await fetch(url) - // const data = await response.json() - // console.log(data) - // } - // - // fetchServerData() - // }, []) - // - - return ( -
- -
- ) + return } export default App diff --git a/packages/client/src/assets/images/enemy-tank_left.png b/packages/client/src/assets/images/enemy-tank_left.png new file mode 100644 index 0000000..3d0ba37 Binary files /dev/null and b/packages/client/src/assets/images/enemy-tank_left.png differ diff --git a/packages/client/src/assets/images/enemy-tank_right.png b/packages/client/src/assets/images/enemy-tank_right.png new file mode 100644 index 0000000..37cffef Binary files /dev/null and b/packages/client/src/assets/images/enemy-tank_right.png differ diff --git a/packages/client/src/assets/images/page-background.png b/packages/client/src/assets/images/page-background.png index f49ec63..6929130 100644 Binary files a/packages/client/src/assets/images/page-background.png and b/packages/client/src/assets/images/page-background.png differ diff --git a/packages/client/src/assets/images/site-logo.svg b/packages/client/src/assets/images/site-logo.svg new file mode 100644 index 0000000..83ef5bb --- /dev/null +++ b/packages/client/src/assets/images/site-logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/packages/client/src/assets/images/smoke-bottom.png b/packages/client/src/assets/images/smoke-bottom.png new file mode 100644 index 0000000..70febc6 Binary files /dev/null and b/packages/client/src/assets/images/smoke-bottom.png differ diff --git a/packages/client/src/assets/images/smoke-middle.png b/packages/client/src/assets/images/smoke-middle.png new file mode 100644 index 0000000..22fcbb3 Binary files /dev/null and b/packages/client/src/assets/images/smoke-middle.png differ diff --git a/packages/client/src/assets/images/smoke-top.png b/packages/client/src/assets/images/smoke-top.png new file mode 100644 index 0000000..e579142 Binary files /dev/null and b/packages/client/src/assets/images/smoke-top.png differ diff --git a/packages/client/src/assets/images/svg/title-decor--bolt.svg b/packages/client/src/assets/images/svg/title-decor--bolt.svg new file mode 100644 index 0000000..60d10be --- /dev/null +++ b/packages/client/src/assets/images/svg/title-decor--bolt.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/client/src/assets/images/svg/title-decor.svg b/packages/client/src/assets/images/svg/title-decor.svg new file mode 100644 index 0000000..255890c --- /dev/null +++ b/packages/client/src/assets/images/svg/title-decor.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/client/src/components/common/Header/Header.scss b/packages/client/src/components/common/Header/Header.scss new file mode 100644 index 0000000..f32ad3b --- /dev/null +++ b/packages/client/src/components/common/Header/Header.scss @@ -0,0 +1,41 @@ +@import '../../../scss/vars'; + +.main-header { + &__container { + display: flex; + justify-content: space-between; + } +} + +.logo-block { + user-select: none; + + &__image { + width: 114px; + margin-bottom: -62px; + } +} + +.main-nav { + display: flex; + gap: $nav_list-gap; + padding: $nav_list-padding-y $nav_list-padding-x; + + &__link { + font-size: $nav_link-font-size; + font-weight: $nav_link-font-weight; + letter-spacing: 1px; + + text-shadow: $main-text-shadow; + text-transform: uppercase; + text-decoration: none; + + color: $text-color; + transition: color $animation-base-speed; + + &:hover, + &_active { + color: $primary-color; + } + } +} diff --git a/packages/client/src/components/common/Header/Header.tsx b/packages/client/src/components/common/Header/Header.tsx new file mode 100644 index 0000000..8b71340 --- /dev/null +++ b/packages/client/src/components/common/Header/Header.tsx @@ -0,0 +1,52 @@ +import { Link, NavLink } from 'react-router-dom' +import SiteLogo from '@/assets/images/site-logo.svg' +import './Header.scss' + +type HeaderProps = { + className?: string +} + +export const Header = (props: HeaderProps) => { + const { className = '' } = props + const getNavLinkClassName = (isActive: boolean) => + isActive ? 'main-nav__link main-nav__link_active' : 'main-nav__link' + + return ( +
+
+
+ + Falcon Tanks Logo + +
+ +
+
+ ) +} diff --git a/packages/client/src/components/ui/Button/Button.scss b/packages/client/src/components/ui/Button/Button.scss index 2a31eec..1e961aa 100644 --- a/packages/client/src/components/ui/Button/Button.scss +++ b/packages/client/src/components/ui/Button/Button.scss @@ -6,9 +6,9 @@ cursor: pointer; border-radius: $border-radius--default; background-color: $c_button; + transition: border-color $animation-base-speed; - padding-top: 20px; - padding-bottom: 20px; + padding: 16px 12px; display: block; border-top: 5px solid $c_button-top; @@ -21,20 +21,29 @@ text-decoration: none; text-align: center; - span { - letter-spacing: 2px; - text-transform: uppercase; - text-shadow: 2px 0 $c_black, -2px 0 $c_black, 0 2px $c_black, - 0 -2px $c_black, 2px 2px $c_black, -2px -2px $c_black, 2px -2px $c_black, - -2px 2px $c_black; + &:hover { + border-bottom-color: $c_button-top; + border-top-color: $c_button-bottom; } &_fix-width { min-width: 300px; } - &:hover { - border-top: 5px solid $c_button-bottom; - border-bottom: 5px solid $c_button-top; + &_blue { + background-color: $c_button_blue; + border-top: 5px solid $c_button-top_blue; + border-bottom: 5px solid $c_button-bottom_blue; + + &:hover { + border-top-color: $c_button-bottom_blue; + border-bottom-color: $c_button-top_blue; + } + } + + span { + letter-spacing: 2px; + text-transform: uppercase; + text-shadow: $main-text-shadow; } } diff --git a/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.scss b/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.scss new file mode 100644 index 0000000..087ee8e --- /dev/null +++ b/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.scss @@ -0,0 +1,120 @@ +@import '../../../scss/vars'; + +@mixin decorParentPosition { + position: absolute; + top: -$border-width; + left: -$border-width; + right: -$border-width; + bottom: -$border-width; +} + +$bg-color: #1e1e1e; +$border-width: 7px; +$border-gradient: linear-gradient(45deg, #414243, #7f7f7f) top left, + linear-gradient(135deg, #7f7f7f, #414243) top right, + linear-gradient(225deg, #414243, #414042) bottom right, + linear-gradient(315deg, #414042, #414243) bottom left; +$border-radius: 24px; +$block-width: 350px; +$outline-color: #101010; + +.custom-page-title { + position: relative; + display: flex; + justify-content: center; + + &__block { + position: relative; + display: block; + border-radius: $border-radius; + z-index: 0; + width: $block-width; + max-width: 100%; + } + + &__border { + @mixin borderDecorSettings($top, $bottom) { + content: ''; + position: absolute; + top: $top; + bottom: $bottom; + left: 0; + right: 0; + height: $border-width; + + background: url('@/assets/images/svg/title-decor.svg') no-repeat center + center; + background-size: contain; + } + + @include decorParentPosition(); + + border-radius: $border-radius; + background: $border-gradient; + background-size: 50% 50%; + background-repeat: no-repeat; + z-index: -1; + padding: 10px; + outline: 3px solid $outline-color; + + &::before { + @include borderDecorSettings(0, 'auto'); + } + + &::after { + @include borderDecorSettings('auto', 0); + + transform: rotate(180deg); + } + } + + &__screws { + @mixin screwSettings($left, $right) { + content: ''; + position: absolute; + left: $left; + right: $right; + top: 50%; + width: 33px; + height: 41px; + z-index: -2; + } + + @include decorParentPosition(); + + &::before { + @include screwSettings(0, 'auto'); + + transform: translate(calc(-100%), -50%) rotate(180deg); + background: url('@/assets/images/svg/title-decor--bolt.svg') no-repeat + center center; + background-size: contain; + } + + &::after { + @include screwSettings('auto', 0); + + transform: translate(calc(100%), -50%); + background: url('@/assets/images/svg/title-decor--bolt.svg') no-repeat + center center; + background-size: contain; + } + } + + &__content { + border-radius: calc($border-radius - 6px); + border: 1px solid $primary-color; + background-color: $bg-color; + text-align: center; + color: $text-color; + padding: 12px; + + & > * { + font-size: 24px; + font-weight: 700; + letter-spacing: 1px; + margin: 0; + padding: 0; + } + } +} diff --git a/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.tsx b/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.tsx new file mode 100644 index 0000000..ab14fd5 --- /dev/null +++ b/packages/client/src/components/ui/CustomPageTitle/CustomPageTitle.tsx @@ -0,0 +1,34 @@ +import './CustomPageTitle.scss' +import React from 'react' + +type PageTitlePropsType = { + text: string + className?: string + tagName?: string +} + +type DynamicTagElementPropsType = { + tagName: string + children: React.ReactNode +} + +export const CustomPageTitle = (props: PageTitlePropsType) => { + const { text, className = '', tagName = 'h2' } = props + const DynamicTagElement = ({ + tagName, + children, + }: DynamicTagElementPropsType) => React.createElement(tagName, null, children) + + return ( +
+
+
+
+ +
+ {text} +
+
+
+ ) +} diff --git a/packages/client/src/components/ui/PageTitle/PageTitle.scss b/packages/client/src/components/ui/PageTitle/PageTitle.scss new file mode 100644 index 0000000..8dc569d --- /dev/null +++ b/packages/client/src/components/ui/PageTitle/PageTitle.scss @@ -0,0 +1,26 @@ +@import '../../../scss/vars'; + +.page-title { + position: relative; + display: block; + margin-bottom: 28px; + + &__block { + position: relative; + display: block; + } + + &__content { + color: $text-color; + + & > * { + font-size: 28px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 1px; + text-shadow: $main-text-shadow; + margin: 0; + padding: 0; + } + } +} diff --git a/packages/client/src/components/ui/PageTitle/PageTitle.tsx b/packages/client/src/components/ui/PageTitle/PageTitle.tsx new file mode 100644 index 0000000..f5ab100 --- /dev/null +++ b/packages/client/src/components/ui/PageTitle/PageTitle.tsx @@ -0,0 +1,31 @@ +import './PageTitle.scss' +import React from 'react' + +type PageTitlePropsType = { + text: string + className?: string + tagName?: string +} + +type DynamicTagElementPropsType = { + tagName: string + children: React.ReactNode +} + +export const PageTitle = (props: PageTitlePropsType) => { + const { text, className = '', tagName = 'h2' } = props + const DynamicTagElement = ({ + tagName, + children, + }: DynamicTagElementPropsType) => React.createElement(tagName, null, children) + + return ( +
+
+
+ {text} +
+
+
+ ) +} diff --git a/packages/client/src/layouts/auth-layout.tsx b/packages/client/src/layouts/AuthLayout/AuthLayout.tsx similarity index 100% rename from packages/client/src/layouts/auth-layout.tsx rename to packages/client/src/layouts/AuthLayout/AuthLayout.tsx diff --git a/packages/client/src/layouts/private-layout.tsx b/packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx similarity index 100% rename from packages/client/src/layouts/private-layout.tsx rename to packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx diff --git a/packages/client/src/layouts/PublicLayout/PublicLayout.scss b/packages/client/src/layouts/PublicLayout/PublicLayout.scss new file mode 100644 index 0000000..166c805 --- /dev/null +++ b/packages/client/src/layouts/PublicLayout/PublicLayout.scss @@ -0,0 +1,14 @@ +@import '../../scss/vars.scss'; + +.public-layout { + display: flex; + flex-direction: column; + position: relative; + min-height: 100vh; + z-index: 0; + + &__body { + flex: 1 1 100%; + padding-top: $layout_body-m-top; + } +} diff --git a/packages/client/src/layouts/PublicLayout/PublicLayout.tsx b/packages/client/src/layouts/PublicLayout/PublicLayout.tsx new file mode 100644 index 0000000..be32a27 --- /dev/null +++ b/packages/client/src/layouts/PublicLayout/PublicLayout.tsx @@ -0,0 +1,14 @@ +import { Header } from '@/components/common/Header/Header' +import { Outlet } from 'react-router-dom' +import './PublicLayout.scss' + +export default function PublicLayout() { + return ( +
+
+
+ +
+
+ ) +} diff --git a/packages/client/src/layouts/root-layout.tsx b/packages/client/src/layouts/RootLayout/RootLayout.tsx similarity index 100% rename from packages/client/src/layouts/root-layout.tsx rename to packages/client/src/layouts/RootLayout/RootLayout.tsx diff --git a/packages/client/src/layouts/public-layout.tsx b/packages/client/src/layouts/public-layout.tsx deleted file mode 100644 index a01a31f..0000000 --- a/packages/client/src/layouts/public-layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Outlet } from 'react-router-dom' - -export default function PublicLayout() { - return -} diff --git a/packages/client/src/pages/Error/Error.scss b/packages/client/src/pages/Error/Error.scss index 22626d0..25ef285 100644 --- a/packages/client/src/pages/Error/Error.scss +++ b/packages/client/src/pages/Error/Error.scss @@ -1,5 +1,16 @@ @import '../../scss/vars'; +.error-page-layout { + height: 600px; + min-height: 100vh; + display: flex; + flex-direction: column; + + &__body { + flex: 1 1 100%; + } +} + .error-page { height: 100%; diff --git a/packages/client/src/pages/Error/Error.tsx b/packages/client/src/pages/Error/Error.tsx index fb45d46..9a4a42f 100644 --- a/packages/client/src/pages/Error/Error.tsx +++ b/packages/client/src/pages/Error/Error.tsx @@ -1,6 +1,7 @@ import { isRouteErrorResponse, useRouteError } from 'react-router-dom' import DestroyedTanksImage from '../../assets/images/destroyed-tanks.png' import './Error.scss' +import { Header } from '@/components/common/Header/Header' export const Error = () => { const error = useRouteError() @@ -16,16 +17,21 @@ export const Error = () => { } return ( -
-
- {status || 'Oops!'} -

{statusText}

+
+
+
+
+
+ {status || 'Oops!'} +

{statusText}

+
+ {'Destroyed +
- {'Destroyed
) } diff --git a/packages/client/src/pages/Main/Main.scss b/packages/client/src/pages/Main/Main.scss index 2ef3c23..d772213 100644 --- a/packages/client/src/pages/Main/Main.scss +++ b/packages/client/src/pages/Main/Main.scss @@ -1,21 +1,27 @@ @import '../../scss/vars'; .promo-page { - background-color: $c_default-background; - height: 100%; - display: flex; - position: relative; + &__content { + width: 600px; + margin: auto; + } - &__logo { - width: 100%; - height: auto; + &__title { + margin-bottom: 40px; } - &__button { - position: absolute; + &__desc { + font-size: 18px; + line-height: 1.6; + text-align: center; + margin-bottom: 60px; + text-shadow: $main-text-shadow; + } - bottom: 100px; - left: 50%; - transform: translateX(-50%); + &__actions { + display: flex; + gap: 20px; + justify-content: center; + flex-wrap: wrap; } } diff --git a/packages/client/src/pages/Main/Main.tsx b/packages/client/src/pages/Main/Main.tsx index ed3332b..e0c06dd 100644 --- a/packages/client/src/pages/Main/Main.tsx +++ b/packages/client/src/pages/Main/Main.tsx @@ -1,18 +1,51 @@ -import PromoImage from '@/assets/images/svg/FT-promo.svg' import './Main.scss' - +import { useEffect, useState } from 'react' +import { CustomPageTitle } from '@/components/ui/CustomPageTitle/CustomPageTitle' import { Button } from '@/components/ui/Button/Button' +import { EnemyTank } from './components/EnemyTanks/EnemyTank' export const Main = () => { + const [isLoaded, setIsLoaded] = useState(false) + + useEffect(() => { + setIsLoaded(true) + }, []) + return (
- {'promoImage'} -
+
+ ) } diff --git a/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.scss b/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.scss new file mode 100644 index 0000000..7b07b16 --- /dev/null +++ b/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.scss @@ -0,0 +1,127 @@ +@import '../../../../scss/vars.scss'; + +@mixin absoluteAndUserselect { + position: absolute; + user-select: none; +} + +@mixin smokeAnimate($delay, $fadeInUp, $float) { + animation-delay: $delay; + animation: fadeInUp $fadeInUp ease-out forwards, + float $float ease-in-out infinite; +} + +.enemy-tank { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 40%; + overflow: hidden; + z-index: -1; + + &_right { + left: auto; + right: 0; + } + + &__machine { + @include absoluteAndUserselect(); + + left: 0; + bottom: 0; + width: 300px; + + &_right { + left: auto; + right: 0; + } + } +} + +.tank-smoke { + &::after { + content: ''; + position: absolute; + width: 600px; + height: 600px; + bottom: 0; + left: 0; + transform: translate(-50%, 50%); + background: $red_ligth_gradient; + } + + &_right { + &::after { + left: auto; + right: 0; + transform: translate(50%, 50%); + } + } + + &__bottom { + @include absoluteAndUserselect(); + @include smokeAnimate(2s, 0.6s, 15s); + + left: -200px; + bottom: -200px; + width: 600px; + + &_right { + left: auto; + right: -200px; + } + } + + &__middle { + @include absoluteAndUserselect(); + @include smokeAnimate(4s, 0.8s, 8s); + + left: -62px; + bottom: 220px; + width: 280px; + + &_right { + left: auto; + right: -62px; + } + } + + &__top { + @include absoluteAndUserselect(); + @include smokeAnimate(0s, 1s, 10s); + + left: -50px; + bottom: 410px; + width: 200px; + + &_right { + left: auto; + right: -50px; + } + } +} + +@keyframes float { + 0% { + transform: translate(0, 0); + } + 25% { + transform: translate(5px, -5px); + } + 50% { + transform: translate(-5px, 10px); + } + 75% { + transform: translate(10px, -5px); + } + 100% { + transform: translate(0, 0); + } +} + +@keyframes fadeInUp { + 0% { + bottom: -300px; + } +} diff --git a/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.tsx b/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.tsx new file mode 100644 index 0000000..faf7db6 --- /dev/null +++ b/packages/client/src/pages/Main/components/EnemyTanks/EnemyTank.tsx @@ -0,0 +1,58 @@ +import './EnemyTank.scss' +import EnemyTankLeft from '@/assets/images/enemy-tank_left.png' +import EnemyTankRight from '@/assets/images/enemy-tank_right.png' +import SmokeBottom from '@/assets/images/smoke-bottom.png' +import SmokeMiddle from '@/assets/images/smoke-middle.png' +import SmokeTop from '@/assets/images/smoke-top.png' + +type EnemyTanksPropsType = { + side?: 'left' | 'right' + title?: string + isLoaded?: boolean +} + +export const EnemyTank = (props: EnemyTanksPropsType) => { + const { side = 'left', title = 'tank wars', isLoaded = false } = props + const tankImage = side === 'right' ? EnemyTankRight : EnemyTankLeft + + return ( +
+
+ + + +
+ +
+ ) +} diff --git a/packages/client/src/scss/base.scss b/packages/client/src/scss/base.scss index ffeb6ef..4bca365 100644 --- a/packages/client/src/scss/base.scss +++ b/packages/client/src/scss/base.scss @@ -2,11 +2,22 @@ box-sizing: border-box; } +html, +body { + overflow-x: hidden; +} + html, body, #root { width: 100%; - height: 100%; + min-height: 100vh; margin: 0; padding: 0; + font-family: $f_default-font-family; + color: $text-color; +} + +#root { + background-image: $img_default-background; } diff --git a/packages/client/src/scss/grid-system.scss b/packages/client/src/scss/grid-system.scss new file mode 100644 index 0000000..784b0ea --- /dev/null +++ b/packages/client/src/scss/grid-system.scss @@ -0,0 +1,40 @@ +@use 'sass:math'; +@import './vars.scss'; + +.container-fluid { + display: flex; + width: 100%; + max-width: $container_fluid-max-width; + padding: $container_fluid-padding; +} + +.container { + max-width: $container-max-width; + margin-right: auto; + margin-left: auto; + padding-right: $gutter-width; + padding-left: $gutter-width; + width: 100%; +} + +.row { + display: flex; + flex-wrap: wrap; + margin-right: calc($gutter-width / 2 * -1); + margin-left: calc($gutter-width / 2 * -1); +} + +.column { + padding-right: calc($gutter-width / 2); + padding-left: calc($gutter-width / 2); + flex-basis: 0; + flex-grow: 1; + max-width: 100%; +} + +@for $i from 1 through $grid-columns { + .col-#{$i} { + flex: 0 0 math.percentage(math.div($i, $grid-columns)); + max-width: math.percentage(math.div($i, $grid-columns)); + } +} diff --git a/packages/client/src/scss/styles.scss b/packages/client/src/scss/styles.scss index 9d0a765..09ce2bc 100644 --- a/packages/client/src/scss/styles.scss +++ b/packages/client/src/scss/styles.scss @@ -1,3 +1,4 @@ -@import 'normalize'; -@import 'base'; -@import 'vars'; +@import './normalize.scss'; +@import './vars.scss'; +@import './base.scss'; +@import './grid-system.scss'; diff --git a/packages/client/src/scss/vars.scss b/packages/client/src/scss/vars.scss index b5a1abf..6993b3e 100644 --- a/packages/client/src/scss/vars.scss +++ b/packages/client/src/scss/vars.scss @@ -6,13 +6,50 @@ $f_default-font-family: 'Roboto', sans-serif; // images $img_default-background: url('@/assets/images/page-background.png'); +// main colors +$primary-color: #839d22; +$second-color: #00aeef; +$text-color: #f8f8f8; + // colors $c_default-background: #010101; -$c_button: #839d22; + +$c_button: $primary-color; $c_button-top: #d9eca2; $c_button-bottom: #53650b; + +$c_button_blue: $second-color; +$c_button-top_blue: #5fe1ff; +$c_button-bottom_blue: #0079a7; + $c_white: #ffffff; $c_black: #000; // fonts/links $c_font-default: $c_white; + +// animations +$animation-base-speed: 0.18s; + +// effects +$red-ligth-gradient: radial-gradient(#fc2204 -40%, transparent 70%); +$main-text-shadow: 1px 0 $c_black, -1px 0 $c_black, 0 1px $c_black, + 0 -1px $c_black, 1px 1px $c_black, -1px -1px $c_black, 1px -1px $c_black, + -1px 1px $c_black; + +// headers +$nav_list-gap: 40px; +$nav_list-padding-y: 48px; +$nav_list-padding-x: 0; +$nav_link-font-size: 18px; +$nav_link-font-weight: 900; + +// layouts +$layout_body-m-top: 40px; + +// grid system +$grid-columns: 12; +$gutter-width: 15px; +$container-max-width: 1140px; +$container_fluid-padding: 0 40px; +$container_fluid-max-width: 100%;