diff --git a/.circleci/config.yml b/.circleci/config.yml index a8e2cb9..8ab0655 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -378,7 +378,7 @@ jobs: deploy_homepage: docker: - - image: circleci/python:3.6 + - image: circleci/python:3.6-node working_directory: ~/offen/homepage environment: - SOURCE_BRANCH: master @@ -398,6 +398,11 @@ jobs: paths: - ~/offen/homepage/venv key: offen-homepage-{{ checksum "requirements.txt" }} + - run: + name: Install image optimization deps + command: | + npm install svgo -g + sudo apt-get install libjpeg-progs optipng - run: name: Deploy command: | diff --git a/homepage/content/pages/deep-dive.md b/homepage/content/pages/deep-dive.md index e433c64..6e47e4b 100644 --- a/homepage/content/pages/deep-dive.md +++ b/homepage/content/pages/deep-dive.md @@ -3,9 +3,11 @@ description: offen is a free and open source analytics software for websites and save_as: deep-dive/index.html href: /deep-dive/ +## Deep dive + ### What is this thing called "my data" and why does seemingly everyone want to get hold of it? -It has a ring, gives a slight spine-chilling sensation and generates a whole lot of clicks: consumer magazines like German "Computer Bild" caution about "Google espionage" [^1] just like the internet has countless tutorials on turning off numerous "data leeches" [^2]. Interestingly, diving into these realms will have you accidentally catching the next toolbar, malware infection or even worse [^3]. +It has a ring, gives a slight spine-chilling sensation and generates a whole lot of clicks: consumer magazines like German "Computer Bild" caution about "Google espionage" [^1] just like the internet has countless tutorials on turning off numerous "data leeches"[^2]. Interestingly, diving into these realms will have you accidentally catching the next toolbar, malware infection or even worse [^3]. [^1]: Gegen Google-Spionage wehren [^2]: Datenkrake Windows 10: So schalten Sie auffällige Funktionen ab diff --git a/homepage/content/pages/index.md b/homepage/content/pages/index.md index 784a7be..dc7dc0b 100644 --- a/homepage/content/pages/index.md +++ b/homepage/content/pages/index.md @@ -2,11 +2,18 @@ Title: Transparent web analytics | offen description: offen is a free and open source analytics software for websites and web applications that allows respectful handling of data. save_as: index.html href: / +template: index + +## Summary __offen__ is a web analytics software that gives users access to the data they are generating. Not only operators running sites or applications are given able to use the analytics tools, but also *the users themselves are granted access to and ownership of their data*. Usage metrics come with explanations about their meaning, relevance, usage and possible privacy implications. __offen__ also details *which kind of data is not collected*. All data can be deleted selectively or in its entirety by the users, or the collection can be disabled altogether. -__offen__ treats both users and operators as parties of equal importance. Users can expect full transparency and are encouraged to make *autonomous and informed decisions regarding the use of their data*. Operators are enabled to gain insights while respecting their users' privacy and their data. +__offen__ treats both users and operators as parties of equal importance. Users can expect full transparency and are encouraged to make *autonomous and informed decisions regarding the use of their data*. Operators are enabled to gain insights while respecting their users' privacy and data. -__offen__ is currently in the early stages of development and is applying for funds to sustain its development. An early alpha version is running on this site: you can visit the [auditorium](https://auditorium-alpha.offen.dev) to access your data. +__offen__ is currently in the early stages of development and is applying for funds to sustain its development. An early alpha version is running on this site: you can *visit the [auditorium](https://auditorium-alpha.offen.dev){: target="_blank"}* to access your data. + + diff --git a/homepage/content/pages/opt-out.md b/homepage/content/pages/opt-out.md index 9f40621..80af01c 100644 --- a/homepage/content/pages/opt-out.md +++ b/homepage/content/pages/opt-out.md @@ -2,7 +2,7 @@ Title: Opt-out | offen description: offen is a free and open source analytics software for websites and web applications that allows respectful handling of data. save_as: opt-out/index.html -### You are opted out +## You are opted out This will prevent __offen__ from aggregating the actions you have taken on participating websites. diff --git a/homepage/content/pages/status.md b/homepage/content/pages/status.md index 07184df..b7964c8 100644 --- a/homepage/content/pages/status.md +++ b/homepage/content/pages/status.md @@ -3,10 +3,11 @@ description: offen is a free and open source analytics software for websites and save_as: status/index.html href: /status/ -### Current status +## Project status -#### July 2019 -We have deployed an alpha version of __offen__ that we are currently testing on a few select sites. Usage data is collected and can be accessed by both users and site operators. Users can opt out and delete their data at any time. You can *follow the development at [github.com/offen/offen](https://github.com/offen/offen)* +### September 2019 + +We have deployed an alpha version of __offen__ that we are currently testing on a few select sites. Usage data is collected and can be accessed by both users and site operators. Users can opt out and delete their data at any time. You can *follow the development at [github.com/offen/offen](https://github.com/offen/offen){: target="_blank"}* --- @@ -29,4 +30,4 @@ Our product story is based on three key questions. What makes __offen__ stand ou #### Publicity -This product story is the starting point for publicty efforts that will start as soon as a beta version is available. They include own blog posts, forum marketing as well as SEO measures. +This product story is the starting point for publicity efforts that will start as soon as a beta version is available. They include own blog posts, forum marketing as well as SEO measures. diff --git a/homepage/docker-compose.yml b/homepage/docker-compose.yml index 0d43786..e105b1a 100644 --- a/homepage/docker-compose.yml +++ b/homepage/docker-compose.yml @@ -12,6 +12,8 @@ services: command: make devserver ports: - 8000:8000 + environment: + DEBUG: '1' volumes: homepagedeps: diff --git a/homepage/pelicanconf.py b/homepage/pelicanconf.py index 8a546fb..9a786bf 100644 --- a/homepage/pelicanconf.py +++ b/homepage/pelicanconf.py @@ -4,12 +4,10 @@ from __future__ import unicode_literals import logging # If your site is available via HTTPS, make sure SITEURL begins with https:// -#SITEURL = 'https://www.offen.dev' RELATIVE_URLS = False AUTHOR = 'offen' SITENAME = 'offen' -SITEURL = 'https://www.offen.dev' PATH = 'content' TIMEZONE = 'Europe/Berlin' DEFAULT_LANG = 'en' @@ -30,6 +28,9 @@ THEME = './theme' # Delete the output directory before generating new files. DELETE_OUTPUT_DIRECTORY = True +PLUGIN_PATHS = ['./plugins'] +PLUGINS = ['assets'] + # dont create following standard pages AUTHORS_SAVE_AS = None ARCHIVES_SAVE_AS = None diff --git a/homepage/plugins/assets/Readme.rst b/homepage/plugins/assets/Readme.rst new file mode 100644 index 0000000..42091cb --- /dev/null +++ b/homepage/plugins/assets/Readme.rst @@ -0,0 +1,106 @@ +Asset management +---------------- + +This plugin allows you to use the `Webassets`_ module to manage assets such as +CSS and JS files. The module must first be installed:: + + pip install webassets + +The Webassets module allows you to perform a number of useful asset management +functions, including: + +* CSS minifier (``cssmin``, ``yui_css``, ...) +* CSS compiler (``less``, ``sass``, ...) +* JS minifier (``uglifyjs``, ``yui_js``, ``closure``, ...) + +Others filters include CSS URL rewriting, integration of images in CSS via data +URIs, and more. Webassets can also append a version identifier to your asset +URL to convince browsers to download new versions of your assets when you use +far-future expires headers. Please refer to the `Webassets documentation`_ for +more information. + +When used with Pelican, Webassets is configured to process assets in the +``OUTPUT_PATH/theme`` directory. You can use Webassets in your templates by +including one or more template tags. The Jinja variable ``{{ ASSET_URL }}`` can +be used in templates and is relative to the ``theme/`` url. The +``{{ ASSET_URL }}`` variable should be used in conjunction with the +``{{ SITEURL }}`` variable in order to generate URLs properly. For example: + +.. code-block:: jinja + + {% assets filters="cssmin", output="css/style.min.css", "css/inuit.css", "css/pygment-monokai.css", "css/main.css" %} + + {% endassets %} + +... will produce a minified css file with a version identifier that looks like: + +.. code-block:: html + + + +These filters can be combined. Here is an example that uses the SASS compiler +and minifies the output: + +.. code-block:: jinja + + {% assets filters="sass,cssmin", output="css/style.min.css", "css/style.scss" %} + + {% endassets %} + +Another example for Javascript: + +.. code-block:: jinja + + {% assets filters="uglifyjs", output="js/packed.js", "js/jquery.js", "js/base.js", "js/widgets.js" %} + + {% endassets %} + +The above will produce a minified JS file: + +.. code-block:: html + + + +Pelican's debug mode is propagated to Webassets to disable asset packaging +and instead work with the uncompressed assets. + +If you need to create named bundles (for example, if you need to compile SASS +files before minifying with other CSS files), you can use the ``ASSET_BUNDLES`` +variable in your settings file. This is an ordered sequence of 3-tuples, where +the 3-tuple is defined as ``(name, args, kwargs)``. This tuple is passed to the +`environment's register() method`_. The following will compile two SCSS files +into a named bundle, using the ``pyscss`` filter: + +.. code-block:: python + + ASSET_BUNDLES = ( + ('scss', ['colors.scss', 'main.scss'], {'filters': 'pyscss'}), + ) + +Many of Webasset's available compilers have additional configuration options +(i.e. 'Less', 'Sass', 'Stylus', 'Closure_js'). You can pass these options to +Webassets using the ``ASSET_CONFIG`` in your settings file. + +The following will handle Google Closure's compilation level and locate +LessCSS's binary: + +.. code-block:: python + + ASSET_CONFIG = (('closure_compressor_optimization', 'WHITESPACE_ONLY'), + ('less_bin', 'lessc.cmd'), ) + +If you wish to place your assets in locations other than the theme output +directory, you can use ``ASSET_SOURCE_PATHS`` in your settings file to provide +webassets with a list of additional directories to search, relative to the +theme's top-level directory: + +.. code-block:: python + + ASSET_SOURCE_PATHS = [ + 'vendor/css', + 'scss', + ] + +.. _Webassets: https://github.com/miracle2k/webassets +.. _Webassets documentation: http://webassets.readthedocs.org/en/latest/builtin_filters.html +.. _environment's register() method: http://webassets.readthedocs.org/en/latest/environment.html#registering-bundles diff --git a/homepage/plugins/assets/__init__.py b/homepage/plugins/assets/__init__.py new file mode 100644 index 0000000..67b75dd --- /dev/null +++ b/homepage/plugins/assets/__init__.py @@ -0,0 +1 @@ +from .assets import * diff --git a/homepage/plugins/assets/assets.py b/homepage/plugins/assets/assets.py new file mode 100644 index 0000000..e204dd6 --- /dev/null +++ b/homepage/plugins/assets/assets.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +""" +Asset management plugin for Pelican +=================================== + +This plugin allows you to use the `webassets`_ module to manage assets such as +CSS and JS files. + +The ASSET_URL is set to a relative url to honor Pelican's RELATIVE_URLS +setting. This requires the use of SITEURL in the templates:: + + + +.. _webassets: https://webassets.readthedocs.org/ + +""" +from __future__ import unicode_literals + +import os +import logging + +from pelican import signals +logger = logging.getLogger(__name__) + +try: + import webassets + from webassets import Environment + from webassets.ext.jinja2 import AssetsExtension +except ImportError: + webassets = None + +def add_jinja2_ext(pelican): + """Add Webassets to Jinja2 extensions in Pelican settings.""" + + if 'JINJA_ENVIRONMENT' in pelican.settings: # pelican 3.7+ + pelican.settings['JINJA_ENVIRONMENT']['extensions'].append(AssetsExtension) + else: + pelican.settings['JINJA_EXTENSIONS'].append(AssetsExtension) + + +def create_assets_env(generator): + """Define the assets environment and pass it to the generator.""" + + theme_static_dir = generator.settings['THEME_STATIC_DIR'] + assets_destination = os.path.join(generator.output_path, theme_static_dir) + generator.env.assets_environment = Environment( + assets_destination, theme_static_dir) + + if 'ASSET_CONFIG' in generator.settings: + for item in generator.settings['ASSET_CONFIG']: + generator.env.assets_environment.config[item[0]] = item[1] + + if 'ASSET_BUNDLES' in generator.settings: + for name, args, kwargs in generator.settings['ASSET_BUNDLES']: + generator.env.assets_environment.register(name, *args, **kwargs) + + if 'ASSET_DEBUG' in generator.settings: + generator.env.assets_environment.debug = generator.settings['ASSET_DEBUG'] + elif logging.getLevelName(logger.getEffectiveLevel()) == "DEBUG": + generator.env.assets_environment.debug = True + + for path in (generator.settings['THEME_STATIC_PATHS'] + + generator.settings.get('ASSET_SOURCE_PATHS', [])): + full_path = os.path.join(generator.theme, path) + generator.env.assets_environment.append_path(full_path) + + +def register(): + """Plugin registration.""" + if webassets: + signals.initialized.connect(add_jinja2_ext) + signals.generator_init.connect(create_assets_env) + else: + logger.warning('`assets` failed to load dependency `webassets`.' + '`assets` plugin not loaded.') diff --git a/homepage/plugins/optimize_images/Readme.md b/homepage/plugins/optimize_images/Readme.md new file mode 100644 index 0000000..8efc926 --- /dev/null +++ b/homepage/plugins/optimize_images/Readme.md @@ -0,0 +1,28 @@ +Optimize Images Plugin For Pelican +================================== + +This plugin applies lossless compression on JPEG, PNG and SVG images, with no +effect on image quality via [jpegtran][], [OptiPNG][] and [svgo][] respectively. +The plugin assumes that all of these tools are installed, with associated +executables available on the system path. + +[jpegtran]: http://jpegclub.org/jpegtran/ +[OptiPNG]: http://optipng.sourceforge.net/ +[SVGO]: https://github.com/svg/svgo + + +Installation +------------ + +To enable, ensure that `optimize_images.py` is put somewhere that is accessible. +Then use as follows by adding the following to your settings.py: + + PLUGIN_PATH = 'path/to/pelican-plugins' + PLUGINS = ["optimize_images"] + +`PLUGIN_PATH` can be a path relative to your settings file or an absolute path. + +Usage +----- +The plugin will activate and optimize images upon `finalized` signal of +Pelican. diff --git a/homepage/plugins/optimize_images/__init__.py b/homepage/plugins/optimize_images/__init__.py new file mode 100644 index 0000000..cbb056a --- /dev/null +++ b/homepage/plugins/optimize_images/__init__.py @@ -0,0 +1 @@ +from .optimize_images import * diff --git a/homepage/plugins/optimize_images/optimize_images.py b/homepage/plugins/optimize_images/optimize_images.py new file mode 100644 index 0000000..33593ce --- /dev/null +++ b/homepage/plugins/optimize_images/optimize_images.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +""" +Optimized images (jpg and png) +Assumes that jpegtran and optipng are isntalled on path. +http://jpegclub.org/jpegtran/ +http://optipng.sourceforge.net/ +Copyright (c) 2012 Irfan Ahmad (http://i.com.pk) +""" + +import logging +import os +from subprocess import call + +from pelican import signals + +logger = logging.getLogger(__name__) + +# Display command output on DEBUG and TRACE +SHOW_OUTPUT = logger.getEffectiveLevel() <= logging.DEBUG + +# A list of file types with their respective commands +COMMANDS = { + # '.ext': ('command {flags} {filename', 'silent_flag', 'verbose_flag') + '.svg': ('svgo {flags} --input="{filename}" --output="{filename}"', '--quiet', ''), + '.jpg': ('jpegtran {flags} -copy none -optimize -outfile "{filename}" "{filename}"', '', '-v'), + '.png': ('optipng {flags} "{filename}"', '--quiet', ''), +} + + +def optimize_images(pelican): + """ + Optimized jpg and png images + + :param pelican: The Pelican instance + """ + for dirpath, _, filenames in os.walk(pelican.settings['OUTPUT_PATH']): + for name in filenames: + if os.path.splitext(name)[1] in COMMANDS.keys(): + optimize(dirpath, name) + +def optimize(dirpath, filename): + """ + Check if the name is a type of file that should be optimized. + And optimizes it if required. + + :param dirpath: Path of the file to be optimzed + :param name: A file name to be optimized + """ + filepath = os.path.join(dirpath, filename) + logger.info('optimizing %s', filepath) + + ext = os.path.splitext(filename)[1] + command, silent, verbose = COMMANDS[ext] + flags = verbose if SHOW_OUTPUT else silent + command = command.format(filename=filepath, flags=flags) + call(command, shell=True) + + +def register(): + signals.finalized.connect(optimize_images) diff --git a/homepage/publishconf.py b/homepage/publishconf.py index cf5b588..e442015 100644 --- a/homepage/publishconf.py +++ b/homepage/publishconf.py @@ -19,9 +19,6 @@ CATEGORY_FEED_ATOM = 'feeds/{slug}.atom.xml' DELETE_OUTPUT_DIRECTORY = True -# Following items are often useful when publishing - -#DISQUS_SITENAME = "" -#GOOGLE_ANALYTICS = "" +PLUGINS += ['optimize_images'] OFFEN_ACCOUNT_ID = "5ec8345a-2a45-4eb9-92e5-8d9e5684db58" diff --git a/homepage/requirements.txt b/homepage/requirements.txt index a9d0eea..a62e2d6 100644 --- a/homepage/requirements.txt +++ b/homepage/requirements.txt @@ -1,2 +1,4 @@ pelican==4.0.1 markdown==3.1.1 +webassets==0.12.1 +cssmin==0.2.0 diff --git a/homepage/theme/static/css/normalize.css b/homepage/theme/static/css/normalize.css new file mode 100644 index 0000000..192eb9c --- /dev/null +++ b/homepage/theme/static/css/normalize.css @@ -0,0 +1,349 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/homepage/theme/static/css/style.css b/homepage/theme/static/css/style.css index 3849338..ad2b1f3 100644 --- a/homepage/theme/static/css/style.css +++ b/homepage/theme/static/css/style.css @@ -1,9 +1,579 @@ -section { -display: flex; -flex-flow: column; + + +/* --------------------------------------------------- +ROOTS +----------------------------------------------------*/ +:root { +--yellow-mid: #F7BF08; +--yellow-bright: #fde28c; +--mint-mid: #BBD9D3; +--black-mid: #39352A; +--grey-mid: #898989; +--grey-bright: #D5D5D5; +--white: #FFF; } -section .footnote { -padding-top: 30px; -order: 100; + +/* --------------------------------------------------- +BASICS +----------------------------------------------------*/ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + + +/* --------------------------------------------------- +LAYOUT & SPACER +----------------------------------------------------*/ +.menu { + width: 100%; + height: 70px; + position: fixed; + z-index: 1; + top: 0; + right: 0; + background-color: var(--yellow-mid); +} +.intro { + width: 100%; + margin: 70px 0 0 0; + background-color: var(--yellow-mid); +} +.feature { + width: 100%; +} +.cta-top { + width: 100%; + color: var(--yellow-mid); +} +.content { + width: 100%; + margin: 70px 0 0 0; + background-color: var(--white); +} +.content-index { + width: 100%; + background-color: var(--white); +} +.cta-bottom, +.outro { + width: 100%; +} +.footer { + width: 100%; + min-height: 300px; + color: var(--grey-mid); + background-color: var(--black-mid); +} +.spacer-intro { + width: 430px; +} +.spacer-right { + width: 400px; + margin: 0 0 0 auto; +} +/* Desktop Styles */ +@media only screen and (min-width: 961px) { + .container-reader { + width: 600px; + margin: 0 auto; + padding: 60px 20px 120px 20px; + } + .container-full { + padding: 60px 80px 120px 80px; + } + .footer { + padding: 40px 40px 0 40px; + } +} +/* Mobile Styles */ +@media only screen and (min-width: 600px) and (max-width: 960px) { + .container-reader, + .container-full { + width: 600px; + margin: 0 auto; + padding: 60px 20px 120px 20px; + } +} +@media only screen and (max-width: 960px) { + .container-reader, + .container-full, + .footer { + padding: 60px 20px 120px 20px; + } +} +/* Mobile Styles*/ +@media only screen and (max-width: 480px) { + .menu { + position: static; + } + .intro { + margin: 0; + } + .content { + margin: 0; + } + .spacer-intro { + width: 300px; + } + .spacer-right { + width: 100%; + margin: 0; + } +} + + +/* --------------------------------------------------- +CARDS +----------------------------------------------------*/ +.card-deck, +.card, +.footer-card-deck { + display: flex; +} +.card { + max-width: 300px; + color: var(--black-mid); +} +.card h2, +.card p { + text-align: center; +} +.footer-card p { + margin: 0 0 2px 0; +} +.footer-card:nth-child(1), +.footer-card:nth-child(2) { + margin: 0 0 20px 0; +} +/* Mobile Styles */ +@media only screen and (max-width: 960px) { + .card-deck, + .card, + .footer-card-deck { + flex-direction: column; + } + .card { + align-self: center; + } + .card:nth-child(2) { + margin: 100px 0 100px 0; + } + .footer-card { + text-align: center; + } +} +/* Desktop Styles */ +@media only screen and (min-width: 961px) { + .card-deck, + .footer-card-deck { + flex-direction: row; + } + .card { + flex-direction: column; + } + .card-deck { + justify-content: space-evenly; + } + .card:nth-child(2) { + margin: 0 40px 0 40px; + } + .footer-card-deck { + justify-content: space-between; + } + .footer-card:nth-child(1), + .footer-card:nth-child(2) { + flex-grow: 1; + } + .footer-card:nth-child(3) { + text-align: right; + flex-grow: 10; + } +} + + +/* --------------------------------------------------- +TYPO +----------------------------------------------------*/ +body { + background-color: var(--white); + font-family: "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.5; + font-weight: 400; + word-wrap: break-word; + color: var(--grey-mid); +} +h1, +h2 { + font-weight: 700; + line-height: 1.3; + color: var(--black-mid); +} +h3, +h4 { + font-size: 14px; + font-weight: 400; + color: var(--black-mid); +} +h3 { + margin: 0 0 20px 0; +} +p + h3 { + margin: 60px 0 20px 0; +} +h4 { + color: var(--grey-mid); +} +/* Desktop Styles */ +@media only screen and (min-width: 481px) { + h1, + h2{ + font-size: 30px; + } + h1 { + margin: 20px 0 10px 0; + } +} +/* Mobile Styles */ +@media only screen and (max-width: 480px) { + h1, + h2 { + font-size: 22px; + } +} + + +/* --------------------------------------------------- +LINKS +----------------------------------------------------*/ +a, +a:hover, +a:focus { + color: var(--grey-mid); + text-decoration: none; +} +p a, +p a:hover, +p a:focus { + font-weight: 700; +} +ol li p a, +ol li p a:hover, +ol li p a:focus { +color: var(--grey-bright); +} +.footer a, +.footer a:hover, +.footer a:focus { + font-weight: 400; +} + + +/* --------------------------------------------------- +TYPO ELEMENTS +----------------------------------------------------*/ +h1 + p { + color: var(--black-mid); +} +.bg h2 { + margin: 0 0 10px 0; +} +#bg-cta-top h2, +#bg-cta-top p, +#bg-cta-top .btn-wrapper, +#bg-outro h2, +#bg-outro p, +#bg-outro .btn-wrapper { + text-align: right; +} +#bg-cta-bottom .btn-wrapper { + text-align: center; +} +#bg-cta-top h2, +#bg-cta-top p { + color: var(--white); +} +#bg-outro h2, +#bg-outro p { + color: var(--black-mid); +} +strong, +h1 + p strong, +.bg strong { + font-weight: 700; +} +.container-reader h2 { + margin: 0 0 20px 0; + color: var(--grey-bright); +} +strong, +h3 strong { + text-decoration: none; + font-weight: 400; + color: var(--black-mid); +} +.cta-top strong { + color: var(--white); +} +.content-index p, +.content p { + margin: 0 0 20px 0; +} +hr { + height: 0; + margin: 80px 0 20px 0; + border-top: 1px solid var(--grey-bright); +} +blockquote { + margin: 0; + padding: 0 0 0 20px; + font-style: italic; + border-left: 1px solid var(--grey-bright); +} +ol { + padding-inline-start: 20px; +} +em { + background: linear-gradient(transparent 66%, var(--yellow-bright) 66%); + font-style: normal; +} +.footer-card h3 strong { + font-weight: 700; + color: var(--yellow-mid); +} +.footer h3, +.footer h4 { + color: var(--yellow-mid); + margin: 0 0 2px 0; +} +.footnote { + color: var(--grey-bright); +} +/* reposition for fixed menu */ +.footnote li { + margin-top: -75px; + padding-top: 75px; +} + + +/* --------------------------------------------------- +BUTTONS +----------------------------------------------------*/ +.btn-wrapper { + margin: 40px 0 0 0; +} +.btn { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0px; + padding: 8px 30px; + text-align: center; + text-decoration: none; +} +.btn-color-yellow, +.btn-color-yellow:visited, +.btn-color-yellow:link, +.btn-color-yellow:hover, +.btn-color-yellow:active { + font-weight: 700; + color: var(--yellow-mid); + border: solid var(--yellow-mid) 5px; +} +.btn-color-black, +.btn-color-black:visited, +.btn-color-black:link, +.btn-color-black:hover, +.btn-color-black:active { + font-weight: 700; + color: var(--black-mid); + border: solid var(--black-mid) 5px; +} +.btn-color-white, +.btn-color-white:visited, +.btn-color-white:link, +.btn-color-white:hover, +.btn-color-white:active { + font-weight: 700; + color: var(--white); + border: solid var(--white) 5px; +} + + +/* --------------------------------------------------- +MENU +----------------------------------------------------*/ +.nav-list { + margin: 0 0 40px 0; +} +.nav-bar { + height: 70px; +} +.brand { + position: absolute; + padding: 12px 0 0 20px; + float: left; + line-height: 70px; +} +body.index .brand { + opacity: 0; +} +.nav-container { + margin: 0 auto; +} +nav { + float: right; +} +nav ul { + list-style: none; + margin: 0; + padding: 0; +} +nav ul li { + float: left; + position: relative; +} +nav ul li a, +nav ul li a:visited { + display: block; + padding: 0 20px; + line-height: 70px; + background: var(--yellow-mid); + color: var(--black-mid); + text-decoration: none; +} +nav ul li a:hover, +nav ul li a:visited:hover { + color: var(--black-mid); +} +nav ul li a:not(:only-child):after, +nav ul li a:visited:not(:only-child):after { + padding-left: 4px; + content: ' ▾'; +} +nav ul li ul li { + min-width: 150px; +} +nav ul li ul li a { + padding: 15px; + line-height: 20px; +} +.nav-dropdown { + position: absolute; + display: none; + z-index: 1; +} +.nav-mobile { + display: none; + position: absolute; + top: 0; + right: 0; + background: var(--yellow-mid); + height: 70px; + width: 70px; +} +/* Mobile Styles */ +@media only screen and (max-width: 960px) { + .nav-mobile { + display: block; + } + nav { + width: 100%; + padding: 70px 0 15px; + } + nav ul { + display: none; + } + nav ul li { + float: none; + } + nav ul li a { + padding: 15px; + line-height: 20px; + padding-left: 25%; + } + nav ul li ul li a { + padding-left: 30%; + } + nav ul li:last-child a { + padding-bottom: 60px; + } + nav ul li:last-child a { + box-shadow: 0px 7px 15px -6px rgba(57,53,42,0.2); + } + .nav-dropdown { + position: static; + } +} +/* Desktop Styles */ +@media screen and (min-width: 961px) { + .nav-list { + display: block !important; + } +} +#nav-toggle { + position: absolute; + left: 18px; + top: 22px; + cursor: pointer; + padding: 12px 35px 16px 0px; +} +#nav-toggle span, +#nav-toggle span:before, +#nav-toggle span:after { + cursor: pointer; + border-radius: 1px; + height: 2px; + width: 35px; + background: var(--black-mid); + position: absolute; + display: block; + content: ''; + /* + transition: all 300ms ease-in-out; + */ +} +#nav-toggle span:before { + top: -10px; +} +#nav-toggle span:after { + bottom: -10px; +} +#nav-toggle.active span { + background-color: transparent; +} +#nav-toggle.active span:before, #nav-toggle.active span:after { + top: 0; +} +#nav-toggle.active span:before { + transform: rotate(45deg); +} +#nav-toggle.active span:after { + transform: rotate(-45deg); +} + + +/* --------------------------------------------------- +GRAPHICS +----------------------------------------------------*/ +#bg-intro { + background: url(/theme/images/gfx-intro.svg) no-repeat center; +} +/*-------------------------*/ +#bg-feature { + background: url(/theme/images/gfx-pattern-mint-bright.svg) center; +} +/*-------------------------*/ +#bg-cta-top { + background: url(/theme/images/gfx-object-white.svg) center; +} +/*-------------------------*/ +#bg-outro { + background: url(/theme/images/gfx-pattern-yellow-bright.svg) center; +} +/*-------------------------*/ +#bg-cta-bottom { + background: url(/theme/images/gfx-pattern-yellow-bright.svg) center; } diff --git a/homepage/theme/static/images/gfx-intro.svg b/homepage/theme/static/images/gfx-intro.svg new file mode 100644 index 0000000..3df8296 --- /dev/null +++ b/homepage/theme/static/images/gfx-intro.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/homepage/theme/static/images/gfx-object-white.svg b/homepage/theme/static/images/gfx-object-white.svg new file mode 100644 index 0000000..21859e9 --- /dev/null +++ b/homepage/theme/static/images/gfx-object-white.svg @@ -0,0 +1,493 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/homepage/theme/static/images/gfx-pattern-mint-bright.svg b/homepage/theme/static/images/gfx-pattern-mint-bright.svg new file mode 100644 index 0000000..fc966b1 --- /dev/null +++ b/homepage/theme/static/images/gfx-pattern-mint-bright.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/homepage/theme/static/images/gfx-pattern-yellow-bright.svg b/homepage/theme/static/images/gfx-pattern-yellow-bright.svg new file mode 100644 index 0000000..9246954 --- /dev/null +++ b/homepage/theme/static/images/gfx-pattern-yellow-bright.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/homepage/theme/static/images/logo.svg b/homepage/theme/static/images/logo.svg deleted file mode 100644 index 8ccdf92..0000000 --- a/homepage/theme/static/images/logo.svg +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/homepage/theme/static/images/offen-brand-white.svg b/homepage/theme/static/images/offen-brand-white.svg new file mode 100644 index 0000000..add91c3 --- /dev/null +++ b/homepage/theme/static/images/offen-brand-white.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/homepage/theme/static/images/offen-sign-brand-white.svg b/homepage/theme/static/images/offen-sign-brand-white.svg new file mode 100644 index 0000000..0526b05 --- /dev/null +++ b/homepage/theme/static/images/offen-sign-brand-white.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/homepage/theme/static/scripts/fade.js b/homepage/theme/static/scripts/fade.js new file mode 100644 index 0000000..f4710a9 --- /dev/null +++ b/homepage/theme/static/scripts/fade.js @@ -0,0 +1,8 @@ +;(function ($) { + $(document).ready(function () { + $(window).scroll(function () { + var scrollProgress = parseInt($(window).scrollTop(), 10) + $('body.index .brand').css('opacity', Math.min(scrollProgress / 100, 1)) + }) + }) +})(window.jQuery) diff --git a/homepage/theme/static/scripts/jquery-3.4.1.min.js b/homepage/theme/static/scripts/jquery-3.4.1.min.js new file mode 100644 index 0000000..a1c07fd --- /dev/null +++ b/homepage/theme/static/scripts/jquery-3.4.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0 +
+ {{ page.content }} +
+ +{% endblock %} diff --git a/homepage/theme/templates/base.html b/homepage/theme/templates/base.html index d7db9e0..d9474cb 100644 --- a/homepage/theme/templates/base.html +++ b/homepage/theme/templates/base.html @@ -1,8 +1,9 @@ - - {% block title %}{% endblock %} + + {% block title %}{{ page.title }}{% endblock %} + @@ -18,23 +19,125 @@ - - - + {% assets filters="cssmin", output="css/style.min.css", "css/normalize.css", "css/fonts.css", "css/style.css" %} + + {% endassets %} {% if OFFEN_ACCOUNT_ID %} {% endif %} - - -
-
- - - -
- - {% block content %}{% endblock %} + + + + {% block content %} +
+
+ {{ page.content }} +
+
+ {% endblock %} + + {% block outro %} +
+
+
+
+
+

+ Participate +

+

+ Development of offen has just started. Do not hesitate to make a contribution and help us handle data with respect. +

+ +
+
+

+ In the making +

+

+ This project is still in alpha. Discover what is already up and running and where we want to go in the coming months. +

+ +
+
+

+ Good cause +

+

+ We're working hard to ensure that offen is independent, cutting-edge and can be sustained for years to come. +

+ +
+
+
+
+
+ {% endblock %} + + + + {% assets filters="rjsmin", output="scripts/packed.js", "scripts/jquery-3.4.1.min.js", "scripts/menu.js", "scripts/fade.js" %} + + {% endassets %} diff --git a/homepage/theme/templates/index.html b/homepage/theme/templates/index.html new file mode 100644 index 0000000..d42216b --- /dev/null +++ b/homepage/theme/templates/index.html @@ -0,0 +1,101 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+
+
+ offen logo +
+

+ Transparent web analytics for operators and users +

+

+ offen is a free and open source analytics software for websites and web applications that allows respectful handling of data. +

+ +
+
+
+
+ +
+
+
+
+
+

+ Free & Open +

+

+ Anyone can audit our open source code to verify it works as intended. offen will always be available free of charge. +

+
+
+

+ Fair & Secure +

+

+ Pay respect to your website visitors and gain insights as a user at the same time. All data is encrypted end-to-end. +

+
+
+

+ Easy to use +

+

+ Simply paste our code into the source of your website. Users can visit the auditorium to access their data. +

+
+
+
+
+
+ + +
+
+
+
+

+ In the making +

+

+ offen is still in alpha. Discover what is already up and running and where we want to go in the coming months. +

+ +
+
+
+
+
+
+ {{ page.content }} +
+
+{% endblock %} + +{% block outro %} +
+
+
+
+

+ Good cause +

+

+ We're working hard to ensure that offen is independent, cutting-edge and can be sustained for years to come. +

+ +
+
+
+
+{% endblock %} diff --git a/homepage/theme/templates/page.html b/homepage/theme/templates/page.html index 38da732..94d9808 100644 --- a/homepage/theme/templates/page.html +++ b/homepage/theme/templates/page.html @@ -1,50 +1 @@ {% extends "base.html" %} - -{% block title %} - {{ page.title }} -{% endblock %} - -{% block content %} -
- {% block before_content %} -

- offen is a free and open source analytics software for websites and web applications that allows respectful handling of data. -

- {% endblock %} - {% block page_content %} - {{ page.content }} - {% endblock %} - {% block after_content %} - - {% endblock %} -
-{% endblock %} diff --git a/styles/index.css b/styles/index.css index 7eee2aa..44ceb40 100644 --- a/styles/index.css +++ b/styles/index.css @@ -423,4 +423,3 @@ td { padding-right: 0; } } -