Compare commits
11 Commits
5a530fe2a9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53e7b02dd9 | ||
|
|
59ffa14673 | ||
|
|
4283789f71 | ||
|
|
49db1e232e | ||
|
|
53a39dabe3 | ||
|
|
2f07ac52b5 | ||
|
|
e65fad2e2e | ||
|
|
e65cbc0c2e | ||
|
|
4725165474 | ||
|
|
0655eb992d | ||
|
|
f8b297eaad |
101
.agent/hugoplate-best-practices/SKILL.md
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
name: hugoplate-best-practices
|
||||
description: Best practices and architectural patterns for working with the Hugoplate Hugo boilerplate. Use this when modifying theme tokens, configuration, content, layouts, or Tailwind v4 styles in a Hugoplate project.
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# Hugoplate Agent Skill
|
||||
|
||||
This skill provides the best practices and architectural patterns for working with the **Hugoplate** boilerplate. Use this as your primary guide when modifying theme tokens, configuration, content, or layouts.
|
||||
|
||||
## 1. Core Architecture
|
||||
|
||||
Hugoplate is a modern Hugo boilerplate built with:
|
||||
|
||||
- **Hugo (Extended)**: Static site generator.
|
||||
- **Tailwind CSS v4**: Utility-first CSS using Hugo Pipes and the `@theme` directive.
|
||||
- **Hugo Modules**: Theme and feature functionality are imported as modules.
|
||||
- **Theme Generator**: A custom Node.js script (`scripts/themeGenerator.js`) that syncs `data/theme.json` with Tailwind CSS variables.
|
||||
|
||||
## 2. Design System (`theme.json`)
|
||||
|
||||
All design tokens (colors, fonts, sizes) are managed in `exampleSite/data/theme.json`.
|
||||
|
||||
### 2.1 Color Tokens
|
||||
|
||||
- **Default (Light)**: `colors.default.theme_color` and `colors.default.text_color`.
|
||||
- **Dark Mode**: `colors.darkmode.theme_color` and `colors.darkmode.text_color`.
|
||||
- **Logic**: The `themeGenerator.js` script maps these to CSS variables (e.g., `--color-primary`, `--color-darkmode-primary`).
|
||||
|
||||
### 2.2 Typography
|
||||
|
||||
- **Google Fonts**: Defined in `fonts.font_family`. Use the syntax `Family:wght@weights` (e.g., `Inter:wght@400;700`).
|
||||
- **Scale**: `fonts.font_size.scale` controls the heading hierarchy (H1-H6).
|
||||
- **Base**: `fonts.font_size.base` sets the root font size in pixels.
|
||||
|
||||
### 2.3 Workflow: Design Changes
|
||||
|
||||
1. **Modify `theme.json`**: Update colors or fonts.
|
||||
2. **Run Dev Server**: `npm run dev` or `yarn dev`. This automatically runs `themeGenerator.js` and `hugo server`.
|
||||
3. **Verify**: Check `assets/css/generated-theme.css` to see the updated variables.
|
||||
|
||||
## 3. Configuration System
|
||||
|
||||
Configuration is split across several files in `exampleSite/config/_default/`:
|
||||
|
||||
- `hugo.toml`: Core site settings, build options, and asset fingerprinting.
|
||||
- `params.toml`: Theme-specific toggles (dark mode, search, navigation, etc.).
|
||||
- `menus.en.toml`: Menu structures for English.
|
||||
- `languages.toml`: Multilingual setup.
|
||||
- `module.toml`: Import declarations for Hugo Modules.
|
||||
|
||||
### 3.1 Feature Toggles (`params.toml`)
|
||||
|
||||
Most UI components (e.g., `preloader`, `announcement`, `cookies`) have an `enable` flag. Toggle them here without touching the code.
|
||||
|
||||
## 4. Content Development
|
||||
|
||||
Content is located in `exampleSite/content/english/`.
|
||||
|
||||
### 4.1 Section Content
|
||||
|
||||
Files in `content/english/sections/` are typically used for homepage sections. They often use `build.render = "never"` because they are pulled into `index.html` via `site.GetPage`.
|
||||
|
||||
### 4.2 Front Matter Standards
|
||||
|
||||
Always include `title`, `description` (for SEO), and `image` (feature image). Use `draft: false` to publish.
|
||||
|
||||
## 5. Layouts & Templates
|
||||
|
||||
- **Base**: `layouts/baseof.html` is the master wrapper.
|
||||
- **Homepage**: `layouts/index.html` iterates through section files.
|
||||
- **Partials**: Reusable fragments in `layouts/partials/`.
|
||||
- **Overriding Modules**: To override a module partial, create a file with the same path in your local `layouts/` directory.
|
||||
|
||||
## 6. CSS & Tailwind Best Practices
|
||||
|
||||
- **Tailwind v4**: Uses `@theme` in `assets/css/main.css`. Avoid creating `tailwind.config.js` as it's not the primary way to configure v4 in this project.
|
||||
- **Layers**: Add custom CSS to `assets/css/custom.css` or within `@layer` blocks in `main.css`.
|
||||
- **Images**: Use the `partial "image"` for automatic Hugo responsive processing and WebP conversion.
|
||||
|
||||
## 7. Development Commands
|
||||
|
||||
| Command | Purpose |
|
||||
| -------------------------- | ------------------------------------------------------ |
|
||||
| `npm run dev` | Start dev server with theme watching. |
|
||||
| `npm run build` | Production build with minification and fingerprinting. |
|
||||
| `npm run update-modules` | Clean and update Hugo modules to latest. |
|
||||
| `npm run remove-darkmode` | Permanently remove dark mode functionality. |
|
||||
| `npm run remove-multilang` | Permanently remove multilingual support. |
|
||||
|
||||
## 8. Troubleshooting
|
||||
|
||||
- **Styles not updating**: Ensure `npm run dev` is running (it needs to regenerate `generated-theme.css`).
|
||||
- **Classes missing**: Tailwind v4 in this project scans `hugo_stats.json`. If a new class isn't working, try a full rebuild.
|
||||
- **Google Fonts error**: Check for spaces or incorrect weight syntax in `theme.json`.
|
||||
|
||||
## 9. AI Agent Guidelines
|
||||
|
||||
- **Always Read Context**: Before modifying a layout, check if a partial exists in `layouts/partials/essentials/` that might already handle it.
|
||||
- **Prefer Tokens**: Never hardcode hex colors in CSS. Add them to `theme.json` and use the generated Tailwind classes.
|
||||
- **Check Params**: Before writing logic to hide/show a section, check `params.toml` for an existing toggle.
|
||||
44
.devcontainer/Dockerfile
Executable file
@@ -0,0 +1,44 @@
|
||||
# Use an official node image as a parent image
|
||||
FROM node:23
|
||||
|
||||
# Set environment variables for versions
|
||||
ARG HUGO_VERSION=0.158.0
|
||||
ARG GO_VERSION=1.24.0
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y ca-certificates openssl git curl wget build-essential && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Determine architecture
|
||||
RUN ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" = "aarch64" ]; then ARCH=arm64; else ARCH=amd64; fi && \
|
||||
echo "Architecture: $ARCH"
|
||||
|
||||
# Download and install Hugo Extended
|
||||
RUN ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" = "aarch64" ]; then ARCH=arm64; else ARCH=amd64; fi && \
|
||||
wget -O hugo_extended_${HUGO_VERSION}.tar.gz https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-${ARCH}.tar.gz && \
|
||||
tar xf hugo_extended_${HUGO_VERSION}.tar.gz && \
|
||||
mv hugo /usr/bin/hugo && \
|
||||
rm hugo_extended_${HUGO_VERSION}.tar.gz && \
|
||||
echo "Hugo installed"
|
||||
|
||||
# Download and install Go
|
||||
RUN ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" = "aarch64" ]; then ARCH=arm64; else ARCH=amd64; fi && \
|
||||
wget -O go${GO_VERSION}.linux-${ARCH}.tar.gz https://dl.google.com/go/go${GO_VERSION}.linux-${ARCH}.tar.gz && \
|
||||
tar -C /usr/local -xzf go${GO_VERSION}.linux-${ARCH}.tar.gz && \
|
||||
rm go${GO_VERSION}.linux-${ARCH}.tar.gz && \
|
||||
echo "Go installed"
|
||||
|
||||
# Export Go path
|
||||
ENV PATH=$PATH:/usr/local/go/bin
|
||||
|
||||
# Verify versions
|
||||
RUN git --version && \
|
||||
hugo version && \
|
||||
go version
|
||||
|
||||
# Default shell
|
||||
CMD ["/bin/bash"]
|
||||
23
.devcontainer/devcontainer.json
Executable file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "Hugo",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
"GO_VERSION": "1.24.0",
|
||||
"HUGO_VERSION": "0.158.0"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
"extensions": [
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"budparr.language-hugo-vscode",
|
||||
"tamasfe.even-better-toml"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remoteUser": "node",
|
||||
"postCreateCommand": "npm run project-setup && npm install && npm run dev",
|
||||
"forwardPorts": [1313]
|
||||
}
|
||||
14
.editorconfig
Executable file
@@ -0,0 +1,14 @@
|
||||
; https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
79
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Executable file
@@ -0,0 +1,79 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report any issues you encounter to make hugoplate even more efficient.
|
||||
|
||||
body:
|
||||
- type: input
|
||||
id: hugo-version
|
||||
attributes:
|
||||
label: What is your Hugo Extended Version
|
||||
description: Check the [README](https://github.com/zeon-studio/hugoplate?tab=readme-ov-file#user-content-️-prerequisites) for the required version. Use "hugo version" in your terminal to see your Hugo version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: go-version
|
||||
attributes:
|
||||
label: What is your Go Version
|
||||
description: Check the [README](https://github.com/zeon-studio/hugoplate?tab=readme-ov-file#user-content-️-prerequisites) for the required version. Use "go version" in your terminal to see your Go version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: node-version
|
||||
attributes:
|
||||
label: What is your Node.js Version
|
||||
description: Check the [README](https://github.com/zeon-studio/hugoplate?tab=readme-ov-file#user-content-️-prerequisites) for the required version. Use "node -v" in your terminal to see your Node.js version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: What is your Operating System
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: make-sure
|
||||
attributes:
|
||||
label: Check for Existing Issues
|
||||
description: |
|
||||
Before reporting a problem, please confirm that you've searched thoroughly for any existing reports on the same issue. If no relevant issues are found, proceed with the report.
|
||||
options:
|
||||
- label: I have searched and found no relevant issues.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A clear description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: |
|
||||
Please explain the steps required to duplicate this issue. Include detailed commands and expected outcomes.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: reproduction-url
|
||||
attributes:
|
||||
label: Code Reproduction URL
|
||||
description: Please reproduce this issue and provide a link to the repository.
|
||||
placeholder: github.com/yourusername/repo
|
||||
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: |
|
||||
List any other information that is relevant to your issue. You can use Markdown for formatting, including code blocks, links, etc.
|
||||
78
.github/workflows/main.yml
vendored
Executable file
@@ -0,0 +1,78 @@
|
||||
# workflow for building and deploying to GitHub Pages
|
||||
name: Deploy Hugo site to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Default to bash
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
# Environment variables available to all jobs and steps in this workflow
|
||||
env:
|
||||
HUGO_ENV: production
|
||||
HUGO_VERSION: "0.158.0"
|
||||
GO_VERSION: "1.23.3"
|
||||
TINA_CLIENT_ID: ${{ secrets.TINA_CLIENT_ID }}
|
||||
TINA_TOKEN: ${{ secrets.TINA_TOKEN }}
|
||||
TINA_SEARCH_TOKEN: ${{ secrets.TINA_SEARCH_TOKEN }}
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- name: Install Hugo
|
||||
run: |
|
||||
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-arm64.deb \
|
||||
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
|
||||
|
||||
- name: Install Go
|
||||
run: |
|
||||
wget -O ${{ runner.temp }}/go.deb https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz \
|
||||
&& sudo tar -C /usr/local -xzf ${{ runner.temp }}/go.deb
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Setup Project
|
||||
run: npm run project-setup
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build site
|
||||
run: npm run build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3.0.1
|
||||
with:
|
||||
path: ./public
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-24.04-arm
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4.0.5
|
||||
17
.gitignore
vendored
Normal file → Executable file
@@ -1 +1,16 @@
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
.dist
|
||||
.tmp
|
||||
.lock
|
||||
.sass-cache
|
||||
npm-debug.log
|
||||
node_modules
|
||||
builds
|
||||
package-lock.json
|
||||
public
|
||||
resources
|
||||
.hugo_build.lock
|
||||
jsconfig.json
|
||||
go.sum
|
||||
yarn.lock
|
||||
38
.gitlab-ci.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
stages:
|
||||
- build
|
||||
|
||||
variables:
|
||||
HUGO_ENV: production
|
||||
HUGO_VERSION: "0.158.0"
|
||||
GO_VERSION: "1.23.3"
|
||||
NODE_VERSION: "18.16.1"
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
default:
|
||||
image: node:${NODE_VERSION}
|
||||
before_script:
|
||||
- echo "USING NODE ${NODE_VERSION}"
|
||||
- apt-get update && apt-get install -y curl
|
||||
- curl -LO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz"
|
||||
- tar -xvf hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
|
||||
- mv hugo /usr/local/bin/
|
||||
- rm hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
|
||||
- echo "HUGO ${HUGO_VERSION} INSTALLED"
|
||||
- curl -LO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz"
|
||||
- tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
|
||||
- export PATH=$PATH:/usr/local/go/bin
|
||||
- rm go${GO_VERSION}.linux-amd64.tar.gz
|
||||
- echo "GO ${GO_VERSION} INSTALLED"
|
||||
- npm install
|
||||
|
||||
pages:
|
||||
stage: build
|
||||
script:
|
||||
- npm run project-setup
|
||||
- npm run build
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
59
.jshintrc
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"maxerr": 50,
|
||||
"bitwise": true,
|
||||
"camelcase": false,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"newcap": false,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonbsp": true,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"undef": true,
|
||||
"unused": false,
|
||||
"strict": true,
|
||||
"maxparams": false,
|
||||
"maxdepth": 4,
|
||||
"maxstatements": false,
|
||||
"maxcomplexity": false,
|
||||
"maxlen": 400,
|
||||
"browser": true,
|
||||
"devel": true,
|
||||
"asi": false,
|
||||
"boss": false,
|
||||
"debug": false,
|
||||
"eqnull": false,
|
||||
"es3": false,
|
||||
"es5": false,
|
||||
"esversion": 12,
|
||||
"moz": false,
|
||||
"evil": true,
|
||||
"expr": true,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": false,
|
||||
"laxcomma": false,
|
||||
"loopfunc": true,
|
||||
"multistr": true,
|
||||
"noyield": false,
|
||||
"notypeof": false,
|
||||
"proto": false,
|
||||
"scripturl": false,
|
||||
"shadow": false,
|
||||
"sub": false,
|
||||
"supernew": false,
|
||||
"validthis": false,
|
||||
"globals": {
|
||||
"jQuery": false,
|
||||
"google": false,
|
||||
"$": false
|
||||
}
|
||||
}
|
||||
5
.markdownlint.json
Executable file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"MD033": false,
|
||||
"MD034": false,
|
||||
"MD013": false
|
||||
}
|
||||
13
.prettierrc
Executable file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"plugins": ["prettier-plugin-go-template"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"options": {
|
||||
"parser": "go-template",
|
||||
"goTemplateBracketSpacing": true,
|
||||
"bracketSameLine": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
12
.sitepins/config.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"content": "exampleSite/content",
|
||||
"media": "exampleSite/assets/images",
|
||||
"public": "exampleSite/static",
|
||||
"configs": [
|
||||
"exampleSite/config/_default",
|
||||
"exampleSite/data",
|
||||
"exampleSite/hugo.toml"
|
||||
],
|
||||
"custom-commit": false,
|
||||
"arrangement": []
|
||||
}
|
||||
7
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"budparr.language-hugo-vscode",
|
||||
"tamasfe.even-better-toml"
|
||||
]
|
||||
}
|
||||
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"tailwindCSS.experimental.configFile": "./themes/hugoplate/assets/css/main.css"
|
||||
}
|
||||
25
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Development",
|
||||
"type": "shell",
|
||||
"command": "yarn dev:example",
|
||||
"isBackground": true,
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build",
|
||||
"type": "shell",
|
||||
"command": "yarn build:example",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
26
LICENSE
@@ -1,21 +1,21 @@
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 StaticMania
|
||||
Copyright (c) 2026 - Present, Sitepins
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
79
README.md
Normal file → Executable file
@@ -1,50 +1,65 @@
|
||||
<h1>Roxo Hugo</h1>
|
||||
<img src="https://user-images.githubusercontent.com/16266381/76162082-10850b80-6164-11ea-8b20-f30b2611f92c.png" alt="screenshot" width="100%">
|
||||
## 🌟 Roxo Hugo
|
||||
|
||||
Roxo Hugo is a digital agency Hugo theme for creative agencies, freelancers, graphic designers, photographers. Can be used for any kind of corporate websites who provides digital services with many expertise such as Design, Digital Products, Development, Campaign & Content, Employer Branding, Animation & Motion Graphics ,Packaging & Product Design, Retail & Spacial, Print & Editorial Design, Concept/Text, Information Design etc. Roxo Hugo’s contact form is supported fabform.
|
||||
A Hugo-powered static website built with Tailwind CSS.
|
||||
|
||||
## Table of Contents
|
||||
### Prerequisites
|
||||
|
||||
- [Live Demo](#live-demo)
|
||||
- [Installation](#installation)
|
||||
- [Main Features](#features)
|
||||
- [Support](#support)
|
||||
- [Licensing](#licensing)
|
||||
- [Hire](#hire)
|
||||
To contribute effectively, you'll need some prerequisites installed on your machine:
|
||||
|
||||
## Live Demo
|
||||
- **Hugo Extended v0.161+**: [[https://gohugo.io/installation/](https://gohugo.io/installation/)]
|
||||
- **Node v18+**: [[https://nodejs.org/en/download/](https://nodejs.org/en/download/)]
|
||||
- **Go v1.22+**: [[https://go.dev/doc/install](https://go.dev/doc/install)]
|
||||
|
||||
Checkout the live demo [here](https://roxo-hugo.staticmania.com/)
|
||||
### Installation (as a theme)
|
||||
|
||||
## Installation
|
||||
To use Roxo in a new Hugo site, install the theme and configure your site with `hugo.toml` (not `config.toml`). The theme expects the Hugo config file to be named `hugo.toml`; using `config.toml` will result in a 404 / "page not found".
|
||||
|
||||
1. Add the repository into your Hugo Project repository as a submodule, `git submodule add git@github.com:StaticMania/roxo-hugo.git themes/roxo-hugo`.
|
||||
2. Copy the `data`, `content`, `static`, `resources` & `config.toml` files from the `exampleSite` directory and paste it on you Hugo Project repository/directory. From the site home directory:
|
||||
```bash
|
||||
hugo new site mysite
|
||||
cd mysite
|
||||
git submodule add https://github.com/furioustheme/roxo-hugo.git themes/roxo-hugo
|
||||
```
|
||||
|
||||
cp -a themes/roxo-hugo/exampleSite/* .
|
||||
Then create `hugo.toml` at the root of your site (copy `themes/roxo-hugo/exampleSite/hugo.toml` as a starting point) and set:
|
||||
|
||||
3. Build your site with `hugo serve` and see the result at `http://localhost:1313/`.
|
||||
```toml
|
||||
theme = "roxo-hugo"
|
||||
```
|
||||
|
||||
Run the site:
|
||||
|
||||
## Features
|
||||
```bash
|
||||
hugo server
|
||||
```
|
||||
|
||||
* Responsive Ready.
|
||||
* Powered by Bootstrap 4.
|
||||
* Dedicated portfolio page.
|
||||
* Blog Support.
|
||||
* Well formatted code.
|
||||
* Easy Customization.
|
||||
* FabForm.io [static website form](https://fabform.io).
|
||||
* Crafted for Design Agency/ Portfolio
|
||||
### Install Dependencies
|
||||
|
||||
## Support
|
||||
Install all the necessary dependencies using the following command:
|
||||
|
||||
Have some question or facing any technical trouble feel free to [Contact Us](https://staticmania.com/contact/)
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Licensing
|
||||
### Project Setup
|
||||
|
||||
This Repository is licensed under the [MIT](https://github.com/StaticMania/roxo-hugo/blob/master/LICENSE) License
|
||||
To set up the project, run the following command:
|
||||
|
||||
## Hire
|
||||
```bash
|
||||
yarn project-setup
|
||||
```
|
||||
|
||||
Need help to build HUGO websites with your custom requirements. Feel free to [contact](https://staticmania.com/contact/) with us. We provide custom development service for HUGO.
|
||||
### Development Command
|
||||
|
||||
Start the development server using the following command:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
### Preview Command
|
||||
|
||||
Start the production server to preview your changes and test functionality:
|
||||
|
||||
```bash
|
||||
yarn preview
|
||||
```
|
||||
|
||||
1
_redirects
Normal file
@@ -0,0 +1 @@
|
||||
/* /en/404.html 404
|
||||
29
amplify.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
version: 1
|
||||
frontend:
|
||||
phases:
|
||||
preBuild:
|
||||
commands:
|
||||
- yum install -y curl
|
||||
- curl -LO "https://github.com/gohugoio/hugo/releases/download/v0.158.0/hugo_extended_0.158.0_Linux-64bit.tar.gz"
|
||||
- tar -xvf hugo_extended_0.158.0_Linux-64bit.tar.gz
|
||||
- mv hugo /usr/local/bin/
|
||||
- rm hugo_extended_0.158.0_Linux-64bit.tar.gz
|
||||
- echo "HUGO 0.158.0 INSTALLED"
|
||||
- curl -LO "https://dl.google.com/go/go1.23.3.linux-amd64.tar.gz"
|
||||
- tar -C /usr/local -xzf go1.23.3.linux-amd64.tar.gz
|
||||
- export PATH=$PATH:/usr/local/go/bin
|
||||
- rm go1.23.3.linux-amd64.tar.gz
|
||||
- echo "GO 1.23.3 INSTALLED"
|
||||
- npm install
|
||||
build:
|
||||
commands:
|
||||
- npm run project-setup
|
||||
- npm run build
|
||||
artifacts:
|
||||
# IMPORTANT - Please verify your build output directory
|
||||
baseDirectory: /public
|
||||
files:
|
||||
- "**/*"
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/**/*
|
||||
@@ -1,2 +0,0 @@
|
||||
+++
|
||||
+++
|
||||
62
assets/css/base.css
Executable file
@@ -0,0 +1,62 @@
|
||||
html {
|
||||
@apply text-base-sm md:text-base;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-body text-base font-primary font-normal leading-relaxed text-text overflow-x-hidden;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@apply font-secondary font-bold leading-tight text-text-dark;
|
||||
span {
|
||||
@apply text-primary;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
.h1 {
|
||||
@apply text-h1-sm md:text-h1;
|
||||
}
|
||||
|
||||
h2,
|
||||
.h2 {
|
||||
@apply text-h2-sm md:text-h2;
|
||||
}
|
||||
|
||||
h3,
|
||||
.h3 {
|
||||
@apply text-h3-sm md:text-h3;
|
||||
}
|
||||
|
||||
h4,
|
||||
.h4 {
|
||||
@apply text-h4;
|
||||
}
|
||||
|
||||
h5,
|
||||
.h5 {
|
||||
@apply text-h5;
|
||||
}
|
||||
|
||||
h6,
|
||||
.h6 {
|
||||
@apply text-h6;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
code {
|
||||
@apply after:border-none;
|
||||
}
|
||||
|
||||
blockquote > p {
|
||||
@apply !my-0;
|
||||
}
|
||||
7
assets/css/bootstrap.css
vendored
44
assets/css/buttons.css
Executable file
@@ -0,0 +1,44 @@
|
||||
.btn {
|
||||
@apply inline-block border-0 rounded-none px-10 py-3.75 font-secondary font-light text-white transition-colors duration-300 cursor-pointer;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.btn-area {
|
||||
@apply block overflow-hidden;
|
||||
|
||||
span {
|
||||
@apply relative inline-block py-[2px] origin-left transition-transform duration-[900ms];
|
||||
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
|
||||
|
||||
&::after {
|
||||
content: attr(data-text);
|
||||
@apply absolute left-0 top-[150%] origin-left;
|
||||
transform: skewY(30deg);
|
||||
transition: transform 0.9s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:visited {
|
||||
.btn-area {
|
||||
span {
|
||||
transform: translateY(-150%) skewY(7deg);
|
||||
|
||||
&::after {
|
||||
transform: skewY(-7deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply border-primary bg-primary/85 hover:bg-primary text-text-light;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply border-secondary bg-secondary/85 hover:bg-secondary text-text-light;
|
||||
}
|
||||
67
assets/css/components.css
Executable file
@@ -0,0 +1,67 @@
|
||||
/* section style */
|
||||
.section {
|
||||
@apply py-24 xl:py-28;
|
||||
}
|
||||
|
||||
.section-sm {
|
||||
@apply py-16 xl:py-20;
|
||||
}
|
||||
|
||||
/* container */
|
||||
.container {
|
||||
@apply mx-auto xl:max-w-[1140px]! px-4;
|
||||
}
|
||||
|
||||
/* social icons */
|
||||
.social-icons {
|
||||
@apply space-x-3;
|
||||
}
|
||||
.social-icons li {
|
||||
@apply inline-block;
|
||||
}
|
||||
.social-icons li a {
|
||||
@apply flex h-6 w-6 items-center justify-center text-center leading-9 text-text-dark;
|
||||
}
|
||||
.social-icons li a svg {
|
||||
@apply h-5 w-5;
|
||||
}
|
||||
|
||||
/* Form Controls */
|
||||
.form-control {
|
||||
@apply bg-transparent border-0 border-b border-primary mb-7 px-0 pb-2.5 pt-0 rounded-none font-light tracking-wider appearance-none h-10 transition-all duration-200 text-text-dark placeholder-text-dark outline-0 focus:ring-0;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
@apply shadow-none bg-transparent border-b border-text-dark outline-none;
|
||||
}
|
||||
|
||||
select.form-control {
|
||||
@apply h-10 cursor-pointer;
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
@apply h-auto;
|
||||
}
|
||||
|
||||
/* content style */
|
||||
.content {
|
||||
@apply prose max-w-none;
|
||||
@apply prose-headings:mb-[.3em] prose-headings:mt-[.6em] prose-headings:text-text-dark;
|
||||
@apply prose-h1:text-h1-sm md:prose-h1:text-h1;
|
||||
@apply prose-h2:text-h2-sm md:prose-h2:text-h2;
|
||||
@apply prose-h3:text-h3-sm md:prose-h3:text-h3;
|
||||
@apply prose-p:text-base prose-p:text-text;
|
||||
@apply prose-a:text-text prose-a:[&.btn]:no-underline;
|
||||
@apply prose-img:max-w-full prose-img:rounded;
|
||||
@apply prose-strong:text-text-dark;
|
||||
@apply prose-hr:border-border;
|
||||
@apply prose-pre:rounded-lg prose-pre:bg-light;
|
||||
|
||||
@apply prose-li:text-text;
|
||||
@apply prose-blockquote:rounded-lg prose-blockquote:border prose-blockquote:border-l-[10px] prose-blockquote:border-primary prose-blockquote:bg-light prose-blockquote:px-8 prose-blockquote:py-10 prose-blockquote:font-secondary prose-blockquote:text-2xl prose-blockquote:not-italic prose-blockquote:text-text-dark;
|
||||
@apply prose-table:relative prose-table:overflow-hidden prose-table:rounded-lg prose-table:before:absolute prose-table:before:left-0 prose-table:before:top-0 prose-table:before:h-full prose-table:before:w-full prose-table:before:rounded-[inherit] prose-table:before:border prose-table:before:border-border prose-table:before:content-[""];
|
||||
@apply prose-thead:border-border prose-thead:bg-light;
|
||||
@apply prose-th:relative prose-th:z-10 prose-th:px-4 prose-th:py-[18px] prose-th:text-text-dark;
|
||||
@apply prose-tr:border-border;
|
||||
@apply prose-td:relative prose-td:z-10 prose-td:px-3 prose-td:py-[18px];
|
||||
}
|
||||
2
assets/css/custom.css
Normal file
@@ -0,0 +1,2 @@
|
||||
/* DO NOT WRITE ANY STYLE IN THIS FILE */
|
||||
/* If you want to add your own styles, please write it in the `./assets/css/custom.css` file. */
|
||||
39
assets/css/generated-theme.css
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Auto-generated from "data/theme.json"
|
||||
* DO NOT EDIT THIS FILE MANUALLY
|
||||
* Run: node scripts/themeGenerator.js
|
||||
*/
|
||||
|
||||
@theme {
|
||||
/* === Colors === */
|
||||
--color-primary: #E07B7B;
|
||||
--color-secondary: #8BC5BF;
|
||||
--color-tertiary: #F7F9FF;
|
||||
--color-body: #fff;
|
||||
--color-border: #eaeaea;
|
||||
--color-light: #f6f6f6;
|
||||
--color-dark: #040404;
|
||||
--color-text: #9D9EA5;
|
||||
--color-text-dark: #00113E;
|
||||
--color-text-light: #fff;
|
||||
|
||||
/* === Font Families === */
|
||||
--font-primary: Josefin Sans, sans-serif;
|
||||
--font-secondary: Montserrat, sans-serif;
|
||||
|
||||
/* === Font Sizes === */
|
||||
--text-base: 16px;
|
||||
--text-base-sm: 12.8px;
|
||||
--text-h6: 1.25rem;
|
||||
--text-h6-sm: 1.125rem;
|
||||
--text-h5: 1.5625rem;
|
||||
--text-h5-sm: 1.40625rem;
|
||||
--text-h4: 1.953125rem;
|
||||
--text-h4-sm: 1.7578125rem;
|
||||
--text-h3: 2.44140625rem;
|
||||
--text-h3-sm: 2.197265625rem;
|
||||
--text-h2: 3.0517578125rem;
|
||||
--text-h2-sm: 2.74658203125rem;
|
||||
--text-h1: 3.814697265625rem;
|
||||
--text-h1-sm: 3.4332275390625rem;
|
||||
}
|
||||
33
assets/css/main.css
Executable file
@@ -0,0 +1,33 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/forms";
|
||||
@plugin "@tailwindcss/typography";
|
||||
@plugin 'tailwind-bootstrap-grid';
|
||||
@source "hugo_stats.json";
|
||||
|
||||
/* Auto-generated theme from "data/theme.json"*/
|
||||
@import "./generated-theme.css";
|
||||
|
||||
@import "./safe.css";
|
||||
@import "./utilities.css";
|
||||
|
||||
@layer base {
|
||||
@import "./base.css";
|
||||
}
|
||||
|
||||
@layer components {
|
||||
@import "./components.css";
|
||||
@import "./navigation.css";
|
||||
@import "./buttons.css";
|
||||
}
|
||||
|
||||
@import "social-share.css";
|
||||
@import "gallery-slider.css";
|
||||
@import "images.css";
|
||||
@import "toc.css";
|
||||
@import "tab.css";
|
||||
@import "accordion.css";
|
||||
@import "modal.css";
|
||||
@import "notice.css";
|
||||
|
||||
@import "module-overrides.css";
|
||||
@import "custom.css";
|
||||
63
assets/css/module-overrides.css
Normal file
@@ -0,0 +1,63 @@
|
||||
/* table of contents */
|
||||
.table-of-content {
|
||||
@apply overflow-hidden rounded;
|
||||
}
|
||||
|
||||
/* share icons */
|
||||
.share-icons .share-link {
|
||||
@apply h-9 w-9 rounded leading-9 bg-primary hover:bg-primary;
|
||||
}
|
||||
|
||||
.share-icons .share-icon svg {
|
||||
}
|
||||
|
||||
.fediverse-input-wrapper {
|
||||
@apply bg-body rounded;
|
||||
input {
|
||||
@apply rounded focus:border-primary focus:ring-0;
|
||||
}
|
||||
button {
|
||||
@apply rounded bg-primary text-light hover:bg-primary;
|
||||
}
|
||||
}
|
||||
|
||||
/* notice */
|
||||
.notice {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
|
||||
/* tab */
|
||||
.tab {
|
||||
@apply border-border overflow-hidden rounded-lg border;
|
||||
}
|
||||
.tab-nav {
|
||||
@apply border-border bg-light pl-4;
|
||||
}
|
||||
.tab-nav-item {
|
||||
@apply text-text-dark px-8 !text-lg;
|
||||
}
|
||||
.tab-nav-item.active {
|
||||
@apply border-dark;
|
||||
}
|
||||
|
||||
.tab-content-panel {
|
||||
@apply px-4 !pt-0;
|
||||
}
|
||||
|
||||
/* accordion */
|
||||
.accordion {
|
||||
@apply border-border bg-light mb-6 overflow-hidden rounded-lg border;
|
||||
}
|
||||
.accordion-header {
|
||||
@apply text-text-dark;
|
||||
}
|
||||
|
||||
/* cookie consent */
|
||||
.cookie-box {
|
||||
@apply !rounded-lg;
|
||||
}
|
||||
|
||||
/* slider */
|
||||
.gallery-slider {
|
||||
@apply !ml-0;
|
||||
}
|
||||
43
assets/css/navigation.css
Executable file
@@ -0,0 +1,43 @@
|
||||
.header {
|
||||
@apply bg-body py-6;
|
||||
}
|
||||
|
||||
/* navbar items */
|
||||
.navbar {
|
||||
@apply relative flex flex-wrap items-center justify-between;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
@apply text-text-dark text-xl font-semibold;
|
||||
image {
|
||||
@apply max-h-full max-w-full;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
@apply text-center lg:text-left;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@apply text-text-dark hover:text-primary block p-3 cursor-pointer font-semibold transition lg:px-2 lg:py-3;
|
||||
}
|
||||
|
||||
.nav-dropdown {
|
||||
@apply mr-0;
|
||||
}
|
||||
|
||||
.nav-dropdown > svg {
|
||||
@apply pointer-events-none;
|
||||
}
|
||||
|
||||
.nav-dropdown-list {
|
||||
@apply bg-body z-10 min-w-[180px] rounded p-4 shadow-sm;
|
||||
}
|
||||
|
||||
.nav-dropdown-item {
|
||||
@apply [&:not(:last-child)]:mb-2;
|
||||
}
|
||||
|
||||
.nav-dropdown-link {
|
||||
@apply text-text-dark hover:text-primary block py-1 font-semibold transition;
|
||||
}
|
||||
12
assets/css/safe.css
Normal file
@@ -0,0 +1,12 @@
|
||||
/* navbar toggler */
|
||||
input#nav-toggle:checked + label #show-button {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
input#nav-toggle:checked + label #hide-button {
|
||||
@apply block;
|
||||
}
|
||||
|
||||
input#nav-toggle:checked ~ div #nav-menu {
|
||||
@apply max-lg:block;
|
||||
}
|
||||
0
layouts/404.html → assets/css/utilities.css
Normal file → Executable file
@@ -1,40 +0,0 @@
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
var form = document.getElementById("contact-form");
|
||||
var button = document.getElementById("contact-form-button");
|
||||
var status = document.getElementById("contact-form-status");
|
||||
|
||||
function success() {
|
||||
form.reset();
|
||||
button.style = "display: none ";
|
||||
status.innerHTML = "Thanks! Contact form is submitted successfully.";
|
||||
}
|
||||
|
||||
function error() {
|
||||
status.innerHTML = "Oops! There was a problem.";
|
||||
}
|
||||
|
||||
// handle the form submission event
|
||||
|
||||
form.addEventListener("submit", function(ev) {
|
||||
ev.preventDefault();
|
||||
var data = new FormData(form);
|
||||
ajax(form.method, form.action, data, success, error);
|
||||
});
|
||||
});
|
||||
|
||||
// helper function for sending an AJAX request
|
||||
|
||||
function ajax(method, url, data, success, error) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(method, url);
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState !== XMLHttpRequest.DONE) return;
|
||||
if (xhr.status === 200) {
|
||||
success(xhr.response, xhr.responseType);
|
||||
} else {
|
||||
error(xhr.status, xhr.response, xhr.responseType);
|
||||
}
|
||||
};
|
||||
xhr.send(data);
|
||||
}
|
||||
43
assets/js/main.js
Executable file
@@ -0,0 +1,43 @@
|
||||
// main script
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// Header shrink on scroll
|
||||
(function () {
|
||||
var header = document.getElementById("site-header");
|
||||
if (!header) return;
|
||||
// only enable shrink behavior when navbar_fixed param is true
|
||||
var navbarFixed = header.dataset && header.dataset.navbarFixed === "true";
|
||||
if (!navbarFixed) return;
|
||||
var lastKnownScrollY = 0;
|
||||
var ticking = false;
|
||||
var threshold = 20;
|
||||
|
||||
function onScroll() {
|
||||
lastKnownScrollY = window.scrollY || window.pageYOffset;
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function requestTick() {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
ticking = true;
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (lastKnownScrollY > threshold) {
|
||||
header.classList.add("py-2", "lg:py-3", "shadow-lg");
|
||||
header.classList.remove("py-6", "lg:py-6");
|
||||
} else {
|
||||
header.classList.remove("py-2", "lg:py-3", "shadow-lg");
|
||||
header.classList.add("py-6", "lg:py-6");
|
||||
}
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
// run on init
|
||||
update();
|
||||
})();
|
||||
})();
|
||||
@@ -1,614 +0,0 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* - Using the 'QRCode for Javascript library'
|
||||
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
|
||||
* - this library has no dependencies.
|
||||
*
|
||||
* @author davidshimjs
|
||||
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
|
||||
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
|
||||
*/
|
||||
var QRCode;
|
||||
|
||||
(function () {
|
||||
//---------------------------------------------------------------------
|
||||
// QRCode for JavaScript
|
||||
//
|
||||
// Copyright (c) 2009 Kazuhiko Arase
|
||||
//
|
||||
// URL: http://www.d-project.com/
|
||||
//
|
||||
// Licensed under the MIT license:
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// The word "QR Code" is registered trademark of
|
||||
// DENSO WAVE INCORPORATED
|
||||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
function QR8bitByte(data) {
|
||||
this.mode = QRMode.MODE_8BIT_BYTE;
|
||||
this.data = data;
|
||||
this.parsedData = [];
|
||||
|
||||
// Added to support UTF-8 Characters
|
||||
for (var i = 0, l = this.data.length; i < l; i++) {
|
||||
var byteArray = [];
|
||||
var code = this.data.charCodeAt(i);
|
||||
|
||||
if (code > 0x10000) {
|
||||
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
|
||||
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
|
||||
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[3] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x800) {
|
||||
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
|
||||
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[2] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x80) {
|
||||
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
|
||||
byteArray[1] = 0x80 | (code & 0x3F);
|
||||
} else {
|
||||
byteArray[0] = code;
|
||||
}
|
||||
|
||||
this.parsedData.push(byteArray);
|
||||
}
|
||||
|
||||
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
|
||||
|
||||
if (this.parsedData.length != this.data.length) {
|
||||
this.parsedData.unshift(191);
|
||||
this.parsedData.unshift(187);
|
||||
this.parsedData.unshift(239);
|
||||
}
|
||||
}
|
||||
|
||||
QR8bitByte.prototype = {
|
||||
getLength: function (buffer) {
|
||||
return this.parsedData.length;
|
||||
},
|
||||
write: function (buffer) {
|
||||
for (var i = 0, l = this.parsedData.length; i < l; i++) {
|
||||
buffer.put(this.parsedData[i], 8);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function QRCodeModel(typeNumber, errorCorrectLevel) {
|
||||
this.typeNumber = typeNumber;
|
||||
this.errorCorrectLevel = errorCorrectLevel;
|
||||
this.modules = null;
|
||||
this.moduleCount = 0;
|
||||
this.dataCache = null;
|
||||
this.dataList = [];
|
||||
}
|
||||
|
||||
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
|
||||
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
|
||||
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
|
||||
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
|
||||
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
|
||||
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
|
||||
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
|
||||
this.modules[r][6]=(r%2==0);}
|
||||
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
|
||||
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
|
||||
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
|
||||
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
|
||||
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
|
||||
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
|
||||
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
|
||||
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
|
||||
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
|
||||
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
|
||||
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
|
||||
+buffer.getLengthInBits()
|
||||
+">"
|
||||
+totalDataCount*8
|
||||
+")");}
|
||||
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
|
||||
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
|
||||
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD1,8);}
|
||||
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
|
||||
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
|
||||
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
|
||||
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
|
||||
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
|
||||
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
|
||||
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
|
||||
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
|
||||
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
|
||||
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
|
||||
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
|
||||
if(r==0&&c==0){continue;}
|
||||
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
|
||||
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
|
||||
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
|
||||
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
|
||||
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
|
||||
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
|
||||
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
|
||||
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
|
||||
while(n>=256){n-=255;}
|
||||
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
|
||||
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
|
||||
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
|
||||
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
|
||||
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
|
||||
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
|
||||
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
|
||||
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
|
||||
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
|
||||
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
|
||||
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
|
||||
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
|
||||
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
|
||||
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
|
||||
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
|
||||
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
|
||||
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
|
||||
|
||||
function _isSupportCanvas() {
|
||||
return typeof CanvasRenderingContext2D != "undefined";
|
||||
}
|
||||
|
||||
// android 2.x doesn't support Data-URI spec
|
||||
function _getAndroid() {
|
||||
var android = false;
|
||||
var sAgent = navigator.userAgent;
|
||||
|
||||
if (/android/i.test(sAgent)) { // android
|
||||
android = true;
|
||||
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
|
||||
|
||||
if (aMat && aMat[1]) {
|
||||
android = parseFloat(aMat[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return android;
|
||||
}
|
||||
|
||||
var svgDrawer = (function() {
|
||||
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
|
||||
this.clear();
|
||||
|
||||
function makeSVG(tag, attrs) {
|
||||
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
|
||||
for (var k in attrs)
|
||||
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
|
||||
return el;
|
||||
}
|
||||
|
||||
var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
|
||||
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||
_el.appendChild(svg);
|
||||
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
if (oQRCode.isDark(row, col)) {
|
||||
var child = makeSVG("use", {"x": String(col), "y": String(row)});
|
||||
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
|
||||
svg.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Drawing.prototype.clear = function () {
|
||||
while (this._el.hasChildNodes())
|
||||
this._el.removeChild(this._el.lastChild);
|
||||
};
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
|
||||
|
||||
// Drawing in DOM by using Table tag
|
||||
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
aHTML.push('<tr>');
|
||||
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
|
||||
}
|
||||
|
||||
aHTML.push('</tr>');
|
||||
}
|
||||
|
||||
aHTML.push('</table>');
|
||||
_el.innerHTML = aHTML.join('');
|
||||
|
||||
// Fix the margin values as real size.
|
||||
var elTable = _el.childNodes[0];
|
||||
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
|
||||
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
|
||||
|
||||
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
|
||||
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._el.innerHTML = '';
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})() : (function () { // Drawing in Canvas
|
||||
function _onMakeImage() {
|
||||
this._elImage.src = this._elCanvas.toDataURL("image/png");
|
||||
this._elImage.style.display = "block";
|
||||
this._elCanvas.style.display = "none";
|
||||
}
|
||||
|
||||
// Android 2.1 bug workaround
|
||||
// http://code.google.com/p/android/issues/detail?id=5141
|
||||
if (this._android && this._android <= 2.1) {
|
||||
var factor = 1 / window.devicePixelRatio;
|
||||
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
|
||||
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
||||
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
|
||||
for (var i = arguments.length - 1; i >= 1; i--) {
|
||||
arguments[i] = arguments[i] * factor;
|
||||
}
|
||||
} else if (typeof dw == "undefined") {
|
||||
arguments[1] *= factor;
|
||||
arguments[2] *= factor;
|
||||
arguments[3] *= factor;
|
||||
arguments[4] *= factor;
|
||||
}
|
||||
|
||||
drawImage.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user's browser supports Data URI or not
|
||||
*
|
||||
* @private
|
||||
* @param {Function} fSuccess Occurs if it supports Data URI
|
||||
* @param {Function} fFail Occurs if it doesn't support Data URI
|
||||
*/
|
||||
function _safeSetDataURI(fSuccess, fFail) {
|
||||
var self = this;
|
||||
self._fFail = fFail;
|
||||
self._fSuccess = fSuccess;
|
||||
|
||||
// Check it just once
|
||||
if (self._bSupportDataURI === null) {
|
||||
var el = document.createElement("img");
|
||||
var fOnError = function() {
|
||||
self._bSupportDataURI = false;
|
||||
|
||||
if (self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
var fOnSuccess = function() {
|
||||
self._bSupportDataURI = true;
|
||||
|
||||
if (self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
el.onabort = fOnError;
|
||||
el.onerror = fOnError;
|
||||
el.onload = fOnSuccess;
|
||||
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
|
||||
return;
|
||||
} else if (self._bSupportDataURI === true && self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
} else if (self._bSupportDataURI === false && self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing QRCode by using canvas
|
||||
*
|
||||
* @constructor
|
||||
* @param {HTMLElement} el
|
||||
* @param {Object} htOption QRCode Options
|
||||
*/
|
||||
var Drawing = function (el, htOption) {
|
||||
this._bIsPainted = false;
|
||||
this._android = _getAndroid();
|
||||
|
||||
this._htOption = htOption;
|
||||
this._elCanvas = document.createElement("canvas");
|
||||
this._elCanvas.width = htOption.width;
|
||||
this._elCanvas.height = htOption.height;
|
||||
el.appendChild(this._elCanvas);
|
||||
this._el = el;
|
||||
this._oContext = this._elCanvas.getContext("2d");
|
||||
this._bIsPainted = false;
|
||||
this._elImage = document.createElement("img");
|
||||
this._elImage.alt = "Scan me!";
|
||||
this._elImage.style.display = "none";
|
||||
this._el.appendChild(this._elImage);
|
||||
this._bSupportDataURI = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _elImage = this._elImage;
|
||||
var _oContext = this._oContext;
|
||||
var _htOption = this._htOption;
|
||||
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = _htOption.width / nCount;
|
||||
var nHeight = _htOption.height / nCount;
|
||||
var nRoundedWidth = Math.round(nWidth);
|
||||
var nRoundedHeight = Math.round(nHeight);
|
||||
|
||||
_elImage.style.display = "none";
|
||||
this.clear();
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
var bIsDark = oQRCode.isDark(row, col);
|
||||
var nLeft = col * nWidth;
|
||||
var nTop = row * nHeight;
|
||||
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.lineWidth = 1;
|
||||
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
|
||||
|
||||
// 안티 앨리어싱 방지 처리
|
||||
_oContext.strokeRect(
|
||||
Math.floor(nLeft) + 0.5,
|
||||
Math.floor(nTop) + 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
|
||||
_oContext.strokeRect(
|
||||
Math.ceil(nLeft) - 0.5,
|
||||
Math.ceil(nTop) - 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this._bIsPainted = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the image from Canvas if the browser supports Data URI.
|
||||
*/
|
||||
Drawing.prototype.makeImage = function () {
|
||||
if (this._bIsPainted) {
|
||||
_safeSetDataURI.call(this, _onMakeImage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return whether the QRCode is painted or not
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
Drawing.prototype.isPainted = function () {
|
||||
return this._bIsPainted;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
|
||||
this._bIsPainted = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Number} nNumber
|
||||
*/
|
||||
Drawing.prototype.round = function (nNumber) {
|
||||
if (!nNumber) {
|
||||
return nNumber;
|
||||
}
|
||||
|
||||
return Math.floor(nNumber * 1000) / 1000;
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the type by string length
|
||||
*
|
||||
* @private
|
||||
* @param {String} sText
|
||||
* @param {Number} nCorrectLevel
|
||||
* @return {Number} type
|
||||
*/
|
||||
function _getTypeNumber(sText, nCorrectLevel) {
|
||||
var nType = 1;
|
||||
var length = _getUTF8Length(sText);
|
||||
|
||||
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
|
||||
var nLimit = 0;
|
||||
|
||||
switch (nCorrectLevel) {
|
||||
case QRErrorCorrectLevel.L :
|
||||
nLimit = QRCodeLimitLength[i][0];
|
||||
break;
|
||||
case QRErrorCorrectLevel.M :
|
||||
nLimit = QRCodeLimitLength[i][1];
|
||||
break;
|
||||
case QRErrorCorrectLevel.Q :
|
||||
nLimit = QRCodeLimitLength[i][2];
|
||||
break;
|
||||
case QRErrorCorrectLevel.H :
|
||||
nLimit = QRCodeLimitLength[i][3];
|
||||
break;
|
||||
}
|
||||
|
||||
if (length <= nLimit) {
|
||||
break;
|
||||
} else {
|
||||
nType++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nType > QRCodeLimitLength.length) {
|
||||
throw new Error("Too long data");
|
||||
}
|
||||
|
||||
return nType;
|
||||
}
|
||||
|
||||
function _getUTF8Length(sText) {
|
||||
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
|
||||
return replacedText.length + (replacedText.length != sText ? 3 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @class QRCode
|
||||
* @constructor
|
||||
* @example
|
||||
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
|
||||
*
|
||||
* @example
|
||||
* var oQRCode = new QRCode("test", {
|
||||
* text : "http://naver.com",
|
||||
* width : 128,
|
||||
* height : 128
|
||||
* });
|
||||
*
|
||||
* oQRCode.clear(); // Clear the QRCode.
|
||||
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
|
||||
*
|
||||
* @param {HTMLElement|String} el target element or 'id' attribute of element.
|
||||
* @param {Object|String} vOption
|
||||
* @param {String} vOption.text QRCode link data
|
||||
* @param {Number} [vOption.width=256]
|
||||
* @param {Number} [vOption.height=256]
|
||||
* @param {String} [vOption.colorDark="#000000"]
|
||||
* @param {String} [vOption.colorLight="#ffffff"]
|
||||
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
|
||||
*/
|
||||
QRCode = function (el, vOption) {
|
||||
this._htOption = {
|
||||
width : 256,
|
||||
height : 256,
|
||||
typeNumber : 4,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRErrorCorrectLevel.H
|
||||
};
|
||||
|
||||
if (typeof vOption === 'string') {
|
||||
vOption = {
|
||||
text : vOption
|
||||
};
|
||||
}
|
||||
|
||||
// Overwrites options
|
||||
if (vOption) {
|
||||
for (var i in vOption) {
|
||||
this._htOption[i] = vOption[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof el == "string") {
|
||||
el = document.getElementById(el);
|
||||
}
|
||||
|
||||
if (this._htOption.useSVG) {
|
||||
Drawing = svgDrawer;
|
||||
}
|
||||
|
||||
this._android = _getAndroid();
|
||||
this._el = el;
|
||||
this._oQRCode = null;
|
||||
this._oDrawing = new Drawing(this._el, this._htOption);
|
||||
|
||||
if (this._htOption.text) {
|
||||
this.makeCode(this._htOption.text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the QRCode
|
||||
*
|
||||
* @param {String} sText link data
|
||||
*/
|
||||
QRCode.prototype.makeCode = function (sText) {
|
||||
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
|
||||
this._oQRCode.addData(sText);
|
||||
this._oQRCode.make();
|
||||
this._el.title = sText;
|
||||
this._oDrawing.draw(this._oQRCode);
|
||||
this.makeImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the Image from Canvas element
|
||||
* - It occurs automatically
|
||||
* - Android below 3 doesn't support Data-URI spec.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
QRCode.prototype.makeImage = function () {
|
||||
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
|
||||
this._oDrawing.makeImage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
QRCode.prototype.clear = function () {
|
||||
this._oDrawing.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* @name QRCode.CorrectLevel
|
||||
*/
|
||||
QRCode.CorrectLevel = QRErrorCorrectLevel;
|
||||
})();
|
||||
@@ -1,35 +0,0 @@
|
||||
$(document).ready(function() {
|
||||
"use strict";
|
||||
// Scroll to top
|
||||
$("a[href='#top']").click(function() {
|
||||
$("html, body").animate({ scrollTop: 0 }, "slow");
|
||||
return false;
|
||||
});
|
||||
|
||||
// Smooth scroll
|
||||
$('a.scroll-to').on('click', function (event) {
|
||||
var $anchor = $(this);
|
||||
$('html, body').stop().animate({
|
||||
scrollTop: ($($anchor.attr('href')).offset().top - 50)
|
||||
}, 700);
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
$('.site-testimonial-item').on('mouseenter', function(){
|
||||
$('.site-testimonial-item').addClass('inactive');
|
||||
$(this).removeClass('inactive').addClass('active');
|
||||
});
|
||||
$('.site-testimonial-item').on('mouseleave', function(){
|
||||
$('.site-testimonial-item').removeClass('inactive');
|
||||
$('.site-testimonial-item').removeClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
$(window).on('scroll', function () {
|
||||
var windscroll = $(window).scrollTop();
|
||||
if (windscroll >= 100) {
|
||||
$('.site-navigation').addClass('nav-bg');
|
||||
} else {
|
||||
$('.site-navigation').removeClass('nav-bg');
|
||||
}
|
||||
});
|
||||
179
assets/plugins/maps/google-map.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/*!***************************************************
|
||||
* Google Map
|
||||
*****************************************************/
|
||||
|
||||
window.marker = null;
|
||||
|
||||
function initialize() {
|
||||
var map,
|
||||
mapId = document.getElementById("map");
|
||||
var latitude = mapId.getAttribute("data-latitude");
|
||||
var longitude = mapId.getAttribute("data-longitude");
|
||||
var mapMarker = mapId.getAttribute("data-marker");
|
||||
var mapMarkerName = mapId.getAttribute("data-marker-name");
|
||||
var nottingham = new google.maps.LatLng(latitude, longitude);
|
||||
var style = [
|
||||
{
|
||||
featureType: "administrative",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
saturation: "-100",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "administrative.province",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
visibility: "off",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "landscape",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
saturation: -100,
|
||||
},
|
||||
{
|
||||
lightness: 65,
|
||||
},
|
||||
{
|
||||
visibility: "on",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "poi",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
saturation: -100,
|
||||
},
|
||||
{
|
||||
lightness: "50",
|
||||
},
|
||||
{
|
||||
visibility: "simplified",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "road",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
saturation: "-100",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "road.highway",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
visibility: "simplified",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "road.arterial",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
lightness: "30",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "road.local",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
lightness: "40",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "transit",
|
||||
elementType: "all",
|
||||
stylers: [
|
||||
{
|
||||
saturation: -100,
|
||||
},
|
||||
{
|
||||
visibility: "simplified",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "water",
|
||||
elementType: "geometry",
|
||||
stylers: [
|
||||
{
|
||||
hue: "#ffff00",
|
||||
},
|
||||
{
|
||||
lightness: -25,
|
||||
},
|
||||
{
|
||||
saturation: -97,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
featureType: "water",
|
||||
elementType: "labels",
|
||||
stylers: [
|
||||
{
|
||||
lightness: -25,
|
||||
},
|
||||
{
|
||||
saturation: -100,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
var mapOptions = {
|
||||
center: nottingham,
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||
backgroundColor: "#000",
|
||||
zoom: 15,
|
||||
panControl: !1,
|
||||
zoomControl: !0,
|
||||
mapTypeControl: !1,
|
||||
scaleControl: !1,
|
||||
streetViewControl: !1,
|
||||
overviewMapControl: !1,
|
||||
zoomControlOptions: {
|
||||
style: google.maps.ZoomControlStyle.LARGE,
|
||||
},
|
||||
};
|
||||
map = new google.maps.Map(document.getElementById("map"), mapOptions);
|
||||
var mapType = new google.maps.StyledMapType(style, {
|
||||
name: "Grayscale",
|
||||
});
|
||||
map.mapTypes.set("grey", mapType);
|
||||
map.setMapTypeId("grey");
|
||||
var marker_image = mapMarker;
|
||||
var pinIcon = new google.maps.MarkerImage(
|
||||
marker_image,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new google.maps.Size(30, 50),
|
||||
);
|
||||
marker = new google.maps.Marker({
|
||||
position: nottingham,
|
||||
map: map,
|
||||
icon: pinIcon,
|
||||
title: mapMarkerName,
|
||||
});
|
||||
}
|
||||
var map = document.getElementById("map");
|
||||
if (map != null) {
|
||||
google.maps.event.addDomListener(window, "load", initialize);
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
.btn{
|
||||
font-family: $secondary-font;
|
||||
border: none;
|
||||
color: $white !important;
|
||||
padding: 20px 45px;
|
||||
border-radius: 0;
|
||||
&:focus{
|
||||
box-shadow: none;
|
||||
}
|
||||
@include desktop{
|
||||
padding: 17px 40px;
|
||||
}
|
||||
.btn-area{
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
span{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 2px 0;
|
||||
transition: transform .9s cubic-bezier(.19,1,.22,1);
|
||||
transform-origin: left center;
|
||||
&::after{
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 150%;
|
||||
left: 0;
|
||||
transform: skewY(30deg);
|
||||
transform-origin: left center;
|
||||
transition: transform .9s cubic-bezier(.19,1,.22,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
.btn-area{
|
||||
span{
|
||||
transform: translateY(-150%) skewY(7deg);
|
||||
&::after{
|
||||
transform: skewY(-7deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:visited{
|
||||
.btn-area{
|
||||
span{
|
||||
transform: translateY(-150%) skewY(7deg);
|
||||
&::after{
|
||||
transform: skewY(-7deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-sm{
|
||||
padding: 15px 40px !important;
|
||||
}
|
||||
|
||||
.btn-sm-rounded{
|
||||
border-radius: 40px;
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
background: $primary-color;
|
||||
color: $white;
|
||||
&:hover{
|
||||
background: darken($color: $primary-color, $amount: 10);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary{
|
||||
background: $secondary-color;
|
||||
color: $white;
|
||||
&:hover{
|
||||
background: darken($color: $secondary-color, $amount: 10);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// html{
|
||||
// scroll-behavior: smooth;
|
||||
// }
|
||||
|
||||
body {
|
||||
background: $body-color;
|
||||
}
|
||||
|
||||
.section-title{
|
||||
margin-bottom: 70px;
|
||||
@include desktop{
|
||||
text-align: center;
|
||||
}
|
||||
h2{
|
||||
font-weight: 300;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 15px;
|
||||
@include desktop{
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
p{
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control{
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
margin-bottom: 30px;
|
||||
padding: 0 0 10px 0;
|
||||
border-width: 0 0 1px 0;
|
||||
border-color: $primary-color;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
-webkit-appearance: none;
|
||||
height: 42px;
|
||||
&:focus{
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
border-color: $text-color;
|
||||
}
|
||||
}
|
||||
|
||||
select.form-control{
|
||||
height: 42px !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.select-wrapper{
|
||||
position: relative;
|
||||
&::before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 10px;
|
||||
background: url('../images/angle-down-select.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-80%);
|
||||
}
|
||||
}
|
||||
|
||||
textarea.form-control{
|
||||
height: auto;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
@mixin mobile-xs{
|
||||
@media(max-width:400px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@mixin mobile{
|
||||
@media(max-width:575px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@mixin tablet{
|
||||
@media(max-width:767px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@mixin desktop{
|
||||
@media(max-width:991px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@mixin desktop-lg{
|
||||
@media(max-width:1200px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-xl{
|
||||
@media(max-width:1400px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-4k{
|
||||
@media(min-width:2000px){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@mixin size($size){
|
||||
width: $size; height: $size;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans:300,400,600,700|Montserrat:300,400,500,600,700&display=swap');
|
||||
|
||||
body{
|
||||
font-family: $primary-font;
|
||||
font-size: 16px;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6{
|
||||
font-family: $secondary-font;
|
||||
font-weight: 600;
|
||||
color: $text-color-dark;
|
||||
}
|
||||
|
||||
p{
|
||||
font-size: 16px;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
h1{
|
||||
font-size: 60px;
|
||||
}
|
||||
|
||||
h2{
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
h3{
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h4{
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
h5{
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h6{
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
//site color variables
|
||||
$body-color: #fff;
|
||||
$primary-color: #EAA4A4;
|
||||
$secondary-color: #ADD6D2;
|
||||
$text-color: #9D9EA5;
|
||||
$text-color-dark: #00113E;
|
||||
$site-ease: cubic-bezier(0.36, 0.03, 0, 0.91);
|
||||
$gray: #F7F9FF;
|
||||
$dark-gray: #646569;
|
||||
|
||||
// solid colors
|
||||
$white: #fff;
|
||||
$black: #000;
|
||||
|
||||
// Font Variables
|
||||
$primary-font: 'Josefin Sans', sans-serif;
|
||||
$secondary-font: 'Montserrat', sans-serif;
|
||||
@@ -1,45 +0,0 @@
|
||||
.site-about{
|
||||
&-header{
|
||||
padding-top: 80px;
|
||||
background-color: $gray;
|
||||
@include mobile{
|
||||
padding-top: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
&-wrapper{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
&-company{
|
||||
background: $primary-color;
|
||||
width: 40%;
|
||||
padding: 70px 38px;
|
||||
@include desktop{
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h1{
|
||||
color: $white;
|
||||
font-weight: 400;
|
||||
font-size: 25px;
|
||||
line-height: 60px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
&-description{
|
||||
width: 60%;
|
||||
padding-left: 50px;
|
||||
@include desktop{
|
||||
width: 100%;
|
||||
padding: 0 38px;
|
||||
}
|
||||
p{
|
||||
font-size: 25px;
|
||||
font-weight: 300;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
.site{
|
||||
&-blog{
|
||||
@extend .site-project;
|
||||
@include mobile{
|
||||
padding: 70px 0;
|
||||
}
|
||||
&.details{
|
||||
padding: 150px 0 80px;
|
||||
@include tablet{
|
||||
padding: 100px 0 60px;
|
||||
}
|
||||
}
|
||||
&-header{
|
||||
padding: 150px 0 0;
|
||||
@include mobile{
|
||||
padding: 100px 0 0;
|
||||
}
|
||||
h1{
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 10px;
|
||||
margin-bottom: 20px;
|
||||
@include mobile{
|
||||
font-size: 35px;
|
||||
}
|
||||
}
|
||||
p{
|
||||
line-height: 28px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
&-pagination{
|
||||
@extend .site-project-pagination;
|
||||
}
|
||||
&-post{
|
||||
@extend .site-project-item;
|
||||
&-thumb{
|
||||
@extend .site-project-item-thumb;
|
||||
}
|
||||
&-content{
|
||||
@extend .site-project-item-content;
|
||||
@include mobile{
|
||||
padding: 15px 25px 40px;
|
||||
}
|
||||
span{
|
||||
font-size: 14px;
|
||||
}
|
||||
h3{
|
||||
margin-bottom: 15px;
|
||||
@include mobile{
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
a.read-more{
|
||||
color: $primary-color;
|
||||
letter-spacing: 2px;
|
||||
@include mobile{
|
||||
transform: translateY(22px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-details{
|
||||
img{
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.blog-title{
|
||||
font-size: 40px;
|
||||
}
|
||||
.feature-image{
|
||||
margin: 20px 0 30px;
|
||||
}
|
||||
h2,h3,h4,h5,h6{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
blockquote{
|
||||
p{
|
||||
color: $text-color-dark;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
cite{
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
.site-client{
|
||||
padding: 100px 0 50px;
|
||||
.section-title{
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
&-wrapper{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@include desktop{
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
&-item{
|
||||
text-align: center;
|
||||
width: 20%;
|
||||
margin-bottom: 50px;
|
||||
@include desktop{
|
||||
width: 33.33%;
|
||||
}
|
||||
@include mobile{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
.site-contact{
|
||||
padding: 150px 0 100px;
|
||||
background: $gray;
|
||||
@include mobile{
|
||||
padding: 120px 0 100px;
|
||||
}
|
||||
&-title{
|
||||
font-weight: 700;
|
||||
@include tablet{
|
||||
font-size: 40px;
|
||||
}
|
||||
span{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
&-form{
|
||||
margin-top: 20px;
|
||||
h4{
|
||||
font-weight: 300;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 50px;
|
||||
letter-spacing: 3px;
|
||||
@include tablet{
|
||||
font-size: 20px;
|
||||
}
|
||||
@include desktop{
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contact-form-generator {
|
||||
margin-top: 20px;
|
||||
a{
|
||||
color: $text-color-dark;
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 50px;
|
||||
letter-spacing: 3px;
|
||||
&:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
@include tablet{
|
||||
font-size: 20px;
|
||||
}
|
||||
@include desktop{
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
.site-counter{
|
||||
padding: 85px 0;
|
||||
color: $white;
|
||||
background: $secondary-color;
|
||||
.section-title{
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
@include mobile{
|
||||
padding: 50px 0;
|
||||
}
|
||||
&-item{
|
||||
@include desktop{
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
&-title{
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
&-number{
|
||||
color: $white;
|
||||
font-size: 60px;
|
||||
margin-bottom: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
.site-cta{
|
||||
padding: 130px 0;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
@include desktop{
|
||||
padding: 100px 0;
|
||||
}
|
||||
&-title{
|
||||
font-size: 70px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 10px;
|
||||
margin-bottom: 60px;
|
||||
@include desktop{
|
||||
letter-spacing: 5px;
|
||||
}
|
||||
@include desktop-lg{
|
||||
font-size: 50px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
@include mobile{
|
||||
font-size: 40px;
|
||||
letter-spacing: 1;
|
||||
}
|
||||
}
|
||||
&-buttons{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
li{
|
||||
display: inline-block;
|
||||
@include mobile{
|
||||
display: block;
|
||||
}
|
||||
&:not(:last-child){
|
||||
margin-right: 40px;
|
||||
@include mobile{
|
||||
margin-right: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
@include mobile{
|
||||
display: block;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
.site-expertise{
|
||||
padding: 100px 0;
|
||||
background: $gray;
|
||||
&-list{
|
||||
padding: 0;
|
||||
margin: 10px 0 0 20px;
|
||||
@include mobile{
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
li{
|
||||
list-style: none;
|
||||
font-size: 25px;
|
||||
font-weight: 300;
|
||||
color: $text-color-dark;
|
||||
&:not(:last-child){
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
.site-footer{
|
||||
background: $secondary-color;
|
||||
padding: 100px 0;
|
||||
&-logo{
|
||||
margin-bottom: 50px;
|
||||
@include mobile{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
&-widget{
|
||||
@include desktop{
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
@include mobile{
|
||||
text-align: center;
|
||||
}
|
||||
&-title{
|
||||
color: $white;
|
||||
margin-bottom: 30px;
|
||||
@include desktop{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
&-description{
|
||||
color: $white;
|
||||
line-height: 30px;
|
||||
a{
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
&-links{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
li{
|
||||
list-style: none;
|
||||
a{
|
||||
color: $white;
|
||||
transition: all 0.3s $site-ease;
|
||||
display: block;
|
||||
}
|
||||
&:not(:last-child){
|
||||
a{
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-top{
|
||||
@include mobile{
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
img{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
p{
|
||||
color: $white;
|
||||
}
|
||||
&:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-copyright{
|
||||
p{
|
||||
color: $white;
|
||||
margin: 50px auto 0;
|
||||
text-align: center;
|
||||
}
|
||||
a{
|
||||
color: $text-color-dark;
|
||||
transition: all .3s ease;
|
||||
@include tablet{
|
||||
font-size: 20px;
|
||||
}
|
||||
@include desktop{
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
.site-hero{
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@include desktop{
|
||||
height: auto;
|
||||
padding: 200px 0;
|
||||
}
|
||||
@include mobile{
|
||||
padding: 150px 0;
|
||||
}
|
||||
&-content{
|
||||
h1{
|
||||
margin-bottom: 75px;
|
||||
@include desktop-lg{
|
||||
font-size: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
@include mobile{
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
&-buttons{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
li{
|
||||
display: inline-block;
|
||||
@include mobile{
|
||||
display: block;
|
||||
}
|
||||
&:not(:last-child){
|
||||
margin-right: 30px;
|
||||
@include mobile{
|
||||
margin-right: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
font-weight: 600;
|
||||
@include mobile{
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-scroll{
|
||||
position: absolute;
|
||||
left: 50%; bottom: 70px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
.site-navigation{
|
||||
padding: 20px 0;
|
||||
background: $white;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
transition: all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
@include desktop{
|
||||
background: $white;
|
||||
margin: 10px;
|
||||
border-radius: 5px;
|
||||
top: 0;
|
||||
width: calc(100% - 20px);
|
||||
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.09);
|
||||
}
|
||||
@include mobile{
|
||||
padding: 15px;
|
||||
}
|
||||
.navbar-brand{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
img{
|
||||
max-width: 78px;
|
||||
}
|
||||
}
|
||||
.nav-item{
|
||||
@include desktop{
|
||||
text-align: center;
|
||||
}
|
||||
.nav-link{
|
||||
font-family: $secondary-font;
|
||||
color: $text-color-dark;
|
||||
transition: all .3s ease;
|
||||
padding: 15px 18px;
|
||||
position: relative;
|
||||
}
|
||||
&:last-child{
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
.navbar-toggler{
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
.icon-bar {
|
||||
height: 2px;
|
||||
width: 25px;
|
||||
transition: all 0.2s;
|
||||
background: $primary-color;
|
||||
display: block;
|
||||
&:not(:last-child){
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
&:nth-child(1){
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 10% 10%;
|
||||
}
|
||||
&:nth-child(2){
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
&:nth-child(3){
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: 10% 90%;
|
||||
}
|
||||
}
|
||||
&.collapsed{
|
||||
.icon-bar{
|
||||
&:nth-child(1){
|
||||
transform: rotate(0);
|
||||
}
|
||||
&:nth-child(2){
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=1);
|
||||
}
|
||||
&:nth-child(3){
|
||||
transform: rotate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.nav-bg{
|
||||
padding: 12px 0;
|
||||
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.09);
|
||||
@include mobile{
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
.site-project{
|
||||
padding: 120px 0;
|
||||
overflow: hidden;
|
||||
&-item{
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
transition: all 0.3s ease-in;
|
||||
&-thumb{
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-content{
|
||||
position: absolute;
|
||||
background: $gray;
|
||||
width: 100%;
|
||||
padding: 45px 50px;
|
||||
bottom: 0;
|
||||
transition: all .3s $site-ease;
|
||||
@include tablet{
|
||||
padding: 30px;
|
||||
padding-bottom: 75px;
|
||||
}
|
||||
span{
|
||||
font-family: $secondary-font;
|
||||
color: $primary-color;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
h3{
|
||||
margin-bottom: 0;
|
||||
a{
|
||||
color: $text-color-dark;
|
||||
transition: 0.3s ease;
|
||||
&:hover{
|
||||
text-decoration: none;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
a.read-more{
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: $text-color;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition: all 0.3s $site-ease;
|
||||
@include tablet{
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
box-shadow:
|
||||
0px 30px 45px 0px rgba(0, 0, 0, 0.01),
|
||||
0px 30px 45px 0px rgba(0, 0, 0, 0.02),
|
||||
0px 30px 45px 0px rgba(0, 0, 0, 0.03),
|
||||
0px 30px 45px 0px rgba(0, 0, 0, 0.04);
|
||||
.site-project-item-content{
|
||||
a{
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
padding-bottom: 75px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-cta{
|
||||
margin-top: 30px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-family: $secondary-font;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: $primary-color;
|
||||
&::before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: $primary-color;
|
||||
bottom: -2px;
|
||||
transition: transform 0.3s $site-ease;
|
||||
transform-origin: right;
|
||||
transform: scaleX(0);
|
||||
}
|
||||
&:hover{
|
||||
color: $primary-color;
|
||||
text-decoration: none;
|
||||
&::before{
|
||||
transform: scaleX(1);
|
||||
transform-origin: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-header{
|
||||
padding: 170px 0 100px;
|
||||
background: $gray;
|
||||
@include tablet{
|
||||
padding: 120px 0 80px;
|
||||
}
|
||||
&-content{
|
||||
h1{
|
||||
font-size: 55px;
|
||||
span{
|
||||
color: $primary-color;
|
||||
}
|
||||
@include tablet{
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
@include desktop{
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
&-action{
|
||||
display: block;
|
||||
text-align: center;
|
||||
span{
|
||||
display: block;
|
||||
font-size: 30px;
|
||||
font-weight: 300;
|
||||
color: $text-color-dark;
|
||||
margin-bottom: 20px;
|
||||
@include tablet{
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
img{
|
||||
width: 66px;
|
||||
@include tablet{
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-pagination{
|
||||
margin-top: 40px;
|
||||
.pagination{
|
||||
justify-content: center;
|
||||
.page-item{
|
||||
&:not(:last-child){
|
||||
margin-right: 10px;
|
||||
}
|
||||
.page-link{
|
||||
font-size: 24px;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
padding: 12px 20px;
|
||||
color: $text-color-dark;
|
||||
font-weight: 300;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
&.active{
|
||||
.page-link{
|
||||
background-color: $primary-color;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
&.disabled{
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-single{
|
||||
&-section{
|
||||
padding: 250px 0 100px;
|
||||
@include tablet{
|
||||
padding: 100px 0;
|
||||
}
|
||||
}
|
||||
h1{
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
&-image{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 30px;
|
||||
img{
|
||||
width: 48%;
|
||||
&:nth-child(2n){
|
||||
margin-left: auto;
|
||||
}
|
||||
@include tablet{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-description{
|
||||
margin-bottom: 50px;
|
||||
p{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
&-action{
|
||||
a{
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
color: $text-color-dark;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
justify-content: flex-end;
|
||||
@include mobile{
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
.link-area{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
span{
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 2px 0;
|
||||
transition: transform .9s cubic-bezier(.19,1,.22,1);
|
||||
transform-origin: left center;
|
||||
&::after{
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 150%;
|
||||
left: 0;
|
||||
transform: skewY(30deg);
|
||||
transform-origin: left center;
|
||||
transition: transform .9s cubic-bezier(.19,1,.22,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
text-decoration: none;
|
||||
.link-area{
|
||||
span{
|
||||
transform: translateY(-150%) skewY(7deg);
|
||||
&::after{
|
||||
transform: skewY(-7deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
img{
|
||||
filter: invert(1);
|
||||
transform: rotate(90deg);
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
.site-team{
|
||||
padding: 100px 0;
|
||||
&-member{
|
||||
background: $gray;
|
||||
padding: 65px 30px 30px;
|
||||
margin: 50px 0 30px;
|
||||
position: relative;
|
||||
@include tablet{
|
||||
text-align: center;
|
||||
}
|
||||
&-image{
|
||||
position: absolute;
|
||||
width: 100px; height: 100px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
left: 30px; top: 0;
|
||||
transform: translateY(-50%);
|
||||
@include tablet{
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
&-content{
|
||||
h3{
|
||||
font-size: 20px;
|
||||
color: $primary-color;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
p{
|
||||
font-size: 18px;
|
||||
color: $text-color-dark;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
&-social{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
li{
|
||||
display: inline-block;
|
||||
a{
|
||||
color: $text-color-dark;
|
||||
}
|
||||
&:not(:last-child){
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
.site-testimonial{
|
||||
background: $gray;
|
||||
padding: 100px 0;
|
||||
overflow: hidden;
|
||||
&-item{
|
||||
background: $white;
|
||||
padding: 30px;
|
||||
margin-bottom: 30px;
|
||||
transition: all 0.3s ease-in;
|
||||
&.active{
|
||||
box-shadow: 0px 30px 45px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
&.inactive{
|
||||
opacity: 0.4;
|
||||
}
|
||||
&-header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
.thumb{
|
||||
width: 80px;
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
margin-right: 15px;
|
||||
}
|
||||
.person{
|
||||
h5{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
p{
|
||||
margin-bottom: 0;
|
||||
color: $dark-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-body{
|
||||
margin-bottom: 0;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
@import "variables";
|
||||
|
||||
@import "typography";
|
||||
|
||||
@import "mixins";
|
||||
|
||||
@import "buttons";
|
||||
|
||||
@import "common";
|
||||
|
||||
@import "components/navigation";
|
||||
|
||||
@import "components/hero";
|
||||
|
||||
@import "components/counter";
|
||||
|
||||
@import "components/project";
|
||||
|
||||
@import "components/blog";
|
||||
|
||||
@import "components/testimonial";
|
||||
|
||||
@import "components/cta";
|
||||
|
||||
@import "components/about";
|
||||
|
||||
@import "components/expertise";
|
||||
|
||||
@import "components/client";
|
||||
|
||||
@import "components/team";
|
||||
|
||||
@import "components/contact";
|
||||
|
||||
@import "components/footer";
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
label: Blog Post
|
||||
hide_body: false
|
||||
fields:
|
||||
- type: text
|
||||
name: title
|
||||
label: title
|
||||
- type: datetime
|
||||
name: date
|
||||
label: date
|
||||
- type: file
|
||||
name: image
|
||||
label: image
|
||||
- type: file
|
||||
name: feature_image
|
||||
label: feature_image
|
||||
- type: text
|
||||
name: author
|
||||
label: author
|
||||
pages:
|
||||
- content/blog/Design-inspiration:-the-best-projects-from-December.md
|
||||
- content/blog/Design-inspiration:-the-best-projects-from-November.md
|
||||
- content/blog/Pt-chooses-Classic-Blue-for-its-colour-of-the-year-2020.md
|
||||
- content/blog/The-10-biggest-rebrands-and-logo-designs-of-2019.md
|
||||
- content/blog/the-10-biggest-product-stories-of-2019.md
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
label: Clients
|
||||
hide_body: true
|
||||
fields:
|
||||
- type: boolean
|
||||
name: enable
|
||||
label: enable
|
||||
- type: text
|
||||
name: title
|
||||
label: title
|
||||
- type: image_gallery
|
||||
name: client_logos
|
||||
label: client_logos
|
||||
pages:
|
||||
- data/clients.yml
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
label: Portfolio
|
||||
hide_body: false
|
||||
fields:
|
||||
- type: text
|
||||
name: title
|
||||
label: title
|
||||
- type: datetime
|
||||
name: date
|
||||
label: date
|
||||
- type: text
|
||||
name: type
|
||||
label: type
|
||||
- type: file
|
||||
name: image
|
||||
label: image
|
||||
- type: list
|
||||
name: category
|
||||
label: category
|
||||
- type: image_gallery
|
||||
name: project_images
|
||||
label: project_images
|
||||
pages:
|
||||
- content/portfolio/seamless-watch.md
|
||||
- content/portfolio/use-less-brand.md
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
label: Team
|
||||
hide_body: true
|
||||
fields:
|
||||
- type: boolean
|
||||
name: enable
|
||||
label: enable
|
||||
- type: text
|
||||
name: title
|
||||
label: title
|
||||
- type: field_group_list
|
||||
name: members
|
||||
label: members
|
||||
fields:
|
||||
- type: file
|
||||
name: image
|
||||
label: image
|
||||
- type: text
|
||||
name: name
|
||||
label: name
|
||||
- type: text
|
||||
name: designation
|
||||
label: designation
|
||||
- type: text
|
||||
name: medium
|
||||
label: medium
|
||||
- type: text
|
||||
name: linkedIn
|
||||
label: linkedIn
|
||||
- type: text
|
||||
name: instagram
|
||||
label: instagram
|
||||
pages:
|
||||
- data/team.yml
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
label: Testimonial
|
||||
hide_body: true
|
||||
fields:
|
||||
- type: boolean
|
||||
name: enable
|
||||
label: enable
|
||||
- type: text
|
||||
name: title
|
||||
label: title
|
||||
- type: text
|
||||
name: subtitle
|
||||
label: subtitle
|
||||
- type: field_group_list
|
||||
name: testimonial_item
|
||||
label: testimonial_item
|
||||
fields:
|
||||
- type: file
|
||||
name: thumb
|
||||
label: thumb
|
||||
- type: text
|
||||
name: name
|
||||
label: name
|
||||
- type: text
|
||||
name: company_position
|
||||
label: company_position
|
||||
- type: textarea
|
||||
name: quote
|
||||
label: quote
|
||||
pages:
|
||||
- data/testimonial.yml
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
new_page_extension: md
|
||||
auto_deploy: false
|
||||
admin_path:
|
||||
webhook_url:
|
||||
sections:
|
||||
- type: document
|
||||
path: data/counter.yml
|
||||
label: Counter
|
||||
- type: document
|
||||
path: data/team.yml
|
||||
label: Team
|
||||
- type: document
|
||||
path: data/clients.yml
|
||||
label: Clients
|
||||
- type: document
|
||||
path: data/testimonial.yml
|
||||
label: Testimonials
|
||||
- type: document
|
||||
path: config.toml
|
||||
label: Configuration
|
||||
- type: directory
|
||||
path: content
|
||||
label: Pages
|
||||
create: all
|
||||
match: "*"
|
||||
- type: directory
|
||||
path: content/blog
|
||||
label: Blog
|
||||
create: all
|
||||
match: "**/*"
|
||||
- type: directory
|
||||
path: content/contact
|
||||
label: Contact
|
||||
create: all
|
||||
match: "**/*"
|
||||
- type: directory
|
||||
path: content/about
|
||||
label: About
|
||||
create: all
|
||||
match: "**/*"
|
||||
- type: directory
|
||||
path: content/portfolio
|
||||
label: Portfolio
|
||||
create: all
|
||||
match: "**/*"
|
||||
upload_dir: static/images
|
||||
public_path: "/images"
|
||||
front_matter_path: ''
|
||||
use_front_matter_path: false
|
||||
file_template: ":filename:"
|
||||
build:
|
||||
preview_env:
|
||||
- HUGO_ENV=staging
|
||||
- HUGO_VERSION=0.63.2
|
||||
preview_output_directory: public
|
||||
preview_docker_image: forestryio/hugo:latest
|
||||
mount_path: "/srv"
|
||||
working_dir: "/srv"
|
||||
instant_preview_command: hugo server -D -E -F --port 8080 --bind 0.0.0.0 --renderToDisk
|
||||
-d public
|
||||
version: 0.63.2
|
||||
1
exampleSite/assets/css/custom.css
Executable file
@@ -0,0 +1 @@
|
||||
/* Add your own custom styles here */
|
||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 700 B After Width: | Height: | Size: 700 B |
|
Before Width: | Height: | Size: 919 B After Width: | Height: | Size: 919 B |
|
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 827 B |
|
Before Width: | Height: | Size: 830 B After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 527 B After Width: | Height: | Size: 527 B |
BIN
exampleSite/assets/images/gallery/01.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
exampleSite/assets/images/gallery/02.jpg
Normal file
|
After Width: | Height: | Size: 697 KiB |
BIN
exampleSite/assets/images/gallery/03.jpg
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
exampleSite/assets/images/gallery/04.jpg
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
exampleSite/assets/images/gallery/05.jpg
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
exampleSite/assets/images/gallery/06.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 495 KiB After Width: | Height: | Size: 495 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
exampleSite/assets/images/og-image.png
Executable file
|
After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 296 KiB After Width: | Height: | Size: 296 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |