Start repo

This commit is contained in:
2026-02-03 01:24:56 +01:00
commit 7f27463f5a
267 changed files with 54491 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
__pycache__
app/static/img/fullsize
app/static/img/portfolio

5
MaPagePerso.py Normal file
View File

@@ -0,0 +1,5 @@
from app import app
if __name__ == '__main__' :
app.run(host=app.config['HOST'], port=app.config['PORT'], debug=True)

11
README.md Normal file
View File

@@ -0,0 +1,11 @@
Creer l'environement virtuel
-> python3 -m venv flaskvenv
lancer l'environment
-> source venv/bin/activate
Enfin installer Flask
-> pip3 install -r requirements.txt
./launch.sh

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

11
app/__init__.py Normal file
View File

@@ -0,0 +1,11 @@
from flask import Flask, url_for
from app.utils import init_app
app = Flask(__name__)
app.config.from_pyfile('config.py')
if init_app(app.config) == False:
exit(1)
from app import routes

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

14
app/config.py Normal file
View File

@@ -0,0 +1,14 @@
HOST="fd01::2"
PORT="8000"
SECRET_KEY = "CHANGE-ME"
STATIC_PATH = './app/static/'
JSON_FILE = './ident.json'
IMAGES_PATH = ['/static/img/portfolio/']
IMAGES_CACHE = STATIC_PATH+'/img/cache/'
#Dossier privé des utilisateurs
USERS_FOLDER = "/home/kitoy/prog/mapageperso/users"
# Le dossiers où sont exporté les sites générer
PUBLIC_FOLDER = "/home/kitoy/prog/mapageperso/public"
DEFAULT_SITE="default"

56
app/forms.py Normal file
View File

@@ -0,0 +1,56 @@
import re
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField
from wtforms import SubmitField, TextAreaField, FileField
from flask_wtf.file import FileField, FileAllowed, FileRequired
from wtforms import validators
from wtforms.validators import DataRequired, Length
class Accueil(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
text = TextAreaField('Présentation', validators=[Length(min=0, max=1000)])
text_button = StringField('Texte du bouton', validators=[])
link = StringField('Lien', validators=[])
image = FileField('image', validators=[FileAllowed(['jpg', 'png', 'gif'], 'Images only!')])
submit = SubmitField('Valider')
class Description(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
text = TextAreaField('Texte', validators=[DataRequired()])
submit = SubmitField('Valider')
class ImageForm(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
subtitle = StringField('Sous-titre',validators=[])
category = StringField('Categories',validators=[])
description = StringField('Description', validators=[])
class ImageUpload(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
subtitle = StringField('Sous-titre',validators=[])
text = StringField('Une description de votre image', validators=[])
category = StringField('Categories',validators=[])
image = FileField('image', validators=[FileRequired(),
FileAllowed(['jpg', 'png', 'gif'], 'Images only!')])
submit = SubmitField('Valider')
class Lien(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
text = StringField('Texte', validators=[DataRequired()])
link = StringField('Lien', validators=[DataRequired()])
text_button = StringField('Texte du bouton', validators=[DataRequired()])
submit = SubmitField('Valider')
class Contact(FlaskForm):
title = StringField('Titre', validators=[])
text = TextAreaField('Texte contact', validators=[])
email = StringField('Email', validators=[])
phone = StringField('Téléphone', validators=[])
address = StringField('Adresse', validators=[])
postal_code = StringField('Code Postal', validators=[])
city = StringField('Ville', validators=[])
submit = SubmitField('Valider')
class Login(FlaskForm):
passwd = PasswordField('Votre mot de passe', validators=[DataRequired()])
submit = SubmitField('Se connecter')

0
app/models/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

31
app/models/blocs.py Normal file
View File

@@ -0,0 +1,31 @@
import json
import os
from werkzeug.utils import secure_filename
from app.forms import *
from PIL import Image
from os import remove, path
class MyBlocs:
def makeForm(bloc):
match bloc['type']:
case 'presentation' :
form = Accueil()
case 'text' :
form = Description()
case 'external_link':
form = Lien()
case 'gallery':
form = ImageForm()
case 'contact':
form = Contact()
case _:
form = None
return form
def imgForm():
return ImageForm()
def newImgForm():
return ImageUpload()

93
app/models/sites.py Normal file
View File

@@ -0,0 +1,93 @@
import json
import os
from werkzeug.utils import secure_filename
from app.forms import *
from PIL import Image
from os import remove, path
class DataSite:
filej = ""
datas = ""
static_path =""
trash = list()
def __init__(self, filej, static_path):
self.filej = filej
self.static_path = static_path
def loadFile(self):
with open(self.filej, 'r') as f:
self.datas = json.load(f)
def updateDatas(self, bloc, form):
match bloc['type']:
case "presentation":
self.datas['blocs'][bloc['name']]['title'] = form.title.data
self.datas['blocs'][bloc['name']]['text'] = form.text.data
self.datas['blocs'][bloc['name']]['text_button']=form.text_button.data
self.datas['blocs'][bloc['name']]['link'] = form.link.data
if form.image.data :
f=form.image.data
filename = secure_filename(f.filename)
extension = filename.rsplit('.', 1)[1].lower()
f.save(os.path.join(
self.static_path, 'img','bg_custom.'+ extension))
self.datas['blocs'][bloc['name']]['bg_img']='bg_custom.'+extension
case "text" :
self.datas['blocs'][bloc['name']]['title']=form.title.data
self.datas['blocs'][bloc['name']]['text']=form.text.data
case "external_link" :
self.datas['blocs'][bloc['name']]['title'] = form.title.data
self.datas['blocs'][bloc['name']]['text'] = form.text.data
self.datas['blocs'][bloc['name']]['link'] = form.link.data
self.datas['blocs'][bloc['name']]['text_button']=form.text_button.data
case 'contact':
self.datas['blocs'][bloc['name']]['title'] = form.title.data
self.datas['blocs'][bloc['name']]['text'] = form.text.data
self.datas['blocs'][bloc['name']]['email'] = form.email.data
self.datas['blocs'][bloc['name']]['phone'] = form.phone.data
self.datas['blocs'][bloc['name']]['postal_code'] = form.postal_code.data
self.datas['blocs'][bloc['name']]['city'] = form.city.data
def updateImg(self, bloc, img, form):
filename = img['file']
img['title'] = form.title.data
img['subtitle'] = form.subtitle.data
img['description'] = form.description.data
img['category'] = form.category.data
self.datas['blocs'][bloc][filename]=img
def addImg(self, bloc, image_uploaded):
img = dict()
img['title'] = ""
img['subtitle']=""
img['text'] = ""
img['category'] = ""
img['file']=image_uploaded
self.datas['blocs'][bloc][image_uploaded]=img
def saveJson(self, datas):
remove(self.filej)
with open (self.filej, 'w') as f:
f.write(json.dumps(datas, indent=4))
def delImg(self, img):
try:
images = self.datas['images']
images.pop(img)
except KeyError:
print("Le fichier n'est pas dans la liste")
else:
self.trash.append(img)
def emptyTrash(self):
for file in self.trash:
try:
remove(self.static_path+'img/portfolio/fullsize/'+file)
except FileNotFoundError:
print (f'Le fichier {file} n\'existe pas')
if path.exists((self.static_path+'img/portfolio/thumbnails/'+file)):
remove(self.static_path+'img/portfolio/thumbnails/'+file)
self.trash.clear()

32
app/models/users.py Normal file
View File

@@ -0,0 +1,32 @@
class Users:
__pub_folder = None
__username = None
__auth_file = None
__auth_method = None
def __init__(self, username, public_path, auth_file):
self.__username = username
self.__pub_folder = public_path + '/' +username
if auth_file != None:
self.__auth_file = auth_file
self.__auth_method = "file"
def getPasswd(self, username):
with open(self.auth_file, 'r') as f:
users_info = f.readlines()
for userinfo in users_info:
user = userinfo.split(':', maxsplit=1)[0]
passwd = userinfo.split(':', maxsplit=1)[1]
if user == username:
return passwd
return None
def getPubfolder:
return __pub_folder
def getUsername:
return __username

208
app/routes.py Normal file
View File

@@ -0,0 +1,208 @@
from app import app
from flask import render_template, url_for, request, flash, redirect, session, make_response
import json
from werkzeug.utils import secure_filename
import os
from app.forms import ImageForm, ImageUpload
from app.models.sites import DataSite
from app.models.blocs import MyBlocs
from PIL import Image
from flask_bcrypt import Bcrypt
from copy import deepcopy
from app.forms import Login
from functools import wraps
from app.utils import login_required
app.config.from_pyfile('config.py')
DB = DataSite(app.config['JSON_FILE'], app.config['STATIC_PATH'])
DB.loadFile()
tmp = deepcopy(DB)
bcrypt = Bcrypt(app)
EXT_IMG = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
@app.route('/')
@app.route('/index.html')
def index():
DB.loadFile()
config = DB.datas['config']
menu = DB.datas['menu']
myblocs = DB.datas['blocs']
return render_template('/index.html.tpl',
config=config,
menu=menu,
myblocs=myblocs)
@app.route('/edit/save')
@login_required
def savefile():
DB.saveJson(tmp.datas)
DB.loadFile()
tmp.emptyTrash()
return redirect(url_for('edit'))
@app.route('/edit')
@login_required
def edit():
theme = tmp.datas['config']['theme']
menu = DB.datas['menu']
myblocs = tmp.datas['blocs']
return render_template('/edit.html.tpl',
blocEdit="",
config=DB.datas['config'],
menu=menu,
myblocs=myblocs
)
@app.route('/edit/<bloc>', methods=['GET', 'POST'])
@login_required
def editBloc(bloc):
theme = tmp.datas['config']['theme']
menu= tmp.datas['menu']
myblocs = tmp.datas['blocs']
form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
bloc = tmp.datas['blocs'][bloc]
if request.method == 'POST':
if form.validate_on_submit():
tmp.updateDatas(bloc, form)
flash(u'Vos changements on été pris en compte', 'success')
if "hx-request" in request.headers:
return render_template(theme+'/_'+bloc['type']+'.html',
bloc=bloc)
else:
return redirect(url_for('edit'))
if "hx-request" in request.headers:
return render_template(theme+'/_'+bloc['type']+'-edit.html',
bloc=bloc,
form=form)
else:
return render_template(theme+'/edit.html',
config=DB.datas['config'],
menu=menu,
myblocs=myblocs,
blocEdit=bloc['name'],
form=form)
@app.route('/view/<bloc>', methods=['GET'])
@login_required
def viewBloc(bloc):
theme = tmp.datas['config']['theme']
myblocs = tmp.datas['blocs']
form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
bloc = tmp.datas['blocs'][bloc]
return render_template(theme+'/_'+bloc['type']+'.html',
bloc=bloc)
@app.route('/edit/images/<bloc>/<image>', methods=['GET', 'POST'])
@login_required
def editPhoto(image, bloc):
theme = tmp.datas['config']['theme']
form = ImageForm()
mesimages = tmp.datas['blocs'][bloc]
if request.method == 'POST':
if form.validate_on_submit():
tmp.updateImg(bloc, mesimages[image], form)
else:
flash(u'Image non modifier', error)
form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
if "hx-request" in request.headers:
return render_template(theme+'/_gallery-edit.html',
bloc=mesimages,
form=form)
else:
return redirect ('/edit#'+bloc)
else:
return render_template(theme+'/_image-edit'+'.html', form=form, image=mesimages[image], bloc=mesimages)
@app.route('/upload-gallery/<bloc>', methods=['POST'])
@login_required
def drop_upload(bloc):
file = request.files['file']
filename = secure_filename(file.filename)
ext = os.path.splitext(filename)[-1]
save_path = "./app/static/img/portfolio"
if ext not in EXT_IMG :
return make_response(('Le fichier n\'est pas une image', 400))
current_chunk = int(request.form['dzchunkindex'])
print (current_chunk)
if (os.path.isfile(os.path.join(save_path, 'fullsize', filename ))) and current_chunk == 0:
return make_response(('Un fichier avec le même nom existe déjà', 400))
try:
with open(os.path.join(save_path, 'fullsize', filename ), 'ab') as f:
f.seek(int(request.form['dzchunkbyteoffset']))
f.write(file.stream.read())
except OSError:
return make_response(("Une erreur est survenue,"
" Impossible d'écrire le fichier sur le disque", 500))
total_chunks = int(request.form['dztotalchunkcount'])
if current_chunk + 1 == total_chunks:
# This was the last chunk, the file should be complete and the size we expect
if os.path.getsize(os.path.join(save_path, 'fullsize', filename )) != int(request.form['dztotalfilesize']):
return make_response(('La taille du fichier source est différentes', 500))
else:
with Image.open(os.path.join(save_path, 'fullsize', filename )) as img :
img.thumbnail((300,300))
img.save(os.path.join(save_path, 'thumbnails', filename ) )
tmp.addImg(bloc, filename)
return make_response(('Chunk upload succesfull', 200))
@app.route('/edit/images/<bloc>/del/<image>', methods=['GET'])
@login_required
def delImage(bloc, image):
tmp.delImg(image)
return redirect ('/edit#'+bloc)
@app.route('/editmenu', methods=['POST'])
@login_required
def editMenu():
print (request.form)
for key in request.form.keys():
print (key)
return make_response(('Update menu succesfull', 200))
@app.route('/login', methods=['GET', 'POST'])
def login():
theme = DB.datas['config']['theme']
form = Login()
if 'username' in session :
resp = redirect(url_for('edit', _external=True))
else :
resp = redirect(url_for('login', _external=True))
if request.method == 'POST' :
password = str(request.form['passwd'])
passwd_bcrypt = DB.datas['config']['passwd']
if bcrypt.check_password_hash(passwd_bcrypt, password) is True:
session['username'] = "logged"
resp = redirect(url_for('edit', _external=True))
else:
flash(u'Mauvais mot de passe', 'error')
else:
resp = render_template(theme+'/login.html', form=form)
return resp
@app.route( '/logout/', methods=['GET'] )
@login_required
def logout():
session.pop('username', None) # Supprimer username de la session s'il s'y trouve
session.clear()
return redirect(url_for('index'))

View File

View File

View File

@@ -0,0 +1,347 @@
body {
font-family: 'Lora';
background: linear-gradient(rgba(47, 23, 15, 0.65), rgba(47, 23, 15, 0.65)), url("../img/background.jpg");
background-attachment: fixed;
background-position: center;
background-size: cover;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Raleway';
}
p {
line-height: 1.75;
}
.text-faded {
color: rgba(255, 255, 255, 0.3);
}
.site-heading {
margin-top: 5rem;
margin-bottom: 5rem;
text-transform: uppercase;
line-height: 1;
font-family: 'Raleway';
}
.site-heading .site-heading-upper {
display: block;
font-size: 2rem;
font-weight: 800;
}
.site-heading .site-heading-lower {
font-size: 4rem;
font-weight: 100;
line-height: 4rem;
}
.page-section {
margin-top: 5rem;
margin-bottom: 5rem;
}
.section-heading {
text-transform: uppercase;
}
.section-heading .section-heading-upper {
display: block;
font-size: 1rem;
font-weight: 800;
}
.section-heading .section-heading-lower {
display: block;
font-size: 1.75rem;
font-weight: 100;
}
.bg-faded {
background-color: rgba(255, 255, 255, 0.85);
}
#mainNav {
background-color: rgba(47, 23, 15, 0.9);
font-family: 'Raleway';
}
#mainNav .navbar-brand {
color: #e6a756;
}
#mainNav .navbar-nav .nav-item .nav-link {
color: rgba(255, 255, 255, 0.7);
font-weight: 800;
}
#mainNav .navbar-nav .nav-item.active .nav-link {
color: #e6a756;
}
@media (min-width: 992px) {
#mainNav .navbar-nav .nav-item .nav-link {
font-size: 0.9rem;
}
#mainNav .navbar-nav .nav-item .nav-link:hover {
color: rgba(255, 255, 255, 0.4);
}
#mainNav .navbar-nav .nav-item.active .nav-link:hover {
color: #e6a756;
}
}
.btn-xl {
font-weight: 700;
font-size: 0.8rem;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
padding-left: 2rem;
padding-right: 2rem;
}
.intro {
position: relative;
}
@media (min-width: 992px) {
.intro .intro-img {
width: 75%;
float: right;
}
.intro .intro-text {
left: 0;
width: 60%;
margin-top: 3rem;
position: absolute;
}
.intro .intro-text .intro-button {
width: 100%;
left: 0;
position: absolute;
bottom: -2rem;
}
}
@media (min-width: 1200px) {
.product-item .product-item-title {
position: relative;
z-index: 1;
margin-bottom: -3rem;
font-size: 3rem;
}
.product-item .product-item-img {
position: relative;
z-index: 0;
height: 50rem;
/*max-width: 80vw;*/
}
.product-item .product-item-description {
position: relative;
z-index: 1;
margin-top: -5rem;
}
.carousel-item {
height: 70rem;
width: 100%;
background-color: rgba(0, 0, 0, 0);
}
.intro .intro-text {
width: 45%;
}
}
.cta {
padding-top: 5rem;
padding-bottom: 5rem;
background-color: rgba(230, 167, 86, 0.9);
}
.cta .cta-inner {
position: relative;
padding: 3rem;
margin: 0.5rem;
background-color: rgba(255, 255, 255, 0.85);
}
.cta .cta-inner:before {
border-radius: 0.5rem;
content: '';
position: absolute;
top: -0.5rem;
bottom: -0.5rem;
left: -0.5rem;
right: -0.5rem;
border: 0.25rem solid rgba(255, 255, 255, 0.85);
}
@media (min-width: 992px) {
.about-heading .about-heading-img {
position: relative;
z-index: 0;
}
.about-heading .about-heading-content {
margin-top: -5rem;
position: relative;
z-index: 1;
}
}
@media (max-width: 768px) {
.section-heading .section-heading-upper {
font-size: 0.5rem;
}
.section-heading .section-heading-lower {
font-size: 1rem;
}
.product-item .product-item-title {
position: relative;
z-index: 0;
margin-bottom: -1rem;
}
.product-item .product-item-img {
position: relative;
z-index: 1;
max-width: 60vw;
}
.product-item .product-item-description {
position: relative;
padding-top: 2rem;
z-index: 0;
}
.carousel-item {
margin-top: -27rem;
height: 60rem;
width: 100%;
background-color: rgba(0, 0, 0, 0);
}
}
@media (min-width: 768px) {
.product-item .product-item-title {
position: relative;
z-index: 1;
margin-bottom: -3rem;
}
.product-item .product-item-img {
position: relative;
z-index: 0;
max-width: 80vw;
max-height: 30rem;
}
.product-item .product-item-description {
position: relative;
z-index: 1;
margin-left: 30%;
margin-top: -0.5rem;
width: 50vw;
}
.carousel-item {
margin-top: -10rem;
height: 50rem;
width: 100%;
background-color: rgba(0, 0, 0, 0);
}
}
.list-hours {
font-size: 0.9rem;
}
.list-hours .list-hours-item {
border-bottom: 1px solid rgba(230, 167, 86, 0.5);
padding-bottom: .25rem;
margin-bottom: 1rem;
font-style: italic;
}
.list-hours .list-hours-item.today {
font-weight: bold;
color: #e6a756;
}
@media (min-width: 992px) {
.list-hours {
width: 50%;
font-size: 1.1rem;
}
}
.address strong {
font-size: 1.2rem;
}
.footer {
background-color: rgba(47, 23, 15, 0.9);
}
.text-primary {
color: #e6a756 !important;
}
.carousel-caption {
color: rgba(47, 23, 15, 0.9);
}
.bg-primary {
background-color: #e6a756 !important;
}
.btn {
box-shadow: 0px 3px 3px 0px rgba(33, 37, 41, 0.1);
}
.btn-primary {
background-color: #e6a756;
border-color: #e6a756;
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
background-color: #df902a;
border-color: #df902a;
}
.font-weight-light {
font-weight: 100 !important;
}
.carousel-item {
width: 100%;
background-color: rgba(0, 0, 0, 0);
}
.product-item .product-item-description {
margin-top: -5rem;
}

346
app/static/css/creative.css Normal file
View File

@@ -0,0 +1,346 @@
body,
html {
width: 100%;
height: 100%;
}
body {
font-family: 'Merriweather', 'Helvetica Neue', Arial, sans-serif;
}
hr {
max-width: 50px;
border-width: 3px;
border-color: #F05F40;
}
hr.light {
border-color: #fff;
}
a {
color: #F05F40;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
.btn-success{
z-index: 999;
position: relative;
}
.img-fluid {
position: relative;
z-index:-30;
}
a:hover {
color: #f05f40;
}
.modal-backdrop{
z-index:auto
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
.bg-primary {
background-color: #F05F40 !important;
}
.bg-dark {
background-color: #212529 !important;
}
.text-faded {
color: rgba(255, 255, 255, 0.7);
}
section {
padding: 8rem 0;
z-index: -1;
}
.section-heading {
margin-top: 0;
}
::-moz-selection {
color: #fff;
background: #212529;
text-shadow: none;
}
::selection {
color: #fff;
background: #212529;
text-shadow: none;
}
img::selection {
color: #fff;
background: transparent;
}
img::-moz-selection {
color: #fff;
background: transparent;
}
#mainNav {
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
background-color: #fff;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
#mainNav .navbar-brand {
font-weight: 700;
text-transform: uppercase;
color: #F05F40;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: #f05f40;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
font-size: .9rem;
font-weight: 700;
text-transform: uppercase;
color: #212529;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #F05F40;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link.active,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active {
color: #F05F40 !important;
background-color: transparent;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover {
background-color: transparent;
}
@media (min-width: 992px) {
#mainNav {
border-color: transparent;
background-color: transparent;
}
#mainNav .navbar-brand {
color: rgba(255, 255, 255, 0.7);
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: #fff;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link {
padding: 0.5rem 1rem;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
color: rgba(255, 255, 255, 0.7);
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #fff;
}
#mainNav.navbar-shrink {
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
background-color: #fff;
}
#mainNav.navbar-shrink .navbar-brand {
color: #F05F40;
}
#mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover {
color: #f05f40;
}
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link,
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus {
color: #212529;
}
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #F05F40;
}
}
header.masthead {
padding-top: 10rem;
padding-bottom: calc(10rem - 56px);
background-position: center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
header.masthead hr {
margin-top: 30px;
margin-bottom: 30px;
}
header.masthead h1 {
font-size: 2rem;
}
header.masthead p {
font-weight: 300;
}
@media (min-width: 768px) {
header.masthead p {
font-size: 1.15rem;
}
}
@media (min-width: 992px) {
header.masthead {
height: 100vh;
min-height: 650px;
padding-top: 0;
padding-bottom: 0;
}
header.masthead h1 {
font-size: 3rem;
}
}
@media (min-width: 1200px) {
header.masthead h1 {
font-size: 4rem;
}
.btn-success {
position: relative;
}
}
.service-box {
max-width: 400px;
}
.portfolio-box {
position: relative;
display: block;
max-width: 650px;
margin: 0 auto;
z-index: 0;
}
.portfolio-box .portfolio-box-caption {
position: absolute;
bottom: 0;
display: block;
width: 100%;
height: 100%;
text-align: center;
opacity: 0;
color: #fff;
background: rgba(240, 95, 64, 0.9);
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
z-index: 0;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
position: absolute;
top: 50%;
width: 100%;
transform: translateY(-50%);
text-align: center;
z-index:-10;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
padding: 0 15px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 18px;
}
.portfolio-box:hover .portfolio-box-caption {
opacity: 1;
}
.portfolio-box:focus {
outline: none;
z-index: 0;
}
@media (min-width: 768px) {
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 16px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 22px;
}
}
.text-primary {
color: #F05F40 !important;
}
.btn {
font-weight: 700;
text-transform: uppercase;
border: none;
border-radius: 300px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
z-index: 100;
}
.btn-xl {
padding: 1rem 2rem;
}
.btn-primary {
background-color: #F05F40;
border-color: #F05F40;
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
color: #fff;
background-color: #ee4b28 !important;
}
.btn-primary:active, .btn-primary:focus {
box-shadow: 0 0 0 0.2rem rgba(240, 95, 64, 0.5) !important;
}
section.bg-dark p {
padding-bottom: 3rem;
}
section.bg-dark {
padding-top: 3rem;
padding-bottom: 3rem;
}

View File

@@ -0,0 +1,346 @@
body,
html {
width: 100%;
height: 100%;
}
body {
font-family: 'Merriweather', 'Helvetica Neue', Arial, sans-serif;
}
hr {
max-width: 50px;
border-width: 3px;
border-color: #F05F40;
}
hr.light {
border-color: #fff;
}
a {
color: #F05F40;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
.btn-success{
z-index: 999;
position: relative;
}
.img-fluid {
position: relative;
z-index:-30;
}
a:hover {
color: #f05f40;
}
.modal-backdrop{
z-index:auto
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
.bg-primary {
background-color: #F05F40 !important;
}
.bg-dark {
background-color: #212529 !important;
}
.text-faded {
color: rgba(255, 255, 255, 0.7);
}
section {
padding: 8rem 0;
z-index: -1;
}
.section-heading {
margin-top: 0;
}
::-moz-selection {
color: #fff;
background: #212529;
text-shadow: none;
}
::selection {
color: #fff;
background: #212529;
text-shadow: none;
}
img::selection {
color: #fff;
background: transparent;
}
img::-moz-selection {
color: #fff;
background: transparent;
}
#mainNav {
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
background-color: #fff;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
#mainNav .navbar-brand {
font-weight: 700;
text-transform: uppercase;
color: #F05F40;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: #f05f40;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
font-size: .9rem;
font-weight: 700;
text-transform: uppercase;
color: #212529;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #F05F40;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link.active,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active {
color: #F05F40 !important;
background-color: transparent;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover {
background-color: transparent;
}
@media (min-width: 992px) {
#mainNav {
border-color: transparent;
background-color: transparent;
}
#mainNav .navbar-brand {
color: rgba(255, 255, 255, 0.7);
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: #fff;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link {
padding: 0.5rem 1rem;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
color: rgba(255, 255, 255, 0.7);
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #fff;
}
#mainNav.navbar-shrink {
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
background-color: #fff;
}
#mainNav.navbar-shrink .navbar-brand {
color: #F05F40;
}
#mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover {
color: #f05f40;
}
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link,
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus {
color: #212529;
}
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: #F05F40;
}
}
header.masthead {
padding-top: 10rem;
padding-bottom: calc(10rem - 56px);
background-position: center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
header.masthead hr {
margin-top: 30px;
margin-bottom: 30px;
}
header.masthead h1 {
font-size: 2rem;
}
header.masthead p {
font-weight: 300;
}
@media (min-width: 768px) {
header.masthead p {
font-size: 1.15rem;
}
}
@media (min-width: 992px) {
header.masthead {
height: 100vh;
min-height: 650px;
padding-top: 0;
padding-bottom: 0;
}
header.masthead h1 {
font-size: 3rem;
}
}
@media (min-width: 1200px) {
header.masthead h1 {
font-size: 4rem;
}
.btn-success {
position: relative;
}
}
.service-box {
max-width: 400px;
}
.portfolio-box {
position: relative;
display: block;
max-width: 650px;
margin: 0 auto;
z-index: 1;
}
.portfolio-box .portfolio-box-caption {
position: absolute;
bottom: 0;
display: block;
width: 100%;
height: 100%;
text-align: center;
opacity: 0;
color: #fff;
background: rgba(240, 95, 64, 0.9);
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
z-index:-10;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
position: absolute;
top: 50%;
width: 100%;
transform: translateY(-50%);
text-align: center;
z-index:-10;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
padding: 0 15px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 18px;
}
.portfolio-box:hover .portfolio-box-caption {
opacity: 1;
}
.portfolio-box:focus {
outline: none;
z-index:-10;
}
@media (min-width: 768px) {
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 16px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 22px;
}
}
.text-primary {
color: #F05F40 !important;
}
.btn {
font-weight: 700;
text-transform: uppercase;
border: none;
border-radius: 300px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
z-index: 100;
}
.btn-xl {
padding: 1rem 2rem;
}
.btn-primary {
background-color: #F05F40;
border-color: #F05F40;
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
color: #fff;
background-color: #ee4b28 !important;
}
.btn-primary:active, .btn-primary:focus {
box-shadow: 0 0 0 0.2rem rgba(240, 95, 64, 0.5) !important;
}
section.bg-dark p {
padding-bottom: 3rem;
}
section.bg-dark {
padding-top: 3rem;
padding-bottom: 3rem;
}

View File

@@ -0,0 +1,73 @@
@font-face {
font-family: 'Merryweather';
src:url("../fontes/Merryweather/Merryweather-Regular.woff");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Merryweather';
src:url("../fontes/Merryweather/Merryweather-Bold.woff");
font-weight: bold;
font-style: bold;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-regular.woff2");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-italic.woff2");
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-300.woff2");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-300italic.woff2");
font-weight: 300;
font-style: italic;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-600.woff2");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-600italic.woff2");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-700.woff2");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src:url("../fontes/OpenSans/open-sans-v15-latin-700italic.woff2");
font-weight: 700;
font-style: italic;
}

31
app/static/css/fontes.css Normal file
View File

@@ -0,0 +1,31 @@
/*Import de fontes trouver sur font2u.com Bon site !!!! */
@font-face {
font-family: 'Lora';
src:url("../fonts/Lora-Regular.woff");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Raleway';
src:url("../fonts/Raleway-Regular.woff");
font-weight: normal;
}
@font-face {
font-family: 'Raleway';
src:url("../fonts/Raleway-Bold.woff");
font-weight: bold;
}
@font-face {
font-family:'Lora-Italic';
src:url("../fonts/Lora-Italic.woff");
}
@font-face {
font-family:'Roboto';
src:url("../fonts/Roboto-Regular.woff");
}

View File

@@ -0,0 +1,283 @@
body {
font-family: 'Lora', 'Helvetica Neue', Helvetica, Arial, sans-serif;
position: relative;
width: 100%;
height: 100%;
color: white;
background-color: black;
}
html {
width: 100%;
height: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Cabin', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700;
margin: 0 0 35px;
letter-spacing: 1px;
text-transform: uppercase;
}
p {
font-size: 16px;
line-height: 1.5;
margin: 0 0 25px;
}
@media (min-width: 768px) {
p {
font-size: 18px;
line-height: 1.6;
margin: 0 0 35px;
}
}
a {
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
color: #42DCA3;
}
a:focus, a:hover {
text-decoration: none;
color: #1d9b6c;
}
#mainNav {
font-family: 'Cabin', 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin-bottom: 0;
text-transform: uppercase;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
background-color: black;
}
#mainNav .navbar-toggler {
font-size: 14px;
padding: 11px;
color: white;
border: 1px solid white;
}
#mainNav .navbar-brand {
font-weight: 700;
}
#mainNav a {
color: white;
}
#mainNav .navbar-nav .nav-item {
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background 0.3s ease-in-out;
}
#mainNav .navbar-nav .nav-item:hover {
color: fade(white, 80%);
outline: none;
background-color: transparent;
}
#mainNav .navbar-nav .nav-item:active, #mainNav .navbar-nav .nav-item:focus {
outline: none;
background-color: transparent;
}
@media (min-width: 992px) {
#mainNav {
padding-top: 20px;
padding-bottom: 20px;
-webkit-transition: background 0.3s ease-in-out, padding-top 0.3s ease-in-out, padding-bottom 0.3s;
-moz-transition: background 0.3s ease-in-out, padding-top 0.3s ease-in-out, padding-bottom 0.3s;
transition: background 0.3s ease-in-out, padding-top 0.3s ease-in-out, padding-bottom 0.3s;
letter-spacing: 1px;
border-bottom: none;
background: transparent;
}
#mainNav.navbar-shrink {
padding-top: 10px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
background: black;
}
#mainNav .nav-link.active {
outline: none;
background-color: rgba(255, 255, 255, 0.3);
}
#mainNav .nav-link.active:hover {
color: white;
}
}
.masthead {
display: table;
width: 100%;
height: auto;
padding: 200px 0;
text-align: center;
color: white;
background: url("../img/header.jpg") no-repeat bottom center scroll;
background-color: black;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.masthead .intro-body {
display: table-cell;
vertical-align: middle;
}
.masthead .intro-body .brand-heading {
font-size: 50px;
}
.masthead .intro-body .intro-text {
font-size: 18px;
}
@media (min-width: 768px) {
.masthead {
height: 100%;
padding: 0;
}
.masthead .intro-body .brand-heading {
font-size: 100px;
}
.masthead .intro-body .intro-text {
font-size: 22px;
}
}
.btn-circle {
font-size: 26px;
width: 55px;
height: 55px;
margin-top: 15px;
line-height: 45px;
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background 0.3s ease-in-out;
color: white;
border: 2px solid white;
border-radius: 100% !important;
background: transparent;
}
.btn-circle:focus, .btn-circle:hover {
color: white;
outline: none;
background: rgba(255, 255, 255, 0.1);
}
.content-section {
padding-top: 150px;
padding-bottom: 150px;
}
.download-section {
color: white;
background: url("../img/background.jpg") no-repeat center center scroll;
background-color: black;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#map {
width: 100%;
height: 300px;
}
@media (min-width: 992px) {
.content-section {
padding-top: 200px;
padding-bottom: 200px;
}
#map {
height: 350px;
}
}
.btn {
font-family: 'Cabin', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 400;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
text-transform: uppercase;
border-radius: 0;
}
.btn-default {
color: #42DCA3;
border: 1px solid #42DCA3;
background-color: transparent;
}
.btn-default:focus, .btn-default:hover {
color: black;
border: 1px solid #42DCA3;
outline: none;
background-color: #42DCA3;
}
ul.banner-social-buttons {
margin-top: 0;
}
@media (max-width: 1199px) {
ul.banner-social-buttons {
margin-top: 15px;
}
}
@media (max-width: 767px) {
ul.banner-social-buttons li {
display: block;
margin-bottom: 20px;
padding: 0;
}
ul.banner-social-buttons li:last-child {
margin-bottom: 0;
}
}
footer {
padding: 50px 0;
}
footer p {
font-size: 14px;
margin: 0;
}
::-moz-selection {
background: #fcfcfc;
background: rgba(255, 255, 255, 0.2);
text-shadow: none;
}
::selection {
background: #fcfcfc;
background: rgba(255, 255, 255, 0.2);
text-shadow: none;
}
img::selection {
background: transparent;
}
img::-moz-selection {
background: transparent;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More