feat: add start section
This commit is contained in:
@@ -1,32 +1,38 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { Geist, Geist_Mono } from 'next/font/google';
|
||||
import './globals.css';
|
||||
import { Open_Sans } from 'next/font/google';
|
||||
import '@core/styles/reset.scss';
|
||||
import '@core/styles/globals.scss';
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: '--font-geist-sans',
|
||||
subsets: ['latin'],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: '--font-geist-mono',
|
||||
subsets: ['latin'],
|
||||
const openSans = Open_Sans({
|
||||
subsets: ['latin', 'cyrillic'],
|
||||
weight: ['300', '400', '500', '600', '700'],
|
||||
variable: '--open-sans',
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Пожарная экспертиза',
|
||||
description: 'Пожарная экспертиза',
|
||||
title: 'Обследование на соответствие пожарной безопасности',
|
||||
description:
|
||||
'Полное обследование объекта на соответствие требованиям пожарной безопасности',
|
||||
openGraph: {
|
||||
title: 'Обследование на соответствие пожарной безопасности',
|
||||
description:
|
||||
'Полное обследование объекта на соответствие требованиям пожарной безопасности',
|
||||
siteName: 'Обследование на соответствие пожарной безопасности',
|
||||
// images: [
|
||||
// {
|
||||
// url: `MetaSR.png`,
|
||||
// alt: 'icon',
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
}: Readonly<{ children: React.ReactNode }>) {
|
||||
return (
|
||||
<html lang='en'>
|
||||
<body className={`${geistSans.variable} ${geistMono.variable}`}>
|
||||
{children}
|
||||
</body>
|
||||
<body className={`${openSans.variable}`}>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import HomePage from '@pages/home';
|
||||
import { HomePage } from '@pages/home';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
6
src/core/styles/functions.scss
Normal file
6
src/core/styles/functions.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
@use 'sass:math';
|
||||
|
||||
@function rem($size) {
|
||||
$remSize: math.div($size, $base-font-size);
|
||||
@return $remSize * 1rem;
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
--foreground: #333333;
|
||||
}
|
||||
|
||||
html,
|
||||
@@ -34,9 +27,3 @@ a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
2
src/core/styles/index.scss
Normal file
2
src/core/styles/index.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import './variables.scss';
|
||||
@import './mixins.scss';
|
||||
23
src/core/styles/mixins.scss
Normal file
23
src/core/styles/mixins.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
@mixin onlymobile {
|
||||
@media (min-width: 0px) and (max-width: calc($tablet - 1px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin iftablet {
|
||||
@media (min-width: $tablet) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin iflaptop {
|
||||
@media (min-width: $laptop) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin ifdesktop {
|
||||
@media (min-width: $desktop) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
106
src/core/styles/reset.scss
Normal file
106
src/core/styles/reset.scss
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Reset and base styles */
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); // stop highlights element blue when tapping
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
|
||||
a,
|
||||
a:link,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: unset;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Components */
|
||||
|
||||
aside,
|
||||
nav,
|
||||
footer,
|
||||
header,
|
||||
section,
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
//margin-block-start: 0;
|
||||
//margin-block-end: 0;
|
||||
}
|
||||
|
||||
ul[role='list'], ol[role='list'] {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul,
|
||||
ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Form */
|
||||
|
||||
input,
|
||||
textarea,
|
||||
button,
|
||||
select {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
input::-ms-clear {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'] {
|
||||
display: inline-block;
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
background: none;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
input:active,
|
||||
button:focus,
|
||||
button:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
}
|
||||
|
||||
img, picture, svg, video, canvas {
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
21
src/core/styles/variables.scss
Normal file
21
src/core/styles/variables.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
//frontend breakpoint
|
||||
$mobile: 360px;
|
||||
$tablet: 768px;
|
||||
$laptop: 1024px;
|
||||
$desktop: 1440px;
|
||||
|
||||
//fonts
|
||||
$font-open-sans: var(--open-sans), sans-serif;
|
||||
|
||||
$font-regular: 500;
|
||||
$font-semi-bold: 600;
|
||||
|
||||
// colors
|
||||
$color-white: #FFFFFF;
|
||||
$color-black: #000000;
|
||||
$color-orange: #E96526;
|
||||
$color-lightgray: #E4E1E1;
|
||||
$color-text: #333333;
|
||||
$color-text-light: #222222;
|
||||
$color-mark: #E96526;
|
||||
106
src/pages/home/home.module.scss
Normal file
106
src/pages/home/home.module.scss
Normal file
@@ -0,0 +1,106 @@
|
||||
.Start {
|
||||
padding: 0px 160px 0px;
|
||||
|
||||
&_BgWrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 900px;
|
||||
z-index: -1;
|
||||
|
||||
& img {
|
||||
object-fit: cover;
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $color-white;
|
||||
height: 80px;
|
||||
|
||||
.Logo {
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
.Buttons {
|
||||
color: $color-white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 30px;
|
||||
|
||||
.Icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.Button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
height: 48px;
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 160px 0 200px;
|
||||
|
||||
.Content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
gap: 60px;
|
||||
|
||||
.Title {
|
||||
font-family: $font-open-sans;
|
||||
font-weight: $font-regular;
|
||||
font-size: 60px;
|
||||
line-height: 1;
|
||||
color: $color-white;
|
||||
max-width: 960px;
|
||||
}
|
||||
|
||||
.List {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.ListItem {
|
||||
font-family: $font-open-sans;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: 26px;
|
||||
line-height: 1;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
.Phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-basis: 40%;
|
||||
gap: 40px;
|
||||
|
||||
.Title {
|
||||
font-family: $font-open-sans;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: 60px;
|
||||
line-height: 1;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/pages/home/home.tsx
Normal file
57
src/pages/home/home.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import s from './home.module.scss';
|
||||
import { Button } from '@shared/ui';
|
||||
import waIcon from '@public/svg/whatsapp.svg';
|
||||
import tgIcon from '@public/svg/telegram.svg';
|
||||
import callBtn from '@public/svg/phone-calling.svg';
|
||||
import bgStart from '@public/images/bg-start-desktop.jpg';
|
||||
import Image from 'next/image';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<section className={s.Start}>
|
||||
<div className={s.Start_BgWrapper}>
|
||||
<Image
|
||||
src={bgStart}
|
||||
placeholder='blur'
|
||||
alt={''}
|
||||
sizes='100vw'
|
||||
quality={100}
|
||||
fill
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<div className={s.Header}>
|
||||
<div className={s.Logo}>Пожарная экспертиза</div>
|
||||
<div className={s.Buttons}>
|
||||
<Image className={s.Icon} src={waIcon} alt='whatsapp' />
|
||||
<Image className={s.Icon} src={tgIcon} alt='telegram' />
|
||||
<Button className={s.Button}>
|
||||
<Image src={callBtn} alt='Call' />
|
||||
Обратный звонок
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className={s.Info}>
|
||||
<div className={s.Content}>
|
||||
<h1 className={s.Title}>
|
||||
Полное обследование объекта на соответствие требованиям пожарной
|
||||
безопасности
|
||||
</h1>
|
||||
<ul className={s.List}>
|
||||
<li className={s.ListItem}>
|
||||
Пожарно-техническое обследование (пожарный аудит)
|
||||
</li>
|
||||
<li className={s.ListItem}>Расчёт пожарного риска</li>
|
||||
<li className={s.ListItem}>
|
||||
Сокращение затрат на модернизацию пожарных систем
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className={s.Phone}>
|
||||
<p className={s.Title}>+7 999 123 45 67</p>
|
||||
<Button variant='orange'>Получить консультацию</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
export { default } from './ui/Home';
|
||||
export { default as HomePage } from './home';
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
function Home() {
|
||||
return <main>Home</main>;
|
||||
}
|
||||
|
||||
export default Home;
|
||||
46
src/shared/ui/button/button.module.scss
Normal file
46
src/shared/ui/button/button.module.scss
Normal file
@@ -0,0 +1,46 @@
|
||||
.Button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 13px 33px;
|
||||
border-radius: 28px;
|
||||
|
||||
font-family: $font-open-sans;
|
||||
font-weight: $font-regular;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
|
||||
transition: all 0.15s linear;
|
||||
white-space: nowrap;
|
||||
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
//fill: var(--text-primary);
|
||||
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover svg {
|
||||
fill: var(--white);
|
||||
}
|
||||
|
||||
&_default {
|
||||
background: $color-lightgray;
|
||||
color: $color-text;
|
||||
}
|
||||
|
||||
&_orange {
|
||||
background: $color-orange;
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
&_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
39
src/shared/ui/button/button.tsx
Normal file
39
src/shared/ui/button/button.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import s from './button.module.scss';
|
||||
import { FunctionComponent, HTMLAttributes, ReactNode, SVGProps } from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
type ButtonProps = {
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
disabled?: boolean;
|
||||
Icon?: FunctionComponent<SVGProps<SVGSVGElement>>;
|
||||
onClick?: () => void;
|
||||
variant?: 'default' | 'orange' | 'ghost';
|
||||
} & HTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
export default function Button({
|
||||
className,
|
||||
children,
|
||||
onClick,
|
||||
Icon,
|
||||
disabled,
|
||||
variant = 'default',
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={clsx(
|
||||
s.Button,
|
||||
disabled && s.Button_disabled,
|
||||
s['Button_' + variant],
|
||||
className,
|
||||
)}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
>
|
||||
{Icon && <Icon />}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
1
src/shared/ui/button/index.ts
Normal file
1
src/shared/ui/button/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Button } from './button';
|
||||
1
src/shared/ui/index.ts
Normal file
1
src/shared/ui/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Button } from './button';
|
||||
Reference in New Issue
Block a user