Commit
|
@ -0,0 +1,282 @@
|
|||
#!/bin/bash -e
|
||||
#Version: 3.1.0
|
||||
#For use on clean Ubuntu 22 only!!!
|
||||
#Cited, Inc https://www.citedcorp.com
|
||||
#Usage Example for State of Delaware:
|
||||
#./Nominatim-Server.sh http://download.geofabrik.de/north-america/us/delaware-latest.osm.pbf
|
||||
#NOTE: It is best to run this via the screen command as it takes some time to finish.
|
||||
|
||||
PBF_URL="${1}"; #get URL from first parameter, http://download.geofabrik.de/europe/germany-latest.osm.pbf
|
||||
|
||||
PROJECT_NAME='nominatim'
|
||||
|
||||
NM_USER='ntim'; #nominatim website
|
||||
NM_PG_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
HNAME=$(hostname -f)
|
||||
|
||||
PG_VER='14'
|
||||
PGIS_VER='3'
|
||||
|
||||
function install_postgresql(){
|
||||
|
||||
#3. Install PostgreSQL
|
||||
apt-get install -y postgresql-${PG_VER} postgresql-client-${PG_VER} postgresql-contrib-${PG_VER} \
|
||||
postgresql-server-dev-${PG_VER} postgresql-${PG_VER}-postgis-${PGIS_VER} postgis
|
||||
|
||||
if [ ! -f /usr/lib/postgresql/${PG_VER}/bin/postgres ]; then
|
||||
echo "Error: Get PostgreSQL version"; exit 1;
|
||||
fi
|
||||
|
||||
ln -sf /usr/lib/postgresql/${PG_VER}/bin/pg_config /usr/bin
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main/ /var/lib/postgresql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/postgresql
|
||||
|
||||
systemctl start postgresql
|
||||
|
||||
#5. Set postgres Password
|
||||
if [ $(grep -m 1 -c 'pg pass' /root/auth.txt) -eq 0 ]; then
|
||||
PG_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
sudo -u postgres psql 2>/dev/null -c "alter user postgres with password '${PG_PASS}'"
|
||||
echo "pg pass: ${PG_PASS}" > /root/auth.txt
|
||||
fi
|
||||
|
||||
#4. Add Postgre variables to environment
|
||||
if [ $(grep -m 1 -c 'PGDATA' /etc/environment) -eq 0 ]; then
|
||||
cat >>/etc/environment <<CMD_EOF
|
||||
export PGDATA=/var/lib/postgresql/${PG_VER}/main
|
||||
CMD_EOF
|
||||
fi
|
||||
|
||||
#6. Configure ph_hba.conf
|
||||
cat >/etc/postgresql/${PG_VER}/main/pg_hba.conf <<CMD_EOF
|
||||
local all all trust
|
||||
host all all 127.0.0.1 255.255.255.255 md5
|
||||
host all all 0.0.0.0/0 md5
|
||||
host all all ::1/128 md5
|
||||
hostssl all all 127.0.0.1 255.255.255.255 md5
|
||||
hostssl all all 0.0.0.0/0 md5
|
||||
hostssl all all ::1/128 md5
|
||||
CMD_EOF
|
||||
sed -i.save "s/.*listen_addresses.*/listen_addresses = '*'/" /etc/postgresql/${PG_VER}/main/postgresql.conf
|
||||
|
||||
#10. Create Symlinks for Backward Compatibility
|
||||
mkdir -p /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/pgsql
|
||||
|
||||
systemctl restart postgresql
|
||||
}
|
||||
|
||||
function install_prerequisites(){
|
||||
apt-get install -y build-essential cmake g++ libboost-dev libboost-system-dev \
|
||||
libboost-filesystem-dev libexpat1-dev zlib1g-dev libxml2-dev\
|
||||
libbz2-dev libpq-dev liblua5.3-dev lua5.3 libgeos-dev libgeos++-dev libproj-dev \
|
||||
postgresql-server-dev-${PG_VER} postgresql-${PG_VER}-postgis-${PGIS_VER} postgresql-contrib-${PG_VER} \
|
||||
apache2 php php-{cgi,cli,intl,pgsql,pear,db} libapache2-mod-php \
|
||||
libicu-dev python3-{dotenv,psycopg2,psutil,jinja2,icu,datrie,sqlalchemy,asyncpg} \
|
||||
git python-pip python3-pyosmium osmosis libboost-python-dev nlohmann-json3-dev
|
||||
}
|
||||
|
||||
function install_nominatim(){
|
||||
|
||||
#download
|
||||
pushd /home/${NM_USER}
|
||||
git clone --recursive https://github.com/openstreetmap/Nominatim.git
|
||||
|
||||
#compile
|
||||
pushd Nominatim
|
||||
git checkout v4.3.1
|
||||
|
||||
wget -O data/country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz
|
||||
|
||||
mkdir build
|
||||
pushd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
make -j $(grep -c 'processor' /proc/cpuinfo)
|
||||
make install
|
||||
chown -R ${NM_USER}:${NM_USER} /home/${NM_USER}/Nominatim
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
#Creating postgres accounts
|
||||
su - postgres <<EOF
|
||||
createuser -sd ${NM_USER}
|
||||
createuser -SDR www-data
|
||||
psql -c "alter user ${NM_USER} with password '${NM_PG_PASS}'"
|
||||
EOF
|
||||
}
|
||||
|
||||
function install_nominatim_ui(){
|
||||
NMUI_VER='3.4.0'
|
||||
|
||||
pushd /home/${NM_USER}
|
||||
|
||||
wget -P/tmp https://github.com/osm-search/nominatim-ui/releases/download/v${NMUI_VER}/nominatim-ui-${NMUI_VER}.tar.gz
|
||||
tar -xf /tmp/nominatim-ui-${NMUI_VER}.tar.gz
|
||||
rm -rf /tmp/nominatim-ui-${NMUI_VER}.tar.gz
|
||||
|
||||
pushd nominatim-ui-${NMUI_VER}
|
||||
mv dist/theme/config.theme.js.example dist/theme/config.theme.js
|
||||
sed -i.save "s|Nominatim_Config.Nominatim_API_Endpoint =.*|Nominatim_Config.Nominatim_API_Endpoint = \"http://${HNAME}/nominatim/\"|" dist/theme/config.theme.js
|
||||
popd
|
||||
|
||||
|
||||
#Add webapp
|
||||
mv nominatim-ui-${NMUI_VER}/dist/* /var/www/html/
|
||||
rm -f /var/www/html/index.html
|
||||
wget --quiet -P/tmp https://github.com/AcuGIS/Nominatim-Server/archive/refs/heads/master.zip
|
||||
unzip /tmp/master.zip -d/tmp
|
||||
cp -r /tmp/Nominatim-Server-master/app/* /var/www/html/
|
||||
rm -rf /tmp/master.zip
|
||||
#sed -i.save "s/localhost/${HNAME}/" /var/www/html/leaflet-example.html
|
||||
|
||||
|
||||
|
||||
|
||||
chown -R www-data:www-data /var/www/html/
|
||||
popd
|
||||
}
|
||||
|
||||
function setup_nm_user(){
|
||||
if [ $(grep -cm 1 "^${NM_USER}:" /etc/passwd) -eq 0 ]; then
|
||||
useradd -m ${NM_USER}
|
||||
fi
|
||||
|
||||
if [ $(grep -m 1 -c "${NM_USER} pass" /root/auth.txt) -eq 0 ]; then
|
||||
USER_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
echo "${NM_USER}:${USER_PASS}" | chpasswd
|
||||
echo "${NM_USER} pass: ${USER_PASS}" >> /root/auth.txt
|
||||
fi
|
||||
}
|
||||
|
||||
function download_optional_data(){
|
||||
for f in wikipedia_article wikipedia_redirect gb_postcode_data; do
|
||||
wget --output-document=/home/${NM_USER}/Nominatim/data/${f}.sql.bin http://www.nominatim.org/data/${f}.sql.bin
|
||||
done
|
||||
}
|
||||
|
||||
function setup_nm_apache(){
|
||||
|
||||
cat >/etc/apache2/conf-available/nominatim_dir.conf <<EOF
|
||||
<Directory "/var/www/${PROJECT_NAME}/website">
|
||||
Options FollowSymLinks MultiViews
|
||||
AddType text/html .php
|
||||
DirectoryIndex search.php
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
Alias /nominatim /var/www/${PROJECT_NAME}/website
|
||||
EOF
|
||||
a2enconf nominatim_dir.conf
|
||||
|
||||
su ${NM_USER} <<EOF
|
||||
psql -d nominatim -c 'GRANT usage ON SCHEMA public TO "www-data"'
|
||||
psql -d nominatim -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "www-data"'
|
||||
EOF
|
||||
|
||||
systemctl restart apache2
|
||||
}
|
||||
|
||||
function import_osm_data(){
|
||||
|
||||
pushd /home/${NM_USER}
|
||||
|
||||
#13. Loading data into your server
|
||||
PBF_FILE="/home/${NM_USER}/${PBF_URL##*/}"
|
||||
wget ${PBF_URL}
|
||||
chown ${NM_USER}:${NM_USER} ${PBF_FILE}
|
||||
|
||||
UPDATE_URL="$(echo ${PBF_URL} | sed 's/latest.osm.pbf/updates/')"
|
||||
|
||||
cat >.env <<CAT_CMD
|
||||
# update replication url
|
||||
NOMINATIM_REPLICATION_URL="${UPDATE_URL}"
|
||||
|
||||
# How often upstream publishes diffs (in seconds)
|
||||
NOMINATIM_REPLICATION_UPDATE_INTERVAL=86400
|
||||
|
||||
# How long to sleep if no update found yet (in seconds)
|
||||
NOMINATIM_REPLICATION_RECHECK_INTERVAL=900
|
||||
|
||||
NOMINATIM_DATABASE_DSN="pgsql:dbname=nominatim;user=${NM_USER};password=${NM_PG_PASS}"
|
||||
CAT_CMD
|
||||
|
||||
|
||||
NP=$(grep -c 'model name' /proc/cpuinfo)
|
||||
let AVAIL_MEM=$(free -m | grep -i 'mem:' | sed 's/[ \t]\+/ /g' | cut -f4,7 -d' ' | tr ' ' '+')
|
||||
let C_MEM=(AVAIL_MEM/4)*3
|
||||
|
||||
mkdir /var/www/${PROJECT_NAME}
|
||||
chown -R ${NM_USER}:${NM_USER} /var/www/${PROJECT_NAME}
|
||||
|
||||
su - ${NM_USER} <<EOF
|
||||
wget -O /home/${NM_USER}/Nominatim/data/country_osm_grid.sql.gz http://www.nominatim.org/data/country_grid.sql.gz
|
||||
nominatim import -j ${NP} --osm-file ${PBF_FILE} --osm2pgsql-cache ${C_MEM} --project-dir /var/www/${PROJECT_NAME} 2>&1 | tee /tmp/setup.log
|
||||
EOF
|
||||
|
||||
rm -f ${PBF_FILE}
|
||||
popd
|
||||
|
||||
chown -R www-data:www-data /var/www/${PROJECT_NAME}
|
||||
}
|
||||
|
||||
function enable_nm_updates(){
|
||||
|
||||
pushd /home/${NM_USER}
|
||||
nominatim replication --init
|
||||
popd
|
||||
|
||||
cat >/etc/systemd/system/nominatim-updates.service <<EOF
|
||||
[Unit]
|
||||
Description=Nominatum Updates
|
||||
Documentation=https://github.com/f1ana/OpenNameSearch
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=${NM_USER}
|
||||
Group=${NM_USER}
|
||||
WorkingDirectory=/home/${NM_USER}/
|
||||
ExecStart=nominatim replication
|
||||
StandardOutput=append:/var/log/nominatim-updates.log
|
||||
StandardError=append:/var/log/nominatim-updates.error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
}
|
||||
|
||||
function install_housenumber(){
|
||||
apt-get install -y python-gdal
|
||||
|
||||
#11Gb download!
|
||||
mkdir -p /home/${NM_USER}/tiger/
|
||||
wget -P/home/${NM_USER}/tiger/ ftp://mirror1.shellbot.com/census/geo/tiger/TIGER2015/EDGES/
|
||||
|
||||
su - ${NM_USER} <<EOF
|
||||
cd /home/${NM_USER}/Nominatim/build
|
||||
./utils/imports.php --parse-tiger /home/${NM_USER}/tiger
|
||||
./utils/setup.php --import-tiger-data
|
||||
EOF
|
||||
}
|
||||
|
||||
#Check input parameters
|
||||
if [ -z "${PBF_URL}" ]; then
|
||||
echo "Usage: $0 <pbf_url>"; exit 1;
|
||||
fi
|
||||
|
||||
touch /root/auth.txt
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
apt-get -y update
|
||||
|
||||
setup_nm_user;
|
||||
install_prerequisites;
|
||||
install_postgresql;
|
||||
install_nominatim;
|
||||
install_nominatim_ui;
|
||||
#download_optional_data; #uncomment if you want optional data. Adds 30Gb to install size
|
||||
import_osm_data;
|
||||
setup_nm_apache;
|
||||
enable_nm_updates;
|
||||
#install_housenumber; #uncomment to install Tiger census data.
|
86
README.md
|
@ -1,2 +1,86 @@
|
|||
# Nominatim-Server
|
||||
# Nominatim Server
|
||||
|
||||
![OpenNameSearch](docs/Nominatim-Server.png)
|
||||
|
||||
* Project page: https://www.acugis.com/Nominatim-Server
|
||||
* Documentation: https://nominatim-server.docs.acugis.com
|
||||
|
||||
[![Documentation Status](https://readthedocs.org/projects/opennamesearch/badge/?version=latest)](https://nominatim-server.docs.acugis.com/en/latest/?badge=latest)
|
||||
|
||||
This script is for building a Nominatim server with OpenStreetMap data.
|
||||
|
||||
Only for use on a clean Ubuntu 22!
|
||||
|
||||
Step 1: Get the Nominatim-Server.sh script from GitHub
|
||||
|
||||
wget https://raw.githubusercontent.com/AcuGIS/Nominatim-Server/master/Nominatim-Server.sh
|
||||
|
||||
Step 2: Make it executable:
|
||||
|
||||
chmod 755 Nominatim-Server.sh
|
||||
|
||||
Step 3: Run the script
|
||||
|
||||
## Script usage:
|
||||
|
||||
The script accepts a PBF url:
|
||||
|
||||
./Nominatim-Server.sh pbf_url
|
||||
|
||||
The pbf_url is the complete PBF url from GeoFarbrik
|
||||
|
||||
## Examples:
|
||||
|
||||
Load Andorra data from GeoFabrik (one of the smallest data sets, good for testing):
|
||||
|
||||
./Nominatim-Server.sh https://download.geofabrik.de/europe/andorra-latest.osm.pbf
|
||||
|
||||
|
||||
## Welcome Page
|
||||
|
||||
Once installation completes, navigate to the IP or hostname on your server.
|
||||
|
||||
You should see a page as below:
|
||||
|
||||
![OpenNameSearch](docs/Nominatim-Server.png)
|
||||
|
||||
Click the Search function (or go to domain.com/search.html)
|
||||
|
||||
You should see a page as below:
|
||||
|
||||
![OpenNameSearch](docs/OpenNameSearch-Search.png)
|
||||
|
||||
To test functionality, enter below into the Search box::
|
||||
|
||||
AD500 Andorra la Vella, Andorra
|
||||
|
||||
Confirm that results are returned
|
||||
|
||||
|
||||
![OpenNameSearch](docs/Search-Results.png)
|
||||
|
||||
|
||||
|
||||
## Loading Additional PBFs, Multiplie PBFs, or Replacing Existing PBFs:
|
||||
|
||||
You can use our reload-Nominatim-Server.sh script via GitHUB script.
|
||||
|
||||
Usage is:
|
||||
<code>
|
||||
./reload-Nominatim-Server.sh [PBF_URL1] ...
|
||||
</code>
|
||||
|
||||
## Enable Automatic Updates
|
||||
|
||||
The script creates an updater service. In order to enable updates:
|
||||
|
||||
<code>
|
||||
systemctl enable nominatim-updates.service
|
||||
systemctl start nominatim-updates.service
|
||||
</code>
|
||||
|
||||
## Credits
|
||||
|
||||
[Produced by AcuGIS. We Make GIS Simple](https://www.acugis.com)
|
||||
|
||||
[Cited, Inc. Wilmington, Delaware](https://citedcorp.com)
|
||||
|
|
|
@ -0,0 +1,885 @@
|
|||
/* Fonts */
|
||||
:root {
|
||||
--font-default: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-primary: "Montserrat", sans-serif;
|
||||
--font-secondary: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
:root {
|
||||
--color-default: #222222;
|
||||
--color-primary: #008374;
|
||||
--color-secondary: #f85a40;
|
||||
}
|
||||
|
||||
/* Smooth scroll behavior */
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-default);
|
||||
color: var(--color-default);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #00b6a1;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 60px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sections-bg {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-header h2:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 3px;
|
||||
background: var(--color-primary);
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.section-header p {
|
||||
margin-bottom: 0;
|
||||
color: #6f6f6f;
|
||||
}
|
||||
|
||||
.breadcrumbs .page-header {
|
||||
padding: 60px 0 60px 0;
|
||||
min-height: 20vh;
|
||||
position: relative;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.breadcrumbs .page-header h2 {
|
||||
font-size: 56px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
font-family: var(--font-secondary);
|
||||
}
|
||||
|
||||
.breadcrumbs .page-header p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.breadcrumbs nav {
|
||||
background-color: #f6f6f6;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.breadcrumbs nav ol {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--color-default);
|
||||
}
|
||||
|
||||
.breadcrumbs nav ol a {
|
||||
color: var(--color-primary);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.breadcrumbs nav ol a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.breadcrumbs nav ol li+li {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.breadcrumbs nav ol li+li::before {
|
||||
display: inline-block;
|
||||
padding-right: 10px;
|
||||
color: var(--color-secondary);
|
||||
content: "/";
|
||||
}
|
||||
|
||||
.scroll-top {
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
right: 15px;
|
||||
bottom: -15px;
|
||||
z-index: 99999;
|
||||
background: var(--color-secondary);
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50px;
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
.scroll-top i {
|
||||
font-size: 24px;
|
||||
color: #fff;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.scroll-top:hover {
|
||||
background: rgba(248, 90, 64, 0.8);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.scroll-top.active {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
bottom: 15px;
|
||||
}
|
||||
|
||||
#preloader {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 999999;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
transition: all 0.6s ease-out;
|
||||
}
|
||||
|
||||
#preloader:before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: calc(50% - 30px);
|
||||
left: calc(50% - 30px);
|
||||
border: 6px solid #fff;
|
||||
border-color: var(--color-primary) transparent var(--color-primary) transparent;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
animation: animate-preloader 1.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes animate-preloader {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
[data-aos-delay] {
|
||||
transition-delay: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.topbar {
|
||||
background: #00796b;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
transition: all 0.5s;
|
||||
color: #fff;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.topbar .contact-info i {
|
||||
font-style: normal;
|
||||
color: #fff;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.topbar .contact-info i a,
|
||||
.topbar .contact-info i span {
|
||||
padding-left: 5px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 575px) {
|
||||
|
||||
.topbar .contact-info i a,
|
||||
.topbar .contact-info i span {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.topbar .contact-info i a {
|
||||
line-height: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.topbar .contact-info i a:hover {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.topbar .social-links a {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
line-height: 0;
|
||||
transition: 0.3s;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.topbar .social-links a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header {
|
||||
transition: all 0.5s;
|
||||
z-index: 997;
|
||||
height: 90px;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.header.sticked {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 70px;
|
||||
box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.header .logo img {
|
||||
max-height: 40px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.header .logo h1 {
|
||||
font-size: 30px;
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.8px;
|
||||
color: #fff;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.header .logo h1 span {
|
||||
color: #f96f59;
|
||||
}
|
||||
|
||||
.sticked-header-offset {
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
section {
|
||||
scroll-margin-top: 70px;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.navbar {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navbar li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navbar>ul>li {
|
||||
white-space: nowrap;
|
||||
padding: 10px 0 10px 28px;
|
||||
}
|
||||
|
||||
.navbar a,
|
||||
.navbar a:focus {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 3px;
|
||||
font-family: var(--font-secondary);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
white-space: nowrap;
|
||||
transition: 0.3s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navbar a i,
|
||||
.navbar a:focus i {
|
||||
font-size: 12px;
|
||||
line-height: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.navbar>ul>li>a:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
bottom: -6px;
|
||||
left: 0;
|
||||
background-color: var(--color-secondary);
|
||||
visibility: hidden;
|
||||
width: 0px;
|
||||
transition: all 0.3s ease-in-out 0s;
|
||||
}
|
||||
|
||||
.navbar a:hover:before,
|
||||
.navbar li:hover>a:before,
|
||||
.navbar .active:before {
|
||||
visibility: visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navbar a:hover,
|
||||
.navbar .active,
|
||||
.navbar .active:focus,
|
||||
.navbar li:hover>a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar .dropdown ul {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
top: calc(100% + 30px);
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
z-index: 99;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
background: #fff;
|
||||
box-shadow: 0px 0px 30px rgba(127, 137, 161, 0.25);
|
||||
transition: 0.3s;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.navbar .dropdown ul li {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.navbar .dropdown ul a {
|
||||
padding: 10px 20px;
|
||||
font-size: 15px;
|
||||
text-transform: none;
|
||||
font-weight: 600;
|
||||
color: #006a5d;
|
||||
}
|
||||
|
||||
.navbar .dropdown ul a i {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.navbar .dropdown ul a:hover,
|
||||
.navbar .dropdown ul .active:hover,
|
||||
.navbar .dropdown ul li:hover>a {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.navbar .dropdown:hover>ul {
|
||||
opacity: 1;
|
||||
top: 100%;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.navbar .dropdown .dropdown ul {
|
||||
top: 0;
|
||||
left: calc(100% - 30px);
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.navbar .dropdown .dropdown:hover>ul {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) and (max-width: 1366px) {
|
||||
.navbar .dropdown .dropdown ul {
|
||||
left: -90%;
|
||||
}
|
||||
|
||||
.navbar .dropdown .dropdown:hover>ul {
|
||||
left: -100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
|
||||
.mobile-nav-show,
|
||||
.mobile-nav-hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1279px) {
|
||||
.navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: -100%;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
bottom: 0;
|
||||
transition: 0.3s;
|
||||
z-index: 9997;
|
||||
}
|
||||
|
||||
.navbar ul {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
padding: 50px 0 10px 0;
|
||||
margin: 0;
|
||||
background: rgba(0, 131, 116, 0.9);
|
||||
overflow-y: auto;
|
||||
transition: 0.3s;
|
||||
z-index: 9998;
|
||||
}
|
||||
|
||||
.navbar a,
|
||||
.navbar a:focus {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 20px;
|
||||
font-family: var(--font-primary);
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
white-space: nowrap;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.navbar a i,
|
||||
.navbar a:focus i {
|
||||
font-size: 12px;
|
||||
line-height: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.navbar a:hover,
|
||||
.navbar .active,
|
||||
.navbar .active:focus,
|
||||
.navbar li:hover>a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar .getstarted,
|
||||
.navbar .getstarted:focus {
|
||||
background: var(--color-primary);
|
||||
padding: 8px 20px;
|
||||
border-radius: 4px;
|
||||
margin: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar .getstarted:hover,
|
||||
.navbar .getstarted:focus:hover {
|
||||
color: #fff;
|
||||
background: rgba(0, 131, 116, 0.8);
|
||||
}
|
||||
|
||||
.navbar .dropdown ul,
|
||||
.navbar .dropdown .dropdown ul {
|
||||
position: static;
|
||||
display: none;
|
||||
padding: 10px 0;
|
||||
margin: 10px 20px;
|
||||
transition: all 0.5s ease-in-out;
|
||||
background-color: #007466;
|
||||
border: 1px solid #006459;
|
||||
}
|
||||
|
||||
.navbar .dropdown>.dropdown-active,
|
||||
.navbar .dropdown .dropdown>.dropdown-active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-nav-show {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 28px;
|
||||
cursor: pointer;
|
||||
line-height: 0;
|
||||
transition: 0.5s;
|
||||
z-index: 9999;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mobile-nav-hide {
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
cursor: pointer;
|
||||
line-height: 0;
|
||||
transition: 0.5s;
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.mobile-nav-active {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mobile-nav-active .navbar {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.mobile-nav-active .navbar:before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 106, 93, 0.8);
|
||||
z-index: 9996;
|
||||
}
|
||||
}
|
||||
|
||||
.faq .content h3 {
|
||||
font-weight: 400;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
.faq .content h4 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.faq .content p {
|
||||
font-size: 15px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.faq .accordion-item {
|
||||
border: 0;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.06);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.faq .accordion-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.faq .accordion-collapse {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.faq .accordion-button {
|
||||
padding: 20px 50px 20px 20px;
|
||||
font-weight: 600;
|
||||
border: 0;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
color: var(--color-default);
|
||||
text-align: left;
|
||||
background: #fff;
|
||||
box-shadow: none;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.faq .accordion-button .num {
|
||||
padding-right: 10px;
|
||||
font-size: 20px;
|
||||
line-height: 0;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.faq .accordion-button:not(.collapsed) {
|
||||
color: var(--color-primary);
|
||||
border-bottom: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.faq .accordion-button:after {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.faq .accordion-body {
|
||||
padding: 0 40px 30px 45px;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
.hero {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: var(--color-primary);
|
||||
padding: 60px 0 0 0;
|
||||
}
|
||||
|
||||
@media (min-width: 1365px) {
|
||||
.hero {
|
||||
background-attachment: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
.hero h2 {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-weight: 400;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.hero .btn-get-started {
|
||||
font-family: var(--font-primary);
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
letter-spacing: 1px;
|
||||
display: inline-block;
|
||||
padding: 14px 40px;
|
||||
border-radius: 50px;
|
||||
transition: 0.3s;
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.08);
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.hero .btn-get-started:hover {
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.hero .btn-watch-video {
|
||||
font-size: 16px;
|
||||
transition: 0.5s;
|
||||
margin-left: 25px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hero .btn-watch-video i {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 32px;
|
||||
transition: 0.3s;
|
||||
line-height: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.hero .btn-watch-video:hover i {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.hero h2 {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.hero .btn-get-started,
|
||||
.hero .btn-watch-video {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.hero .icon-boxes {
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.hero .icon-boxes:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: calc(50% + 20px);
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.hero .icon-box {
|
||||
padding: 60px 30px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #008d7d;
|
||||
box-shadow: 0 0 29px 0 rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease-in-out;
|
||||
border-radius: 8px;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero .icon-box .title {
|
||||
font-weight: 700;
|
||||
margin-bottom: 15px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.hero .icon-box .title a {
|
||||
color: #fff;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.hero .icon-box .icon {
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
display: inline-block;
|
||||
transition: all 0.3s ease-in-out;
|
||||
font-size: 48px;
|
||||
line-height: 1;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.hero .icon-box:hover {
|
||||
background: #009786;
|
||||
}
|
||||
|
||||
.hero .icon-box:hover .title a,
|
||||
.hero .icon-box:hover .icon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 14px;
|
||||
background-color: var(--color-primary);
|
||||
padding: 50px 0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.footer .footer-info .logo {
|
||||
line-height: 0;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.footer .footer-info .logo img {
|
||||
max-height: 40px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.footer .footer-info .logo span {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
color: #fff;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.footer .footer-info p {
|
||||
font-size: 14px;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.footer .social-links a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-right: 10px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.footer .social-links a:hover {
|
||||
color: #fff;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
.footer h4 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.footer .footer-links {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.footer .footer-links ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer .footer-links ul i {
|
||||
padding-right: 2px;
|
||||
color: rgba(0, 131, 116, 0.8);
|
||||
font-size: 12px;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.footer .footer-links ul li {
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer .footer-links ul li:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.footer .footer-links ul a {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
transition: 0.3s;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.footer .footer-links ul a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.footer .footer-contact p {
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.footer .copyright {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer .credits {
|
||||
padding-top: 4px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.footer .credits a {
|
||||
color: #fff;
|
||||
}
|
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 491 B |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 109 KiB |
|
@ -0,0 +1,244 @@
|
|||
document.addEventListener('DOMContentLoaded', () => {
|
||||
"use strict";
|
||||
|
||||
const preloader = document.querySelector('#preloader');
|
||||
if (preloader) {
|
||||
window.addEventListener('load', () => {
|
||||
preloader.remove();
|
||||
});
|
||||
}
|
||||
|
||||
const selectHeader = document.querySelector('#header');
|
||||
if (selectHeader) {
|
||||
let headerOffset = selectHeader.offsetTop;
|
||||
let nextElement = selectHeader.nextElementSibling;
|
||||
|
||||
const headerFixed = () => {
|
||||
if ((headerOffset - window.scrollY) <= 0) {
|
||||
selectHeader.classList.add('sticked');
|
||||
if (nextElement) nextElement.classList.add('sticked-header-offset');
|
||||
} else {
|
||||
selectHeader.classList.remove('sticked');
|
||||
if (nextElement) nextElement.classList.remove('sticked-header-offset');
|
||||
}
|
||||
}
|
||||
window.addEventListener('load', headerFixed);
|
||||
document.addEventListener('scroll', headerFixed);
|
||||
}
|
||||
|
||||
let navbarlinks = document.querySelectorAll('#navbar a');
|
||||
|
||||
function navbarlinksActive() {
|
||||
navbarlinks.forEach(navbarlink => {
|
||||
|
||||
if (!navbarlink.hash) return;
|
||||
|
||||
let section = document.querySelector(navbarlink.hash);
|
||||
if (!section) return;
|
||||
|
||||
let position = window.scrollY + 200;
|
||||
|
||||
if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
|
||||
navbarlink.classList.add('active');
|
||||
} else {
|
||||
navbarlink.classList.remove('active');
|
||||
}
|
||||
})
|
||||
}
|
||||
window.addEventListener('load', navbarlinksActive);
|
||||
document.addEventListener('scroll', navbarlinksActive);
|
||||
|
||||
const mobileNavShow = document.querySelector('.mobile-nav-show');
|
||||
const mobileNavHide = document.querySelector('.mobile-nav-hide');
|
||||
|
||||
document.querySelectorAll('.mobile-nav-toggle').forEach(el => {
|
||||
el.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
mobileNavToogle();
|
||||
})
|
||||
});
|
||||
|
||||
function mobileNavToogle() {
|
||||
document.querySelector('body').classList.toggle('mobile-nav-active');
|
||||
mobileNavShow.classList.toggle('d-none');
|
||||
mobileNavHide.classList.toggle('d-none');
|
||||
}
|
||||
|
||||
document.querySelectorAll('#navbar a').forEach(navbarlink => {
|
||||
|
||||
if (!navbarlink.hash) return;
|
||||
|
||||
let section = document.querySelector(navbarlink.hash);
|
||||
if (!section) return;
|
||||
|
||||
navbarlink.addEventListener('click', () => {
|
||||
if (document.querySelector('.mobile-nav-active')) {
|
||||
mobileNavToogle();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
const navDropdowns = document.querySelectorAll('.navbar .dropdown > a');
|
||||
|
||||
navDropdowns.forEach(el => {
|
||||
el.addEventListener('click', function(event) {
|
||||
if (document.querySelector('.mobile-nav-active')) {
|
||||
event.preventDefault();
|
||||
this.classList.toggle('active');
|
||||
this.nextElementSibling.classList.toggle('dropdown-active');
|
||||
|
||||
let dropDownIndicator = this.querySelector('.dropdown-indicator');
|
||||
dropDownIndicator.classList.toggle('bi-chevron-up');
|
||||
dropDownIndicator.classList.toggle('bi-chevron-down');
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const glightbox = GLightbox({
|
||||
selector: '.glightbox'
|
||||
});
|
||||
|
||||
const scrollTop = document.querySelector('.scroll-top');
|
||||
if (scrollTop) {
|
||||
const togglescrollTop = function() {
|
||||
window.scrollY > 100 ? scrollTop.classList.add('active') : scrollTop.classList.remove('active');
|
||||
}
|
||||
window.addEventListener('load', togglescrollTop);
|
||||
document.addEventListener('scroll', togglescrollTop);
|
||||
scrollTop.addEventListener('click', window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
}));
|
||||
}
|
||||
|
||||
new PureCounter();
|
||||
|
||||
new Swiper('.clients-slider', {
|
||||
speed: 400,
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 5000,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
pagination: {
|
||||
el: '.swiper-pagination',
|
||||
type: 'bullets',
|
||||
clickable: true
|
||||
},
|
||||
breakpoints: {
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 40
|
||||
},
|
||||
480: {
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 60
|
||||
},
|
||||
640: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 80
|
||||
},
|
||||
992: {
|
||||
slidesPerView: 6,
|
||||
spaceBetween: 120
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Swiper('.slides-1', {
|
||||
speed: 600,
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 5000,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
pagination: {
|
||||
el: '.swiper-pagination',
|
||||
type: 'bullets',
|
||||
clickable: true
|
||||
},
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
}
|
||||
});
|
||||
|
||||
new Swiper('.slides-3', {
|
||||
speed: 600,
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 5000,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
pagination: {
|
||||
el: '.swiper-pagination',
|
||||
type: 'bullets',
|
||||
clickable: true
|
||||
},
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
},
|
||||
breakpoints: {
|
||||
320: {
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 40
|
||||
},
|
||||
|
||||
1200: {
|
||||
slidesPerView: 3,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let portfolionIsotope = document.querySelector('.portfolio-isotope');
|
||||
|
||||
if (portfolionIsotope) {
|
||||
|
||||
let portfolioFilter = portfolionIsotope.getAttribute('data-portfolio-filter') ? portfolionIsotope.getAttribute('data-portfolio-filter') : '*';
|
||||
let portfolioLayout = portfolionIsotope.getAttribute('data-portfolio-layout') ? portfolionIsotope.getAttribute('data-portfolio-layout') : 'masonry';
|
||||
let portfolioSort = portfolionIsotope.getAttribute('data-portfolio-sort') ? portfolionIsotope.getAttribute('data-portfolio-sort') : 'original-order';
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
let portfolioIsotope = new Isotope(document.querySelector('.portfolio-container'), {
|
||||
itemSelector: '.portfolio-item',
|
||||
layoutMode: portfolioLayout,
|
||||
filter: portfolioFilter,
|
||||
sortBy: portfolioSort
|
||||
});
|
||||
|
||||
let menuFilters = document.querySelectorAll('.portfolio-isotope .portfolio-flters li');
|
||||
menuFilters.forEach(function(el) {
|
||||
el.addEventListener('click', function() {
|
||||
document.querySelector('.portfolio-isotope .portfolio-flters .filter-active').classList.remove('filter-active');
|
||||
this.classList.add('filter-active');
|
||||
portfolioIsotope.arrange({
|
||||
filter: this.getAttribute('data-filter')
|
||||
});
|
||||
if (typeof aos_init === 'function') {
|
||||
aos_init();
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function aos_init() {
|
||||
AOS.init({
|
||||
duration: 1000,
|
||||
easing: 'ease-in-out',
|
||||
once: true,
|
||||
mirror: false
|
||||
});
|
||||
}
|
||||
window.addEventListener('load', () => {
|
||||
aos_init();
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,885 @@
|
|||
/* Fonts */
|
||||
:root {
|
||||
--font-default: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-primary: "Montserrat", sans-serif;
|
||||
--font-secondary: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
:root {
|
||||
--color-default: #222222;
|
||||
--color-primary: #008374;
|
||||
--color-secondary: #f85a40;
|
||||
}
|
||||
|
||||
/* Smooth scroll behavior */
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-default);
|
||||
color: var(--color-default);
|
||||
}
|
||||
|
||||