├── .gitignore
├── .nvmrc
├── README.md
├── components
├── ConvertForm.js
├── CopyButton.js
├── Footer.js
├── Header.js
├── HorizontalLineText.js
├── Loader.js
├── Main.js
└── SchemaView.js
├── jsconfig.json
├── netlify.toml
├── next.config.js
├── package-lock.json
├── package.json
├── pages
├── 404.js
├── 500.js
├── _app.js
├── _document.js
├── _error.js
└── index.js
├── public
├── convert-collection-file.gif
├── convert-collection-url.gif
├── favicon.ico
├── images
│ ├── copy.png
│ ├── cover-image.jpg
│ └── overlay.png
└── logo.png
├── renovate.json
├── sentry.client.config.js
├── sentry.properties
├── sentry.server.config.js
└── styles
├── base
├── _page.scss
└── _typography.scss
├── components
├── _box.scss
├── _button.scss
├── _form.scss
├── _icon.scss
├── _image.scss
├── _list.scss
└── _table.scss
├── error.module.scss
├── horizontalLineText.module.scss
├── ie9.scss
├── layout
├── _bg.scss
├── _footer.scss
├── _header.scss
├── _main.scss
└── _wrapper.scss
├── libs
├── _functions.scss
├── _mixins.scss
├── _skel.scss
└── _vars.scss
├── loader.module.scss
├── main.scss
├── noscript.scss
└── schemaView.module.scss
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
32 | # Local Netlify folder
33 | .netlify
34 |
35 | # Sentry
36 | .sentryclirc
37 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v16.9.1
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Postman to OpenAPI online converter
2 |
3 | [](https://app.netlify.com/sites/next-dev-starter/deploys)
4 |
5 | A small utility to convert Postman collections to Open API schema in one click.
6 | All the conversion happens on your browser itself hence your collection data is completely secure and no data is exchanged after page is loaded.
7 |
8 | You can either load the collection from an exported JSON or directly use the collection URL.
9 | ## 🏠 [Homepage](https://p2o.defcon007.com)
10 |
11 | ## ✨ Demo
12 | #### Convert collection JSON file to OpenAPI schema
13 | 
14 |
15 | #### Convert collection via URL to OpenAPI schema
16 | 
17 |
18 |
19 | ### Installation
20 |
21 | **Option one:** One-click deploy
22 |
23 | [](https://app.netlify.com/start/deploy?repository=https://github.com/DefCon-007/postman-to-openapi-online.git)
24 |
25 | **Option two:** Manual clone
26 |
27 | 1. Clone this repo: `git clone https://github.com/DefCon-007/postman-to-openapi-online.git`
28 | 2. Use supported node version by `nvm use`
29 | 3. Navigate to the directory and run `npm install`
30 | 4. Run `npm run dev`
31 | 5. Make your changes
32 |
--------------------------------------------------------------------------------
/components/ConvertForm.js:
--------------------------------------------------------------------------------
1 | import * as Sentry from "@sentry/nextjs";
2 | import { usePostHog } from 'posthog-js/react';
3 | import postmanToOpenApi from 'postman-to-openapi-module';
4 | import { useState } from 'react';
5 | import { toast } from 'react-toastify';
6 | import HorizontalLineText from './HorizontalLineText';
7 | import Loader from './Loader';
8 |
9 | const JSON_FILE_ERROR = 'Unable to parse uploaded collection JSON. Please check the uploaded file',
10 | EMPTY_FORM_SUBMIT = 'Either enter a collection URL or upload collection JSON.',
11 | GENERAL_ERROR = 'Unable to parse collection data. Please try again.',
12 | PARSING_ERROR = "Following error occurred while parsing the collection.",
13 | INVALID_URL = 'Unable to fetch collection data. Please check the url';
14 |
15 | function ConvertForm(props) {
16 | const [fetchingCollection, setFetchingCollection] = useState(false),
17 | updateConvertedSchema = props.updateConvertedSchema,
18 | posthog = usePostHog();
19 |
20 | const handleFormSubmit = (event) => {
21 | try {
22 | event.preventDefault(); // don't redirect the page
23 |
24 | const collectionFile = event.target['collection-file'].files,
25 | collectionUrl = event.target['collection-url'].value;
26 |
27 | if (collectionFile.length > 0) {
28 | // User uploaded a file, parse from it
29 | const reader = new FileReader()
30 | reader.onload = async (e) => {
31 | try {
32 | const text = postmanToOpenApi(e.target.result)
33 | updateConvertedSchema(text);
34 | } catch (err) {
35 | toast.error(
{
14 | copyTextToClipboard(props.copyText)
15 | .then(() => {
16 | toast.success(props.alertText);
17 | });
18 | }}
19 | />
20 | )
21 |
22 | CopyButton.propTypes = {
23 | copyText: PropTypes.string,
24 | alertText: PropTypes.string.isRequired
25 | }
26 |
27 | export default CopyButton
28 |
--------------------------------------------------------------------------------
/components/Footer.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | const Footer = (props) => (
4 |
7 | )
8 |
9 | Footer.propTypes = {
10 | timeout: PropTypes.bool
11 | }
12 |
13 | export default Footer
14 |
--------------------------------------------------------------------------------
/components/Header.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 | import { usePostHog } from 'posthog-js/react';
3 | import PropTypes from 'prop-types';
4 | import logo from '../public/logo.png';
5 |
6 | const Header = (props) => {
7 | const { onOpenArticle } = props,
8 | posthog = usePostHog(),
9 | handleLinkClick = (event, articleId) => {
10 | event.preventDefault();
11 | onOpenArticle(articleId);
12 |
13 | posthog.capture(
14 | "navigation_clicked",
15 | {
16 | id: articleId
17 | }
18 | );
19 | };
20 |
21 | return (
22 |
40 | )
41 | };
42 |
43 | Header.propTypes = {
44 | onOpenArticle: PropTypes.func,
45 | timeout: PropTypes.bool
46 | }
47 |
48 | export default Header
49 |
--------------------------------------------------------------------------------
/components/HorizontalLineText.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import styles from '@styles/horizontalLineText.module.scss';
3 |
4 | const HorizontalLineText = (props) => (
5 |
6 |
7 |
{props.text}
8 |
9 |
10 | )
11 |
12 | HorizontalLineText.propTypes = {
13 | text: PropTypes.string
14 | }
15 |
16 | export default HorizontalLineText
17 |
--------------------------------------------------------------------------------
/components/Loader.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import styles from '@styles/loader.module.scss';
3 | import Image from 'next/image';
4 | import logo from '../public/logo.png';
5 |
6 | const Loader = (props) => (
7 |
8 |
9 |
{props.text}
10 |
11 | )
12 |
13 | Loader.propTypes = {
14 | text: PropTypes.string
15 | }
16 |
17 | export default Loader
18 |
--------------------------------------------------------------------------------
/components/Main.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import ConvertForm from './ConvertForm';
4 | import CopyButton from './CopyButton';
5 | import SchemaView from './SchemaView';
6 |
7 | class Main extends React.Component {
8 | constructor() {
9 | super();
10 |
11 | this.state = {
12 | convertedSchema: ''
13 | }
14 |
15 | this.updateConvertedSchema = this.updateConvertedSchema.bind(this);
16 | this.getSchemaView = this.getSchemaView.bind(this);
17 | }
18 |
19 | updateConvertedSchema(convertedSchema) {
20 | console.log('Updating converted schema')
21 | this.setState({
22 | convertedSchema
23 | });
24 | }
25 |
26 | getSchemaView(schema) {
27 | const lines = schema.split('\n');
28 | const schemaView = lines.map((line, index) => {
29 | return (
30 |
{line}
31 | )
32 | });
33 |
34 | return schemaView;
35 | }
36 |
37 | render() {
38 |
39 | const close = (
40 |
{
41 | if (this.state.convertedSchema) {
42 | this.setState({
43 | convertedSchema: ''
44 | });
45 | } else {
46 | this.props.onCloseArticle()
47 | }
48 |
49 | }}>
50 | );
51 |
52 | return (
53 |
54 |
55 |
56 |
57 | {
58 | this.state.convertedSchema ? (
59 |
60 | ) : (
61 | <>
62 | Convert
63 |
64 | >
65 | )
66 | }
67 | {this.state.convertedSchema && }
68 | {close}
69 |
70 |
71 |
72 | About
73 |
74 | A small utility to convert Postman collections to Open API schema in one click.
75 | All the conversion happens on your browser itself hence your collection data is completely secure and no data is exchanged after page is loaded.
76 |
77 | You can either load the collection from an exported JSON or directly use the collection URL.
78 | Note: If your collection is not public, create an access token in Postman and add {'?apikey='}
at end of the URL to access it.
79 |
80 | Acknowledgements
81 |
82 | Thanks to @joolfe for the awesome postman-to-openapi npm package which made conversion easy.
83 | Website design taken from codebushi and theme name is Next.js Dimension
84 |
85 | {close}
86 |
87 |
88 | )
89 | }
90 | }
91 |
92 | Main.propTypes = {
93 | route: PropTypes.object,
94 | article: PropTypes.string,
95 | articleTimeout: PropTypes.bool,
96 | onCloseArticle: PropTypes.func,
97 | timeout: PropTypes.bool
98 | }
99 |
100 | export default Main
--------------------------------------------------------------------------------
/components/SchemaView.js:
--------------------------------------------------------------------------------
1 | import styles from '@styles/schemaView.module.scss';
2 |
3 |
4 | function SchemaView(props) {
5 | const schema = props.schema;
6 |
7 | if (!schema) {
8 | return (
9 | <>>
10 | )
11 | } else {
12 | const lines = schema.split('\n');
13 |
14 | return (
15 |
16 | {
17 | lines.map((line) => {
18 | return (
19 | {line}
20 | )
21 | })
22 | }
23 |
24 | );
25 | }
26 | }
27 |
28 | export default SchemaView
29 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./",
4 | "paths": {
5 | "@components/*": ["components/*"],
6 | "@styles/*": ["styles/*"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "npm run build"
3 | publish = ".next"
4 |
5 | [[plugins]]
6 | package = "@netlify/plugin-nextjs"
7 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | // This file sets a custom webpack configuration to use your Next.js app
2 | // with Sentry.
3 | // https://nextjs.org/docs/api-reference/next.config.js/introduction
4 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/
5 |
6 | const { withSentryConfig } = require('@sentry/nextjs');
7 |
8 | const moduleExports = {
9 | // Your existing module.exports
10 | };
11 |
12 | const sentryWebpackPluginOptions = {
13 | // Additional config options for the Sentry Webpack plugin. Keep in mind that
14 | // the following options are set automatically, and overriding them is not
15 | // recommended:
16 | // release, url, org, project, authToken, configFile, stripPrefix,
17 | // urlPrefix, include, ignore
18 |
19 | silent: true, // Suppresses all logs
20 | // For all available options, see:
21 | // https://github.com/getsentry/sentry-webpack-plugin#options.
22 | };
23 |
24 | // Make sure adding Sentry options is the last code to run before exporting, to
25 | // ensure that your source maps include changes from all other Webpack plugins
26 | module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions);
27 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "postman-to-openapi-online",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "export": "next export"
9 | },
10 | "dependencies": {
11 | "@sentry/nextjs": "^6.19.7",
12 | "next": "^12.1.5",
13 | "posthog-js": "^1.56.0",
14 | "postman-to-openapi-module": "https://github.com/DefCon-007/postman-to-openapi.git#master-client-side-module",
15 | "prop-types": "^15.8.1",
16 | "react": "^17.0.2",
17 | "react-dom": "^17.0.2",
18 | "react-toastify": "^9.1.3"
19 | },
20 | "devDependencies": {
21 | "@netlify/plugin-nextjs": "^4.7.0",
22 | "sass": "^1.51.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/pages/404.js:
--------------------------------------------------------------------------------
1 | import styles from '@styles/error.module.scss';
2 |
3 |
4 | export default function Custom404() {
5 | return
404 - Page Not Found
6 | }
--------------------------------------------------------------------------------
/pages/500.js:
--------------------------------------------------------------------------------
1 | import styles from '@styles/error.module.scss';
2 |
3 |
4 | export default function Custom404() {
5 | return
500 - Server Error
6 | }
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '@styles/main.scss';
2 | import { useRouter } from 'next/router';
3 | import posthog from "posthog-js";
4 | import { PostHogProvider } from 'posthog-js/react';
5 | import { useEffect } from 'react';
6 | import { ToastContainer } from 'react-toastify';
7 | import 'react-toastify/dist/ReactToastify.css';
8 |
9 |
10 | // Check that PostHog is client-side
11 | if (typeof window !== 'undefined') {
12 | posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
13 | api_host: 'https://app.posthog.com',
14 | // Enable debug mode in development
15 | loaded: (posthog) => {
16 | if (process.env.NODE_ENV === 'development') posthog.debug()
17 | }
18 | })
19 | }
20 |
21 |
22 | function Application({ Component, pageProps }) {
23 | const router = useRouter()
24 |
25 | useEffect(() => {
26 | // Track page views
27 | const handleRouteChange = () => posthog?.capture('$pageview')
28 | router.events.on('routeChangeComplete', handleRouteChange)
29 |
30 | return () => {
31 | router.events.off('routeChangeComplete', handleRouteChange)
32 | }
33 | }, [])
34 |
35 | return (
36 | <>
37 |
38 |
39 |
52 |
53 | >
54 | )
55 |
56 | }
57 |
58 | export default Application
59 |
--------------------------------------------------------------------------------
/pages/_document.js:
--------------------------------------------------------------------------------
1 | import Document, { Html, Head, Main, NextScript } from 'next/document'
2 |
3 | export default class MyDocument extends Document {
4 | render() {
5 | return (
6 |
7 |
8 | {/* Global Site Tag (gtag.js) - Google Analytics */}
9 |
13 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | )
33 | }
34 | }
--------------------------------------------------------------------------------
/pages/_error.js:
--------------------------------------------------------------------------------
1 | import NextErrorComponent from 'next/error';
2 |
3 | import * as Sentry from '@sentry/nextjs';
4 |
5 | const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => {
6 | if (!hasGetInitialPropsRun && err) {
7 | // getInitialProps is not called in case of
8 | // https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
9 | // err via _app.js so it can be captured
10 | Sentry.captureException(err);
11 | // Flushing is not required in this case as it only happens on the client
12 | }
13 |
14 | return
;
15 | };
16 |
17 | MyError.getInitialProps = async (context) => {
18 | const errorInitialProps = await NextErrorComponent.getInitialProps(context);
19 |
20 | const { res, err, asPath } = context;
21 |
22 | // Workaround for https://github.com/vercel/next.js/issues/8592, mark when
23 | // getInitialProps has run
24 | errorInitialProps.hasGetInitialPropsRun = true;
25 |
26 | // Returning early because we don't want to log 404 errors to Sentry.
27 | if (res?.statusCode === 404) {
28 | return errorInitialProps;
29 | }
30 |
31 | // Running on the server, the response object (`res`) is available.
32 | //
33 | // Next.js will pass an err on the server if a page's data fetching methods
34 | // threw or returned a Promise that rejected
35 | //
36 | // Running on the client (browser), Next.js will provide an err if:
37 | //
38 | // - a page's `getInitialProps` threw or returned a Promise that rejected
39 | // - an exception was thrown somewhere in the React lifecycle (render,
40 | // componentDidMount, etc) that was caught by Next.js's React Error
41 | // Boundary. Read more about what types of exceptions are caught by Error
42 | // Boundaries: https://reactjs.org/docs/error-boundaries.html
43 |
44 | if (err) {
45 | Sentry.captureException(err);
46 |
47 | // Flushing before returning is necessary if deploying to Vercel, see
48 | // https://vercel.com/docs/platform/limits#streaming-responses
49 | await Sentry.flush(2000);
50 |
51 | return errorInitialProps;
52 | }
53 |
54 | // If this point is reached, getInitialProps was called without any
55 | // information about what the error might be. This is unexpected and may
56 | // indicate a bug introduced in Next.js, so record it in Sentry
57 | Sentry.captureException(
58 | new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
59 | );
60 | await Sentry.flush(2000);
61 |
62 | return errorInitialProps;
63 | };
64 |
65 | export default MyError;
66 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Head from "next/head"
3 |
4 | import Header from "../components/Header"
5 | import Main from "../components/Main"
6 | import Footer from "../components/Footer"
7 |
8 | const baseUrl = 'https://p2o.defcon007.com',
9 | title = 'Postman to OpenAPI',
10 | description = 'Convert Postman collections to Open API schema in one click. Works locally on the browser without sending any data to any server.',
11 | coverImageUrl = baseUrl + '/images/cover-image.jpg';
12 |
13 | class IndexPage extends React.Component {
14 | constructor(props) {
15 | super(props)
16 | this.state = {
17 | isArticleVisible: false,
18 | timeout: false,
19 | articleTimeout: false,
20 | article: "",
21 | loading: "is-loading"
22 | }
23 | this.handleOpenArticle = this.handleOpenArticle.bind(this)
24 | this.handleCloseArticle = this.handleCloseArticle.bind(this)
25 | }
26 |
27 | componentDidMount() {
28 | this.timeoutId = setTimeout(() => {
29 | this.setState({ loading: "" })
30 | }, 100)
31 | }
32 |
33 | componentWillUnmount() {
34 | if (this.timeoutId) {
35 | clearTimeout(this.timeoutId)
36 | }
37 | }
38 |
39 | handleOpenArticle(article) {
40 | this.setState({
41 | isArticleVisible: !this.state.isArticleVisible,
42 | article
43 | })
44 |
45 | setTimeout(() => {
46 | this.setState({
47 | timeout: !this.state.timeout
48 | })
49 | }, 325)
50 |
51 | setTimeout(() => {
52 | this.setState({
53 | articleTimeout: !this.state.articleTimeout
54 | })
55 | }, 350)
56 | }
57 |
58 | handleCloseArticle() {
59 | this.setState({
60 | articleTimeout: !this.state.articleTimeout
61 | })
62 |
63 | setTimeout(() => {
64 | this.setState({
65 | timeout: !this.state.timeout
66 | })
67 | }, 325)
68 |
69 | setTimeout(() => {
70 | this.setState({
71 | isArticleVisible: !this.state.isArticleVisible,
72 | article: ""
73 | })
74 | }, 350)
75 | }
76 | render() {
77 | return (
78 |
79 |
80 |
81 | {/* Primary Meta Tags */}
82 |
{title}
83 |
84 |
85 |
86 | {/* Open Graph / Facebook */}
87 |
88 |
89 |
90 |
91 |
92 |
93 | {/* Twitter */}
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | )
117 | }
118 | }
119 |
120 | export default IndexPage
121 |
--------------------------------------------------------------------------------
/public/convert-collection-file.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/convert-collection-file.gif
--------------------------------------------------------------------------------
/public/convert-collection-url.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/convert-collection-url.gif
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/images/copy.png
--------------------------------------------------------------------------------
/public/images/cover-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/images/cover-image.jpg
--------------------------------------------------------------------------------
/public/images/overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/images/overlay.png
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DefCon-007/postman-to-openapi-online/ed64895c7436eb0d395274169846730c33b91eaa/public/logo.png
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "local>netlify-templates/renovate-config"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/sentry.client.config.js:
--------------------------------------------------------------------------------
1 | // This file configures the initialization of Sentry on the browser.
2 | // The config you add here will be used whenever a page is visited.
3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4 |
5 | import * as Sentry from '@sentry/nextjs';
6 |
7 | const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8 |
9 | Sentry.init({
10 | dsn: SENTRY_DSN,
11 | // Adjust this value in production, or use tracesSampler for greater control
12 | tracesSampleRate: 1.0,
13 | // ...
14 | // Note: if you want to override the automatic release value, do not set a
15 | // `release` value here - use the environment variable `SENTRY_RELEASE`, so
16 | // that it will also get attached to your source maps
17 | });
18 |
--------------------------------------------------------------------------------
/sentry.properties:
--------------------------------------------------------------------------------
1 | defaults.url=https://sentry.io/
2 | defaults.org=defcon
3 | defaults.project=p2o
4 | cli.executable=../../.npm/_npx/a8388072043b4cbc/node_modules/@sentry/cli/bin/sentry-cli
5 |
--------------------------------------------------------------------------------
/sentry.server.config.js:
--------------------------------------------------------------------------------
1 | // This file configures the initialization of Sentry on the server.
2 | // The config you add here will be used whenever the server handles a request.
3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4 |
5 | import * as Sentry from '@sentry/nextjs';
6 |
7 | const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8 |
9 | Sentry.init({
10 | dsn: SENTRY_DSN,
11 | // Adjust this value in production, or use tracesSampler for greater control
12 | tracesSampleRate: 1.0,
13 | // ...
14 | // Note: if you want to override the automatic release value, do not set a
15 | // `release` value here - use the environment variable `SENTRY_RELEASE`, so
16 | // that it will also get attached to your source maps
17 | });
18 |
--------------------------------------------------------------------------------
/styles/base/_page.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Basic */
8 |
9 | // MSIE: Required for IEMobile.
10 | @-ms-viewport {
11 | width: device-width;
12 | }
13 |
14 | // Ensures page width is always >=320px.
15 | @include breakpoint(xsmall) {
16 | html, body {
17 | min-width: 320px;
18 | }
19 | }
20 |
21 | body {
22 | background: _palette(bg);
23 |
24 | // Prevents animation/transition "flicker" on page load.
25 | // Automatically added/removed by js/main.js.
26 | &.is-loading,
27 | .body.is-loading,
28 | &.is-switching {
29 | *, *:before, *:after {
30 | @include vendor('animation', 'none !important');
31 | @include vendor('transition', 'none !important');
32 | @include vendor('transition-delay', 'none !important');
33 | }
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/styles/base/_typography.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Type */
8 |
9 | html {
10 | font-size: 16pt;
11 |
12 | @include breakpoint(xlarge) {
13 | font-size: 12pt;
14 | }
15 |
16 | @include breakpoint(small) {
17 | font-size: 11pt;
18 | }
19 |
20 | @include breakpoint(xxsmall) {
21 | font-size: 10pt;
22 | }
23 | }
24 |
25 | body, input, select, textarea {
26 | color: _palette(fg);
27 | font-family: _font(family);
28 | font-weight: _font(weight);
29 | font-size: 1rem;
30 | line-height: 1.65;
31 | }
32 |
33 | a {
34 | @include vendor('transition', (
35 | 'color #{_duration(transition)} ease-in-out',
36 | 'background-color #{_duration(transition)} ease-in-out',
37 | 'border-bottom-color #{_duration(transition)} ease-in-out'
38 | ));
39 | border-bottom: dotted 1px _palette(fg-light);
40 | text-decoration: none;
41 | color: inherit;
42 |
43 | &:hover {
44 | border-bottom-color: transparent;
45 | }
46 | }
47 |
48 | strong, b {
49 | color: _palette(fg-bold);
50 | font-weight: _font(weight-bold);
51 | }
52 |
53 | em, i {
54 | font-style: italic;
55 | }
56 |
57 | p {
58 | margin: 0 0 _size(element-margin) 0;
59 | }
60 |
61 | h1, h2, h3, h4, h5, h6 {
62 | color: _palette(fg-bold);
63 | font-weight: _font(weight-bold);
64 | line-height: 1.5;
65 | margin: 0 0 (_size(element-margin) * 0.5) 0;
66 | text-transform: uppercase;
67 | letter-spacing: _font(letter-spacing);
68 |
69 | a {
70 | color: inherit;
71 | text-decoration: none;
72 | }
73 |
74 | &.major {
75 | border-bottom: solid _size(border-width) _palette(border);
76 | width: -moz-max-content;
77 | width: -webkit-max-content;
78 | width: -ms-max-content;
79 | width: max-content;
80 | padding-bottom: 0.5rem;
81 | margin: 0 0 (_size(element-margin) * 1) 0;
82 | }
83 | }
84 |
85 | h1 {
86 | font-size: 2.25rem;
87 | line-height: 1.3;
88 | letter-spacing: _font(letter-spacing-heading);
89 | }
90 |
91 | h2 {
92 | font-size: 1.5rem;
93 | line-height: 1.4;
94 | letter-spacing: _font(letter-spacing-heading);
95 | }
96 |
97 | h3 {
98 | font-size: 1rem;
99 | }
100 |
101 | h4 {
102 | font-size: 0.8rem;
103 | }
104 |
105 | h5 {
106 | font-size: 0.7rem;
107 | }
108 |
109 | h6 {
110 | font-size: 0.6rem;
111 | }
112 |
113 | @include breakpoint(small) {
114 | h1 {
115 | font-size: 1.75rem;
116 | line-height: 1.4;
117 | }
118 |
119 | h2 {
120 | font-size: 1.25em;
121 | line-height: 1.5;
122 | }
123 | }
124 |
125 | sub {
126 | font-size: 0.8rem;
127 | position: relative;
128 | top: 0.5rem;
129 | }
130 |
131 | sup {
132 | font-size: 0.8rem;
133 | position: relative;
134 | top: -0.5rem;
135 | }
136 |
137 | blockquote {
138 | border-left: solid (_size(border-width) * 4) _palette(border);
139 | font-style: italic;
140 | margin: 0 0 _size(element-margin) 0;
141 | padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin);
142 | }
143 |
144 | code {
145 | background: _palette(border-bg);
146 | border-radius: _size(border-radius);
147 | font-family: _font(family-fixed);
148 | font-size: 0.9rem;
149 | margin: 0 0.25rem;
150 | padding: 0.25rem 0.65rem;
151 | }
152 |
153 | pre {
154 | -webkit-overflow-scrolling: touch;
155 | font-family: _font(family-fixed);
156 | font-size: 0.9rem;
157 | margin: 0 0 _size(element-margin) 0;
158 |
159 | code {
160 | display: block;
161 | line-height: 1.75;
162 | padding: 1rem 1.5rem;
163 | overflow-x: auto;
164 | }
165 | }
166 |
167 | hr {
168 | border: 0;
169 | border-bottom: solid _size(border-width) _palette(border);
170 | margin: (_size(element-margin) * 1.375) 0;
171 | }
172 |
173 | .align-left {
174 | text-align: left;
175 | }
176 |
177 | .align-center {
178 | text-align: center;
179 | }
180 |
181 | .align-right {
182 | text-align: right;
183 | }
--------------------------------------------------------------------------------
/styles/components/_box.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Box */
8 |
9 | .box {
10 | border-radius: _size(border-radius);
11 | border: solid _size(border-width) _palette(border);
12 | margin-bottom: _size(element-margin);
13 | padding: 1.5em;
14 |
15 | > :last-child,
16 | > :last-child > :last-child,
17 | > :last-child > :last-child > :last-child {
18 | margin-bottom: 0;
19 | }
20 |
21 | &.alt {
22 | border: 0;
23 | border-radius: 0;
24 | padding: 0;
25 | }
26 | }
--------------------------------------------------------------------------------
/styles/components/_button.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Button */
8 |
9 | input[type="submit"],
10 | input[type="reset"],
11 | input[type="button"],
12 | button,
13 | .button {
14 | @include vendor('appearance', 'none');
15 | @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out, color #{_duration(transition)} ease-in-out');
16 | background-color: transparent;
17 | border-radius: _size(border-radius);
18 | border: 0;
19 | box-shadow: inset 0 0 0 _size(border-width) _palette(border);
20 | color: _palette(fg-bold) !important;
21 | cursor: pointer;
22 | display: inline-block;
23 | font-size: 0.8rem;
24 | font-weight: _font(weight);
25 | height: _size(element-height);
26 | letter-spacing: _font(letter-spacing);
27 | line-height: _size(element-height);
28 | outline: 0;
29 | padding: 0 1.25rem 0 (1.25rem + (_font(letter-spacing) * 0.5));
30 | text-align: center;
31 | text-decoration: none;
32 | text-transform: uppercase;
33 | white-space: nowrap;
34 |
35 | &:hover {
36 | background-color: _palette(border-bg);
37 | }
38 |
39 | &:active {
40 | background-color: _palette(border-bg-alt);
41 | }
42 |
43 | &.icon {
44 | &:before {
45 | margin-right: 0.5em;
46 | }
47 | }
48 |
49 | &.fit {
50 | display: block;
51 | margin: 0 0 (_size(element-margin) * 0.5) 0;
52 | width: 100%;
53 | }
54 |
55 | &.special {
56 | background-color: _palette(fg-bold);
57 | color: _palette(bg) !important;
58 | font-weight: _font(weight-bold);
59 |
60 | &:hover {
61 | }
62 |
63 | &:active {
64 | }
65 | }
66 |
67 | &.disabled,
68 | &:disabled {
69 | @include vendor('pointer-events', 'none');
70 | cursor: default;
71 | opacity: 0.25;
72 | }
73 | }
74 |
75 | input[type="submit"],
76 | input[type="reset"],
77 | input[type="button"],
78 | button {
79 | line-height: calc(#{_size(element-height)} - 2px);
80 | }
--------------------------------------------------------------------------------
/styles/components/_form.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Form */
8 |
9 | form {
10 | $gutter: _size(element-margin) * 0.75;
11 |
12 | margin: 0 0 (_size(element-margin) * 1.25) 0;
13 |
14 | .field {
15 | margin: 0 0 ($gutter * 1) 0;
16 |
17 | &.half {
18 | width: 50%;
19 | float: left;
20 | padding: 0 0 0 ($gutter * 1 * 0.5);
21 |
22 | &.first {
23 | padding: 0 ($gutter * 1 * 0.5) 0 0;
24 | }
25 | }
26 | }
27 |
28 | > .actions {
29 | margin: ($gutter * 1.25) 0 0 0 !important;
30 | }
31 |
32 | @include breakpoint(small) {
33 | .field {
34 | margin: 0 0 ($gutter * 0.75) 0;
35 |
36 | &.half {
37 | padding: 0 0 0 ($gutter * 0.75 * 0.5);
38 |
39 | &.first {
40 | padding: 0 ($gutter * 0.75 * 0.5) 0 0;
41 | }
42 | }
43 | }
44 |
45 | > .actions {
46 | margin: ($gutter * 1) 0 0 0 !important;
47 | }
48 | }
49 |
50 | @include breakpoint(xsmall) {
51 | .field {
52 | &.half {
53 | width: 100%;
54 | float: none;
55 | padding: 0;
56 |
57 | &.first {
58 | padding: 0;
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
65 | label {
66 | color: _palette(fg-bold);
67 | display: block;
68 | font-size: 0.8rem;
69 | font-weight: _font(weight);
70 | letter-spacing: _font(letter-spacing);
71 | line-height: 1.5;
72 | margin: 0 0 (_size(element-margin) * 0.5) 0;
73 | text-transform: uppercase;
74 | }
75 |
76 | input[type="text"],
77 | input[type="url"],
78 | input[type="file"]
79 | select,
80 | textarea {
81 | @include vendor('appearance', 'none');
82 | @include vendor('transition', (
83 | 'border-color #{_duration(transition)} ease-in-out',
84 | 'box-shadow #{_duration(transition)} ease-in-out',
85 | 'background-color #{_duration(transition)} ease-in-out'
86 | ));
87 | background: transparent;
88 | border-radius: _size(border-radius);
89 | border: solid _size(border-width) _palette(border);
90 | color: inherit;
91 | display: block;
92 | outline: 0;
93 | padding: 0 1rem;
94 | text-decoration: none;
95 | width: 100%;
96 |
97 | &:invalid {
98 | box-shadow: none;
99 | }
100 |
101 | &:focus {
102 | background: _palette(border-bg);
103 | border-color: _palette(fg-bold);
104 | box-shadow: 0 0 0 _size(border-width) _palette(fg-bold);
105 | }
106 | }
107 |
108 | select {
109 | option {
110 | background: _palette(bg);
111 | color: _palette(fg);
112 | }
113 | }
114 |
115 | .select-wrapper {
116 | @include icon;
117 | display: block;
118 | position: relative;
119 |
120 | &:before {
121 | color: _palette(border);
122 | content: '\f107';
123 | display: block;
124 | height: _size(element-height);
125 | //line-height: _size(element-height);
126 | line-height: calc(#{_size(element-height)} + 0em);
127 | pointer-events: none;
128 | position: absolute;
129 | right: 0;
130 | text-align: center;
131 | top: 0;
132 | width: _size(element-height);
133 | }
134 |
135 | select::-ms-expand {
136 | display: none;
137 | }
138 | }
139 |
140 | input[type="text"],
141 | input[type="url"],
142 | input[type="file"]
143 | select {
144 | height: _size(element-height);
145 | }
146 |
147 | textarea {
148 | padding: 0.75rem 1rem;
149 | }
150 |
151 | input[type="checkbox"],
152 | input[type="radio"], {
153 | @include vendor('appearance', 'none');
154 | display: block;
155 | float: left;
156 | margin-right: -2rem;
157 | opacity: 0;
158 | width: 1rem;
159 | z-index: -1;
160 |
161 | & + label {
162 | @include icon;
163 | @include vendor('user-select', 'none');
164 | color: _palette(fg);
165 | cursor: pointer;
166 | display: inline-block;
167 | font-size: 0.8rem;
168 | font-weight: _font(weight);
169 | margin: 0 0 (_size(element-margin) * 0.25) 0;
170 | padding-left: (_size(element-height) * 0.6) + 1rem;
171 | padding-right: 0.75rem;
172 | position: relative;
173 |
174 | &:before {
175 | @include vendor('transition', (
176 | 'border-color #{_duration(transition)} ease-in-out',
177 | 'box-shadow #{_duration(transition)} ease-in-out',
178 | 'background-color #{_duration(transition)} ease-in-out'
179 | ));
180 | border-radius: _size(border-radius);
181 | border: solid _size(border-width) _palette(border);
182 | content: '';
183 | display: inline-block;
184 | height: (_size(element-height) * 0.6);
185 | left: 0;
186 | //line-height: (_size(element-height) * 0.575);
187 | line-height: calc(#{_size(element-height) * 0.575} + 0em);
188 | position: absolute;
189 | text-align: center;
190 | top: -0.125rem;
191 | width: (_size(element-height) * 0.6);
192 | }
193 | }
194 |
195 | &:checked + label {
196 | &:before {
197 | background: _palette(fg-bold) !important;
198 | border-color: _palette(fg-bold) !important;
199 | color: _palette(bg);
200 | content: '\f00c';
201 | }
202 | }
203 |
204 | &:focus + label {
205 | &:before {
206 | background: _palette(border-bg);
207 | border-color: _palette(fg-bold);
208 | box-shadow: 0 0 0 _size(border-width) _palette(fg-bold);
209 | }
210 | }
211 | }
212 |
213 | input[type="checkbox"] {
214 | & + label {
215 | &:before {
216 | border-radius: _size(border-radius);
217 | }
218 | }
219 | }
220 |
221 | input[type="radio"] {
222 | & + label {
223 | &:before {
224 | border-radius: 100%;
225 | }
226 | }
227 | }
228 |
229 | ::-webkit-input-placeholder {
230 | color: _palette(fg-light) !important;
231 | opacity: 1.0;
232 | }
233 |
234 | :-moz-placeholder {
235 | color: _palette(fg-light) !important;
236 | opacity: 1.0;
237 | }
238 |
239 | ::-moz-placeholder {
240 | color: _palette(fg-light) !important;
241 | opacity: 1.0;
242 | }
243 |
244 | :-ms-input-placeholder {
245 | color: _palette(fg-light) !important;
246 | opacity: 1.0;
247 | }
248 |
249 | .formerize-placeholder {
250 | color: _palette(fg-light) !important;
251 | opacity: 1.0;
252 | }
--------------------------------------------------------------------------------
/styles/components/_icon.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Icon */
8 |
9 | .icon {
10 | @include icon;
11 | border-bottom: none;
12 | position: relative;
13 |
14 | > .label {
15 | display: none;
16 | }
17 | }
--------------------------------------------------------------------------------
/styles/components/_image.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Image */
8 |
9 | .image {
10 | border-radius: _size(border-radius);
11 | border: 0;
12 | display: inline-block;
13 | position: relative;
14 |
15 | &:before {
16 | @include vendor('pointer-events', 'none');
17 | background-image: url('/images/overlay.png');
18 | background-color: _palette(bg-overlay);
19 | border-radius: _size(border-radius);
20 | content: '';
21 | display: block;
22 | height: 100%;
23 | left: 0;
24 | opacity: 0.5;
25 | position: absolute;
26 | top: 0;
27 | width: 100%;
28 | }
29 |
30 | img {
31 | border-radius: _size(border-radius);
32 | display: block;
33 | }
34 |
35 | &.left,
36 | &.right {
37 | max-width: 40%;
38 |
39 | img {
40 | width: 100%;
41 | }
42 | }
43 |
44 | &.left {
45 | float: left;
46 | padding: 0 1.5em 1em 0;
47 | top: 0.25em;
48 | }
49 |
50 | &.right {
51 | float: right;
52 | padding: 0 0 1em 1.5em;
53 | top: 0.25em;
54 | }
55 |
56 | &.fit {
57 | display: block;
58 | margin: 0 0 _size(element-margin) 0;
59 | width: 100%;
60 |
61 | img {
62 | width: 100%;
63 | }
64 | }
65 |
66 | &.main {
67 | display: block;
68 | margin: (_size(element-margin) * 1.25) 0;
69 | width: 100%;
70 |
71 | img {
72 | width: 100%;
73 | }
74 | }
75 |
76 | @include breakpoint(small) {
77 | &.main {
78 | margin: (_size(element-margin) * 1) 0;
79 | }
80 | }
81 |
82 | @include breakpoint(xsmall) {
83 | &.main {
84 | margin: (_size(element-margin) * 0.75) 0;
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/styles/components/_list.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* List */
8 |
9 | ol {
10 | list-style: decimal;
11 | margin: 0 0 _size(element-margin) 0;
12 | padding-left: 1.25em;
13 |
14 | li {
15 | padding-left: 0.25em;
16 | }
17 | }
18 |
19 | ul {
20 | list-style: disc;
21 | margin: 0 0 _size(element-margin) 0;
22 | padding-left: 1em;
23 |
24 | li {
25 | padding-left: 0.5em;
26 | }
27 |
28 | &.alt {
29 | list-style: none;
30 | padding-left: 0;
31 |
32 | li {
33 | border-top: solid _size(border-width) _palette(border);
34 | padding: 0.5em 0;
35 |
36 | &:first-child {
37 | border-top: 0;
38 | padding-top: 0;
39 | }
40 | }
41 | }
42 |
43 | &.icons {
44 | cursor: default;
45 | list-style: none;
46 | padding-left: 0;
47 |
48 | li {
49 | display: inline-block;
50 | padding: 0 0.75em 0 0;
51 |
52 | &:last-child {
53 | padding-right: 0;
54 | }
55 |
56 | a {
57 | border-radius: 100%;
58 | box-shadow: inset 0 0 0 _size(border-width) _palette(border);
59 | display: inline-block;
60 | height: 2.25rem;
61 | line-height: 2.25rem;
62 | text-align: center;
63 | width: 2.25rem;
64 |
65 | &:hover {
66 | background-color: _palette(border-bg);
67 | }
68 |
69 | &:active {
70 | background-color: _palette(border-bg-alt);
71 | }
72 | }
73 | }
74 | }
75 |
76 | &.actions {
77 | cursor: default;
78 | list-style: none;
79 | padding-left: 0;
80 |
81 | li {
82 | display: inline-block;
83 | padding: 0 (_size(element-margin) * 0.5) 0 0;
84 | vertical-align: middle;
85 |
86 | &:last-child {
87 | padding-right: 0;
88 | }
89 | }
90 |
91 | &.small {
92 | li {
93 | padding: 0 (_size(element-margin) * 0.25) 0 0;
94 | }
95 | }
96 |
97 | &.vertical {
98 | li {
99 | display: block;
100 | padding: (_size(element-margin) * 0.5) 0 0 0;
101 |
102 | &:first-child {
103 | padding-top: 0;
104 | }
105 |
106 | > * {
107 | margin-bottom: 0;
108 | }
109 | }
110 |
111 | &.small {
112 | li {
113 | padding: (_size(element-margin) * 0.25) 0 0 0;
114 |
115 | &:first-child {
116 | padding-top: 0;
117 | }
118 | }
119 | }
120 | }
121 |
122 | &.fit {
123 | display: table;
124 | margin-left: (_size(element-margin) * -0.5);
125 | padding: 0;
126 | table-layout: fixed;
127 | width: calc(100% + #{(_size(element-margin) * 0.5)});
128 |
129 | li {
130 | display: table-cell;
131 | padding: 0 0 0 (_size(element-margin) * 0.5);
132 |
133 | > * {
134 | margin-bottom: 0;
135 | }
136 | }
137 |
138 | &.small {
139 | margin-left: (_size(element-margin) * -0.25);
140 | width: calc(100% + #{(_size(element-margin) * 0.25)});
141 |
142 | li {
143 | padding: 0 0 0 (_size(element-margin) * 0.25);
144 | }
145 | }
146 | }
147 |
148 | @include breakpoint(xsmall) {
149 | margin: 0 0 _size(element-margin) 0;
150 |
151 | li {
152 | padding: (_size(element-margin) * 0.5) 0 0 0;
153 | display: block;
154 | text-align: center;
155 | width: 100%;
156 |
157 | &:first-child {
158 | padding-top: 0;
159 | }
160 |
161 | > * {
162 | width: 100%;
163 | margin: 0 !important;
164 |
165 | &.icon {
166 | &:before {
167 | margin-left: -2em;
168 | }
169 | }
170 | }
171 | }
172 |
173 | &.small {
174 | li {
175 | padding: (_size(element-margin) * 0.25) 0 0 0;
176 |
177 | &:first-child {
178 | padding-top: 0;
179 | }
180 | }
181 | }
182 | }
183 | }
184 | }
185 |
186 | dl {
187 | margin: 0 0 _size(element-margin) 0;
188 |
189 | dt {
190 | display: block;
191 | font-weight: _font(weight-bold);
192 | margin: 0 0 (_size(element-margin) * 0.5) 0;
193 | }
194 |
195 | dd {
196 | margin-left: _size(element-margin);
197 | }
198 | }
--------------------------------------------------------------------------------
/styles/components/_table.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Table */
8 |
9 | .table-wrapper {
10 | -webkit-overflow-scrolling: touch;
11 | overflow-x: auto;
12 | }
13 |
14 | table {
15 | margin: 0 0 _size(element-margin) 0;
16 | width: 100%;
17 |
18 | tbody {
19 | tr {
20 | border: solid _size(border-width) _palette(border);
21 | border-left: 0;
22 | border-right: 0;
23 |
24 | &:nth-child(2n + 1) {
25 | background-color: _palette(border-bg);
26 | }
27 | }
28 | }
29 |
30 | td {
31 | padding: 0.75em 0.75em;
32 | }
33 |
34 | th {
35 | color: _palette(fg-bold);
36 | font-size: 0.9em;
37 | font-weight: _font(weight-bold);
38 | padding: 0 0.75em 0.75em 0.75em;
39 | text-align: left;
40 | }
41 |
42 | thead {
43 | border-bottom: solid (_size(border-width) * 2) _palette(border);
44 | }
45 |
46 | tfoot {
47 | border-top: solid (_size(border-width) * 2) _palette(border);
48 | }
49 |
50 | &.alt {
51 | border-collapse: separate;
52 |
53 | tbody {
54 | tr {
55 | td {
56 | border: solid _size(border-width) _palette(border);
57 | border-left-width: 0;
58 | border-top-width: 0;
59 |
60 | &:first-child {
61 | border-left-width: _size(border-width);
62 | }
63 | }
64 |
65 | &:first-child {
66 | td {
67 | border-top-width: _size(border-width);
68 | }
69 | }
70 | }
71 | }
72 |
73 | thead {
74 | border-bottom: 0;
75 | }
76 |
77 | tfoot {
78 | border-top: 0;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/styles/error.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | }
--------------------------------------------------------------------------------
/styles/horizontalLineText.module.scss:
--------------------------------------------------------------------------------
1 | @import './libs/vars';
2 | @import './libs/functions';
3 | // @import 'libs/mixins';
4 | @import 'libs/skel';
5 |
6 | .separator{
7 | display:flex;
8 | align-items: center;
9 | }
10 |
11 | .separator .line {
12 | height: 3px;
13 | flex: 1;
14 | margin: 0 1rem;
15 | background-color: _palette(fg-light);
16 | }
17 |
18 | .text {
19 | padding: 0 1rem;
20 | margin-bottom: 0 !important;
21 | }
22 |
--------------------------------------------------------------------------------
/styles/ie9.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/skel';
5 |
6 | /*
7 | Dimension by HTML5 UP
8 | html5up.net | @ajlkn
9 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
10 | */
11 |
12 | /* BG */
13 |
14 | #bg {
15 | &:before {
16 | background: _palette(bg-overlay);
17 | }
18 | }
19 |
20 | /* Header */
21 |
22 | #header {
23 | .logo {
24 | margin: 0 auto;
25 | }
26 |
27 | .content {
28 | display: inline-block;
29 | }
30 |
31 | nav {
32 | ul {
33 | display: inline-block;
34 |
35 | li {
36 | display: inline-block;
37 | }
38 | }
39 | }
40 | }
41 |
42 | /* Main */
43 |
44 | #main {
45 | article {
46 | margin: 0 auto;
47 | }
48 | }
--------------------------------------------------------------------------------
/styles/layout/_bg.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* BG */
8 |
9 | #bg {
10 | @include vendor('transform', 'scale(1.0)');
11 | -webkit-backface-visibility: hidden;
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | width: 100%;
16 | height: 100vh;
17 | z-index: 1;
18 |
19 | &:before, &:after {
20 | content: '';
21 | display: block;
22 | position: absolute;
23 | top: 0;
24 | left: 0;
25 | width: 100%;
26 | height: 100%;
27 | }
28 |
29 | &:before {
30 | @include vendor('transition', 'background-color #{_duration(bg)} ease-in-out');
31 | @include vendor('transition-delay', '#{_duration(intro)}');
32 | background-image: linear-gradient(to top, #{_palette(bg-overlay)}, #{_palette(bg-overlay)}),
33 | url('/images/overlay.png');
34 | background-size: auto,
35 | 256px 256px;
36 | background-position: center,
37 | center;
38 | background-repeat: no-repeat,
39 | repeat;
40 | z-index: 2;
41 | }
42 |
43 | &:after {
44 | @include vendor('transform', 'scale(1.125)');
45 | @include vendor('transition', (
46 | 'transform #{_duration(article)} ease-in-out',
47 | 'filter #{_duration(article)} ease-in-out'
48 | ));
49 | background-position: center;
50 | background-size: cover;
51 | background-repeat: no-repeat;
52 | z-index: 1;
53 | }
54 |
55 | .body.is-article-visible & {
56 | &:after {
57 | @include vendor('transform', 'scale(1.0825)');
58 | @include vendor('filter', 'blur(0.2rem)');
59 | }
60 | }
61 |
62 | .body.is-loading & {
63 | &:before {
64 | background-color: _palette(bg-alt);
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/styles/layout/_footer.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Footer */
8 |
9 | #footer {
10 | @include vendor('transition', (
11 | 'transform #{_duration(article)} ease-in-out',
12 | 'filter #{_duration(article)} ease-in-out',
13 | 'opacity #{_duration(article)} ease-in-out',
14 | ));
15 | width: 100%;
16 | max-width: 100%;
17 | margin-top: 2rem;
18 | text-align: center;
19 |
20 | .copyright {
21 | letter-spacing: _font(letter-spacing);
22 | font-size: 0.6rem;
23 | opacity: 0.75;
24 | margin-bottom: 0;
25 | text-transform: uppercase;
26 | }
27 |
28 | .body.is-article-visible & {
29 | @include vendor('transform', 'scale(0.95)');
30 | @include vendor('filter', 'blur(0.1rem)');
31 | opacity: 0;
32 | }
33 |
34 | .body.is-loading & {
35 | opacity: 0;
36 | }
37 | }
--------------------------------------------------------------------------------
/styles/layout/_header.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Header */
8 |
9 | #header {
10 | @include vendor('display', 'flex');
11 | @include vendor('flex-direction', 'column');
12 | @include vendor('align-items', 'center');
13 | @include vendor('transition', (
14 | 'transform #{_duration(article)} ease-in-out',
15 | 'filter #{_duration(article)} ease-in-out',
16 | 'opacity #{_duration(article)} ease-in-out',
17 | ));
18 | background-image: -moz-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%);
19 | background-image: -webkit-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%);
20 | background-image: -ms-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%);
21 | background-image: radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%);
22 | max-width: 100%;
23 | text-align: center;
24 |
25 | > * {
26 | @include vendor('transition', 'opacity #{_duration(article)} ease-in-out');
27 | position: relative;
28 | margin-top: 3.5rem;
29 |
30 | &:before {
31 | content: '';
32 | display: block;
33 | position: absolute;
34 | top: calc(-3.5rem - 1px);
35 | left: calc(50% - #{_size(border-width) * 1});
36 | width: _size(border-width);
37 | height: calc(3.5rem + 1px);
38 | background: _palette(border);
39 | }
40 | }
41 |
42 | > :first-child {
43 | margin-top: 0;
44 |
45 | &:before {
46 | display: none;
47 | }
48 | }
49 |
50 | .logo {
51 | width: 5.5rem;
52 | height: 5.5rem;
53 | line-height: 5.5rem;
54 |
55 | .icon {
56 | &:before {
57 | font-size: 2rem;
58 | }
59 | }
60 | }
61 |
62 | .content {
63 | border-style: solid;
64 | border-color: _palette(border);
65 | border-top-width: _size(border-width);
66 | border-bottom-width: _size(border-width);
67 | max-width: 100%;
68 |
69 | .inner {
70 | @include vendor('transition', (
71 | 'max-height #{_duration(intro)} ease',
72 | 'padding #{_duration(intro)} ease',
73 | 'opacity #{_duration(article)} ease-in-out'
74 | ));
75 | @include vendor('transition-delay', '0.25s');
76 | padding: 3rem 2rem;
77 | max-height: 40rem;
78 | overflow: hidden;
79 |
80 | > :last-child {
81 | margin-bottom: 0;
82 | }
83 | }
84 |
85 | p {
86 | text-transform: uppercase;
87 | letter-spacing: _font(letter-spacing);
88 | font-size: 0.8rem;
89 | line-height: 2;
90 | }
91 | }
92 |
93 | nav {
94 | ul {
95 | @include vendor('display', 'flex');
96 | margin-bottom: 0;
97 | list-style: none;
98 | padding-left: 0;
99 | border: solid _size(border-width) _palette(border);
100 | border-radius: _size(border-radius);
101 |
102 | li {
103 | padding-left: 0;
104 | border-left: solid _size(border-width) _palette(border);
105 |
106 | &:first-child {
107 | border-left: 0;
108 | }
109 |
110 | a {
111 | display: block;
112 | min-width: 7.5rem;
113 | height: 2.75rem;
114 | line-height: 2.75rem;
115 | padding: 0 1.25rem 0 (1.25rem + _font(letter-spacing));
116 | text-transform: uppercase;
117 | letter-spacing: _font(letter-spacing);
118 | font-size: 0.8rem;
119 | border-bottom: 0;
120 |
121 | &:hover {
122 | background-color: _palette(border-bg);
123 | }
124 |
125 | &:active {
126 | background-color: _palette(border-bg-alt);
127 | }
128 | }
129 | }
130 | }
131 |
132 | &.use-middle {
133 | &:after {
134 | content: '';
135 | display: block;
136 | position: absolute;
137 | top: 0;
138 | left: calc(50% - #{_size(border-width) * 1});
139 | width: _size(border-width);
140 | height: 100%;
141 | background: _palette(border);
142 | }
143 |
144 | ul {
145 | li {
146 | &.is-middle {
147 | border-left: 0;
148 | }
149 | }
150 | }
151 | }
152 | }
153 |
154 | .body.is-article-visible & {
155 | @include vendor('transform', 'scale(0.95)');
156 | @include vendor('filter', 'blur(0.1rem)');
157 | opacity: 0;
158 | }
159 |
160 | .body.is-loading & {
161 | > * {
162 | opacity: 0;
163 | }
164 |
165 | @include vendor('filter', 'blur(0.125rem)');
166 |
167 | .content {
168 | .inner {
169 | max-height: 0;
170 | padding-top: 0;
171 | padding-bottom: 0;
172 | opacity: 0;
173 | }
174 | }
175 | }
176 |
177 | @include breakpoint(medium) {
178 | .content {
179 | p {
180 | br {
181 | display: none;
182 | }
183 | }
184 | }
185 | }
186 |
187 | @include breakpoint(small) {
188 | > * {
189 | margin-top: 2rem;
190 |
191 | &:before {
192 | top: calc(-2rem - 1px);
193 | height: calc(2rem + 1px);
194 | }
195 | }
196 |
197 | .logo {
198 | width: 4.75rem;
199 | height: 4.75rem;
200 | line-height: 4.75rem;
201 |
202 | .icon {
203 | &:before {
204 | font-size: 1.75rem;
205 | }
206 | }
207 | }
208 |
209 | .content {
210 | .inner {
211 | padding: 2.5rem 1rem;
212 | }
213 |
214 | p {
215 | line-height: 1.875;
216 | }
217 | }
218 | }
219 |
220 | @include breakpoint(xsmall) {
221 | padding: 1.5rem 0;
222 |
223 | .content {
224 | .inner {
225 | padding: 2.5rem 0;
226 | }
227 | }
228 |
229 | nav {
230 | ul {
231 | @include vendor('flex-direction', 'column');
232 | min-width: 10rem;
233 | max-width: 100%;
234 |
235 | li {
236 | border-left: 0;
237 | border-top: solid _size(border-width) _palette(border);
238 |
239 | &:first-child {
240 | border-top: 0;
241 | }
242 |
243 | a {
244 | height: 3rem;
245 | line-height: 3rem;
246 | min-width: 0;
247 | width: 100%;
248 | }
249 | }
250 | }
251 |
252 | &.use-middle {
253 | &:after {
254 | display: none;
255 | }
256 | }
257 | }
258 | }
259 | }
--------------------------------------------------------------------------------
/styles/layout/_main.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Main */
8 |
9 | #main {
10 | @include vendor('flex-grow', '1');
11 | @include vendor('flex-shrink', '1');
12 | @include vendor('display', 'flex');
13 | @include vendor('align-items', 'center');
14 | @include vendor('justify-content', 'center');
15 | @include vendor('flex-direction', 'column');
16 | position: relative;
17 | max-width: 100%;
18 | z-index: 3;
19 | display: none;
20 |
21 | article {
22 | @include vendor('transform', 'translateY(0.25rem)');
23 | @include vendor('transition', (
24 | 'opacity #{_duration(article)} ease-in-out',
25 | 'transform #{_duration(article)} ease-in-out'
26 | ));
27 | @include padding(2.5rem, 2.5rem, (2rem, 0, 1rem, 0));
28 | position: relative;
29 | width: 40rem;
30 | max-width: 100%;
31 | background-color: transparentize(_palette(bg), 0.15);
32 | border-radius: _size(border-radius);
33 | opacity: 0;
34 |
35 | &.timeout {
36 | display: none;
37 | }
38 |
39 | &.active.timeout {
40 | @include vendor('transform', 'translateY(0)');
41 | opacity: 1;
42 | }
43 |
44 | &.active {
45 | display: block !important;
46 | }
47 |
48 | .close {
49 | display: block;
50 | position: absolute;
51 | top: 0;
52 | right: 0;
53 | width: 4rem;
54 | height: 4rem;
55 | cursor: pointer;
56 | text-indent: 4rem;
57 | overflow: hidden;
58 | white-space: nowrap;
59 |
60 | &:before {
61 | @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out');
62 | content: '';
63 | display: block;
64 | position: absolute;
65 | top: 0.75rem;
66 | left: 0.75rem;
67 | width: 2.5rem;
68 | height: 2.5rem;
69 | border-radius: 100%;
70 | background-position: center;
71 | background-image: svg-url('
');
72 | background-size: 20px 20px;
73 | background-repeat: no-repeat;
74 | }
75 |
76 | &:hover {
77 | &:before {
78 | background-color: _palette(border-bg);
79 | }
80 | }
81 |
82 | &:active {
83 | &:before {
84 | background-color: _palette(border-bg-alt);
85 | }
86 | }
87 | }
88 |
89 | .copy-button {
90 | display: block;
91 | position: absolute;
92 | top: 0;
93 | right: 5rem;
94 | width: 4rem;
95 | height: 4rem;
96 | cursor: pointer;
97 | text-indent: 4rem;
98 | overflow: hidden;
99 | white-space: nowrap;
100 |
101 | &:before {
102 | @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out');
103 | content: '';
104 | display: block;
105 | position: absolute;
106 | top: 0.75rem;
107 | left: 0.75rem;
108 | width: 2.5rem;
109 | height: 2.5rem;
110 | border-radius: 100%;
111 | background-position: center;
112 | background-image: url('/images/copy.png');
113 | background-size: 20px 20px;
114 | background-repeat: no-repeat;
115 | }
116 |
117 | &:hover {
118 | &:before {
119 | background-color: _palette(border-bg);
120 | }
121 | }
122 |
123 | &:active {
124 | &:before {
125 | background-color: _palette(border-bg-alt);
126 | }
127 | }
128 | }
129 |
130 | }
131 |
132 | @include breakpoint(small) {
133 | article {
134 | @include padding(2rem, 2rem, (1.5rem, 0, 0.5rem, 0));
135 | .close {
136 | &:before {
137 | top: 0.875rem;
138 | left: 0.875rem;
139 | width: 2.25rem;
140 | height: 2.25rem;
141 | background-size: 14px 14px;
142 | }
143 | }
144 |
145 | .copy-button {
146 | &:before {
147 | top: 0.875rem;
148 | left: 0.875rem;
149 | width: 2.25rem;
150 | height: 2.25rem;
151 | background-size: 14px 14px;
152 | }
153 | }
154 | }
155 | }
156 |
157 | @include breakpoint(xsmall) {
158 | article {
159 | @include padding(2rem, 1.5rem, (1rem, 0, 0.5rem, 0));
160 | }
161 | }
162 | }
--------------------------------------------------------------------------------
/styles/layout/_wrapper.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Dimension by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Wrapper */
8 |
9 | #wrapper {
10 | @include vendor('display', 'flex');
11 | @include vendor('flex-direction', 'column');
12 | @include vendor('align-items', 'center');
13 | @include vendor('justify-content', 'space-between');
14 | position: relative;
15 | min-height: 100vh;
16 | width: 100%;
17 | padding: 4rem 2rem;
18 | z-index: 3;
19 |
20 | &:before {
21 | content: '';
22 | display: block;
23 | }
24 |
25 | @include breakpoint(xlarge) {
26 | padding: 3rem 2rem;
27 | }
28 |
29 | @include breakpoint(small) {
30 | padding: 2rem 1rem;
31 | }
32 |
33 | @include breakpoint(xsmall) {
34 | padding: 1rem;
35 | }
36 |
37 | &.page {
38 | @include vendor('justify-content', 'flex-start');
39 | }
40 | }
--------------------------------------------------------------------------------
/styles/libs/_functions.scss:
--------------------------------------------------------------------------------
1 | /// Gets a duration value.
2 | /// @param {string} $keys Key(s).
3 | /// @return {string} Value.
4 | @function _duration($keys...) {
5 | @return val($duration, $keys...);
6 | }
7 |
8 | /// Gets a font value.
9 | /// @param {string} $keys Key(s).
10 | /// @return {string} Value.
11 | @function _font($keys...) {
12 | @return val($font, $keys...);
13 | }
14 |
15 | /// Gets a misc value.
16 | /// @param {string} $keys Key(s).
17 | /// @return {string} Value.
18 | @function _misc($keys...) {
19 | @return val($misc, $keys...);
20 | }
21 |
22 | /// Gets a palette value.
23 | /// @param {string} $keys Key(s).
24 | /// @return {string} Value.
25 | @function _palette($keys...) {
26 | @return val($palette, $keys...);
27 | }
28 |
29 | /// Gets a size value.
30 | /// @param {string} $keys Key(s).
31 | /// @return {string} Value.
32 | @function _size($keys...) {
33 | @return val($size, $keys...);
34 | }
--------------------------------------------------------------------------------
/styles/libs/_mixins.scss:
--------------------------------------------------------------------------------
1 | /// Makes an element's :before pseudoelement a FontAwesome icon.
2 | /// @param {string} $content Optional content value to use.
3 | /// @param {string} $where Optional pseudoelement to target (before or after).
4 | @mixin icon($content: false, $where: before) {
5 |
6 | text-decoration: none;
7 |
8 | &:#{$where} {
9 |
10 | @if $content {
11 | content: $content;
12 | }
13 |
14 | -moz-osx-font-smoothing: grayscale;
15 | -webkit-font-smoothing: antialiased;
16 | font-family: FontAwesome;
17 | font-style: normal;
18 | font-weight: normal;
19 | text-transform: none !important;
20 |
21 | }
22 |
23 | }
24 |
25 | /// Applies padding to an element, taking the current element-margin value into account.
26 | /// @param {mixed} $tb Top/bottom padding.
27 | /// @param {mixed} $lr Left/right padding.
28 | /// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left)
29 | /// @param {bool} $important If true, adds !important.
30 | @mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) {
31 |
32 | @if $important {
33 | $important: '!important';
34 | }
35 |
36 | $x: 0.1em;
37 |
38 | @if unit(_size(element-margin)) == 'rem' {
39 | $x: 0.1rem;
40 | }
41 |
42 | padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important};
43 |
44 | }
45 |
46 | /// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp).
47 | /// @param {string} $svg SVG data URL.
48 | /// @return {string} Encoded SVG data URL.
49 | @function svg-url($svg) {
50 |
51 | $svg: str-replace($svg, '"', '\'');
52 | $svg: str-replace($svg, '%', '%25');
53 | $svg: str-replace($svg, '<', '%3C');
54 | $svg: str-replace($svg, '>', '%3E');
55 | $svg: str-replace($svg, '&', '%26');
56 | $svg: str-replace($svg, '#', '%23');
57 | $svg: str-replace($svg, '{', '%7B');
58 | $svg: str-replace($svg, '}', '%7D');
59 | $svg: str-replace($svg, ';', '%3B');
60 |
61 | @return url("data:image/svg+xml;charset=utf8,#{$svg}");
62 |
63 | }
64 |
65 | /// Initializes base flexgrid classes.
66 | /// @param {string} $vertical-align Vertical alignment of cells.
67 | /// @param {string} $horizontal-align Horizontal alignment of cells.
68 | @mixin flexgrid-base($vertical-align: null, $horizontal-align: null) {
69 |
70 | // Grid.
71 | @include vendor('display', 'flex');
72 | @include vendor('flex-wrap', 'wrap');
73 |
74 | // Vertical alignment.
75 | @if ($vertical-align == top) {
76 | @include vendor('align-items', 'flex-start');
77 | }
78 | @else if ($vertical-align == bottom) {
79 | @include vendor('align-items', 'flex-end');
80 | }
81 | @else if ($vertical-align == center) {
82 | @include vendor('align-items', 'center');
83 | }
84 | @else {
85 | @include vendor('align-items', 'stretch');
86 | }
87 |
88 | // Horizontal alignment.
89 | @if ($horizontal-align != null) {
90 | text-align: $horizontal-align;
91 | }
92 |
93 | // Cells.
94 | > * {
95 | @include vendor('flex-shrink', '1');
96 | @include vendor('flex-grow', '0');
97 | }
98 |
99 | }
100 |
101 | /// Sets up flexgrid columns.
102 | /// @param {integer} $columns Columns.
103 | @mixin flexgrid-columns($columns) {
104 |
105 | > * {
106 | $cell-width: 100% / $columns;
107 | width: #{$cell-width};
108 | }
109 |
110 | }
111 |
112 | /// Sets up flexgrid gutters.
113 | /// @param {integer} $columns Columns.
114 | /// @param {number} $gutters Gutters.
115 | @mixin flexgrid-gutters($columns, $gutters) {
116 |
117 | // Apply padding.
118 | > * {
119 | $cell-width: 100% / $columns;
120 |
121 | padding: ($gutters * 0.5);
122 | width: $cell-width;
123 | }
124 |
125 | }
126 |
127 | /// Sets up flexgrid gutters (flush).
128 | /// @param {integer} $columns Columns.
129 | /// @param {number} $gutters Gutters.
130 | @mixin flexgrid-gutters-flush($columns, $gutters) {
131 |
132 | // Apply padding.
133 | > * {
134 | $cell-width: 100% / $columns;
135 | $cell-width-pad: $gutters / $columns;
136 |
137 | padding: ($gutters * 0.5);
138 | width: calc(#{$cell-width} + #{$cell-width-pad});
139 | }
140 |
141 | // Clear top/bottom gutters.
142 | > :nth-child(-n + #{$columns}) {
143 | padding-top: 0;
144 | }
145 |
146 | > :nth-last-child(-n + #{$columns}) {
147 | padding-bottom: 0;
148 | }
149 |
150 | // Clear left/right gutters.
151 | > :nth-child(#{$columns}n + 1) {
152 | padding-left: 0;
153 | }
154 |
155 | > :nth-child(#{$columns}n) {
156 | padding-right: 0;
157 | }
158 |
159 | // Adjust widths of leftmost and rightmost cells.
160 | > :nth-child(#{$columns}n + 1),
161 | > :nth-child(#{$columns}n) {
162 | $cell-width: 100% / $columns;
163 | $cell-width-pad: ($gutters / $columns) - ($gutters / 2);
164 |
165 | width: calc(#{$cell-width} + #{$cell-width-pad});
166 | }
167 |
168 | }
169 |
170 | /// Reset flexgrid gutters (flush only).
171 | /// Used to override a previous set of flexgrid gutter classes.
172 | /// @param {integer} $columns Columns.
173 | /// @param {number} $gutters Gutters.
174 | /// @param {integer} $prev-columns Previous columns.
175 | @mixin flexgrid-gutters-flush-reset($columns, $gutters, $prev-columns) {
176 |
177 | // Apply padding.
178 | > * {
179 | $cell-width: 100% / $prev-columns;
180 | $cell-width-pad: $gutters / $prev-columns;
181 |
182 | padding: ($gutters * 0.5);
183 | width: calc(#{$cell-width} + #{$cell-width-pad});
184 | }
185 |
186 | // Clear top/bottom gutters.
187 | > :nth-child(-n + #{$prev-columns}) {
188 | padding-top: ($gutters * 0.5);
189 | }
190 |
191 | > :nth-last-child(-n + #{$prev-columns}) {
192 | padding-bottom: ($gutters * 0.5);
193 | }
194 |
195 | // Clear left/right gutters.
196 | > :nth-child(#{$prev-columns}n + 1) {
197 | padding-left: ($gutters * 0.5);
198 | }
199 |
200 | > :nth-child(#{$prev-columns}n) {
201 | padding-right: ($gutters * 0.5);
202 | }
203 |
204 | // Adjust widths of leftmost and rightmost cells.
205 | > :nth-child(#{$prev-columns}n + 1),
206 | > :nth-child(#{$prev-columns}n) {
207 | $cell-width: 100% / $columns;
208 | $cell-width-pad: $gutters / $columns;
209 |
210 | padding: ($gutters * 0.5);
211 | width: calc(#{$cell-width} + #{$cell-width-pad});
212 | }
213 |
214 | }
215 |
216 | /// Adds debug styles to current flexgrid element.
217 | @mixin flexgrid-debug() {
218 |
219 | box-shadow: 0 0 0 1px red;
220 |
221 | > * {
222 | box-shadow: inset 0 0 0 1px blue;
223 | position: relative;
224 |
225 | > * {
226 | position: relative;
227 | box-shadow: inset 0 0 0 1px green;
228 | }
229 | }
230 |
231 | }
232 |
233 | /// Initializes the current element as a flexgrid.
234 | /// @param {integer} $columns Columns (optional).
235 | /// @param {number} $gutters Gutters (optional).
236 | /// @param {bool} $flush If true, clears padding around the very edge of the grid.
237 | @mixin flexgrid($settings: ()) {
238 |
239 | // Settings.
240 |
241 | // Debug.
242 | $debug: false;
243 |
244 | @if (map-has-key($settings, 'debug')) {
245 | $debug: map-get($settings, 'debug');
246 | }
247 |
248 | // Vertical align.
249 | $vertical-align: null;
250 |
251 | @if (map-has-key($settings, 'vertical-align')) {
252 | $vertical-align: map-get($settings, 'vertical-align');
253 | }
254 |
255 | // Horizontal align.
256 | $horizontal-align: null;
257 |
258 | @if (map-has-key($settings, 'horizontal-align')) {
259 | $horizontal-align: map-get($settings, 'horizontal-align');
260 | }
261 |
262 | // Columns.
263 | $columns: null;
264 |
265 | @if (map-has-key($settings, 'columns')) {
266 | $columns: map-get($settings, 'columns');
267 | }
268 |
269 | // Gutters.
270 | $gutters: 0;
271 |
272 | @if (map-has-key($settings, 'gutters')) {
273 | $gutters: map-get($settings, 'gutters');
274 | }
275 |
276 | // Flush.
277 | $flush: true;
278 |
279 | @if (map-has-key($settings, 'flush')) {
280 | $flush: map-get($settings, 'flush');
281 | }
282 |
283 | // Initialize base grid.
284 | @include flexgrid-base($vertical-align, $horizontal-align);
285 |
286 | // Debug?
287 | @if ($debug) {
288 | @include flexgrid-debug;
289 | }
290 |
291 | // Columns specified?
292 | @if ($columns != null) {
293 |
294 | // Initialize columns.
295 | @include flexgrid-columns($columns);
296 |
297 | // Gutters specified?
298 | @if ($gutters > 0) {
299 |
300 | // Flush gutters?
301 | @if ($flush) {
302 |
303 | // Initialize gutters (flush).
304 | @include flexgrid-gutters-flush($columns, $gutters);
305 |
306 | }
307 |
308 | // Otherwise ...
309 | @else {
310 |
311 | // Initialize gutters.
312 | @include flexgrid-gutters($columns, $gutters);
313 |
314 | }
315 |
316 | }
317 |
318 | }
319 |
320 | }
321 |
322 | /// Resizes a previously-initialized grid.
323 | /// @param {integer} $columns Columns.
324 | /// @param {number} $gutters Gutters (optional).
325 | /// @param {list} $reset A list of previously-initialized grid columns (only if $flush is true).
326 | /// @param {bool} $flush If true, clears padding around the very edge of the grid.
327 | @mixin flexgrid-resize($settings: ()) {
328 |
329 | // Settings.
330 |
331 | // Columns.
332 | $columns: 1;
333 |
334 | @if (map-has-key($settings, 'columns')) {
335 | $columns: map-get($settings, 'columns');
336 | }
337 |
338 | // Gutters.
339 | $gutters: 0;
340 |
341 | @if (map-has-key($settings, 'gutters')) {
342 | $gutters: map-get($settings, 'gutters');
343 | }
344 |
345 | // Previous columns.
346 | $prev-columns: false;
347 |
348 | @if (map-has-key($settings, 'prev-columns')) {
349 | $prev-columns: map-get($settings, 'prev-columns');
350 | }
351 |
352 | // Flush.
353 | $flush: true;
354 |
355 | @if (map-has-key($settings, 'flush')) {
356 | $flush: map-get($settings, 'flush');
357 | }
358 |
359 | // Resize columns.
360 | @include flexgrid-columns($columns);
361 |
362 | // Gutters specified?
363 | @if ($gutters > 0) {
364 |
365 | // Flush gutters?
366 | @if ($flush) {
367 |
368 | // Previous columns specified?
369 | @if ($prev-columns) {
370 |
371 | // Convert to list if it isn't one already.
372 | @if (type-of($prev-columns) != list) {
373 | $prev-columns: ($prev-columns);
374 | }
375 |
376 | // Step through list of previous columns and reset them.
377 | @each $x in $prev-columns {
378 | @include flexgrid-gutters-flush-reset($columns, $gutters, $x);
379 | }
380 |
381 | }
382 |
383 | // Resize gutters (flush).
384 | @include flexgrid-gutters-flush($columns, $gutters);
385 |
386 | }
387 |
388 | // Otherwise ...
389 | @else {
390 |
391 | // Resize gutters.
392 | @include flexgrid-gutters($columns, $gutters);
393 |
394 | }
395 |
396 | }
397 |
398 | }
--------------------------------------------------------------------------------
/styles/libs/_skel.scss:
--------------------------------------------------------------------------------
1 | // skel.scss v3.0.2-dev | (c) skel.io | MIT licensed */
2 |
3 | // Vars.
4 |
5 | /// Breakpoints.
6 | /// @var {list}
7 | $breakpoints: () !global;
8 |
9 | /// Vendor prefixes.
10 | /// @var {list}
11 | $vendor-prefixes: (
12 | '-moz-',
13 | '-webkit-',
14 | '-ms-',
15 | ''
16 | );
17 |
18 | /// Properties that should be vendorized.
19 | /// @var {list}
20 | $vendor-properties: (
21 | 'align-content',
22 | 'align-items',
23 | 'align-self',
24 | 'animation',
25 | 'animation-delay',
26 | 'animation-direction',
27 | 'animation-duration',
28 | 'animation-fill-mode',
29 | 'animation-iteration-count',
30 | 'animation-name',
31 | 'animation-play-state',
32 | 'animation-timing-function',
33 | 'appearance',
34 | 'backface-visibility',
35 | 'box-sizing',
36 | 'filter',
37 | 'flex',
38 | 'flex-basis',
39 | 'flex-direction',
40 | 'flex-flow',
41 | 'flex-grow',
42 | 'flex-shrink',
43 | 'flex-wrap',
44 | 'justify-content',
45 | 'object-fit',
46 | 'object-position',
47 | 'order',
48 | 'perspective',
49 | 'pointer-events',
50 | 'transform',
51 | 'transform-origin',
52 | 'transform-style',
53 | 'transition',
54 | 'transition-delay',
55 | 'transition-duration',
56 | 'transition-property',
57 | 'transition-timing-function',
58 | 'user-select'
59 | );
60 |
61 | /// Values that should be vendorized.
62 | /// @var {list}
63 | $vendor-values: (
64 | 'filter',
65 | 'flex',
66 | 'linear-gradient',
67 | 'radial-gradient',
68 | 'transform'
69 | );
70 |
71 | // Functions.
72 |
73 | /// Removes a specific item from a list.
74 | /// @author Hugo Giraudel
75 | /// @param {list} $list List.
76 | /// @param {integer} $index Index.
77 | /// @return {list} Updated list.
78 | @function remove-nth($list, $index) {
79 |
80 | $result: null;
81 |
82 | @if type-of($index) != number {
83 | @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
84 | }
85 | @else if $index == 0 {
86 | @warn "List index 0 must be a non-zero integer for `remove-nth`.";
87 | }
88 | @else if abs($index) > length($list) {
89 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
90 | }
91 | @else {
92 |
93 | $result: ();
94 | $index: if($index < 0, length($list) + $index + 1, $index);
95 |
96 | @for $i from 1 through length($list) {
97 |
98 | @if $i != $index {
99 | $result: append($result, nth($list, $i));
100 | }
101 |
102 | }
103 |
104 | }
105 |
106 | @return $result;
107 |
108 | }
109 |
110 | /// Replaces a substring within another string.
111 | /// @author Hugo Giraudel
112 | /// @param {string} $string String.
113 | /// @param {string} $search Substring.
114 | /// @param {string} $replace Replacement.
115 | /// @return {string} Updated string.
116 | @function str-replace($string, $search, $replace: '') {
117 |
118 | $index: str-index($string, $search);
119 |
120 | @if $index {
121 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
122 | }
123 |
124 | @return $string;
125 |
126 | }
127 |
128 | /// Replaces a substring within each string in a list.
129 | /// @param {list} $strings List of strings.
130 | /// @param {string} $search Substring.
131 | /// @param {string} $replace Replacement.
132 | /// @return {list} Updated list of strings.
133 | @function str-replace-all($strings, $search, $replace: '') {
134 |
135 | @each $string in $strings {
136 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
137 | }
138 |
139 | @return $strings;
140 |
141 | }
142 |
143 | /// Gets a value from a map.
144 | /// @author Hugo Giraudel
145 | /// @param {map} $map Map.
146 | /// @param {string} $keys Key(s).
147 | /// @return {string} Value.
148 | @function val($map, $keys...) {
149 |
150 | @if nth($keys, 1) == null {
151 | $keys: remove-nth($keys, 1);
152 | }
153 |
154 | @each $key in $keys {
155 | $map: map-get($map, $key);
156 | }
157 |
158 | @return $map;
159 |
160 | }
161 |
162 | // Mixins.
163 |
164 | /// Sets the global box model.
165 | /// @param {string} $model Model (default is content).
166 | @mixin boxModel($model: 'content') {
167 |
168 | $x: $model + '-box';
169 |
170 | *, *:before, *:after {
171 | -moz-box-sizing: #{$x};
172 | -webkit-box-sizing: #{$x};
173 | box-sizing: #{$x};
174 | }
175 |
176 | }
177 |
178 | /// Wraps @content in a @media block using a given breakpoint.
179 | /// @param {string} $breakpoint Breakpoint.
180 | /// @param {map} $queries Additional queries.
181 | @mixin breakpoint($breakpoint: null, $queries: null) {
182 |
183 | $query: 'screen';
184 |
185 | // Breakpoint.
186 | @if $breakpoint and map-has-key($breakpoints, $breakpoint) {
187 | $query: $query + ' and ' + map-get($breakpoints, $breakpoint);
188 | }
189 |
190 | // Queries.
191 | @if $queries {
192 | @each $k, $v in $queries {
193 | $query: $query + ' and (' + $k + ':' + $v + ')';
194 | }
195 | }
196 |
197 | @media #{$query} {
198 | @content;
199 | }
200 |
201 | }
202 |
203 | /// Wraps @content in a @media block targeting a specific orientation.
204 | /// @param {string} $orientation Orientation.
205 | @mixin orientation($orientation) {
206 | @media screen and (orientation: #{$orientation}) {
207 | @content;
208 | }
209 | }
210 |
211 | /// Utility mixin for containers.
212 | /// @param {mixed} $width Width.
213 | @mixin containers($width) {
214 |
215 | // Locked?
216 | $lock: false;
217 |
218 | @if length($width) == 2 {
219 | $width: nth($width, 1);
220 | $lock: true;
221 | }
222 |
223 | // Modifiers.
224 | .container.\31 25\25 { width: 100%; max-width: $width * 1.25; min-width: $width; }
225 | .container.\37 5\25 { width: $width * 0.75; }
226 | .container.\35 0\25 { width: $width * 0.5; }
227 | .container.\32 5\25 { width: $width * 0.25; }
228 |
229 | // Main class.
230 | .container {
231 | @if $lock {
232 | width: $width !important;
233 | }
234 | @else {
235 | width: $width;
236 | }
237 | }
238 |
239 | }
240 |
241 | /// Utility mixin for grid.
242 | /// @param {list} $gutters Column and row gutters (default is 40px).
243 | /// @param {string} $breakpointName Optional breakpoint name.
244 | @mixin grid($gutters: 40px, $breakpointName: null) {
245 |
246 | // Gutters.
247 | @include grid-gutters($gutters);
248 | @include grid-gutters($gutters, \32 00\25, 2);
249 | @include grid-gutters($gutters, \31 50\25, 1.5);
250 | @include grid-gutters($gutters, \35 0\25, 0.5);
251 | @include grid-gutters($gutters, \32 5\25, 0.25);
252 |
253 | // Cells.
254 | $x: '';
255 |
256 | @if $breakpointName {
257 | $x: '\\28' + $breakpointName + '\\29';
258 | }
259 |
260 | .\31 2u#{$x}, .\31 2u\24#{$x} { width: 100%; clear: none; margin-left: 0; }
261 | .\31 1u#{$x}, .\31 1u\24#{$x} { width: 91.6666666667%; clear: none; margin-left: 0; }
262 | .\31 0u#{$x}, .\31 0u\24#{$x} { width: 83.3333333333%; clear: none; margin-left: 0; }
263 | .\39 u#{$x}, .\39 u\24#{$x} { width: 75%; clear: none; margin-left: 0; }
264 | .\38 u#{$x}, .\38 u\24#{$x} { width: 66.6666666667%; clear: none; margin-left: 0; }
265 | .\37 u#{$x}, .\37 u\24#{$x} { width: 58.3333333333%; clear: none; margin-left: 0; }
266 | .\36 u#{$x}, .\36 u\24#{$x} { width: 50%; clear: none; margin-left: 0; }
267 | .\35 u#{$x}, .\35 u\24#{$x} { width: 41.6666666667%; clear: none; margin-left: 0; }
268 | .\34 u#{$x}, .\34 u\24#{$x} { width: 33.3333333333%; clear: none; margin-left: 0; }
269 | .\33 u#{$x}, .\33 u\24#{$x} { width: 25%; clear: none; margin-left: 0; }
270 | .\32 u#{$x}, .\32 u\24#{$x} { width: 16.6666666667%; clear: none; margin-left: 0; }
271 | .\31 u#{$x}, .\31 u\24#{$x} { width: 8.3333333333%; clear: none; margin-left: 0; }
272 |
273 | .\31 2u\24#{$x} + *,
274 | .\31 1u\24#{$x} + *,
275 | .\31 0u\24#{$x} + *,
276 | .\39 u\24#{$x} + *,
277 | .\38 u\24#{$x} + *,
278 | .\37 u\24#{$x} + *,
279 | .\36 u\24#{$x} + *,
280 | .\35 u\24#{$x} + *,
281 | .\34 u\24#{$x} + *,
282 | .\33 u\24#{$x} + *,
283 | .\32 u\24#{$x} + *,
284 | .\31 u\24#{$x} + * {
285 | clear: left;
286 | }
287 |
288 | .\-11u#{$x} { margin-left: 91.6666666667% }
289 | .\-10u#{$x} { margin-left: 83.3333333333% }
290 | .\-9u#{$x} { margin-left: 75% }
291 | .\-8u#{$x} { margin-left: 66.6666666667% }
292 | .\-7u#{$x} { margin-left: 58.3333333333% }
293 | .\-6u#{$x} { margin-left: 50% }
294 | .\-5u#{$x} { margin-left: 41.6666666667% }
295 | .\-4u#{$x} { margin-left: 33.3333333333% }
296 | .\-3u#{$x} { margin-left: 25% }
297 | .\-2u#{$x} { margin-left: 16.6666666667% }
298 | .\-1u#{$x} { margin-left: 8.3333333333% }
299 |
300 | }
301 |
302 | /// Utility mixin for grid.
303 | /// @param {list} $gutters Gutters.
304 | /// @param {string} $class Optional class name.
305 | /// @param {integer} $multiplier Multiplier (default is 1).
306 | @mixin grid-gutters($gutters, $class: null, $multiplier: 1) {
307 |
308 | // Expand gutters if it's not a list.
309 | @if length($gutters) == 1 {
310 | $gutters: ($gutters, 0);
311 | }
312 |
313 | // Get column and row gutter values.
314 | $c: nth($gutters, 1);
315 | $r: nth($gutters, 2);
316 |
317 | // Get class (if provided).
318 | $x: '';
319 |
320 | @if $class {
321 | $x: '.' + $class;
322 | }
323 |
324 | // Default.
325 | .row#{$x} > * { padding: ($r * $multiplier) 0 0 ($c * $multiplier); }
326 | .row#{$x} { margin: ($r * $multiplier * -1) 0 -1px ($c * $multiplier * -1); }
327 |
328 | // Uniform.
329 | .row.uniform#{$x} > * { padding: ($c * $multiplier) 0 0 ($c * $multiplier); }
330 | .row.uniform#{$x} { margin: ($c * $multiplier * -1) 0 -1px ($c * $multiplier * -1); }
331 |
332 | }
333 |
334 | /// Wraps @content in vendorized keyframe blocks.
335 | /// @param {string} $name Name.
336 | @mixin keyframes($name) {
337 |
338 | @-moz-keyframes #{$name} { @content; }
339 | @-webkit-keyframes #{$name} { @content; }
340 | @-ms-keyframes #{$name} { @content; }
341 | @keyframes #{$name} { @content; }
342 |
343 | }
344 |
345 | ///
346 | /// Sets breakpoints.
347 | /// @param {map} $x Breakpoints.
348 | ///
349 | @mixin skel-breakpoints($x: ()) {
350 | $breakpoints: $x !global;
351 | }
352 |
353 | ///
354 | /// Initializes layout module.
355 | /// @param {map} config Config.
356 | ///
357 | @mixin skel-layout($config: ()) {
358 |
359 | // Config.
360 | $configPerBreakpoint: ();
361 |
362 | $z: map-get($config, 'breakpoints');
363 |
364 | @if $z {
365 | $configPerBreakpoint: $z;
366 | }
367 |
368 | // Reset.
369 | $x: map-get($config, 'reset');
370 |
371 | @if $x {
372 |
373 | /* Reset */
374 |
375 | @include reset($x);
376 |
377 | }
378 |
379 | // Box model.
380 | $x: map-get($config, 'boxModel');
381 |
382 | @if $x {
383 |
384 | /* Box Model */
385 |
386 | @include boxModel($x);
387 |
388 | }
389 |
390 | // Containers.
391 | $containers: map-get($config, 'containers');
392 |
393 | @if $containers {
394 |
395 | /* Containers */
396 |
397 | .container {
398 | margin-left: auto;
399 | margin-right: auto;
400 | }
401 |
402 | // Use default is $containers is just "true".
403 | @if $containers == true {
404 | $containers: 960px;
405 | }
406 |
407 | // Apply base.
408 | @include containers($containers);
409 |
410 | // Apply per-breakpoint.
411 | @each $name in map-keys($breakpoints) {
412 |
413 | // Get/use breakpoint setting if it exists.
414 | $x: map-get($configPerBreakpoint, $name);
415 |
416 | // Per-breakpoint config exists?
417 | @if $x {
418 | $y: map-get($x, 'containers');
419 |
420 | // Setting exists? Use it.
421 | @if $y {
422 | $containers: $y;
423 | }
424 |
425 | }
426 |
427 | // Create @media block.
428 | @media screen and #{map-get($breakpoints, $name)} {
429 | @include containers($containers);
430 | }
431 |
432 | }
433 |
434 | }
435 |
436 | // Grid.
437 | $grid: map-get($config, 'grid');
438 |
439 | @if $grid {
440 |
441 | /* Grid */
442 |
443 | // Use defaults if $grid is just "true".
444 | @if $grid == true {
445 | $grid: ();
446 | }
447 |
448 | // Sub-setting: Gutters.
449 | $grid-gutters: 40px;
450 | $x: map-get($grid, 'gutters');
451 |
452 | @if $x {
453 | $grid-gutters: $x;
454 | }
455 |
456 | // Rows.
457 | .row {
458 | border-bottom: solid 1px transparent;
459 | -moz-box-sizing: border-box;
460 | -webkit-box-sizing: border-box;
461 | box-sizing: border-box;
462 | }
463 |
464 | .row > * {
465 | float: left;
466 | -moz-box-sizing: border-box;
467 | -webkit-box-sizing: border-box;
468 | box-sizing: border-box;
469 | }
470 |
471 | .row:after, .row:before {
472 | content: '';
473 | display: block;
474 | clear: both;
475 | height: 0;
476 | }
477 |
478 | .row.uniform > * > :first-child {
479 | margin-top: 0;
480 | }
481 |
482 | .row.uniform > * > :last-child {
483 | margin-bottom: 0;
484 | }
485 |
486 | // Gutters (0%).
487 | @include grid-gutters($grid-gutters, \30 \25, 0);
488 |
489 | // Apply base.
490 | @include grid($grid-gutters);
491 |
492 | // Apply per-breakpoint.
493 | @each $name in map-keys($breakpoints) {
494 |
495 | // Get/use breakpoint setting if it exists.
496 | $x: map-get($configPerBreakpoint, $name);
497 |
498 | // Per-breakpoint config exists?
499 | @if $x {
500 | $y: map-get($x, 'grid');
501 |
502 | // Setting exists?
503 | @if $y {
504 |
505 | // Sub-setting: Gutters.
506 | $x: map-get($y, 'gutters');
507 |
508 | @if $x {
509 | $grid-gutters: $x;
510 | }
511 |
512 | }
513 |
514 | }
515 |
516 | // Create @media block.
517 | @media screen and #{map-get($breakpoints, $name)} {
518 | @include grid($grid-gutters, $name);
519 | }
520 |
521 | }
522 |
523 | }
524 |
525 | }
526 |
527 | /// Resets browser styles.
528 | /// @param {string} $mode Mode (default is 'normalize').
529 | @mixin reset($mode: 'normalize') {
530 |
531 | @if $mode == 'normalize' {
532 |
533 | // normalize.css v3.0.2 | MIT License | git.io/normalize
534 | html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
535 |
536 | }
537 | @else if $mode == 'full' {
538 |
539 | // meyerweb.com/eric/tools/css/reset v2.0 | 20110126 | License: none (public domain)
540 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}body{line-height:1;}ol,ul{list-style:none;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}table{border-collapse:collapse;border-spacing:0;}body{-webkit-text-size-adjust:none}
541 |
542 | }
543 |
544 | }
545 |
546 | /// Vendorizes a declaration's property and/or value(s).
547 | /// @param {string} $property Property.
548 | /// @param {mixed} $value String/list of value(s).
549 | @mixin vendor($property, $value) {
550 |
551 | // Determine if property should expand.
552 | $expandProperty: index($vendor-properties, $property);
553 |
554 | // Determine if value should expand (and if so, add '-prefix-' placeholder).
555 | $expandValue: false;
556 |
557 | @each $x in $value {
558 | @each $y in $vendor-values {
559 | @if $y == str-slice($x, 1, str-length($y)) {
560 |
561 | $value: set-nth($value, index($value, $x), '-prefix-' + $x);
562 | $expandValue: true;
563 |
564 | }
565 | }
566 | }
567 |
568 | // Expand property?
569 | @if $expandProperty {
570 | @each $vendor in $vendor-prefixes {
571 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
572 | }
573 | }
574 |
575 | // Expand just the value?
576 | @elseif $expandValue {
577 | @each $vendor in $vendor-prefixes {
578 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
579 | }
580 | }
581 |
582 | // Neither? Treat them as a normal declaration.
583 | @else {
584 | #{$property}: #{$value};
585 | }
586 |
587 | }
--------------------------------------------------------------------------------
/styles/libs/_vars.scss:
--------------------------------------------------------------------------------
1 | // Misc.
2 | $misc: (
3 | z-index-base: 10000
4 | );
5 |
6 | // Duration.
7 | $duration: (
8 | transition: 0.2s,
9 | bg: 2.5s,
10 | intro: 0.75s,
11 | article: 0.325s
12 | );
13 |
14 | // Size.
15 | $size: (
16 | border-radius: 4px,
17 | border-width: 1px,
18 | element-height: 2.75rem,
19 | element-margin: 2rem
20 | );
21 |
22 | // Font.
23 | $font: (
24 | family: ('Source Sans Pro', sans-serif),
25 | family-fixed: ('Courier New', monospace),
26 | weight: 300,
27 | weight-bold: 600,
28 | letter-spacing: 0.2rem,
29 | letter-spacing-heading: 0.5rem
30 | );
31 |
32 | // Palette.
33 | $palette: (
34 | bg: #1b1f22,
35 | bg-alt: #000000,
36 | bg-overlay: rgba(19,21,25,0.5),
37 | fg: #ffffff,
38 | fg-bold: #ffffff,
39 | fg-light: rgba(255,255,255,0.5),
40 | border: #ffffff,
41 | border-bg: rgba(255,255,255,0.075),
42 | border-bg-alt: rgba(255,255,255,0.175)
43 | );
--------------------------------------------------------------------------------
/styles/loader.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | }
7 |
8 | .rotate {
9 | padding: 15px !important;
10 | animation: rotation 6s infinite linear;
11 | }
12 |
13 | @keyframes rotation {
14 | from {
15 | transform: rotate(0deg);
16 | }
17 | to {
18 | transform: rotate(359deg);
19 | }
20 | }
--------------------------------------------------------------------------------
/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/skel';
5 |
6 | /*
7 | Dimension by HTML5 UP
8 | html5up.net | @ajlkn
9 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
10 | */
11 |
12 | @include skel-breakpoints((
13 | xlarge: '(max-width: 1680px)',
14 | large: '(max-width: 1280px)',
15 | medium: '(max-width: 980px)',
16 | small: '(max-width: 736px)',
17 | xsmall: '(max-width: 480px)',
18 | xxsmall: '(max-width: 360px)'
19 | ));
20 |
21 | @include skel-layout((
22 | reset: 'full',
23 | boxModel: 'border'
24 | ));
25 |
26 | // Base.
27 |
28 | @import 'base/page';
29 | @import 'base/typography';
30 |
31 | // Component.
32 |
33 | @import 'components/form';
34 | @import 'components/box';
35 | @import 'components/icon';
36 | @import 'components/image';
37 | @import 'components/list';
38 | @import 'components/table';
39 | @import 'components/button';
40 |
41 | // Layout.
42 |
43 | @import 'layout/bg';
44 | @import 'layout/wrapper';
45 | @import 'layout/header';
46 | @import 'layout/main';
47 | @import 'layout/footer';
--------------------------------------------------------------------------------
/styles/noscript.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/skel';
5 |
6 | /*
7 | Dimension by HTML5 UP
8 | html5up.net | @ajlkn
9 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
10 | */
11 |
12 | /* Main */
13 |
14 | #main {
15 | article {
16 | opacity: 1;
17 | margin: (_size(element-margin) * 2) 0 0 0;
18 | }
19 | }
--------------------------------------------------------------------------------
/styles/schemaView.module.scss:
--------------------------------------------------------------------------------
1 | .codeContainer {
2 | white-space: pre-wrap; /* Since CSS 2.1 */
3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
4 | white-space: -pre-wrap; /* Opera 4-6 */
5 | white-space: -o-pre-wrap; /* Opera 7 */
6 | word-wrap: break-word; /* Internet Explorer 5.5+ */
7 |
8 | counter-reset: line;
9 | }
10 |
11 | .codeContainer .line {
12 | display: block;
13 |
14 | }
15 |
16 | .codeContainer .line:before {
17 | counter-increment: line;
18 | content: counter(line);
19 | display: inline-block;
20 | // border-right: 1px solid #ddd;
21 |
22 | margin-right: .5rem;
23 | color: #888;
24 | width: 60px;
25 | padding-right: 0.5rem;
26 | margin-right: 10px;
27 | text-align: right;
28 | }
29 |
--------------------------------------------------------------------------------