mirror of
https://github.com/rubjo/victor-mono.git
synced 2024-10-05 13:27:09 +03:00
Initial
This commit is contained in:
commit
449f8ce118
18
.eslintrc.js
Normal file
18
.eslintrc.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
'extends': [
|
||||
'plugin:vue/recommended',
|
||||
'@vue/standard'
|
||||
],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'prouduction' ? 'error' : 'off',
|
||||
'import/no-webpack-loader-syntax': 'off'
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
}
|
||||
}
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
.log
|
11
.stylelintrc.js
Normal file
11
.stylelintrc.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
'extends': [
|
||||
'stylelint-config-standard',
|
||||
'stylelint-config-recess-order'
|
||||
],
|
||||
'rules': {
|
||||
'no-empty-source': null,
|
||||
'rule-empty-line-before': null
|
||||
}
|
||||
}
|
19
.travis.yml
Normal file
19
.travis.yml
Normal file
@ -0,0 +1,19 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "10"
|
||||
|
||||
install:
|
||||
- yarn install
|
||||
- yarn build
|
||||
|
||||
deploy:
|
||||
local_dir: dist
|
||||
provider: pages
|
||||
skip_cleanup: true
|
||||
github_token: $GITHUB_TOKEN # Set in the settings page of your repository, as a secure variable
|
||||
keep_history: true
|
||||
on:
|
||||
branch: master
|
||||
|
||||
script: echo "done"
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Rune Bjørnerås
|
||||
|
||||
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.
|
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Victor Mono
|
||||
|
||||
<img src="https://github.com/rubjo/victor-mono/raw/master/src/assets/video/cycle.gif" alt="Glyphs" align="right">
|
||||
|
||||
![GitHub release](https://img.shields.io/github/release/rubjo/victor-mono.svg) ![GitHub Release Date](https://img.shields.io/github/release-date/rubjo/victor-mono.svg)
|
||||
|
||||
![Travis (.org)](https://img.shields.io/travis/rubjo/victor-mono.svg?logo=travis) ![GitHub](https://img.shields.io/github/license/rubjo/victor-mono.svg) ![GitHub stars](https://img.shields.io/github/stars/rubjo/victor-mono.svg?style=social)
|
||||
|
||||
A programming font with semi-connected cursive italics and some symbol ligatures.
|
||||
|
||||
I made it because I couldn’t find another (free or paid) typeface I was entirely satisfied with.
|
||||
|
||||
More information and download: [rubjo.github.io/victor-mono](https://rubjo.github.io/victor-mono). I would be grateful if you point others to the same URL.
|
||||
|
||||
If you like it and want to say thanks, [donations](https://www.paypal.me/runbjo) are welcome.
|
14
babel.config.js
Normal file
14
babel.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
'component',
|
||||
{
|
||||
libraryName: 'element-ui',
|
||||
styleLibraryName: 'theme-chalk'
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
22
deploy.sh
Normal file
22
deploy.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# abort on errors
|
||||
set -e
|
||||
|
||||
# build
|
||||
yarn build
|
||||
|
||||
# navigate into the build output directory
|
||||
cd dist
|
||||
|
||||
# if you are deploying to a custom domain
|
||||
# echo 'www.example.com' > CNAME
|
||||
|
||||
git init
|
||||
git add -A
|
||||
git commit -m 'deploy'
|
||||
|
||||
# if you are deploying to https://<USERNAME>.github.io/<REPO>
|
||||
git push -f git@github.com:rubjo/victor-mono.git master:gh-pages
|
||||
|
||||
cd -
|
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "victor-mono",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"animejs": "^3.0.1",
|
||||
"core-js": "^2.6.5",
|
||||
"dom-confetti": "^0.1.1",
|
||||
"element-ui": "^2.4.5",
|
||||
"granim": "^2.0.0",
|
||||
"typed.js": "^2.0.10",
|
||||
"vue": "^2.6.10",
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-faq-accordion": "^1.2.1",
|
||||
"vue-scrollTo": "^2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.7.0",
|
||||
"@vue/cli-plugin-eslint": "^3.7.0",
|
||||
"@vue/cli-service": "^3.7.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"node-sass": "^4.9.2",
|
||||
"raw-loader": "^2.0.0",
|
||||
"sass": "^1.18.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"stylelint": "^10.0.1",
|
||||
"stylelint-config-recess-order": "^2.0.2",
|
||||
"stylelint-config-standard": "^18.3.0",
|
||||
"vue-cli-plugin-element": "^1.0.1",
|
||||
"vue-template-compiler": "^2.5.21"
|
||||
}
|
||||
}
|
5
postcss.config.js
Normal file
5
postcss.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
BIN
public/.DS_Store
vendored
Normal file
BIN
public/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
public/Victor Mono.zip
Normal file
BIN
public/Victor Mono.zip
Normal file
Binary file not shown.
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
36
public/index.html
Normal file
36
public/index.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-140418082-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-140418082-1');
|
||||
</script>
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-PLTRSCB');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Victor Mono</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PLTRSCB"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
<noscript>
|
||||
<strong>We're sorry but Victor Mono doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
BIN
src/.DS_Store
vendored
Normal file
BIN
src/.DS_Store
vendored
Normal file
Binary file not shown.
740
src/App.vue
Normal file
740
src/App.vue
Normal file
@ -0,0 +1,740 @@
|
||||
<template>
|
||||
<div
|
||||
id="app"
|
||||
>
|
||||
<NavBar
|
||||
ref="navbar"
|
||||
:show="showNav"
|
||||
:show-go-to-top="showGoToTop"
|
||||
@darkTheme="theme = 'dark'"
|
||||
@lightTheme="theme = 'light'"
|
||||
/>
|
||||
<Header
|
||||
ref="header"
|
||||
:show-text="showHeaderText"
|
||||
:theme="theme"
|
||||
/>
|
||||
<div class="content">
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<p class="columns">
|
||||
Victor Mono is a programming font with
|
||||
<em>semi-connected cursive italics</em>
|
||||
and some symbol ligatures (!=, ->>, =>, ===, && ++).
|
||||
<br><br>
|
||||
It was drawn from scratch as a pet project / experiment
|
||||
<a
|
||||
v-scroll-to="'#why'"
|
||||
href="javascript:void(0)"
|
||||
>because I couldn’t find another</a>
|
||||
(free or paid) typeface I was entirely satisfied with.
|
||||
<br><br>
|
||||
<video
|
||||
autobuffer
|
||||
autoloop
|
||||
loop
|
||||
controls
|
||||
alt="The glyphs"
|
||||
class="specimen-loop"
|
||||
:class="{ 'inverted': theme === 'light' }"
|
||||
>
|
||||
<source src="@/assets/video/cycle.mp4">
|
||||
</video>
|
||||
The typeface is quite strict in style and features a large x-height.
|
||||
It is optimised for code and legibility at small to medium sizes on high-DPI displays where the
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="= might look weird on Windoze or in Electron-based apps"
|
||||
placement="top-start"
|
||||
>
|
||||
<span>OS and app</span>
|
||||
</el-tooltip>
|
||||
tries to render fonts nicely.
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content alternate-bg">
|
||||
<div
|
||||
id="try"
|
||||
class="scroll-head"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<h1 class="centre">
|
||||
<em>Try it</em>
|
||||
</h1>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<CodeView
|
||||
:theme="theme"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
id="why"
|
||||
class="scroll-head"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<h1 class="centre">
|
||||
<em>Why</em>
|
||||
</h1>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<p class="columns">
|
||||
I'm rather particular about what width, weight, style etc makes an effective and enjoyable typeface for code.
|
||||
<br><br>
|
||||
All fonts or typeface combo mashups I tried using while coding had several of these shortcomings (<em>subjectively, of course</em>):
|
||||
<ul>
|
||||
<li>No cursive italics</li>
|
||||
<li>Had nice italics, but regular/Roman style was not to my taste</li>
|
||||
<li>No programming symbol ligatures</li>
|
||||
<li>Too heavy and inelegant</li>
|
||||
<li>Too light and straining to read</li>
|
||||
<li>Too wide and wasted space</li>
|
||||
<li>Too narrow and hard to scan</li>
|
||||
<li>Seemed unfinished or had weird/misaligned curves/artifacts</li>
|
||||
<li>Seemed childish or unprofessional (too soft or informal appearance)</li>
|
||||
<li>Seemed imbalanced or inconsistent</li>
|
||||
<li>Combined two eye-poppingly-too-different-in-style fonts</li>
|
||||
<li>Very expensive</li>
|
||||
</ul>
|
||||
So eventually, a couple of months ago I had the idea of trying to make something on my own. Both designing it and making a website to present it has been an interesting experiment, and has resulted in a typeface which feels right to me.
|
||||
<br><br>
|
||||
You might like it as well. That's brilliant! You might not. That's also fine: you are free to use a different font. 😛
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="horisontal-large-image">
|
||||
<img :src="specimenBanner">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
id="download"
|
||||
class="scroll-head"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<h1 class="centre">
|
||||
<em>Get it</em>
|
||||
</h1>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<p class="columns">
|
||||
The font is available in Roman and <em>Italic</em> styles.
|
||||
If you think the latter is a bit too much, an <em class="alt">Oblique</em> style is also included.
|
||||
<br><br>
|
||||
If you do try it out and like it, I would be very grateful for any
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
@click="thanks"
|
||||
>donations</a>.
|
||||
After initially pondering whether or not to sell it, I decided to give it away:
|
||||
<br><br>
|
||||
First, I couldn't be bothered to set up hosting/payment and commit to providing support the way a commercial product should.
|
||||
<br><br>
|
||||
Secondly, this has been an experiment to see if I could make something I wanted to use myself. As it stands, the font doesn't have a huge number of glyphs and ligatures — although I
|
||||
<a
|
||||
v-scroll-to="'#faq'"
|
||||
href="javascript:void(0)"
|
||||
>might add more</a>
|
||||
in the future.
|
||||
<br><br>
|
||||
Finally, I can identify with not wanting to shell out €100++ on a font. If you are able to and want to contribute: a sincere thank you! 🙏
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col class="centre">
|
||||
<el-button
|
||||
id="donate-button"
|
||||
icon="el-icon-medal-1"
|
||||
type="primary"
|
||||
round
|
||||
@click="thanks"
|
||||
>
|
||||
Donate
|
||||
</el-button>
|
||||
|
||||
<a href="Victor Mono.zip">
|
||||
<el-button
|
||||
id="download-button"
|
||||
icon="el-icon-download"
|
||||
round
|
||||
>
|
||||
Download
|
||||
</el-button>
|
||||
</a>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<p class="small centre">
|
||||
<em>If you have a nice screenshot of the font in use / used it for something cool, I'd love to
|
||||
<a
|
||||
target="_blank"
|
||||
href="mailto:victor.mono.font@gmail.com?subject=Here's how I used the font"
|
||||
>hear from you</a>.
|
||||
</em>
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="content alternate-bg">
|
||||
<div
|
||||
id="faq"
|
||||
class="scroll-head"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<h1
|
||||
class="centre"
|
||||
@mouseenter="revealFaq = true"
|
||||
@touchstart="revealFaq = true"
|
||||
@mouseleave="revealFaq = false"
|
||||
>
|
||||
<em>FAQ*</em>
|
||||
</h1>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div
|
||||
class="caption centre full-width"
|
||||
>
|
||||
|
||||
<em v-show="revealFaq">Frequently Anticipated Questions</em>
|
||||
</div>
|
||||
</transition>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<VueFaqAccordion
|
||||
:items="faqItems"
|
||||
border-color="transparent"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div
|
||||
id="credits"
|
||||
class="scroll-head"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<h1 class="centre">
|
||||
<em>Credits</em>
|
||||
</h1>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
>
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="18"
|
||||
:lg="18"
|
||||
>
|
||||
<p class="small centre">
|
||||
If making this font has been a learning experiment, the same can be said for trying out a number of frameworks/packages to make this web site. Big thanks to the following:
|
||||
<br><br><br>
|
||||
<em>Lovely gradients</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://sarcadass.github.io/granim.js/"
|
||||
>
|
||||
Granim.js</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://twitter.com/Sarcadass"
|
||||
>
|
||||
Benjamin Blonde</a>
|
||||
<br><br>
|
||||
<em>Cool animated typing</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/mattboldt/typed.js/"
|
||||
>
|
||||
Typed.js</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://mattboldt.com"
|
||||
>
|
||||
Matt Boldt</a>
|
||||
<br><br>
|
||||
<em>Code editor</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/surmon-china/vue-codemirror"
|
||||
>
|
||||
Vue-Codemirror</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/surmon-china"
|
||||
>
|
||||
Surmon</a> and
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://codemirror.net"
|
||||
>
|
||||
codemirror.net</a>
|
||||
<br><br>
|
||||
<em>Animations here & there</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://animejs.com"
|
||||
>
|
||||
Anime.js</a>
|
||||
<br><br>
|
||||
<em>Smooth scrolling</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://vue-scrollto.netlify.com"
|
||||
>
|
||||
vue-scrollto</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/rigor789"
|
||||
>
|
||||
Igor Randjelovic</a>
|
||||
<br><br>
|
||||
<em>FAQ component</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/gerasimvol/vue-faq-accordion"
|
||||
>
|
||||
vue-faq-accordion</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/gerasimvol"
|
||||
>
|
||||
Vladimir Gerasimenko</a>
|
||||
<br><br>
|
||||
<em>Thank-you-confetti</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://www.npmjs.com/package/dom-confetti"
|
||||
>
|
||||
dom-confetti</a>
|
||||
by
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://twitter.com/danielundin"
|
||||
>
|
||||
Daniel Lundin</a>
|
||||
<br><br>
|
||||
<em>CSS framework / component library</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://element.eleme.io/#/en-US"
|
||||
>
|
||||
Element</a>
|
||||
<br><br>
|
||||
<em>The nice JS framework</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://vuejs.org"
|
||||
>
|
||||
Vue.js</a>
|
||||
<br><br>
|
||||
<em>Supercool scaffolding and tools for Vue.js development</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://cli.vuejs.org"
|
||||
>
|
||||
Vue CLI</a>
|
||||
<br><br>
|
||||
<em>Very nice (and rather expensive) font design software</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://glyphsapp.com"
|
||||
>
|
||||
Glyphs</a>
|
||||
<br><br>
|
||||
<em>Font and web site</em>
|
||||
<br>
|
||||
<a
|
||||
target="_blank"
|
||||
href="mailto:victor.mono.font@gmail.com?subject=Thanks for making such a nice font"
|
||||
>
|
||||
Rune B</a>
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavBar from '@/components/NavBar'
|
||||
import Header from '@/components/Header'
|
||||
import CodeView from '@/components/CodeView'
|
||||
import VueFaqAccordion from 'vue-faq-accordion'
|
||||
import anime from 'animejs'
|
||||
import { confetti } from 'dom-confetti'
|
||||
|
||||
export default {
|
||||
name: 'Home',
|
||||
components: {
|
||||
NavBar,
|
||||
Header,
|
||||
CodeView,
|
||||
VueFaqAccordion
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showHeaderText: false,
|
||||
showNav: true,
|
||||
showGoToTop: true,
|
||||
revealFaq: false,
|
||||
theme: localStorage.getItem('theme') || 'dark',
|
||||
faqItems: [
|
||||
{
|
||||
title: 'The typeface is a bit light/heavy to my liking. Will you offer more weights in the future?',
|
||||
value: '<a href="https://paypal.me/runbjo" target="_blank">Maybe</a>.',
|
||||
category: 'Design & features'
|
||||
}, {
|
||||
title: 'There’s a feature of the font that I don’t like. Could you change it?',
|
||||
value: 'Probably not. You can always use a different font. 😛',
|
||||
category: 'Design & features'
|
||||
}, {
|
||||
title: 'Will you add some stylistic variations, like a slashed zero, sharper brackets etc.?',
|
||||
value: '<a href="https://paypal.me/runbjo" target="_blank">I might</a>.',
|
||||
category: 'Design & features'
|
||||
}, {
|
||||
title: 'Will you make a custom style generator, where one can pick the preferred stylistic alternatives and download the corresponding font files?',
|
||||
value: 'Probably not. It depends on the reception and <a href="https://paypal.me/runbjo" target="_blank">donations</a>, as this is something I do in my spare time.',
|
||||
category: 'Design & features'
|
||||
}, {
|
||||
title: 'Can I use the font for anything?',
|
||||
value: 'Yes. If you\'d like to say thanks, you can <a href="https://paypal.me/runbjo" target="_blank">donate</a>.',
|
||||
category: 'Usage'
|
||||
}, {
|
||||
title: 'How do I use it?',
|
||||
value: '1) <a href="#download">Download</a> the font<br>2) Unpack the ZIP<br>3) <a href="https://www.google.com/search?q=how+to+install+fonts" target="_blank">Install</a> the font',
|
||||
category: 'Usage'
|
||||
}, {
|
||||
title: 'I found a bug. Where do I report it?',
|
||||
value: 'Please <a href="https://github.com/rubjo/victor-mono/issues/new" target="_blank">open an issue</a>.',
|
||||
category: 'Usage'
|
||||
}, {
|
||||
title: 'Since it’s called Victor Mono, will a Victor Sans or Serif be released in the future?',
|
||||
value: 'Probably not.',
|
||||
category: 'Other'
|
||||
}, {
|
||||
title: 'How does one simply make a font?',
|
||||
value: 'Trial and error, some research, good software, patience and time.',
|
||||
category: 'Other'
|
||||
}, {
|
||||
title: 'Why are you giving it away?',
|
||||
value: 'I originally planned on selling it for some (smaller or much larger) sum, like others do. But I eventually decided against it: I couldn’t be bothered to set up hosting, payment, EULAs etc, nor do I have time for the level of support I feel should accompany a commercial product. This typeface isn’t meant to be the perfect font for anyone - I just made the one perfect for me. If you’re unemployed or struggle to make ends meet, download the font with a clear conscience. If you work in a corporate setting or are relatively well off, consider <a href="https://paypal.me/runbjo" target="_blank">supporting</a> the hours spent designing this font. If you want to and are able to donate anything: thank you!',
|
||||
category: 'Other'
|
||||
}, {
|
||||
title: 'Did you know that the [insert typeface property here] violates some 500-year old font design convention?',
|
||||
value: 'I might. If I did, I didn’t care, or I deliberately chose to go a different direction.',
|
||||
category: 'Design & features'
|
||||
}, {
|
||||
title: 'The font is missing an obscure ligature symbol used for indicating an infinite loop in the language Goskell when writing in ancient Ghiscari. Would you be willing to add it?',
|
||||
value: 'Not very likely, but <a href="https://paypal.me/runbjo" target="_blank">I might</a>.',
|
||||
category: 'Design & features'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
specimenBanner () {
|
||||
return require('./assets/img/specimen-' + this.theme + '.png')
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.initScrollWatcher()
|
||||
this.setHeaderHeight()
|
||||
this.calculateHeaderText()
|
||||
},
|
||||
methods: {
|
||||
initScrollWatcher () {
|
||||
function throttle (fn, wait) {
|
||||
let time = Date.now()
|
||||
return function () {
|
||||
if ((time + wait - Date.now()) < 0) {
|
||||
setTimeout(fn, wait)
|
||||
time = Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
['scroll', 'resize'].forEach(event => {
|
||||
window.addEventListener(event, throttle(this.setHeaderHeight, 250))
|
||||
window.addEventListener(event, throttle(this.calculateHeaderText, 250))
|
||||
})
|
||||
},
|
||||
setHeaderHeight () {
|
||||
const top = window.scrollY
|
||||
const mainTitle = this.$refs.header.$el.querySelector('h1')
|
||||
const margin = parseInt(window.getComputedStyle(mainTitle).marginTop)
|
||||
const navBarHeight = mainTitle.offsetTop - margin
|
||||
const headerHeight = this.$refs.header.$el.offsetHeight
|
||||
const triggerHeight = headerHeight - navBarHeight
|
||||
if (top !== triggerHeight) {
|
||||
const offset = this.$refs.header.$el.getBoundingClientRect().y
|
||||
if (offset !== triggerHeight) {
|
||||
this.$refs.header.$el.style.top = triggerHeight * -1
|
||||
anime({
|
||||
targets: this.$refs.header.$el,
|
||||
top: [offset, triggerHeight * -1],
|
||||
duration: 100,
|
||||
easing: 'easeInOutSine'
|
||||
})
|
||||
}
|
||||
this.$refs.header.$el.style.webkitPosition = 'sticky'
|
||||
this.$refs.header.$el.style.position = 'sticky'
|
||||
this.$refs.header.$el.style.position = '-webkit-sticky'
|
||||
document.querySelector('body').style.paddingTop = 0
|
||||
this.showGoToTop = true
|
||||
} else {
|
||||
document.querySelector('body').style.paddingTop = headerHeight + 'px'
|
||||
this.$refs.header.$el.style.webkitPosition = 'absolute'
|
||||
this.$refs.header.$el.style.position = 'absolute'
|
||||
this.$refs.header.$el.style.top = 0
|
||||
this.showGoToTop = false
|
||||
}
|
||||
},
|
||||
calculateHeaderText () {
|
||||
const top = window.scrollY
|
||||
const mainTitle = this.$refs.header.$el.querySelector('h1')
|
||||
const margin = parseInt(window.getComputedStyle(mainTitle).marginTop)
|
||||
const navBarHeight = mainTitle.offsetTop - margin
|
||||
const headerHeight = this.$refs.header.$el.offsetHeight
|
||||
const triggerHeight = headerHeight - navBarHeight
|
||||
if (top > triggerHeight) {
|
||||
this.showHeaderText = false
|
||||
} else {
|
||||
this.showHeaderText = true
|
||||
}
|
||||
|
||||
const hideStart = mainTitle.getBoundingClientRect().top + margin
|
||||
this.showNav = window.scrollY < hideStart || window.scrollY > triggerHeight
|
||||
},
|
||||
celebrate (target) {
|
||||
confetti(target, {
|
||||
angle: 90,
|
||||
spread: 60,
|
||||
startVelocity: 50,
|
||||
elementCount: 250,
|
||||
dragFriction: 0.125,
|
||||
duration: 3000,
|
||||
stagger: 2,
|
||||
width: '10px',
|
||||
height: '10px',
|
||||
colors: [
|
||||
'#393939',
|
||||
'#747369',
|
||||
'#515151',
|
||||
'#a09f93',
|
||||
'#2b2b2b',
|
||||
'#ffffff',
|
||||
'#e2e0d7',
|
||||
'#ff7a7f',
|
||||
'#f99157',
|
||||
'#dd99dd',
|
||||
'#66aadd',
|
||||
'#ffee66',
|
||||
'#6699cc',
|
||||
'#66ffdd',
|
||||
'#99dd99',
|
||||
'#99cc99',
|
||||
'#ff332a',
|
||||
'#66cccc',
|
||||
'#d27b53',
|
||||
'#f92672',
|
||||
'#a6e22e',
|
||||
'#967efb',
|
||||
'#565656'
|
||||
]
|
||||
})
|
||||
|
||||
window.removeEventListener('focus', this.celebrate)
|
||||
},
|
||||
thanks (e) {
|
||||
window.open('https://paypal.me/runbjo')
|
||||
setTimeout(() => {
|
||||
window.addEventListener('focus', this.celebrate(e.target))
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import 'styles/globals.scss';
|
||||
|
||||
.scroll-head {
|
||||
height: calc(36px + 2vw);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10px 10px 40px 10px;
|
||||
}
|
||||
|
||||
.horisontal-large-image {
|
||||
width: 100vw;
|
||||
height: 37vw;
|
||||
margin-top: 2em;
|
||||
overflow: hidden;
|
||||
img {
|
||||
position: relative;
|
||||
top: -5vw;
|
||||
left: -50vw;
|
||||
width: 200vw;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
em.alt {
|
||||
font-family: 'VictorMono-Oblique', monospace;
|
||||
}
|
||||
|
||||
.specimen-loop {
|
||||
float: right;
|
||||
width: 60%;
|
||||
margin: 5px 0 5px 15px;
|
||||
filter: invert(1);
|
||||
mix-blend-mode: screen;
|
||||
&.inverted {
|
||||
filter: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.content .el-button {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.content section.faq {
|
||||
padding: 0;
|
||||
font-size: 1.1em;
|
||||
.faq-wrapper {
|
||||
max-width: none;
|
||||
p {
|
||||
font-size: 85%;
|
||||
line-height: 170%;
|
||||
}
|
||||
.faq__nav-item {
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
transition: inherit;
|
||||
&.faq__nav-item_active {
|
||||
font-style: italic;
|
||||
}
|
||||
&:hover {
|
||||
color: var(--color-text-accented);
|
||||
}
|
||||
}
|
||||
.accordion__toggle-button[data-v-36e025b4] {
|
||||
&::before,
|
||||
&::after {
|
||||
background: var(--color-text-primary);
|
||||
transition: background 1s;
|
||||
}
|
||||
}
|
||||
.accordion__title {
|
||||
padding: 20px 0 10px 0;
|
||||
color: inherit;
|
||||
transition: inherit;
|
||||
&:hover {
|
||||
color: var(--color-text-accented);
|
||||
.accordion__toggle-button[data-v-36e025b4] {
|
||||
&::before,
|
||||
&::after {
|
||||
background: var(--color-text-accented);
|
||||
}
|
||||
}
|
||||
}
|
||||
button {
|
||||
padding-left: 20px;
|
||||
margin-left: 5vw;
|
||||
}
|
||||
}
|
||||
.accordion__value {
|
||||
padding: 0 25px 25px 50px;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
BIN
src/assets/.DS_Store
vendored
Normal file
BIN
src/assets/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Italic.eot
Normal file
BIN
src/assets/VictorMono-Italic.eot
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Italic.otf
Normal file
BIN
src/assets/VictorMono-Italic.otf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Italic.ttf
Normal file
BIN
src/assets/VictorMono-Italic.ttf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Italic.woff
Normal file
BIN
src/assets/VictorMono-Italic.woff
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Italic.woff2
Normal file
BIN
src/assets/VictorMono-Italic.woff2
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Oblique.eot
Normal file
BIN
src/assets/VictorMono-Oblique.eot
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Oblique.otf
Normal file
BIN
src/assets/VictorMono-Oblique.otf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Oblique.ttf
Normal file
BIN
src/assets/VictorMono-Oblique.ttf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Oblique.woff
Normal file
BIN
src/assets/VictorMono-Oblique.woff
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Oblique.woff2
Normal file
BIN
src/assets/VictorMono-Oblique.woff2
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Regular.eot
Normal file
BIN
src/assets/VictorMono-Regular.eot
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Regular.otf
Normal file
BIN
src/assets/VictorMono-Regular.otf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Regular.ttf
Normal file
BIN
src/assets/VictorMono-Regular.ttf
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Regular.woff
Normal file
BIN
src/assets/VictorMono-Regular.woff
Normal file
Binary file not shown.
BIN
src/assets/VictorMono-Regular.woff2
Normal file
BIN
src/assets/VictorMono-Regular.woff2
Normal file
Binary file not shown.
BIN
src/assets/img/.DS_Store
vendored
Normal file
BIN
src/assets/img/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/assets/img/specimen-dark.png
Normal file
BIN
src/assets/img/specimen-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 MiB |
BIN
src/assets/img/specimen-light.png
Normal file
BIN
src/assets/img/specimen-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
BIN
src/assets/video/.DS_Store
vendored
Normal file
BIN
src/assets/video/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/assets/video/cycle.gif
Normal file
BIN
src/assets/video/cycle.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 600 KiB |
BIN
src/assets/video/cycle.mp4
Normal file
BIN
src/assets/video/cycle.mp4
Normal file
Binary file not shown.
BIN
src/assets/video/headerbg.mp4
Normal file
BIN
src/assets/video/headerbg.mp4
Normal file
Binary file not shown.
BIN
src/assets/video/headerbg.webm
Normal file
BIN
src/assets/video/headerbg.webm
Normal file
Binary file not shown.
170
src/components/CodeView.vue
Normal file
170
src/components/CodeView.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="window"
|
||||
:class="{ 'light': theme !== 'dark' }"
|
||||
>
|
||||
<div class="controls">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="Not an actual window :P"
|
||||
placement="top-start"
|
||||
>
|
||||
<span>
|
||||
<div class="close" />
|
||||
<div class="min" />
|
||||
<div class="max" />
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<codemirror
|
||||
ref="myCm"
|
||||
class="code"
|
||||
:value="code"
|
||||
:options="cmOptions"
|
||||
@ready="onCmReady"
|
||||
@focus="onCmFocus"
|
||||
@input="onCmCodeChange"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="theme === 'dark'"
|
||||
class="right caption"
|
||||
>
|
||||
Based on
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/rubjo/ultimate-dark"
|
||||
>Ultimate Dark</a>
|
||||
colour scheme
|
||||
(<a
|
||||
target="_blank"
|
||||
href="https://packagecontrol.io/packages/Ultimate%20Dark"
|
||||
>Sublime Text 3 package</a>)
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="right caption"
|
||||
>
|
||||
Based on
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/chriskempson/base16"
|
||||
>Base 16 Light</a>
|
||||
colour scheme by Chris Kempson
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// language
|
||||
import 'codemirror/mode/vue/vue.js'
|
||||
// themes css
|
||||
import '@/styles/ultimate-dark.css'
|
||||
import '@/styles/base-16-light.css'
|
||||
// active-line.js
|
||||
import 'codemirror/addon/selection/active-line.js'
|
||||
// styleSelectedText
|
||||
import 'codemirror/addon/selection/mark-selection.js'
|
||||
// keyMap
|
||||
import 'codemirror/addon/edit/matchbrackets.js'
|
||||
import 'codemirror/addon/comment/comment.js'
|
||||
|
||||
// sample code
|
||||
// eslint-disable-next-line
|
||||
import code from '!raw-loader!@/components/Sample.vue'
|
||||
|
||||
export default {
|
||||
name: 'CodeView',
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
default: localStorage.getItem('theme') || 'dark'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
code,
|
||||
cmOptions: {
|
||||
mode: 'text/x-vue',
|
||||
tabSize: 2,
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
line: true,
|
||||
styleSelectedText: true,
|
||||
matchBrackets: true,
|
||||
showCursorWhenSelecting: true,
|
||||
theme: this.theme === 'dark' ? 'ultimate-dark' : 'base16-light'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
theme (newVal, oldVal) {
|
||||
this.cm.setOption('theme', newVal === 'dark' ? 'ultimate-dark' : 'base16-light')
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
methods: {
|
||||
onCmReady (cm) {
|
||||
this.cm = cm
|
||||
cm.setSize('100%', '100%')
|
||||
},
|
||||
onCmFocus (cm) {
|
||||
},
|
||||
onCmCodeChange (newCode) {
|
||||
this.code = newCode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style
|
||||
scoped
|
||||
lang="scss"
|
||||
>
|
||||
.window {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
height: 65vh;
|
||||
border: 1px solid #303030;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
transition: border 1s;
|
||||
.controls {
|
||||
height: 34px;
|
||||
background: #303030;
|
||||
transition: background 1s;
|
||||
div {
|
||||
float: left;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 10px 0 0 10px;
|
||||
background: #999;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.close {
|
||||
background: #ff544e;
|
||||
}
|
||||
.min {
|
||||
background: #feb429;
|
||||
}
|
||||
.max {
|
||||
background: #26c138;
|
||||
}
|
||||
}
|
||||
&.light {
|
||||
border-color: #ccc;
|
||||
.controls {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.code {
|
||||
height: calc(100% - 34px);
|
||||
font-size: 16px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
</style>
|
302
src/components/Header.vue
Normal file
302
src/components/Header.vue
Normal file
@ -0,0 +1,302 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div
|
||||
ref="videoBg"
|
||||
class="video-bg"
|
||||
>
|
||||
<video
|
||||
ref="video"
|
||||
autobuffer
|
||||
autoplay
|
||||
muted
|
||||
autoloop
|
||||
playsinline
|
||||
loop
|
||||
>
|
||||
<source
|
||||
src="../assets/video/headerbg.mp4"
|
||||
type="video/mp4"
|
||||
>
|
||||
<source
|
||||
src="../assets/video/headerbg.webm"
|
||||
type="video/webm"
|
||||
>
|
||||
</video>
|
||||
</div>
|
||||
<canvas
|
||||
ref="gradients"
|
||||
class="header-gradients"
|
||||
/>
|
||||
<div
|
||||
class="text"
|
||||
:class="{ 'hidden': !showText }"
|
||||
>
|
||||
<h1 ref="mainTitle">
|
||||
Victor Mono
|
||||
</h1>
|
||||
<h2>
|
||||
The <em class="property" />
|
||||
<br class="hidden-sm-and-up">
|
||||
programming font
|
||||
</h2>
|
||||
<el-row
|
||||
type="flex"
|
||||
class="row-bg"
|
||||
justify="center"
|
||||
>
|
||||
<el-col :span="6">
|
||||
<div class="grid-content">
|
||||
<div
|
||||
v-scroll-to="'#try'"
|
||||
class="large-icon"
|
||||
>
|
||||
<i class="el-icon-arrow-down" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Granim from 'granim'
|
||||
import Typed from 'typed.js'
|
||||
import anime from 'animejs'
|
||||
|
||||
export default {
|
||||
name: 'Header',
|
||||
props: {
|
||||
showText: Boolean,
|
||||
theme: {
|
||||
type: String,
|
||||
default: localStorage.getItem('theme') || 'dark'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
theme: {
|
||||
async handler (newVal, oldVal) {
|
||||
const oldOpacity = this.theme === 'dark' ? 0.2 : 0.5
|
||||
const newOpacity = this.theme === 'dark' ? 0.5 : 0.2
|
||||
|
||||
await anime({
|
||||
targets: this.$refs.videoBg,
|
||||
opacity: [oldOpacity, 0],
|
||||
duration: 250,
|
||||
easing: 'linear'
|
||||
}).finished
|
||||
|
||||
if (newVal === 'light') {
|
||||
this.$refs.gradients.style.mixBlendMode = 'multiply'
|
||||
this.$refs.videoBg.style.filter = 'invert(1)'
|
||||
} else {
|
||||
this.$refs.gradients.style.mixBlendMode = 'screen'
|
||||
this.$refs.videoBg.style.filter = 'invert(0)'
|
||||
}
|
||||
|
||||
anime({
|
||||
targets: this.$refs.videoBg,
|
||||
opacity: [0, newOpacity],
|
||||
duration: 250,
|
||||
easing: 'linear'
|
||||
})
|
||||
|
||||
return Promise.resolve()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.initGradient()
|
||||
this.initTyped()
|
||||
},
|
||||
methods: {
|
||||
initGradient () {
|
||||
function shuffle (a) {
|
||||
var j, x, i
|
||||
for (i = a.length - 1; i > 0; i--) {
|
||||
j = Math.floor(Math.random() * (i + 1))
|
||||
x = a[i]
|
||||
a[i] = a[j]
|
||||
a[j] = x
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
const gradients = [
|
||||
[
|
||||
{ color: 'rgba(253,199,141,1)', pos: 0 },
|
||||
{ color: 'rgba(249,143,253,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(253,239,132,1)', pos: 0 },
|
||||
{ color: 'rgba(21,186,196,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(243,31,105,1)', pos: 0 },
|
||||
{ color: 'rgba(249,233,47,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(56,230,250,1)', pos: 0 },
|
||||
{ color: 'rgba(52,116,243,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(19,248,87,1)', pos: 0 },
|
||||
{ color: 'rgba(235,202,16,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(101,161,86,1)', pos: 0 },
|
||||
{ color: 'rgba(255,178,63,1)', pos: 1 }
|
||||
], [
|
||||
{ color: 'rgba(255,100,241,1)', pos: 0 },
|
||||
{ color: 'rgba(67,220,255,1)', pos: 1 }
|
||||
]
|
||||
]
|
||||
|
||||
return new Granim({
|
||||
element: '.header-gradients',
|
||||
direction: 'diagonal',
|
||||
isPausedWhenNotInView: true,
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: shuffle(gradients),
|
||||
transitionSpeed: 5000
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
initTyped () {
|
||||
const options = {
|
||||
strings: [
|
||||
'==>',
|
||||
'cursive',
|
||||
'<span style="text-decoration: line-through;">modest</span>',
|
||||
'break-the-wheel',
|
||||
'be-all and end-all',
|
||||
'donate-what-it\'s-worth',
|
||||
'good-looking',
|
||||
'schizophrenic',
|
||||
'de facto',
|
||||
'one true',
|
||||
'awesome',
|
||||
'essential',
|
||||
'go-to',
|
||||
'best',
|
||||
'invaluable',
|
||||
'free',
|
||||
'no-compromise',
|
||||
'retina-ready',
|
||||
'friendly',
|
||||
'elegant',
|
||||
'crisp',
|
||||
'slender',
|
||||
'consistent',
|
||||
'fancy',
|
||||
'nice',
|
||||
'hip(ster)',
|
||||
'cool',
|
||||
'must-have',
|
||||
'democratic',
|
||||
'scannable',
|
||||
'readable',
|
||||
'enjoyable',
|
||||
'lovely',
|
||||
'effective',
|
||||
'perfect',
|
||||
'beautiful',
|
||||
'ideal',
|
||||
'slightly whimsical',
|
||||
'victorious',
|
||||
'"#%§§##/&*!',
|
||||
'experimental',
|
||||
'definitive',
|
||||
'real',
|
||||
'attractive',
|
||||
'cozy',
|
||||
'budget-friendly',
|
||||
'trustworthy',
|
||||
'poor man’s',
|
||||
'real aesthete’s'
|
||||
],
|
||||
startDelay: 1000,
|
||||
typeSpeed: 50,
|
||||
backSpeed: 10,
|
||||
smartBackspace: true,
|
||||
backDelay: 1500,
|
||||
loop: true,
|
||||
shuffle: true
|
||||
}
|
||||
|
||||
return new Typed('.property', options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style
|
||||
scoped
|
||||
lang="scss"
|
||||
>
|
||||
.header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
padding-top: calc(48px + 2vw);
|
||||
text-align: center;
|
||||
h1 {
|
||||
margin: calc(3vw + 5px) 0 0 0;
|
||||
font-size: calc(80px + 6vw);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 2vw 0 5vw 0;
|
||||
font-size: calc(18px + 1.5vw);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.large-icon {
|
||||
margin: 0 0 1vw 0;
|
||||
font-size: 3vw;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.text {
|
||||
opacity: 1;
|
||||
transition: opacity 2s;
|
||||
h1,
|
||||
h2 {
|
||||
transition: transform 10s ease-out;
|
||||
transform: scale(1);
|
||||
}
|
||||
&.hidden {
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s;
|
||||
h1,
|
||||
h2 {
|
||||
transition-duration: 0s;
|
||||
transform: scale(0.85);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: -2;
|
||||
width: 100%;
|
||||
height: calc(100% - 1px);
|
||||
overflow: hidden;
|
||||
opacity: 0.5;
|
||||
video {
|
||||
width: 100%;
|
||||
min-width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-gradients {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
</style>
|
215
src/components/NavBar.vue
Normal file
215
src/components/NavBar.vue
Normal file
@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div
|
||||
v-show="show"
|
||||
class="navbar"
|
||||
>
|
||||
<a
|
||||
v-show="showGoToTop"
|
||||
v-scroll-to="'#app'"
|
||||
href="#"
|
||||
>
|
||||
<i class="el-icon-arrow-up" /></a>
|
||||
<a
|
||||
v-scroll-to="'#try'"
|
||||
href="#"
|
||||
>
|
||||
Try</a>
|
||||
<a
|
||||
v-scroll-to="'#why'"
|
||||
href="#"
|
||||
>
|
||||
Why</a>
|
||||
<a
|
||||
v-scroll-to="'#download'"
|
||||
href="#"
|
||||
>
|
||||
Get</a>
|
||||
<a
|
||||
v-scroll-to="'#faq'"
|
||||
href="#"
|
||||
>
|
||||
FAQ</a>
|
||||
<a
|
||||
v-scroll-to="'#credits'"
|
||||
href="#"
|
||||
>
|
||||
Credits</a>
|
||||
<a
|
||||
ref="themeIcon"
|
||||
class="themeIcon"
|
||||
href="javascript:void(0)"
|
||||
@click="toggleTheme"
|
||||
>
|
||||
<div
|
||||
v-show="theme === 'light'"
|
||||
class="moon theme"
|
||||
>
|
||||
<svg
|
||||
height="52"
|
||||
width="38"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M26.01 1A25.02 25.02 0 0 0 1 26.01a25.03 25.03 0 0 0 35.01 22.91 1.2 1.2 0 0 0 0-2.18 22.62 22.62 0 0 1 0-41.46 1.2 1.2 0 0 0 0-2.18 24.93 24.93 0 0 0-10-2.1z"
|
||||
fill="none"
|
||||
:stroke="textColour"
|
||||
stroke-width="2"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
v-show="theme === 'dark'"
|
||||
class="sun theme"
|
||||
>
|
||||
<svg
|
||||
height="53"
|
||||
width="53"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
:stroke="textColour"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle
|
||||
cx="26.58"
|
||||
cy="26.62"
|
||||
r="9.44"
|
||||
/>
|
||||
<path d="M26.58 11.78V1.7M26.58 51.85v-10.1M41.09 26.25H51.2M1.64 26.25h10.13" />
|
||||
<path d="M15.85 15.9L8.7 8.76M44.18 44.23l-7.14-7.14M36.34 15.86l7.16-7.15M8.45 43.76l7.16-7.16" />
|
||||
<path d="M32.38 12.6l3.86-9.32M17.05 49.62l3.86-9.32M40.25 31.53l9.35 3.87M3.8 16.43l9.36 3.88" />
|
||||
<path d="M20.77 12.6l-3.86-9.32M36.1 49.62l-3.86-9.32M39.72 20.42l9.35-3.87M3.28 35.51l9.35-3.87" />
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import anime from 'animejs'
|
||||
|
||||
export default {
|
||||
name: 'NavBar',
|
||||
props: {
|
||||
show: Boolean,
|
||||
showGoToTop: Boolean
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
theme: localStorage.getItem('theme') || 'dark',
|
||||
backgroundColour: '#595959',
|
||||
textColour: '#eee'
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.setAppearance()
|
||||
anime({
|
||||
targets: '.themeIcon svg',
|
||||
rotate: [360, 315],
|
||||
strokeColor: ['#f0f', '#000'],
|
||||
delay: 500,
|
||||
duration: 3000,
|
||||
easing: 'easeInOutSine'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
toggleTheme () {
|
||||
this.$refs.themeIcon.style.transform = 'scale(0)'
|
||||
|
||||
anime({
|
||||
targets: '.themeIcon circle',
|
||||
scale: [0, 1],
|
||||
duration: 1500,
|
||||
easing: 'easeInOutSine'
|
||||
})
|
||||
|
||||
anime({
|
||||
targets: '.themeIcon path',
|
||||
strokeDashoffset: [anime.setDashoffset, 0],
|
||||
easing: 'easeInOutSine',
|
||||
duration: 2500,
|
||||
delay (el, i) { return i * 250 + 250 },
|
||||
direction: 'normal',
|
||||
loop: false
|
||||
})
|
||||
|
||||
anime({
|
||||
targets: '.themeIcon svg',
|
||||
rotate: [0, 315],
|
||||
strokeColor: ['#f0f', '#000'],
|
||||
delay: 500,
|
||||
duration: 3000,
|
||||
easing: 'easeInOutSine'
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
this.theme = this.theme === 'dark' ? 'light' : 'dark'
|
||||
localStorage.setItem('theme', this.theme)
|
||||
this.setAppearance()
|
||||
this.$refs.themeIcon.style.transform = 'scale(0.5)'
|
||||
}, 100)
|
||||
},
|
||||
setAppearance () {
|
||||
if (this.theme === 'dark') {
|
||||
this.$emit('darkTheme')
|
||||
this.backgroundColour = '#595959'
|
||||
this.alternateBackgroundColour = '#505050'
|
||||
this.textColour = '#eee'
|
||||
} else {
|
||||
this.$emit('lightTheme')
|
||||
this.backgroundColour = '#fff'
|
||||
this.alternateBackgroundColour = '#f2f2f2'
|
||||
this.textColour = '#222'
|
||||
}
|
||||
|
||||
const root = document.documentElement
|
||||
root.style.setProperty('--background-color-base', this.backgroundColour)
|
||||
root.style.setProperty('--background-color-alternate', this.alternateBackgroundColour)
|
||||
root.style.setProperty('--color-text-primary', this.textColour)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
font-size: calc(18px + 0.8vw);
|
||||
text-align: center;
|
||||
a {
|
||||
flex: 1;
|
||||
padding: calc(12px + 0.7vw) 0;
|
||||
color: var(--color-text-primary);
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
.themeIcon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 0.7vw 0;
|
||||
transform: scale(0.5);
|
||||
.theme {
|
||||
text-align: center;
|
||||
svg {
|
||||
circle {
|
||||
transform-origin-x: 50%;
|
||||
transform-origin-y: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
78
src/components/Sample.vue
Normal file
78
src/components/Sample.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<h1>My App!</h1>
|
||||
<MainView />
|
||||
</div>
|
||||
<!-- A comment -->
|
||||
</template>
|
||||
|
||||
<script> /* eslint-disable */
|
||||
import MainView from './components/MainView.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MainView
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
// ABCDEFGHILJKLMNOPQRSTUVWXYZÆØÅÄÖ
|
||||
// abcdefghiljklmnopqrstuvwxyzæøåäö
|
||||
// 1 2 3 4 5 6 7 8 9 0
|
||||
// .,-;:_!"#$%&/|\§(){}[]=?*+~^@€`´<>
|
||||
// ==> -> == === !== != <- <==
|
||||
|
||||
// An empty arrow function returns undefined
|
||||
let empty = () => {}
|
||||
|
||||
const simple = a => a > 15 ? 15 : a
|
||||
simple(16) // 15
|
||||
simple(10) // 10
|
||||
|
||||
let max = (a, b) => a > b ? a : b
|
||||
|
||||
// Easy array filtering, mapping, ...
|
||||
const arr = [5, 6, 13, 0, 1, 18, 23]
|
||||
const sum = arr.reduce((a, b) => a + b) // 66
|
||||
const even = arr.filter(v => v % 2 === 0) // [6, 0, 18]
|
||||
const double = arr.map(v => v * 2) // [10, 12, 26, 0, 2, 36, 46]
|
||||
|
||||
// More concise promise chains
|
||||
func().then(a => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (a !== 1) resolve()
|
||||
else reject(new Error('This aint right'))
|
||||
})
|
||||
}).then(b => {
|
||||
// ...
|
||||
}).catch(err => {
|
||||
handle(err)
|
||||
})
|
||||
|
||||
// Parameterless arrow functions that are visually easier to parse
|
||||
setTimeout(() => {
|
||||
console.log('I happen sooner')
|
||||
setTimeout(() => {
|
||||
// deeper code
|
||||
console.log('I happen later')
|
||||
}, 1)
|
||||
}, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './global-variables.scss';
|
||||
|
||||
#app {
|
||||
font-family: 'VictorMono', monospace;
|
||||
line-height: 42;
|
||||
color: $wild-gradient;
|
||||
}
|
||||
|
||||
h1 { // Mwwhooahhaha, they'll never know what hit them
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -1000px;
|
||||
}
|
||||
</style>
|
28
src/main.js
Normal file
28
src/main.js
Normal file
@ -0,0 +1,28 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import VueScrollTo from 'vue-scrollTo'
|
||||
import './plugins/element.js'
|
||||
import VueCodemirror from 'vue-codemirror'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.use(VueScrollTo, {
|
||||
container: 'body',
|
||||
duration: 5000,
|
||||
easing: 'ease',
|
||||
offset: -200,
|
||||
force: true,
|
||||
cancelable: true,
|
||||
onStart: false,
|
||||
onDone: false,
|
||||
onCancel: false,
|
||||
x: false,
|
||||
y: true
|
||||
})
|
||||
|
||||
Vue.use(VueCodemirror)
|
||||
|
||||
window.application = new Vue({
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
9
src/plugins/element.js
Normal file
9
src/plugins/element.js
Normal file
@ -0,0 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import { Row, Col, Button, Tooltip } from 'element-ui'
|
||||
|
||||
import 'element-ui/lib/theme-chalk/display.css'
|
||||
|
||||
Vue.use(Row)
|
||||
Vue.use(Col)
|
||||
Vue.use(Button)
|
||||
Vue.use(Tooltip)
|
38
src/styles/base-16-light.css
Normal file
38
src/styles/base-16-light.css
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
|
||||
Name: Base16 Default Light
|
||||
Author: Chris Kempson (http://chriskempson.com)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; transition: background 1s, colour 1s; }
|
||||
.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0;}
|
||||
.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; }
|
||||
.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }
|
||||
.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; transition: background 1s, colour 1s; }
|
||||
.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; }
|
||||
.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; }
|
||||
.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; }
|
||||
.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; }
|
||||
|
||||
.cm-s-base16-light span.cm-comment { color: #8f5536; font-style: italic;}
|
||||
.cm-s-base16-light span.cm-atom { color: #aa759f; }
|
||||
.cm-s-base16-light span.cm-number { color: #aa759f; }
|
||||
|
||||
.cm-s-base16-light span.cm-attribute { color: #90a959; font-style: italic;}
|
||||
.cm-s-base16-light span.cm-keyword { color: #ac4142; font-style: italic;}
|
||||
.cm-s-base16-light span.cm-string { color: #f4bf75; }
|
||||
|
||||
.cm-s-base16-light span.cm-variable, .cm-s-base16-light span.cm-builtin, .cm-s-base16-light span.cm-qualifier { color: #90a959; font-style: italic;}
|
||||
.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
|
||||
.cm-s-base16-light span.cm-def { color: #d28445; }
|
||||
.cm-s-base16-light span.cm-bracket { color: #202020; }
|
||||
.cm-s-base16-light span.cm-tag { color: #ac4142; }
|
||||
.cm-s-base16-light span.cm-link { color: #aa759f; }
|
||||
.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; }
|
||||
|
||||
.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; transition: background 1s, colour 1s; }
|
||||
.cm-s-base16-light .CodeMirror-matchingbracket { color: #f5f5f5 !important; background-color: #6A9FB5 !important}
|
97
src/styles/globals.scss
Normal file
97
src/styles/globals.scss
Normal file
@ -0,0 +1,97 @@
|
||||
@font-face {
|
||||
font-family: 'VictorMono';
|
||||
font-style: normal;
|
||||
src: url('assets/VictorMono-Regular.eot');
|
||||
src: url('assets/VictorMono-Regular.eot?#iefix') format('embedded-opentype'), url('assets/VictorMono-Regular.woff') format('woff'), url('assets/VictorMono-Regular.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'VictorMono';
|
||||
font-style: italic;
|
||||
src: url('assets/VictorMono-Italic.eot');
|
||||
src: url('assets/VictorMono-Italic.eot?#iefix') format('embedded-opentype'), url('assets/VictorMono-Italic.woff') format('woff'), url('assets/VictorMono-Italic.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'VictorMono-Oblique';
|
||||
font-style: oblique;
|
||||
src: url('assets/VictorMono-Oblique.eot');
|
||||
src: url('assets/VictorMono-Oblique.eot?#iefix') format('embedded-opentype'), url('assets/VictorMono-Oblique.woff') format('woff'), url('assets/VictorMono-Oblique.ttf') format('truetype');
|
||||
}
|
||||
|
||||
:root {
|
||||
--background-color-base: #595959;
|
||||
--background-color-alternate: #505050;
|
||||
--color-text-primary: #fff;
|
||||
--color-text-accented: #0bf;
|
||||
}
|
||||
|
||||
html,
|
||||
* {
|
||||
font-family: 'VictorMono', monospace;
|
||||
}
|
||||
|
||||
html {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--background-color-base);
|
||||
transition: color 1s, background 1s;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-text-primary);
|
||||
transition: color 1s;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0 0 50px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-bottom: 10px;
|
||||
font-size: calc(0.9rem + 0.3vw);
|
||||
line-height: calc(1.8rem + 0.6vw);
|
||||
&.columns {
|
||||
column-count: 2;
|
||||
column-width: 18em;
|
||||
column-gap: 75px;
|
||||
}
|
||||
&.small {
|
||||
font-size: calc(0.75rem + 0.2vw);
|
||||
line-height: calc(1.5rem + 0.2vw);
|
||||
}
|
||||
}
|
||||
|
||||
.alternate-bg {
|
||||
background: var(--background-color-alternate);
|
||||
transition: background 1s;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.centre {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.caption {
|
||||
margin-top: 5px;
|
||||
font-size: 0.75em;
|
||||
font-style: italic;
|
||||
color: #aaa;
|
||||
a {
|
||||
color: #aaa;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #aaa;
|
||||
transition: color 0.5s, border-color 0.5s;
|
||||
&:hover {
|
||||
color: #ccc;
|
||||
border-bottom: 1px dotted #ccc;
|
||||
}
|
||||
}
|
||||
}
|
106
src/styles/ultimate-dark.css
Normal file
106
src/styles/ultimate-dark.css
Normal file
@ -0,0 +1,106 @@
|
||||
.cm-s-ultimate-dark.CodeMirror {
|
||||
background: #2b2b2b;
|
||||
color: #e2e0d7;
|
||||
transition: background 1s, colour 1s;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark div.CodeMirror-selected {
|
||||
background: #515151;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-line::selection,
|
||||
.cm-s-ultimate-dark .CodeMirror-line>span::selection,
|
||||
.cm-s-ultimate-dark .CodeMirror-line>span>span::selection {
|
||||
background: rgba(45, 45, 45, 0.99);
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-gutters {
|
||||
background: #393939;
|
||||
border-right: 0px;
|
||||
transition: background 1s;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-guttermarker {
|
||||
color: #ff7a7f;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-guttermarker-subtle {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-linenumber {
|
||||
color: #515151;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-cursor {
|
||||
border-left: 1px solid #6A6A6A;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-comment {
|
||||
font-style: italic;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-atom {
|
||||
color: #e2e0d7;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-number {
|
||||
color: #f99157;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-attribute {
|
||||
font-style: italic;
|
||||
color: #f99157;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-keyword {
|
||||
font-style: italic;
|
||||
color: #ff7a7f;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-string {
|
||||
color: #99dd99;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-variable,
|
||||
.cm-s-ultimate-dark span.cm-builtin,
|
||||
.cm-s-ultimate-dark span.cm-qualifier {
|
||||
font-style: italic;
|
||||
color: #f99157;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-variable-2 {
|
||||
color: #66aadd;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-def {
|
||||
color: #66aadd;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-bracket {
|
||||
color: #e2e0d7;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-tag {
|
||||
color: #ff7a7f;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-link {
|
||||
color: #e2e0d7;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark span.cm-error {
|
||||
background: #ff7a7f;
|
||||
color: #6A6A6A;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-activeline-background {
|
||||
background: #444;
|
||||
transition: background 1s;
|
||||
}
|
||||
|
||||
.cm-s-ultimate-dark .CodeMirror-matchingbracket {
|
||||
text-decoration: underline;
|
||||
color: white !important;
|
||||
}
|
9
vue.config.js
Normal file
9
vue.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? '/victor-mono/'
|
||||
: '/',
|
||||
devServer: {
|
||||
compress: true,
|
||||
disableHostCheck: true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user