Compare commits
31 Commits
front
...
bea27be461
| Author | SHA1 | Date | |
|---|---|---|---|
| bea27be461 | |||
| 11879ffd39 | |||
| 001922c5e2 | |||
| beef191051 | |||
| 7ddee3f12d | |||
| 3ec7aa43e5 | |||
| 942a287b26 | |||
| eb97ed0e4a | |||
| 916d020909 | |||
| dd41046e75 | |||
| 6b6361b25a | |||
| 0932c40127 | |||
| d58bfbb7c1 | |||
| 66b6878e50 | |||
| 7bdf422c32 | |||
| 9a259cb637 | |||
| 54072eb87d | |||
| ecf374685f | |||
| 62d58e30cd | |||
| a13b88bd32 | |||
| ea7bfc64f2 | |||
| 0e2a17a3e3 | |||
| 185cefe250 | |||
| 25ec2c7bcb | |||
| b667cde3d7 | |||
| d30af82765 | |||
| efd8510853 | |||
| e558aa6bdd | |||
| bd9210a3b5 | |||
| 1eba5623a3 | |||
| c762662231 |
@@ -4,23 +4,41 @@ http://ru.homyk.space {
|
||||
https://ru.homyk.space {
|
||||
encode gzip
|
||||
|
||||
# --- API ---
|
||||
handle /api/* {
|
||||
reverse_proxy backend:{$PORT}
|
||||
}
|
||||
|
||||
# --- Frontend ---
|
||||
root * /srv
|
||||
file_server
|
||||
handle_path /main/* {
|
||||
@images path_regexp \.(jpg|jpeg|png|webp|gif|svg)$
|
||||
header @images Cache-Control "public, max-age=604800"
|
||||
|
||||
forward_auth backend:{$PORT} {
|
||||
uri /api/verify
|
||||
copy_headers Authorization
|
||||
}
|
||||
root * /srv/main
|
||||
file_server
|
||||
}
|
||||
|
||||
handle_errors {
|
||||
@unauth expression {http.error.status_code} == 401
|
||||
redir @unauth / 302
|
||||
}
|
||||
handle {
|
||||
root * /srv/auth
|
||||
file_server {
|
||||
index login.html
|
||||
}
|
||||
}
|
||||
|
||||
log {
|
||||
output file /data/logs/caddy.log {
|
||||
roll_size 5mb
|
||||
roll_keep 5
|
||||
roll_keep_for 72h
|
||||
}
|
||||
format json
|
||||
}
|
||||
format json
|
||||
}
|
||||
}
|
||||
https://music.homyk.space {
|
||||
encode gzip
|
||||
@@ -35,7 +53,7 @@ https://music.homyk.space {
|
||||
roll_size 5mb
|
||||
roll_keep 5
|
||||
roll_keep_for 72h
|
||||
}
|
||||
format json
|
||||
}
|
||||
format json
|
||||
}
|
||||
}
|
||||
9
makefile
@@ -1,12 +1,15 @@
|
||||
VENV=source ./.venv/bin/activate;
|
||||
ALEMBIC=alembic -c ./server/backend/database/alembic/alembic.ini
|
||||
#VENV=source ./.venv/bin/activate;
|
||||
#ALEMBIC=alembic -c ./server/backend/database/alembic/alembic.ini
|
||||
VENV= .venv\Scripts\activate #Windows
|
||||
ALEMBIC=alembic -c server\backend\database\alembic\alembic.ini
|
||||
.PHONY: run run_debug migrate_head migrate_down migrate_history migrate_current migrate_heads migrate_stamp migrate
|
||||
run:
|
||||
$(VENV) python run.py --user_name admin
|
||||
run_debug:
|
||||
$(VENV) python run.py --mode debug --user_name admin
|
||||
migrate_head:
|
||||
$(VENV) $(ALEMBIC) upgrade head
|
||||
$(VENV) $(ALEMBIC)
|
||||
|
||||
migrate_down:
|
||||
$(VENV) $(ALEMBIC) downgrade -1
|
||||
migrate_history:
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
from fastapi import FastAPI, Depends, HTTPException,status
|
||||
from fastapi import FastAPI, Depends, HTTPException,status, Response, Cookie
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
import server.backend.schema.pydantic as pydantic
|
||||
import server.backend.database.db as db
|
||||
from server.backend.auth.JWT import signJWT, decodeJWT
|
||||
api = FastAPI(openapi_url="/api/openapi.json",docs_url="/api/docs", redoc_url="/api/redoc")
|
||||
security = HTTPBearer()
|
||||
security = HTTPBearer(auto_error=False)
|
||||
|
||||
async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
||||
token = credentials.credentials
|
||||
async def get_current_user(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
token_cookie: str = Cookie(default=None)
|
||||
):
|
||||
token = credentials.credentials if credentials else token_cookie
|
||||
if not token:
|
||||
raise HTTPException(status_code=401, detail="Not authenticated")
|
||||
user = decodeJWT(token)
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
return user
|
||||
async def check_roles(user=Depends(get_current_user)):
|
||||
user_check = await db.list_user(user["user_id"])
|
||||
@@ -58,10 +63,29 @@ async def list_users(user=Depends(check_roles)):
|
||||
list_of_users = await db.list_users()
|
||||
return list_of_users
|
||||
|
||||
@api.post("/api/auth",response_model=pydantic.Token)
|
||||
async def auth(code:pydantic.UserAccess):
|
||||
@api.post("/api/auth")
|
||||
async def auth(code: pydantic.UserAccess, response: Response):
|
||||
login = await db.login_user(code)
|
||||
if login == None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Forbidden")
|
||||
if login is None:
|
||||
raise HTTPException(status_code=401, detail="Forbidden")
|
||||
token = signJWT(login)
|
||||
response.set_cookie(
|
||||
key="token",
|
||||
value=token,
|
||||
httponly=True,
|
||||
secure=True,
|
||||
samesite="strict"
|
||||
)
|
||||
return {"access_token": token, "token_type": "bearer"}
|
||||
@api.get("/api/verify")
|
||||
async def verify(token: str = Cookie(default=None)):
|
||||
if not token:
|
||||
raise HTTPException(status_code=401, detail="No token")
|
||||
user = decodeJWT(token)
|
||||
if not user:
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
return {"status": "ok"}
|
||||
@api.post("/api/logout")
|
||||
async def logout(response: Response):
|
||||
response.delete_cookie(key="token")
|
||||
return {"status": "ok"}
|
||||
1
server/frontend/auth/fonts/MurreyC/COPYRIGHT.txt
Normal file
@@ -0,0 +1 @@
|
||||
DoubleRus encoding by Diai; unfinished
|
||||
BIN
server/frontend/auth/fonts/MurreyC/murreyc.eot
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.ttf
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.woff
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.woff2
Normal file
BIN
server/frontend/auth/image/bg.webp
Normal file
|
After Width: | Height: | Size: 357 KiB |
BIN
server/frontend/auth/image/hamster.webp
Normal file
|
After Width: | Height: | Size: 264 KiB |
@@ -0,0 +1,126 @@
|
||||
@font-face {
|
||||
font-family: "MurreyC";
|
||||
src: url("fonts/MurreyC/murreyc.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "MurreyC";
|
||||
src: url("fonts/MurreyC/murreyc.woff") format("woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "MurreyC";
|
||||
src: url("fonts/MurreyC/murreyc.eot") format("eot");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
body, html {
|
||||
font-family: "MurreyC";
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.bg {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
background: url("image/bg.webp") center center / cover no-repeat;
|
||||
|
||||
z-index: -1;
|
||||
}
|
||||
.glass-container {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
backdrop-filter: blur(16px);
|
||||
background: rgba(20,20,20,.35);
|
||||
}
|
||||
.login-box {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
background: url('./image/hamster.webp') no-repeat 50% 50%;
|
||||
padding-top: 50px;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
h2 {
|
||||
font-weight: 900;
|
||||
font-size: 50px;
|
||||
text-decoration: underline;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
input {
|
||||
width: 320px;
|
||||
height: 50px;
|
||||
padding: 0 20px;
|
||||
border-radius: 25px;
|
||||
border: 1px solid #000;
|
||||
background-color: #ffffff;
|
||||
outline: none;
|
||||
font-size: 30px;
|
||||
}
|
||||
button {
|
||||
margin-top: 10px;
|
||||
font-size: 30px;
|
||||
background-color: #3a1f09;
|
||||
padding: 10px 15px;
|
||||
border-radius: 33px;
|
||||
transition:
|
||||
transform .1s ease,
|
||||
background-color .1s ease,
|
||||
color .1s ease;
|
||||
color: #e5b97e;
|
||||
box-shadow: 0 4px 12px rgba(58,31,9,.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #f0c590;
|
||||
color: #b06029;
|
||||
transform: scale(1.015);
|
||||
}
|
||||
|
||||
/* ----------------------------------ADAPTIVE------------------------------------- */
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.login-box {
|
||||
background-size: 190%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 620px) {
|
||||
.login-box {
|
||||
background-size: 220%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 520px) {
|
||||
.login-box {
|
||||
background-size: 260%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 420px) {
|
||||
.login-box {
|
||||
background-size: 310%;
|
||||
}
|
||||
input {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 320px) {
|
||||
.login-box {
|
||||
background-size: 420%;
|
||||
background: url('./image/hamster.png') no-repeat 55% 50%;
|
||||
}
|
||||
input {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,25 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="login.css">
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/MurreyC/murreyc.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
>
|
||||
</head>
|
||||
<body>
|
||||
<div class="bg"></div>
|
||||
<div class="glass-container">
|
||||
<div class="login-box">
|
||||
<h2>Login</h2>
|
||||
<h2>Введите код</h2>
|
||||
<form id="loginForm">
|
||||
<input type="password" id="password" name="password" required placeholder="Code">
|
||||
<button type="submit">Login</button>
|
||||
<input type="password" id="password" name="password" required placeholder="Код">
|
||||
<button type="submit">Войти</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="login.js"></script>
|
||||
<script src="login.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,73 +1,64 @@
|
||||
function getToken() {
|
||||
return localStorage.getItem("token") || sessionStorage.getItem("token");
|
||||
}
|
||||
function tokenCheck(){
|
||||
const token = getToken();
|
||||
if (token) {
|
||||
window.location.href = "http://localhost:5500/server/frontend/main/index.html";
|
||||
}
|
||||
}
|
||||
document.getElementById('loginForm').addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
const password = document.getElementById('password').value;
|
||||
const userData = {
|
||||
password
|
||||
};
|
||||
try {
|
||||
const response = await fetch("http://localhost:8000/api/auth", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
password: userData.password
|
||||
}),
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
fetch('/api/verify', { credentials: 'include' })
|
||||
.then(r => { if (r.ok) window.location.href = '/main/'; })
|
||||
.catch(() => {});
|
||||
|
||||
const data = await response.json(); // читаем только один раз
|
||||
if (response.ok) { // сохраняем только при успехе
|
||||
// в sessionstorage до перезахода в браузер(
|
||||
sessionStorage.setItem("token", data.access_token);
|
||||
document.getElementById('loginForm').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
window.location.href = 'http://localhost:5500/server/frontend/main/index.html';
|
||||
} else { //парсинг и вывод ошибок, если есть
|
||||
if (Array.isArray(data.detail)) {
|
||||
const messages = data.detail.map(e => {
|
||||
const field = e.loc.filter(locPart => locPart !== 'body').join(' -> ');
|
||||
return `${field}: ${e.msg}`;
|
||||
});
|
||||
showError(messages);
|
||||
} else if (typeof data.detail === 'string') {
|
||||
showError([data.detail]);
|
||||
const code = document.getElementById('password').value;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/auth', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include', // ← чтобы браузер принял cookie
|
||||
body: JSON.stringify({ code })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
window.location.href = '/main/';
|
||||
} else {
|
||||
showError(['Unknown error']);
|
||||
if (Array.isArray(data.detail)) {
|
||||
const messages = data.detail.map(e => {
|
||||
const field = e.loc.filter(p => p !== 'body').join(' -> ');
|
||||
return `${field}: ${e.msg}`;
|
||||
});
|
||||
showError(messages);
|
||||
} else if (typeof data.detail === 'string') {
|
||||
showError([data.detail]);
|
||||
} else {
|
||||
showError(['Unknown error']);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
showError(['Connection error: ' + err.message]);
|
||||
}
|
||||
} catch (err) {
|
||||
showError(['Connection error: ' + err.message]);
|
||||
}
|
||||
});
|
||||
});
|
||||
function showError(messages){ //Добавление их на form со стилями
|
||||
|
||||
function showError(messages) {
|
||||
let errorElem = document.getElementById('formError');
|
||||
let container = document.getElementById('glass-container');
|
||||
if (!errorElem){
|
||||
if (!errorElem) {
|
||||
errorElem = document.createElement('div');
|
||||
errorElem.style.transition="3s";
|
||||
errorElem.id = 'formError';
|
||||
errorElem.style.color = 'red';
|
||||
errorElem.style.marginTop = '20px';
|
||||
errorElem.style.fontSize = '14px';
|
||||
errorElem.style.fontWeight = '100';
|
||||
errorElem.style.marginBottom = '20px';
|
||||
errorElem.style.lineHeight="120%";
|
||||
errorElem.style.height = 'auto';
|
||||
const form = document.getElementById('loginForm');
|
||||
form.insertAdjacentElement('afterend', errorElem);
|
||||
};
|
||||
errorElem.style.cssText = `
|
||||
color: red;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 100;
|
||||
line-height: 120%;
|
||||
transition: 3s;
|
||||
`;
|
||||
document.getElementById('loginForm').insertAdjacentElement('afterend', errorElem);
|
||||
}
|
||||
errorElem.innerHTML = '';
|
||||
messages.forEach(msg => {
|
||||
const li = document.createElement('li');
|
||||
li.style.listStyleType="none";
|
||||
li.style.listStyleType = 'none';
|
||||
li.textContent = msg;
|
||||
errorElem.appendChild(li);
|
||||
});
|
||||
|
||||
@@ -1,69 +1,55 @@
|
||||
function getToken() {
|
||||
return localStorage.getItem("token") || sessionStorage.getItem("token");
|
||||
}
|
||||
function tokenCheck(){
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
window.location.href = "http://localhost:5500/server/frontend/auth/login.html";
|
||||
}
|
||||
}
|
||||
|
||||
tokenCheck()
|
||||
document.getElementById('logoutForm').addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
localStorage.removeItem("token");
|
||||
sessionStorage.removeItem("token");
|
||||
tokenCheck();
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const form = document.querySelector(".form-info");
|
||||
|
||||
form.addEventListener("submit", async (e) => {
|
||||
// Проверка авторизации через cookie
|
||||
fetch('/api/verify', { credentials: 'include' })
|
||||
.then(r => { if (!r.ok) window.location.href = '/'; })
|
||||
.catch(() => { window.location.href = '/'; });
|
||||
|
||||
// Logout — удаляем cookie на бэкенде
|
||||
document.getElementById('logoutForm').addEventListener('click', async function(e) {
|
||||
e.preventDefault();
|
||||
// try {
|
||||
// собираем данные из формы
|
||||
const name = document.getElementById('ffname').value || "";
|
||||
const middlename = document.getElementById('fmname').value || "";
|
||||
const surname = document.getElementById('flname').value || "";
|
||||
const text_field = document.getElementById('text_field')?.value || "";
|
||||
const food = document.querySelector('input[name="food"]:checked')?.value || "";
|
||||
const types_of_alco = Array.from(document.querySelectorAll('input[name="drink"]:checked'))
|
||||
.map(el => el.value)
|
||||
.join(', ');
|
||||
await fetch('/api/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'include'
|
||||
});
|
||||
window.location.href = '/';
|
||||
});
|
||||
|
||||
const guestData = {
|
||||
name: name,
|
||||
middlename: middlename,
|
||||
surname: surname,
|
||||
text_field: text_field,
|
||||
activated: true,
|
||||
types_of_food: food,
|
||||
types_of_alco: types_of_alco
|
||||
};
|
||||
console.log(guestData)
|
||||
document.querySelector(".form-info").addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// отправка на /api/update с Authorization
|
||||
// const updateResponse = await fetch('/api/update', {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// 'Authorization': `Bearer ${token}`
|
||||
// },
|
||||
// body: JSON.stringify(guestData)
|
||||
// });
|
||||
const guestData = {
|
||||
name: document.getElementById('ffname').value || "",
|
||||
middlename: document.getElementById('fmname').value || "",
|
||||
surname: document.getElementById('flname').value || "",
|
||||
text_field: document.getElementById('text_field')?.value || "",
|
||||
activated: true,
|
||||
types_of_food: document.querySelector('input[name="food"]:checked')?.value || "",
|
||||
types_of_alco: Array.from(document.querySelectorAll('input[name="drink"]:checked'))
|
||||
.map(el => el.value)
|
||||
.join(', ')
|
||||
};
|
||||
|
||||
// if (!updateResponse.ok) {
|
||||
// throw new Error('Ошибка при отправке формы');
|
||||
// }
|
||||
try {
|
||||
const response = await fetch('/api/update', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include', // ← токен идёт через cookie
|
||||
body: JSON.stringify(guestData)
|
||||
});
|
||||
|
||||
// const updateData = await updateResponse.json();
|
||||
// console.log('Форма успешно отправлена:', updateData);
|
||||
if (!response.ok) {
|
||||
const err = await response.json();
|
||||
throw new Error(JSON.stringify(err.detail || 'Ошибка при отправке'));
|
||||
}
|
||||
|
||||
// } catch (err) {
|
||||
// console.error(err);
|
||||
// alert('Ошибка: ' + err.message);
|
||||
// }
|
||||
const data = await response.json();
|
||||
console.log('Успешно:', data);
|
||||
alert('Данные сохранены!');
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Ошибка: ' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
BIN
server/frontend/main/images/25.webp
Normal file
|
After Width: | Height: | Size: 323 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 288 KiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 612 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 16 KiB |
3
server/frontend/main/images/icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?><svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css">
|
||||
.st0{display:none;}
|
||||
</style><g class="st0" id="grid"/><g id="icon"><path d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z"/><path d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z"/><path d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
server/frontend/main/images/maps/loft.webp
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
server/frontend/main/images/maps/zags.webp
Normal file
|
After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 362 KiB |
|
Before Width: | Height: | Size: 197 KiB |
BIN
server/frontend/main/images/people/bride.webp
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
server/frontend/main/images/people/groom.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
server/frontend/main/images/photos/1.webp
Normal file
|
After Width: | Height: | Size: 689 KiB |
BIN
server/frontend/main/images/photos/10.webp
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
server/frontend/main/images/photos/2.webp
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
server/frontend/main/images/photos/3.webp
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
server/frontend/main/images/photos/4.webp
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
server/frontend/main/images/photos/5.webp
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
server/frontend/main/images/photos/6.webp
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
server/frontend/main/images/photos/7.webp
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
server/frontend/main/images/photos/8.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
server/frontend/main/images/photos/9.webp
Normal file
|
After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 525 KiB |
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#37BBFE"/>
|
||||
<stop offset="1" stop-color="#007DBB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 920 B |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/camera.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB |
BIN
server/frontend/main/images/time/disco-ball_18181959.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
server/frontend/main/images/time/food.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
server/frontend/main/images/time/guest1.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/ring.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/wedding-dinner_11196102.webp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 74 KiB |
@@ -7,59 +7,68 @@
|
||||
<title>Wedding invitation</title>
|
||||
<link rel="stylesheet" href="reset.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
|
||||
<link rel="preload" href="fonts/yourfont.woff2" as="font" type="font/woff2" crossorigin>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="bg"></div>
|
||||
<header class="header">
|
||||
<nav class="nav">
|
||||
|
||||
<div class="burger" id="burger">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
|
||||
<nav class="nav" id="nav">
|
||||
<ul class="menu">
|
||||
<!-- 1 -->
|
||||
<li class="item">
|
||||
<a href="#heading" class="link">
|
||||
Добро пожаловать!
|
||||
</a>
|
||||
</li>
|
||||
<!-- 2 -->
|
||||
<li class="item">
|
||||
<a href="#people" class="link">
|
||||
Список гостей
|
||||
</a>
|
||||
</li>
|
||||
<!-- 3 -->
|
||||
<li class="item">
|
||||
<a href="#timetable" class="link">
|
||||
Расписание
|
||||
</a>
|
||||
</li>
|
||||
<!-- 4 -->
|
||||
<li class="item">
|
||||
<a href="#transfer" class="link">
|
||||
Путешествие
|
||||
</a>
|
||||
</li>
|
||||
<!-- 5 -->
|
||||
<li class="item">
|
||||
<a href="#photos" class="link">
|
||||
Фотографии
|
||||
</a>
|
||||
</li>
|
||||
<!-- 6 -->
|
||||
<li class="item">
|
||||
<a href="#to-do-list" class="link">
|
||||
Список задач
|
||||
</a>
|
||||
</li>
|
||||
<!-- 7 -->
|
||||
<li class="item">
|
||||
<a href="#answer" class="link">
|
||||
Прошу ответить
|
||||
</a>
|
||||
</li>
|
||||
<div class="items_up">
|
||||
<!-- 1 -->
|
||||
<li class="item">
|
||||
<a href="#" class="link">
|
||||
Добро пожаловать!
|
||||
</a>
|
||||
</li>
|
||||
<!-- 2 -->
|
||||
<li class="item">
|
||||
<a href="#people" class="link">
|
||||
Список гостей
|
||||
</a>
|
||||
</li>
|
||||
<!-- 3 -->
|
||||
<li class="item">
|
||||
<a href="#timetable" class="link">
|
||||
Расписание
|
||||
</a>
|
||||
</li>
|
||||
<!-- 4 -->
|
||||
<li class="item">
|
||||
<a href="#transfer" class="link">
|
||||
Путешествие
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
<div class="items_down">
|
||||
<!-- 5 -->
|
||||
<li class="item item_none">
|
||||
<a href="#photos" class="link">
|
||||
Фотографии
|
||||
</a>
|
||||
</li>
|
||||
<!-- 6 -->
|
||||
<li class="item">
|
||||
<a href="#to-do-list" class="link">
|
||||
Список задач
|
||||
</a>
|
||||
</li>
|
||||
<!-- 7 -->
|
||||
<li class="item">
|
||||
<a href="#answer" class="link">
|
||||
Прошу ответить
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -74,21 +83,25 @@
|
||||
</h2>
|
||||
<h3 class="heading_date">22 августа 2026</h3>
|
||||
<p class="heading_text">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste possimus ipsa, labore repudiandae
|
||||
ratione placeat dolore vitae praesentium perspiciatis ipsam non illum reiciendis accusamus quae
|
||||
quo veritatis maiores quod sequi. Ipsam at consequatur quia recusandae, rem dicta autem quaerat
|
||||
placeat?
|
||||
Мы — та самая история, которая началась со странного сообщения и превратилась в нечто настоящее.
|
||||
В нас есть легкость и смех, который когда-то стал началом всего, любовь к простым вещам вроде
|
||||
чашки чая и бесконечных разговоров обо всем на свете. Мы разные и неидеальные, но именно в этом
|
||||
— наше совпадение: нам всегда интересно друг с другом, спокойно и по-настоящему. Мы умеем
|
||||
смеяться до слез, поддерживать в нужный момент и находить радость в мелочах. И, пожалуй, самое
|
||||
важное — мы с самого начала почувствовали, что это надолго, и с каждым днем только убеждаемся в
|
||||
этом.
|
||||
</p>
|
||||
<button class="btn_share" button>
|
||||
Подтвердить участие
|
||||
<a class="btn_link" href="#answer">
|
||||
Подтвердить участие
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<aside>
|
||||
<div class="time">
|
||||
<!-- отсчет до даты -->
|
||||
00:00:00
|
||||
<p id="demo"></p>
|
||||
</div>
|
||||
</aside>
|
||||
<section class="people" id="people">
|
||||
@@ -97,30 +110,33 @@
|
||||
</h4>
|
||||
<div class="newlywed">
|
||||
<div class="newlywed_item">
|
||||
<img class="img_newlywed" src="images/people//IMG_20260107_140110_500.jpg" alt="groom">
|
||||
<img class="img_newlywed" src="images/people/groom.webp" alt="groom" loading="lazy"
|
||||
decoding="async">
|
||||
<div class="newlywed_text">
|
||||
<h3 class="newlywed_title">Жених</h3>
|
||||
<p class="newlywed_info">Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui voluptatum
|
||||
odio autem, ut dolorum suscipit soluta reiciendis quam reprehenderit saepe doloribus
|
||||
asperiores
|
||||
architecto? Debitis magnam, exercitationem nam temporibus eos molestias?</p>
|
||||
<p class="newlywed_info">
|
||||
Самый лучший, милый,классный, очаровательный, крутой, забавный, любящий, удивительный,
|
||||
необычный, прелестный, веселый, смешной, умный, добрый,красивый, гениальный</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="newlywed_item">
|
||||
<img class="img_newlywed" src="images/people/IMG_20260107_140120_301.jpg" alt="bride">
|
||||
<img class="img_newlywed" src="images/people/bride.webp" alt="bride" loading="lazy"
|
||||
decoding="async">
|
||||
<div class="newlywed_text">
|
||||
<h3 class="newlywed_title">Невеста</h3>
|
||||
<p class="newlywed_info">Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui voluptatum
|
||||
odio autem, ut dolorum suscipit soluta reiciendis quam reprehenderit saepe doloribus
|
||||
asperiores
|
||||
architecto? Debitis magnam, exercitationem nam temporibus eos molestias?</p>
|
||||
<p class="newlywed_info">Я — творческий и активный человек, люблю петь, путешествовать и
|
||||
создавать что-то своими руками. Увлекаюсь готовкой, особенно десертами, которыми радую
|
||||
близких. Люблю веселье, тусовки, животных и жизнь без
|
||||
скуки.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="guest_list">
|
||||
<!-- <div class="guest_list">
|
||||
<div class="guest_inner">
|
||||
<!-- 1 -->
|
||||
<div class="guest_item">
|
||||
<!-- <div class="guest_item">
|
||||
<div class="guest_index">
|
||||
Стол 1
|
||||
</div>
|
||||
@@ -147,9 +163,9 @@
|
||||
Lorem, ipsum.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2 -->
|
||||
<div class="guest_item">
|
||||
</div> -->
|
||||
<!-- 2 -->
|
||||
<!-- <div class="guest_item">
|
||||
<div class="guest_index">
|
||||
Стол 1
|
||||
</div>
|
||||
@@ -176,9 +192,9 @@
|
||||
Lorem, ipsum.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3 -->
|
||||
<div class="guest_item">
|
||||
</div> -->
|
||||
<!-- 3 -->
|
||||
<!-- <div class="guest_item">
|
||||
<div class="guest_index">
|
||||
Стол 1
|
||||
</div>
|
||||
@@ -205,8 +221,8 @@
|
||||
Lorem, ipsum.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="timetable" id="timetable">
|
||||
@@ -220,70 +236,68 @@
|
||||
<!-- 1 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/ring.png" alt="ring" class="time_img">
|
||||
<h6 class="time_h6">10:40</h6>
|
||||
<p class="time_p">Церемония</p>
|
||||
<div class="time_comment">Начало нашего свадебного дня и самый важный момент для нас
|
||||
<img src="images/time/guest1.webp" alt="ring" class="time_img" loading="lazy"
|
||||
decoding="async">
|
||||
<h6 class="time_h6">10:10</h6>
|
||||
<p class="time_p">Сбор гостей</p>
|
||||
<div class="time_comment">Приходите заранее, чтобы спокойно встретиться и сделать
|
||||
фото
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/camera.png" alt="camera" class="time_img">
|
||||
<img src="images/time/ring.webp" alt="ring" class="time_img" loading="lazy"
|
||||
decoding="async">
|
||||
<h6 class="time_h6">10:40</h6>
|
||||
<p class="time_p">Церемония</p>
|
||||
<div class="time_comment">Самый трогательный и важный момент дня — регистрация
|
||||
нашего брака
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/camera.webp" alt="camera" class="time_img" loading="lazy"
|
||||
decoding="async">
|
||||
<h6 class="time_h6">11:30</h6>
|
||||
<p class="time_p">Фотосессия</p>
|
||||
<div class="time_comment">После церемонии мы ненадолго отправимся на фотосессию,
|
||||
чтобы сохранить этот день в памяти</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/wedding-dinner_11196102.png" alt="" class="time_img">
|
||||
<h6 class="time_h6">14:00</h6>
|
||||
<p class="time_p">Фуршет и бармен</p>
|
||||
<div class="time_comment">Берем напиток, закуски и наслаждаемся началом вечера</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="time_row_down">
|
||||
<!-- 4 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/free-icon-fireworks-7201451.png" alt="" class="time_img">
|
||||
<h6 class="time_h6">14:30</h6>
|
||||
<p class="time_p">Поздравления и подарки</p>
|
||||
<div class="time_comment">Мы будем рады теплым словам и подаркам во время фуршета
|
||||
</div>
|
||||
<img src="images/time/wedding-dinner_11196102.webp" alt="" class="time_img"
|
||||
loading="lazy" decoding="async">
|
||||
<h6 class="time_h6">18:30</h6>
|
||||
<p class="time_p">Сбор гостей и фуршет</p>
|
||||
<div class="time_comment">Берем напиток, закуски и наслаждаемся началом вечера</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="time_line"></div>
|
||||
<div class="time_row_down">
|
||||
<!-- 5 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/food.png" alt="" class="time_img">
|
||||
<h6 class="time_h6">17:00</h6>
|
||||
<img src="images/time/food.webp" alt="" class="time_img" loading="lazy"
|
||||
decoding="async">
|
||||
<h6 class="time_h6">19:00</h6>
|
||||
<p class="time_p">Банкет</p>
|
||||
<div class="time_comment">Приглашаем вас за столы, чтобы продолжить вечер в тёплой и
|
||||
уютной атмосфере. Приветственный тост</div>
|
||||
уютной атмосфере
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 6 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/cake.png" alt="" class="time_img">
|
||||
<h6 class="time_h6">19:00</h6>
|
||||
<p class="time_p">Свадебный торт</p>
|
||||
<div class="time_comment">Самый сладкий момент вечера. Чай или кофе находятся в
|
||||
велком зоне</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 7 -->
|
||||
<div class="row_up_item">
|
||||
<div class="time_img_box">
|
||||
<img src="images/time/disco-ball_18181959.png" alt="" class="time_img">
|
||||
<h6 class="time_h6">19:30</h6>
|
||||
<img src="images/time/disco-ball_18181959.webp" alt="" class="time_img"
|
||||
loading="lazy" decoding="async">
|
||||
<h6 class="time_h6">22:00</h6>
|
||||
<p class="time_p">Танцы</p>
|
||||
<div class="time_comment">Приглашаем вас на танцпол. Танцуйте столько, сколько
|
||||
захочется</div>
|
||||
@@ -293,6 +307,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="transfer" id="transfer">
|
||||
<h4 class="transfer_title">
|
||||
@@ -301,25 +316,34 @@
|
||||
<div class="transfer_inner">
|
||||
<div class="transfer_map">
|
||||
<div class="map">
|
||||
<div style="position:relative;overflow:hidden; border-radius: 33px;">
|
||||
<a href="https://www.google.com/maps/place/Glavnoye+Upravleniye+Zapisi+Aktov+Grazhdanskogo+Sostoyaniya+Tverskoy+Oblasti/@56.8571039,35.901453,17z/data=!3m1!4b1!4m6!3m5!1s0x46b687a4d4edacad:0x15df9a38c874eb5d!8m2!3d56.857101!4d35.9040279!16s%2Fg%2F11ls6j2lvj?entry=ttu&g_ep=EgoyMDI2MDMxMS4wIKXMDSoASAFQAw%3D%3D"
|
||||
style="color:#eee;font-size:12px;position:absolute;top:0px;">
|
||||
Главное управление записи актов гражданского состояния</a>
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2181.349338718406!2d35.901452977352925!3d56.85710390639812!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x46b687a4d4edacad%3A0x15df9a38c874eb5d!2sGlavnoye%20Upravleniye%20Zapisi%20Aktov%20Grazhdanskogo%20Sostoyaniya%20Tverskoy%20Oblasti!5e0!3m2!1sen!2s!4v1773428540512!5m2!1sen!2s" width="760" height="500" style="border:1px;" allowfullscreen="true" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
<div class="map_div">
|
||||
<a href="https://maps.app.goo.gl/ZYTyA2qTvCpnXTdN7" target="_blank" class="map_link">
|
||||
<img src="images/maps/zags.webp" alt="ЗАГС" class="map_preview" loading="lazy">
|
||||
|
||||
<div class="map_btn">
|
||||
Открыть маршрут
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p class="map_adress">Тверь, Свободный переулок, 5</p>
|
||||
<a href="https://maps.app.goo.gl/ZYTyA2qTvCpnXTdN7" class="map_adress" target="_blank">Тверь,
|
||||
Свободный переулок, 5</a>
|
||||
<h6 class="map_info">Начало в</h6>
|
||||
<h6 class="map_time">10:30</h6>
|
||||
<h6 class="map_time">10:10</h6>
|
||||
</div>
|
||||
<div class="map">
|
||||
<div style="position:relative;overflow:hidden; border-radius: 33px;">
|
||||
<a href="https://www.google.com/maps/place/Loft+1870+%7C+%D0%9F%D0%BB%D0%BE%D1%89%D0%B0%D0%B4%D0%BA%D0%B0+%D0%B4%D0%BB%D1%8F+%D0%BC%D0%B5%D1%80%D0%BE%D0%BF%D1%80%D0%B8%D1%8F%D1%82%D0%B8%D0%B9+%D0%A2%D0%B2%D0%B5%D1%80%D1%8C+%7C+%D0%BA%D0%B5%D0%B9%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B3+%D0%BD%D0%B0+%D1%81%D0%B2%D0%B0%D0%B4%D1%8C%D0%B1%D1%83,+%D0%B1%D0%B0%D0%BD%D0%BA%D0%B5%D1%82%D0%BD%D1%8B%D0%B9+%D0%B7%D0%B0%D0%BB/@56.850656,35.8603082,17.32z/data=!3m1!5s0x46b687a53bac0dcf:0x5c270d07d710d5a!4m6!3m5!1s0x46b68764eb0c1387:0x7cb135f5414bc1e0!8m2!3d56.8508612!4d35.8650531!16s%2Fg%2F11p0wc5v7q?entry=ttu&g_ep=EgoyMDI2MDMxMS4wIKXMDSoASAFQAw%3D%3D"
|
||||
style="color:#eee;font-size:12px;position:absolute;top:0px;">Лофт 1870</a>
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1749.675516895515!2d35.86030818806184!3d56.850656040536194!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x46b68764eb0c1387%3A0x7cb135f5414bc1e0!2zTG9mdCAxODcwIHwg0J_Qu9C-0YnQsNC00LrQsCDQtNC70Y8g0LzQtdGA0L7Qv9GA0LjRj9GC0LjQuSDQotCy0LXRgNGMIHwg0LrQtdC50YLQtdGA0LjQvdCzINC90LAg0YHQstCw0LTRjNCx0YMsINCx0LDQvdC60LXRgtC90YvQuSDQt9Cw0Ls!5e0!3m2!1sen!2s!4v1773428705434!5m2!1sen!2s" width="760" height="500" style="border:1px;" allowfullscreen="true" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
<div class="map_div">
|
||||
<a href="https://maps.app.goo.gl/5WFQzNhDqmo2dBxXA" target="_blank" class="map_link">
|
||||
<img src="images/maps/loft.webp" alt="ЗАГС" class="map_preview" loading="lazy">
|
||||
|
||||
<div class="map_btn">
|
||||
Открыть маршрут
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p class="map_adress">Тверь, улица Двор Пролетарки, 16</p>
|
||||
<a href="https://maps.app.goo.gl/5WFQzNhDqmo2dBxXA" class="map_adress" target="_blank">Тверь,
|
||||
улица Двор Пролетарки, 16</a>
|
||||
<h6 class="map_info">Начало в</h6>
|
||||
<h6 class="map_time">14:00</h6>
|
||||
<h6 class="map_time">18:30</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -329,54 +353,61 @@
|
||||
Фотографии
|
||||
</h4>
|
||||
<!-- Slider main container -->
|
||||
<div class="swiper">
|
||||
<!-- Additional required wrapper -->
|
||||
<div class="swiper-wrapper">
|
||||
<!-- Slides -->
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos//IMG_20260223_151049_713.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151049_713.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151049_713.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
||||
</div>
|
||||
</div>
|
||||
<!-- If we need pagination -->
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper">
|
||||
<!-- Additional required wrapper -->
|
||||
<div class="swiper-wrapper">
|
||||
<!-- Slides -->
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/1.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/2.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/3.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/4.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/5.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/6.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/7.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/8.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/9.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
<div class="swiper-slide">
|
||||
<img class="swiper_img" src="images/photos/10.webp" alt="photo" width="500" height="500"
|
||||
loading="lazy" decoding="async">
|
||||
</div>
|
||||
</div>
|
||||
<!-- If we need pagination -->
|
||||
<div class="swiper-pagination"></div>
|
||||
|
||||
<!-- If we need navigation buttons -->
|
||||
<div class="swiper-button-prev"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<!-- If we need navigation buttons -->
|
||||
<div class="swiper-button-prev"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
|
||||
<!-- If we need scrollbar -->
|
||||
<div class="swiper-scrollbar"></div>
|
||||
</div>
|
||||
<!-- If we need scrollbar -->
|
||||
<div class="swiper-scrollbar"></div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="to-do-list" id="to-do-list">
|
||||
<h4 class="do-list_title">
|
||||
@@ -385,133 +416,279 @@
|
||||
<div class="to-do-list_wrapper">
|
||||
<div class="to-do-list_items">
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Поздравить молодых и сказать тёплые слова
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Вручить подарок молодожёнам
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Сделать фото и видео, чтобы потом было что выложить
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Поднять тост за любовь
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Добраться до свадебного торта, сфотографировать его
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Потанцевать хотя бы один медленный танец
|
||||
</div>
|
||||
<div class="to-do-list_item">
|
||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
||||
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<g class="st0" id="grid" />
|
||||
<g id="icon">
|
||||
<path
|
||||
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||
<path
|
||||
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||
<path
|
||||
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||
</g>
|
||||
</svg>
|
||||
Повеселиться так, чтобы этот день запомнился
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="answer" id="answer">
|
||||
<h4 class="answer_title">Прошу ответить</h4>
|
||||
<h4 class="answer_title">Прошу ответить</h4>
|
||||
|
||||
<div class="answer_wrapper">
|
||||
<h6 class="answer_heading">
|
||||
Просим Вас заполнить форму и подтвердить своё участие
|
||||
</h6>
|
||||
<div class="answer_wrapper">
|
||||
<h6 class="answer_heading">
|
||||
Просим Вас заполнить форму и подтвердить своё участие
|
||||
</h6>
|
||||
|
||||
<form class="form-info">
|
||||
<form class="form-info">
|
||||
|
||||
<!-- Левая колонка -->
|
||||
<div class="form_name">
|
||||
<label>Имя
|
||||
<input type="text" name="firstName" id="ffname" required>
|
||||
</label>
|
||||
<!-- Левая колонка -->
|
||||
<div class="form_name">
|
||||
<label class="label_style">Имя
|
||||
<input type="text" name="firstName" id="ffname" required>
|
||||
</label>
|
||||
|
||||
<label>Отчество
|
||||
<input type="text" name="middleName" id="fmname" required>
|
||||
</label>
|
||||
<label class="label_style">Отчество
|
||||
<input type="text" name="middleName" id="fmname" required>
|
||||
</label>
|
||||
|
||||
<label>Фамилия
|
||||
<input type="text" name="lastName" id="flname" required>
|
||||
</label>
|
||||
<label class="label_style">Фамилия
|
||||
<input type="text" name="lastName" id="flname" required>
|
||||
</label>
|
||||
|
||||
<label class="label_1">Комментарий
|
||||
<textarea cols="1.5" rows="1" type="text" name="lastName" id="fename"
|
||||
placeholder="Напишите здесь о ваших особых предпочтениях и аллергиях"></textarea>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Средняя колонка -->
|
||||
<div class="form_menu">
|
||||
<p class="block_title">Горячее блюдо</p>
|
||||
|
||||
<label class="option">
|
||||
<input type="radio" name="food" id="rmeat" value="meat" required>
|
||||
Мясо
|
||||
</label>
|
||||
|
||||
<label class="option">
|
||||
<input type="radio" name="food" id="rfish" value="fish">
|
||||
Рыба
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Правая колонка -->
|
||||
<div class="form_drink">
|
||||
<p class="block_title">Напитки</p>
|
||||
|
||||
<label class="option"><input type="checkbox" name="drink" value="champagne" id="cchampagne">
|
||||
Шампанское</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="wine" id="cwine"> Вино</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="vodka" id="cvodka">
|
||||
Водка</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="whiskey" id="cwhiskey">
|
||||
Виски</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="tequila" id="ctequila">
|
||||
Текила</label>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
<form class="form-connect">
|
||||
<button type="submit" class="answer_btn" id="bsubmit">
|
||||
Подтвердить участие
|
||||
</button>
|
||||
<button type="logout" class="answer_btn" id="logoutForm">
|
||||
Выйти
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Средняя колонка -->
|
||||
<div class="form_menu">
|
||||
<p class="block_title">Горячее блюдо</p>
|
||||
|
||||
<label class="option">
|
||||
<input type="radio" name="food" id="rmeat" value="meat" required>
|
||||
Мясо
|
||||
</label>
|
||||
|
||||
<label class="option">
|
||||
<input type="radio" name="food" id="rfish" value="fish">
|
||||
Рыба
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Правая колонка -->
|
||||
<div class="form_drink">
|
||||
<p class="block_title">Напитки</p>
|
||||
|
||||
<label class="option"><input type="checkbox" name="drink" value="champagne" id="cchampagne"> Шампанское</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="wine" id="cwine"> Вино</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="vodka" id="cvodka"> Водка</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="whiskey" id="cwhiskey"> Виски</label>
|
||||
<label class="option"><input type="checkbox" name="drink" value="tequila" id="ctequila"> Текила</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="answer_btn" id="bsubmit">
|
||||
Подтвердить участие
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer_inner">
|
||||
<div class="footer_title">
|
||||
<h1 class="fotter_logo">
|
||||
Алёна и Дмитрий
|
||||
</h1>
|
||||
<p class="footer_date">22 августа 2026</p>
|
||||
<p class="footer_place">LOFT 1870</p>
|
||||
<h1 class="fotter_logo">
|
||||
Алёна и Дмитрий
|
||||
</h1>
|
||||
<p class="footer_date">22 августа 2026</p>
|
||||
<p class="footer_place">LOFT 1870</p>
|
||||
</div>
|
||||
<div class="footer_contacts">
|
||||
<p class="footer_text">"С нетерпением ждем встречи!"</p>
|
||||
<div class="footer_cntcts">
|
||||
<a class="footer_cnt" href="https://t.me/Alena7729" target="_blank"><?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#37BBFE"/>
|
||||
<stop offset="1" stop-color="#007DBB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
Алёна</a>
|
||||
<a class="footer_cnt" href="https://t.me/DisaTylov" target="_blank"><?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#37BBFE"/>
|
||||
<stop offset="1" stop-color="#007DBB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
Дмитрий</a>
|
||||
</div>
|
||||
<a class="footer_cnt" href="https://t.me/Alena7729" target="_blank">
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)" />
|
||||
<path
|
||||
d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z"
|
||||
fill="white" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#37BBFE" />
|
||||
<stop offset="1" stop-color="#007DBB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
Алёна
|
||||
</a>
|
||||
<a class="footer_cnt" href="https://t.me/DisaTylov" target="_blank">
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)" />
|
||||
<path
|
||||
d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z"
|
||||
fill="white" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#37BBFE" />
|
||||
<stop offset="1" stop-color="#007DBB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
Дмитрий
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_copy">
|
||||
<div class="footer_hashtag">#свадьба2026</div>
|
||||
|
||||
@@ -1,30 +1,91 @@
|
||||
const swiper = new Swiper('.swiper', {
|
||||
// Optional parameters
|
||||
direction: 'horizontal',
|
||||
loop: true,
|
||||
|
||||
// Navigation arrows
|
||||
direction: 'horizontal',
|
||||
loop: false,
|
||||
|
||||
// Производительность
|
||||
preloadImages: false,
|
||||
lazy: true,
|
||||
watchSlidesProgress: true,
|
||||
|
||||
// Слайды
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 15,
|
||||
|
||||
// Анимация
|
||||
speed: 700,
|
||||
|
||||
// Навигация
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
},
|
||||
|
||||
// And if we need scrollbar
|
||||
// Скроллбар
|
||||
scrollbar: {
|
||||
el: '.swiper-scrollbar',
|
||||
hide: true,
|
||||
},
|
||||
|
||||
speed: 1000,
|
||||
breakpoints: {
|
||||
740: {
|
||||
slidesPerView: 1,
|
||||
},
|
||||
1200: {
|
||||
slidesPerView: 2,
|
||||
},
|
||||
1600: {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
// Адаптив
|
||||
breakpoints: {
|
||||
330: {
|
||||
slidesPerView: 1,
|
||||
},
|
||||
|
||||
768: {
|
||||
slidesPerView: 2,
|
||||
},
|
||||
|
||||
1400: {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Set the date we're counting down to
|
||||
var countDownDate = new Date("Aug 22, 2026 10:40:00").getTime();
|
||||
|
||||
// Update the count down every 1 second
|
||||
var x = setInterval(function() {
|
||||
|
||||
// Get today's date and time
|
||||
var now = new Date().getTime();
|
||||
|
||||
// Find the distance between now and the count down date
|
||||
var distance = countDownDate - now;
|
||||
|
||||
// Time calculations for days, hours, minutes and seconds
|
||||
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||
|
||||
// Display the result in the element with id="demo"
|
||||
document.getElementById("demo").innerHTML = days + "д " + hours + "ч "
|
||||
+ minutes + "м " + seconds + "с ";
|
||||
|
||||
// If the count down is finished, write some text
|
||||
if (distance < 0) {
|
||||
clearInterval(x);
|
||||
document.getElementById("demo").innerHTML = "EXPIRED";
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
|
||||
const burger = document.getElementById('burger');
|
||||
const nav = document.getElementById('nav');
|
||||
const links = document.querySelectorAll('.menu .link');
|
||||
|
||||
burger.addEventListener('click', () => {
|
||||
burger.classList.toggle('active');
|
||||
nav.classList.toggle('active');
|
||||
});
|
||||
|
||||
links.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
burger.classList.remove('active');
|
||||
nav.classList.remove('active');
|
||||
});
|
||||
});
|
||||