├── .github └── workflows │ ├── rake.yml │ └── release.yml ├── .gitignore ├── .rubocop.yml ├── .rubocop_todo.yml ├── CHANGELOG.adoc ├── CI_OPS.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── _config.yml ├── _config_test.yml ├── _data └── placeholder.yml ├── _includes ├── _nav-item.html ├── _post-meta.html ├── external-link.html ├── featured_posts.html ├── featured_software.html ├── featured_specs.html ├── head.html ├── home-hero.html ├── home-hub.html ├── home-project.html ├── index-page-hero.html ├── index-page-item-filter.html ├── item-doc-page.html ├── item-external-links.html ├── legal.html ├── logo.html ├── nav-links.html ├── nav-page-link.html ├── post-author-pic.html ├── post-card.html ├── project-doc-page.html ├── project-nav.html ├── scripts.html ├── social-links.html ├── software-card-hub.html ├── software-symbol.html ├── symbol.svg ├── tag-list.html └── title.html ├── _layouts ├── blog-index.html ├── default.html ├── docs-base.html ├── home.html ├── page.html ├── post.html ├── product.html ├── project-index.html ├── software-index.html ├── spec-index.html └── spec.html ├── _pages ├── blog.html ├── software.html └── specs.html ├── _posts └── 2018-04-20-welcome-to-jekyll.markdown ├── _sass ├── headroom.scss ├── jekyll-theme-open-project.scss ├── jekyll-theme-rop.scss ├── normalize.scss ├── rop-base.scss ├── rop-header-footer.scss └── rop-mixins.scss ├── assets ├── css │ └── style.scss ├── fa │ ├── fa-brands.js │ ├── fa-solid.js │ └── fontawesome.js ├── img │ └── external-link.svg ├── js │ ├── adoc-toc.js │ ├── anchor-scroll.js │ ├── clipboard.min.js │ ├── headroom.min.js │ └── opf.js └── listing-widget.js ├── ci_ops └── Rakefile ├── develop ├── build └── check-html ├── index.md ├── jekyll-theme-rop.gemspec └── lib ├── jekyll-theme-open-project.rb ├── jekyll-theme-rop.rb ├── rop.rb └── rop ├── _plugins ├── blog_index.rb ├── filterable_index.rb ├── png_diagram.html ├── png_diagram_page.rb ├── project_reader.rb ├── site_type.rb ├── spec_builder.rb └── version.rb /.github/workflows/rake.yml: -------------------------------------------------------------------------------- 1 | # Auto-generated by Cimas: Do not edit it manually! 2 | # See https://github.com/metanorma/cimas 3 | name: rake 4 | 5 | on: 6 | push: 7 | branches: [ master, main ] 8 | tags: [ v* ] 9 | pull_request: 10 | 11 | jobs: 12 | rake: 13 | uses: metanorma/ci/.github/workflows/generic-rake.yml@main 14 | secrets: 15 | pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Auto-generated by Cimas: Do not edit it manually! 2 | # See https://github.com/metanorma/cimas 3 | name: release 4 | 5 | on: 6 | workflow_dispatch: 7 | inputs: 8 | next_version: 9 | description: | 10 | Next release version. Possible values: x.y.z, major, minor, patch (or pre|rc|etc). 11 | Also, you can pass 'skip' to skip 'git tag' and do 'gem push' for the current version 12 | required: true 13 | default: 'skip' 14 | repository_dispatch: 15 | types: [ do-release ] 16 | 17 | jobs: 18 | release: 19 | uses: metanorma/ci/.github/workflows/rubygems-release.yml@main 20 | with: 21 | next_version: ${{ github.event.inputs.next_version }} 22 | secrets: 23 | rubygems-api-key: ${{ secrets.RIBOSE_RUBYGEMS_API_KEY }} 24 | pat_token: ${{ secrets.RIBOSE_CI_PAT_TOKEN }} 25 | 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site/* 2 | *.scssc 3 | Gemfile.lock 4 | jekyll-theme-rop-*.gem -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2025-05-24 10:37:55 UTC using RuboCop version 1.75.7. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 1 10 | # Configuration parameters: Severity, Include. 11 | # Include: **/*.gemspec 12 | Gemspec/RequiredRubyVersion: 13 | Exclude: 14 | - 'jekyll-theme-rop.gemspec' 15 | 16 | # Offense count: 2 17 | # Configuration parameters: AllowedParentClasses. 18 | Lint/MissingSuper: 19 | Exclude: 20 | - 'lib/rop/filterable_index.rb' 21 | - 'lib/rop/png_diagram_page.rb' 22 | 23 | # Offense count: 11 24 | # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. 25 | Metrics/AbcSize: 26 | Max: 62 27 | 28 | # Offense count: 1 29 | # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. 30 | # AllowedMethods: refine 31 | Metrics/BlockLength: 32 | Max: 30 33 | 34 | # Offense count: 1 35 | # Configuration parameters: CountBlocks, CountModifierForms. 36 | Metrics/BlockNesting: 37 | Max: 4 38 | 39 | # Offense count: 1 40 | # Configuration parameters: CountComments, CountAsOne. 41 | Metrics/ClassLength: 42 | Max: 217 43 | 44 | # Offense count: 7 45 | # Configuration parameters: AllowedMethods, AllowedPatterns. 46 | Metrics/CyclomaticComplexity: 47 | Max: 14 48 | 49 | # Offense count: 12 50 | # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. 51 | Metrics/MethodLength: 52 | Max: 63 53 | 54 | # Offense count: 2 55 | # Configuration parameters: CountKeywordArgs, MaxOptionalParameters. 56 | Metrics/ParameterLists: 57 | Max: 6 58 | 59 | # Offense count: 7 60 | # Configuration parameters: AllowedMethods, AllowedPatterns. 61 | Metrics/PerceivedComplexity: 62 | Max: 17 63 | 64 | # Offense count: 2 65 | # Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. 66 | # CheckDefinitionPathHierarchyRoots: lib, spec, test, src 67 | # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS 68 | Naming/FileName: 69 | Exclude: 70 | - 'Rakefile.rb' 71 | - 'lib/jekyll-theme-open-project.rb' 72 | - 'lib/jekyll-theme-rop.rb' 73 | 74 | # Offense count: 1 75 | # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs. 76 | # NamePrefix: is_, has_, have_, does_ 77 | # ForbiddenPrefixes: is_, has_, have_, does_ 78 | # AllowedMethods: is_a? 79 | # MethodDefinitionMacros: define_method, define_singleton_method 80 | Naming/PredicateName: 81 | Exclude: 82 | - 'spec/**/*' 83 | - 'lib/rop/project_reader.rb' 84 | 85 | # Offense count: 1 86 | Style/ClassVars: 87 | Exclude: 88 | - 'lib/rop/project_reader.rb' 89 | 90 | # Offense count: 9 91 | # Configuration parameters: AllowedConstants. 92 | Style/Documentation: 93 | Exclude: 94 | - 'spec/**/*' 95 | - 'test/**/*' 96 | - 'lib/jekyll-theme-rop.rb' 97 | - 'lib/rop/filterable_index.rb' 98 | - 'lib/rop/png_diagram_page.rb' 99 | - 'lib/rop/project_reader.rb' 100 | - 'lib/rop/spec_builder.rb' 101 | 102 | # Offense count: 5 103 | # Configuration parameters: AllowedVariables. 104 | Style/GlobalVars: 105 | Exclude: 106 | - 'ci_ops/Rakefile' 107 | 108 | # Offense count: 2 109 | # This cop supports safe autocorrection (--autocorrect). 110 | # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. 111 | # URISchemes: http, https 112 | Layout/LineLength: 113 | Max: 136 114 | -------------------------------------------------------------------------------- /CI_OPS.md: -------------------------------------------------------------------------------- 1 | # Setting up the site with continuous delivery via Gitlab CI and AWS 2 | 3 | This summarizes a couple simple CD setup options 4 | with single main repository branch getting automatically 5 | built and deployed to a public AWS S3 bucket 6 | and served through your chosen domain name. 7 | 8 | ## Outcome 9 | 10 | After each push to the main branch, the site will be built and deployed to S3, 11 | updating live site under corresponding domain. 12 | 13 | ## Option 1: GitHub + Rakefile + Travis CI + AWS S3 14 | 15 | ### Pre-requisites 16 | 17 | Provided you have 18 | 19 | * set up the Jekyll site based on README and have its source on GitHub 20 | in a repo connected to Travis CI, 21 | * got the domain name you want to use to publish the site, 22 | * got an AWS account and created a public S3 bucket 23 | named after the domain name 24 | with appropriate Route 53 and optionally CloudFront configuration 25 | to map the bucket to the domain 26 | (Option 2 in this document covers a basic S3 + Route 53 setup). 27 | 28 | ### Steps 29 | 30 | 0. Configure environment variables in repository settings on Travis CI: 31 | 32 | - AWS_ACCESS_KEY_ID 33 | - AWS_SECRET_ACCESS_KEY 34 | - AWS_REGION 35 | - CLOUDFRONT_DISTRIBUTION_ID 36 | - CLOUDFRONT_STAGING_DISTRIBUTION_ID 37 | - S3_BUCKET_NAME 38 | - S3_STAGING_BUCKET_NAME 39 | 40 | 1. Copy `travis.yml` and `Rakefile` from Open Project theme file tree 41 | into your Jekyll site repository root, and rename the copied 42 | `travis.yml` to `.travis.yml` (prepend a dot to filename). 43 | 44 | 2. Add new gems to your Gemfile for building & testing: 45 | 46 | ``` 47 | gem "rake" 48 | gem "html-proofer", "= 3.9.2" 49 | ``` 50 | 51 | 3. That’s it, site should build for you on the next push lest there’re 52 | issues preventing Jekyll build from succeeding 53 | (test it locally first; see README). 54 | 55 | ## Option 2: Gitlab CI + AWS S3 56 | 57 | ### Pre-requisites 58 | 59 | Provided you have set up the Jekyll site based on README, 60 | you own the domain you want to use to publish the site, 61 | you have AWS account, you know how to use AWS web console, 62 | and you have an Route 53 hosted zone associated with your domain. 63 | 64 | ### Steps 65 | 66 | 0. Choose the desired domain name for the site and take a note of it. 67 | 68 | 1. Set up an S3 bucket for the static site, naming it after full domain name, 69 | and configure as follows: 70 | 71 | - Add public read permissions: since it’ll be used for website hosting, 72 | everyone must be able to access it. 73 | 74 | - Enable static website hosting in bucket settings, 75 | set index document path to index.html. 76 | 77 | - Add bucket policy like below (it is recommended to use S3 policy generator 78 | provided by AWS; the goal is to enable anyone to s3:GetObject 79 | on any object inside the bucket): 80 | 81 | ```json 82 | { 83 | "Id": "PolicyNNNNNNNNNNNNN", 84 | "Version": "2012-10-17", 85 | "Statement": [ 86 | { 87 | "Sid": "StmtNNNNNNNNNNNNN", 88 | "Action": [ 89 | "s3:GetObject" 90 | ], 91 | "Effect": "Allow", 92 | "Resource": "/*", 93 | "Principal": "*" 94 | } 95 | ] 96 | } 97 | ``` 98 | 99 | Take note of bucket’s ARN. 100 | 101 | Note: Never use the created bucket for storing anything sensitive. 102 | All contents will be visible to the entire Internet. 103 | 104 | 2. Add Alias record to your chosen domain’s hosted zone in Route 53, 105 | and select the S3 bucket as the target. 106 | 107 | 3. Create an IAM group, don’t assign any managed policies. 108 | This group will be used to facilitate CD updating bucket contents after each 109 | automatic site build. 110 | 111 | 4. To the group, attach an inline policy that looks like below, 112 | giving s3:PutObject permission on the contents of the bucket you created. 113 | 114 | You are advised to use AWS console inline policy wizard instead of 115 | manually entering this. Note that you’ll need your bucket’s ARN. 116 | 117 | ```json 118 | { 119 | "Version": "2012-10-17", 120 | "Statement": [ 121 | { 122 | "Sid": "StmtNNNNNNNNNNNNN", 123 | "Effect": "Allow", 124 | "Action": [ 125 | "s3:PutObject" 126 | ], 127 | "Resource": [ 128 | "/*" 129 | ] 130 | } 131 | ] 132 | } 133 | ``` 134 | 135 | 5. Create an IAM user in that group. Enable programmatic access (AWS API). 136 | Copy key and secret—this will be used during deployment. 137 | 138 | 6. Connect repository with your Jekyll site to Gitlab CI with configuration like this: 139 | 140 | ```yaml 141 | stages: 142 | - build 143 | - deploy 144 | 145 | build: 146 | stage: build 147 | image: ruby:2.4.4 148 | before_script: 149 | 150 | # Add SSH key to enable site build pull from repos. 151 | # You may be able to omit this if you specify HTTPS URLs for Git repos 152 | # (e.g., open project’s site.git_repo_url frontmatter variable). 153 | - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' 154 | - eval $(ssh-agent -s) 155 | - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null 156 | - mkdir -p ~/.ssh 157 | - chmod 700 ~/.ssh 158 | 159 | - gem install jekyll bundler 160 | - bundle 161 | script: 162 | - bundle exec jekyll build 163 | artifacts: 164 | paths: 165 | - _site/ 166 | 167 | deploy: 168 | stage: deploy 169 | image: python:latest 170 | before_script: 171 | - pip install awscli 172 | script: 173 | - aws s3 cp _site/ s3://$S3_BUCKET_NAME/ --recursive 174 | after_script: 175 | - rm -r _site 176 | ``` 177 | 178 | 7. Add following secret variables to your Gitlab CI configuration: 179 | 180 | - AWS_ACCESS_KEY_ID: your IAM user’s API key ID 181 | - AWS_DEFAULT_REGION: region chosen when creating S3 bucket 182 | - AWS_SECRET_ACCESS_KEY: your IAM user’s API key secret 183 | - S3_BUCKET_NAME: name of S3 bucket 184 | - SSH_PRIVATE_KEY: private key of GitHub user who’s authorized to clone 185 | requisite source repositories 186 | 187 | 8. Test by making a change and pushing it to the main branch. 188 | 189 | ### Troubleshooting 190 | 191 | #### Build: Gem not found 192 | 193 | If build stage fails with an error about gem not found, 194 | try updating CI build script, changing `bundle` to `bundle --full-index`. 195 | This may be needed if you’re using the latest theme version which 196 | was just recently published. --full-index will make build take longer, 197 | it’s advised to get rid of it when theme dependency becomes stable. 198 | 199 | #### Deploy: Access denied 200 | 201 | Ensure IAM group policy is correct. Bucket ARN should be correct, 202 | and should have the form of "arn:aws:s3:::/*" 203 | where the closing `/*` is important. 204 | 205 | ### Further improvements 206 | 207 | - In the long run it is recommended to avoid maintaining two separate copies 208 | of data (e.g., same project data for project site, and one for parent hub site, 209 | or reposting posts from project site blogs into hub blog). 210 | 211 | Ideally, during static site build the automation would pull relevant data 212 | from a centralized or distributed source and place it as needed 213 | inside Jekyll site structure before executing `jekyll build`. 214 | 215 | Common items that this documentation doesn’t cover, 216 | but guides are available elsewhere: 217 | 218 | - You may want to have separate staging and production branches in your 219 | CI configuration. 220 | 221 | - You may want to put CloudFront in front of your S3-hosted site. 222 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | gemspec 5 | 6 | gem 'bundler' 7 | gem 'rake' 8 | gem 'rubocop' 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Ribose 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | # require "rspec/core/rake_task" 5 | 6 | # Uncomment to enable the "spec" task 7 | # RSpec::Core::RakeTask.new(:spec) 8 | # 9 | # task :default => :spec 10 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | markdown: kramdown 2 | 3 | includes_dir: . 4 | 5 | permalink: /blog/:year-:month-:day-:title/ 6 | 7 | # algolia_search: 8 | # api_key: '' 9 | # index_name: '' 10 | # Uncomment this if you want to use Algolia’s search. 11 | # It’s free for open-source projects. 12 | 13 | exclude: 14 | - home-hero.html 15 | - title.html 16 | - nav-links.html 17 | - flavor-sample-summary.html 18 | - project-nav.html 19 | - /**/.git/* 20 | - /_projects/**/_*_repo/* 21 | - /_projects/*/assets/css/* 22 | - /_projects/**/docs/* 23 | - .sass-cache/ 24 | 25 | external_links: 26 | selector: 'body.site--project main a, body.site--hub.layout--post main a' 27 | ignored_selectors: 28 | - .layout--home a 29 | - a[href*=travis] 30 | - a[href*=coverity] 31 | - a[href*=codecov] 32 | 33 | landing_priority: [software, specs, blog] 34 | 35 | plugins: 36 | - jekyll-theme-rop 37 | - jekyll-seo-tag 38 | - jekyll-sitemap 39 | - jekyll-data 40 | - jekyll-asciidoc 41 | - jekyll-redirect-from 42 | - kramdown-parser-gfm 43 | - kramdown-syntax-coderay 44 | 45 | collections: 46 | projects: 47 | output: false 48 | software: 49 | output: true 50 | permalink: /software/:path/ 51 | specs: 52 | output: true 53 | permalink: /specs/:path/ 54 | posts: 55 | output: true 56 | permalink: /blog/:month-:day-:year/:title/ 57 | pages: 58 | output: true 59 | permalink: /:name/ 60 | 61 | fontawesome_cdn: 62 | version: v5.8.1 63 | integrity: "sha384-g5uSoOSBd7KkhAMlnQILrecXvzst9TdC09/VM+pjDTCM+1il8RHz5fKANTFFb+gQ" 64 | # Only applies if no_auto_fontawesome is not set. 65 | 66 | no_auto_fontawesome: false 67 | # If set to yes, site (with default design) must specify 29 | {% endunless %} 30 | 31 | {% if site.algolia_search %} 32 | 33 | {% endif %} 34 | 35 | {% if page.extra_stylesheets %} 36 | {% for ss in page.extra_stylesheets %} 37 | 38 | {% endfor %} 39 | {% endif %} 40 | 41 | {% if page.extra_scripts %} 42 | {% for sc in page.extra_scripts %} 43 | 44 | {% endfor %} 45 | {% endif %} 46 | 47 | {% seo %} 48 | 49 | {% include head.html %} 50 | 51 | 52 | {% assign num_projects = site.projects | size %} 53 | 62 |
63 |
64 |

{% include logo.html %}

65 | 68 | 69 | {% include social-links.html %} 70 | 71 | 75 | 76 | 83 |
84 | 85 | {% if page.hero_include %} 86 |
{% include {{ page.hero_include }} %}
87 | {% endif %} 88 |
89 | 90 |
91 | {{ content }} 92 |
93 | 94 | 127 | 128 | {% if site.algolia_search %} 129 | 130 | 131 | {% comment %} 132 | This would break a strict CSP, but Jekyll refuses to Liquid-process JS files 133 | without also adding HTML wrapping. Eek. 134 | TODO: Move this to data attributes on . 135 | {% endcomment %} 136 | 148 | {% endif %} 149 | 150 | 151 | 152 | 153 | 154 | 155 | {% include scripts.html %} 156 | 157 | -------------------------------------------------------------------------------- /_layouts/docs-base.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | {% assign title = page.title | default: layout.title %} 6 | {% assign prominent_title = page.article_header_title | default: layout.article_header_title %} 7 | {% assign nav = page.navigation | default: layout.navigation %} 8 | {% assign base_url = nav.base_url | default: page.base_url | default: layout.base_url | default: "" %} 9 | {% assign num_top_nav_items = nav.items | size %} 10 | 11 |
12 | 32 |
33 | 34 | 35 |
36 | 43 | 44 |
45 |
46 |
47 |

{{ prominent_title | default: title }}

48 |
49 | 50 | {% if site.github_repo_url or num_top_nav_items > 0 %} 51 | 60 | {% endif %} 61 | 62 |
63 |
{{ page.description }}
64 |
65 | 66 | {% if selected_item.items %} 67 | 76 | {% endif %} 77 |
78 | 79 |
80 | {{ content }} 81 |
82 | 83 |
84 |
85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | {{ content }} 6 | 7 | {% assign num_projects = site.projects | size %} 8 | 9 | {% if num_projects > 0 %} 10 | {% include home-hub.html %} 11 | {% else %} 12 | {% include home-project.html %} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | {{ content }} 6 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 |

{{ page.title }}

8 | 9 |
10 | {% include _post-meta.html post=page %} 11 |
12 |
13 | 14 | {% assign num_social_links = page.author.social_links | size %} 15 | {% if num_social_links > 0 %} 16 | 52 | {% endif %} 53 | 54 |
55 | {{ content }} 56 |
57 |
58 | -------------------------------------------------------------------------------- /_layouts/product.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | html-class: docs-page 4 | --- 5 | 6 | {% include item-doc-page.html items=site.software item_type='software' %} 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /_layouts/project-index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | {% assign projects = site.projects | where_exp: "item", "item.home_url != nil" %} 5 | {% assign num_projects = projects | size %} 6 | 7 | {% if num_projects > 0 %} 8 |
9 | {% include assets/symbol.svg %} 10 | 11 | {% for project in projects %} 12 | 15 | 16 |
17 |
18 | {% assign symbol_path = project.path | split: "/" | slice: 1, 1 | join: "/" | append: "/assets/symbol.svg" %} 19 | {% assign relative_symbol_path = "/projects/" | append: symbol_path %} 20 | 21 |
22 |

{{ project.title }}

23 |
24 | 25 |

26 | {{ project.description }} 27 |

28 | 29 |
30 | {% assign num_tags = project.tags | size %} 31 | {% if num_tags > 0 %} 32 |
    33 | {% for tag in project.tags %} 34 |
  • {{ tag }}
  • 35 | {% endfor %} 36 |
37 | {% endif %} 38 |
39 | 40 |
41 | {% endfor %} 42 |
43 | {% else %} 44 |

No projects to display.

45 | {% endif %} 46 | -------------------------------------------------------------------------------- /_layouts/software-index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | {% include index-page-item-filter.html url_tag_prefix="/software/" tag_namespaces="software" items=site.all_software tag=page.tag %} 6 | 7 |
8 | {% if site.is_hub %} 9 | {% include assets/symbol.svg %} 10 | {% endif %} 11 | 12 | {% if page.tag and page.items %} 13 | {% for item in page.items %} 14 | {% include software-card-hub.html item=item item_type='software' %} 15 | {% endfor %} 16 | {% elsif site.is_hub %} 17 | {% for item in site.all_software %} 18 | {% include software-card-hub.html item=item item_type='software' %} 19 | {% endfor %} 20 | {% else %} 21 | {% if site.num_featured_software > 0 %} 22 | {% for item in site.featured_software %} 23 | {% include software-card-hub.html item=item item_type='software' %} 24 | {% endfor %} 25 |
26 | {% endif %} 27 | {% for item in site.non_featured_software %} 28 | {% include software-card-hub.html item=item item_type='software' %} 29 | {% endfor %} 30 | {% endif %} 31 |
32 | -------------------------------------------------------------------------------- /_layouts/spec-index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | {% include index-page-item-filter.html url_tag_prefix="/specs/" tag_namespaces="specs" items=site.all_specs tag=page.tag %} 6 | 7 |
8 | {% if site.is_hub %} 9 | {% include assets/symbol.svg %} 10 | {% endif %} 11 | 12 | {% if page.tag and page.items %} 13 | {% for item in page.items %} 14 | {% include software-card-hub.html item=item item_type='specs' %} 15 | {% endfor %} 16 | {% elsif site.is_hub %} 17 | {% for item in site.all_specs %} 18 | {% include software-card-hub.html item=item item_type='specs' %} 19 | {% endfor %} 20 | {% else %} 21 | {% if site.num_featured_specs > 0 %} 22 | {% for item in site.featured_specs %} 23 | {% include software-card-hub.html item=item item_type='specs' %} 24 | {% endfor %} 25 |
26 | {% endif %} 27 | {% for item in site.non_featured_specs %} 28 | {% include software-card-hub.html item=item item_type='specs' %} 29 | {% endfor %} 30 | {% endif %} 31 |
32 | -------------------------------------------------------------------------------- /_layouts/spec.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | html-class: docs-page 4 | --- 5 | 6 | {% include item-doc-page.html items=site.specs item_type='specs' %} 7 | -------------------------------------------------------------------------------- /_pages/blog.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | description: >- 4 | Get the latest announcements and technical how-to’s 5 | about our software and projects. 6 | layout: blog-index 7 | hero_include: index-page-hero.html 8 | --- 9 | -------------------------------------------------------------------------------- /_pages/software.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Software ecosystem 3 | description: Open-source tools conforming to our specifications. 4 | layout: software-index 5 | hero_include: index-page-hero.html 6 | --- 7 | -------------------------------------------------------------------------------- /_pages/specs.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Specifications 3 | description: Standards at the foundation of this project. 4 | layout: spec-index 5 | hero_include: index-page-hero.html 6 | --- 7 | -------------------------------------------------------------------------------- /_posts/2018-04-20-welcome-to-jekyll.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Welcome to Jekyll!" 4 | date: 2018-04-20 00:29:11 +0700 5 | categories: jekyll update 6 | author: John Smith 7 | --- 8 | You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated. 9 | 10 | To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works. 11 | 12 | Jekyll also offers powerful support for code snippets: 13 | 14 | {% highlight ruby %} 15 | def print_hi(name) 16 | puts "Hi, #{name}" 17 | end 18 | print_hi('Tom') 19 | #=> prints 'Hi, Tom' to STDOUT. 20 | {% endhighlight %} 21 | 22 | Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk]. 23 | 24 | [jekyll-docs]: https://jekyllrb.com/docs/home 25 | [jekyll-gh]: https://github.com/jekyll/jekyll 26 | [jekyll-talk]: https://talk.jekyllrb.com/ 27 | -------------------------------------------------------------------------------- /_sass/headroom.scss: -------------------------------------------------------------------------------- 1 | .headroom { 2 | will-change: transform; 3 | transition: transform .1s linear; 4 | } 5 | .headroom--pinned { 6 | transform: translateY(0%); 7 | } 8 | .headroom--unpinned { 9 | transform: translateY(-100%); 10 | } 11 | 12 | body.with-headroom { 13 | &.docs-page { 14 | .underlay.header { 15 | position: fixed; 16 | top: 0; 17 | left: 0; 18 | right: 0; 19 | z-index: 6; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /_sass/jekyll-theme-open-project.scss: -------------------------------------------------------------------------------- 1 | // Compatibility file for old name 2 | @import "jekyll-theme-rop"; 3 | -------------------------------------------------------------------------------- /_sass/jekyll-theme-rop.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Inconsolata'); 2 | 3 | $font-family: Helvetica, Arial, sans-serif !default; 4 | $font-family-source: Inconsolata, monospace; 5 | 6 | $main-font-color: #000; 7 | 8 | $code-listing-background-color: rgba($main-font-color, 0.03); 9 | $code-listing-border-color: lighten($main-font-color, 70); 10 | 11 | $primary-color: lightblue !default; 12 | $primary-dark-color: $primary-color !default; 13 | $accent-color: red !default; 14 | 15 | $warning-color: red !default; 16 | $important-color: orange !default; 17 | 18 | $main-background: linear-gradient(315deg, $accent-color 0%, $primary-color 74%) !default; 19 | $header-background: $main-background !default; 20 | 21 | $hub-software--primary-color: lightsalmon !default; 22 | $hub-software--primary-dark-color: tomato !default; 23 | $hub-software--hero-background: $hub-software--primary-dark-color !default; 24 | 25 | $hub-specs--primary-color: lightpink !default; 26 | $hub-specs--primary-dark-color: palevioletred !default; 27 | $hub-specs--hero-background: $hub-specs--primary-dark-color !default; 28 | 29 | $gutter: 15px; 30 | $featured-cols: 3; 31 | $featured-cols-narrow: 2; 32 | $grid-cols: 3; 33 | $grid-cols-narrow: 2; 34 | 35 | $widescreen-breakpoint: 1140px + $gutter * 2; 36 | $bigscreen-breakpoint: 800px + $gutter * 2; 37 | 38 | $external-links-side-margin: 16px; // for external links 39 | 40 | 41 | @import "rop-base"; 42 | @import "rop-header-footer"; 43 | @import "headroom"; 44 | 45 | 46 | main { 47 | 48 | /* Generic */ 49 | 50 | .layout--home > & { 51 | padding-bottom: 2em; 52 | 53 | > .featured-posts { 54 | @extend .main-section; 55 | 56 | .items { 57 | @extend .item-grid; 58 | justify-content: center; 59 | } 60 | 61 | .item { 62 | @extend .item-card; 63 | @extend .post-card; 64 | @include hoverable-card(4px, 12px, rgba(0, 0, 0, 0.08)); 65 | 66 | padding: 32px 30px; 67 | box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08); 68 | 69 | .header { 70 | font-size: 22px; 71 | } 72 | 73 | .body, .meta { 74 | font-size: 15px; 75 | } 76 | 77 | @media screen and (min-width: $bigscreen-breakpoint) { 78 | box-sizing: border-box; 79 | flex-basis: calc( 100%/#{$featured-cols-narrow} - #{$gutter} ); 80 | 81 | // Hide third element (there’re at most 3) 82 | &:nth-child(3) { 83 | opacity: 0; 84 | display: none; 85 | } 86 | } 87 | 88 | @media screen and (min-width: $widescreen-breakpoint) { 89 | box-sizing: border-box; 90 | flex-basis: calc( 100%/#{$featured-cols} - #{$gutter} ); 91 | 92 | // Show third element 93 | &:nth-child(3) { 94 | opacity: 1; 95 | display: flex; 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | .layout--spec-index > &, 103 | .layout--software-index > &, 104 | .layout--blog-index > &, 105 | .layout--product > &, 106 | .layout--post > &, 107 | .layout--spec > &, 108 | .layout--project-index > &, 109 | .docs-page > & { 110 | padding-bottom: 50px; 111 | 112 | @media screen and (min-width: $bigscreen-breakpoint) { 113 | padding-bottom: 100px; 114 | } 115 | } 116 | 117 | .layout--home > & { 118 | padding-bottom: 50px; 119 | } 120 | 121 | .layout--spec-index > &, 122 | .layout--software-index > & { 123 | > .filter-header { 124 | // Shown when a tag is selected. 125 | background-color: #fafafa; 126 | font-size: 80%; 127 | box-shadow: 0 4px 40px -14px rgba(0, 0, 0, 0.4); 128 | border-radius: .5em; 129 | margin-top: -.5em; 130 | 131 | .title { 132 | font-weight: normal; 133 | text-align: center; 134 | 135 | .tag { 136 | white-space: nowrap; 137 | font-weight: bold; 138 | 139 | .namespace { 140 | font-weight: normal; 141 | } 142 | 143 | &:before { content: "“"; font-weight: normal; } 144 | &:after { content: "”"; font-weight: normal; } 145 | } 146 | a.show-all { 147 | white-space: nowrap; 148 | } 149 | } 150 | } 151 | > .item-filter { 152 | padding: 18px 2em; 153 | background-color: #F3F3F3; 154 | align-self: stretch; 155 | text-align: left; 156 | 157 | .namespace, ul.tags { 158 | font-size: 14px; 159 | } 160 | 161 | .namespace { 162 | display: flex; 163 | flex-flow: row nowrap; 164 | align-items: flex-start; 165 | margin-top: .5em; 166 | 167 | .namespace-title { 168 | margin-right: 14px; 169 | } 170 | 171 | &.empty { 172 | display: none; 173 | } 174 | 175 | &:first-child { 176 | margin-top: 0; 177 | } 178 | } 179 | 180 | ul.tags { 181 | flex: 1; 182 | 183 | list-style: none; 184 | margin: 0; 185 | padding: 0; 186 | 187 | white-space: nowrap; 188 | overflow-x: scroll; 189 | overflow-y: hidden; 190 | 191 | text-overflow: ellipsis; 192 | 193 | > li { 194 | display: inline; 195 | margin: 0; 196 | padding: 0; 197 | 198 | > * { 199 | font-weight: 700; 200 | margin: 0 4px; 201 | padding: 3px 10px 3px 10px; 202 | white-space: nowrap; 203 | 204 | &:first-child { 205 | margin-left: -10px; 206 | } 207 | } 208 | > a { 209 | color: grey; 210 | } 211 | } 212 | 213 | &.scrolled { 214 | text-overflow: unset; 215 | } 216 | } 217 | } 218 | } 219 | // Item filter: color override for selected tags 220 | > .item-filter ul.tags li > span { 221 | .layout--software-index > & { 222 | color: $hub-software--primary-dark-color; 223 | background-color: rgba($hub-software--primary-color, 0.1); 224 | } 225 | .layout--spec-index > & { 226 | color: $hub-specs--primary-dark-color; 227 | background-color: rgba($hub-specs--primary-color, 0.1); 228 | } 229 | } 230 | 231 | .layout--blog-index > & { 232 | > .items { 233 | @extend .item-grid; 234 | @extend .index-item-grid; 235 | 236 | .item { 237 | @extend .item-card; 238 | @extend .post-card; 239 | @include hoverable-card(4px, 12px, rgba(0, 0, 0, 0.08)); 240 | 241 | padding: 30px 30px 16px 30px; 242 | 243 | .header { 244 | font-size: 22px; 245 | } 246 | .body { 247 | font-size: 15px; 248 | } 249 | 250 | @media screen and (min-width: $bigscreen-breakpoint) { 251 | box-sizing: border-box; 252 | flex-basis: calc( 100%/#{$featured-cols-narrow} - #{$gutter} ); 253 | margin-bottom: $gutter; 254 | 255 | &.has-cover-image { 256 | flex-basis: 100%; 257 | } 258 | } 259 | @media screen and (min-width: $widescreen-breakpoint) { 260 | box-sizing: border-box; 261 | flex-basis: calc( 100%/#{$featured-cols} - #{$gutter} ); 262 | margin-bottom: $gutter; 263 | 264 | &.has-cover-image { 265 | flex-basis: calc( 100%/#{$featured-cols} * 2 - #{$gutter} ); 266 | } 267 | } 268 | } 269 | } 270 | 271 | > .items.one-row { 272 | justify-content: center; 273 | } 274 | } 275 | 276 | .layout--post > & { 277 | > article { 278 | @extend .main-article; 279 | 280 | > header { 281 | > .title { 282 | margin-bottom: 14px; 283 | } 284 | > .meta { 285 | @extend .post-meta-row; 286 | margin-bottom: 36px; 287 | } 288 | } 289 | aside.social-links { 290 | position: relative; 291 | top: -10px; 292 | margin-bottom: 14px; 293 | 294 | .ico-ext { 295 | display: none; 296 | } 297 | 298 | @media screen and (min-width: $bigscreen-breakpoint) { 299 | // "Remove" from the flow, and offset to the left 300 | $height: 100px; 301 | 302 | height: $height; 303 | width: 80px; 304 | 305 | margin-bottom: -$height; 306 | 307 | top: 10px; 308 | left: -140px; 309 | 310 | display: flex; 311 | flex-flow: column nowrap; 312 | align-items: flex-start; 313 | } 314 | 315 | > .ico { 316 | margin-right: 5px; 317 | 318 | @media screen and (min-width: $bigscreen-breakpoint) { 319 | margin-right: 0; 320 | margin-bottom: 5px; 321 | } 322 | 323 | .fa-layers { 324 | > .fa-circle { 325 | color: $primary-color; 326 | } 327 | > :not(.fa-circle) { 328 | color: white; 329 | } 330 | } 331 | } 332 | } 333 | } 334 | } 335 | } 336 | 337 | 338 | /* Hub */ 339 | 340 | .site--hub { 341 | 342 | &.layout--home > main { 343 | > .featured-projects { 344 | @extend .main-section; 345 | 346 | > .title:after { 347 | border-bottom-color: rgba($primary-dark-color, 0.12); 348 | } 349 | 350 | .items { 351 | @extend .item-grid; 352 | justify-content: center; 353 | } 354 | 355 | .item { 356 | @extend .item-card; 357 | @include hoverable-card(4px, 16px, rgba(0, 0, 0, 0.12)); 358 | 359 | padding: 40px 32px; 360 | text-align: center; 361 | 362 | display: flex; 363 | flex-flow: column nowrap; 364 | 365 | box-sizing: border-box; 366 | 367 | @media screen and (min-width: $bigscreen-breakpoint) { 368 | flex-basis: calc( 100%/#{$featured-cols} - #{$gutter} ); 369 | } 370 | 371 | .logo { 372 | display: inline-block; 373 | height: 80px; 374 | width: 80px; 375 | 376 | // Without this, some items’ logos don’t conform to above dimensions 377 | overflow: hidden; 378 | } 379 | 380 | header > .title { 381 | font-size: 24px; 382 | margin: 0; 383 | } 384 | 385 | .body { 386 | flex: 1; 387 | font-size: 16px; 388 | margin-bottom: 1em; 389 | overflow: hidden; 390 | text-overflow: ellipsis; 391 | 392 | @media screen and (min-width: $bigscreen-breakpoint) { 393 | height: 100px; 394 | padding-bottom: 0; 395 | } 396 | } 397 | 398 | .cta-view-project { 399 | text-align: center; 400 | 401 | .button { 402 | display: inline-block; 403 | padding: 8px 18px; 404 | border-radius: 4px; 405 | font-size: 16px; 406 | font-weight: 700; 407 | color: white; 408 | background-color: $accent-color; 409 | } 410 | } 411 | } 412 | } 413 | 414 | > .other-projects { 415 | @extend .main-section; 416 | @extend .with-symbol-background; 417 | 418 | .items { 419 | @extend .item-grid; 420 | } 421 | 422 | > .title:after { 423 | border-bottom-color: rgba($primary-color, 0.12); 424 | } 425 | } 426 | } 427 | 428 | &.layout--software-index > main, 429 | &.layout--spec-index > main { 430 | > .items { 431 | @extend .item-grid; 432 | @extend .index-item-grid; 433 | 434 | .item { 435 | @extend .item-card; 436 | @include hoverable-card(4px, 12px, rgba(0, 0, 0, 0.08)); 437 | 438 | padding: 16px 30px 22px 30px; 439 | 440 | .header { 441 | font-size: 18px; 442 | } 443 | .body { 444 | font-size: 15px; 445 | } 446 | 447 | @media screen and (min-width: $bigscreen-breakpoint) { 448 | box-sizing: border-box; 449 | flex-basis: calc( 100%/#{$grid-cols-narrow} - #{$gutter} ); 450 | margin-bottom: $gutter; 451 | } 452 | 453 | @media screen and (min-width: $widescreen-breakpoint) { 454 | box-sizing: border-box; 455 | flex-basis: calc( 100%/#{$grid-cols} - #{$gutter} ); 456 | margin-bottom: $gutter; 457 | } 458 | } 459 | } 460 | } 461 | 462 | &.layout--project-index > main { 463 | .items { 464 | @extend .item-grid; 465 | @extend .index-item-grid; 466 | } 467 | } 468 | 469 | &.layout--project-index > main, 470 | &.layout--blog-index > main, 471 | &.layout--software-index > main, 472 | &.layout--spec-index > main { 473 | > .items { 474 | @extend .with-symbol-background; 475 | } 476 | } 477 | 478 | &.layout--home > main > .other-projects, 479 | &.layout--project-index > main { 480 | .items.one-row { 481 | justify-content: center; 482 | } 483 | 484 | .item { 485 | @extend .item-card; 486 | @include hoverable-card(2px, 10px, rgba(desaturate($primary-color, 50), 0.08)); 487 | 488 | padding: 32px 30px; 489 | text-align: center; 490 | 491 | .logo { 492 | display: inline-block; 493 | height: 60px; 494 | width: 60px; 495 | } 496 | 497 | header > .title { 498 | font-size: 18px; 499 | margin: 0; 500 | } 501 | 502 | .body { 503 | font-size: 15px; 504 | } 505 | 506 | @media screen and (min-width: $bigscreen-breakpoint) { 507 | box-sizing: border-box; 508 | flex-basis: calc( 100%/#{$featured-cols} - #{$gutter} ); 509 | } 510 | } 511 | } 512 | } 513 | 514 | 515 | /* Project */ 516 | 517 | body.site--project { 518 | &.layout--home { 519 | background: $main-background; 520 | } 521 | 522 | &.layout--home > main { 523 | .item { 524 | background: linear-gradient(120deg, white 20%, rgba(white, 0.9) 80%, rgba(white, 0.75) 100%); 525 | 526 | display: flex; 527 | flex-flow: column nowrap; 528 | padding: 1em 1.5em; 529 | 530 | .body { 531 | flex: 1; 532 | } 533 | 534 | .title { 535 | font-size: 24px; 536 | font-weight: normal; 537 | word-break: break-word; 538 | } 539 | 540 | .docs-nav { 541 | flex-basis: 100%; 542 | margin-bottom: 1em; 543 | @include item-nav-toc(); 544 | } 545 | 546 | .external-links { 547 | @include item-external-links(); 548 | margin-left: -1.5em; 549 | margin-right: -1.5em; 550 | 551 | .nav-items { 552 | display: flex; 553 | flex-direction: row; 554 | flex-wrap: wrap-reverse; 555 | 556 | a { 557 | white-space: nowrap; 558 | } 559 | } 560 | } 561 | } 562 | 563 | > .custom-intro { 564 | .summary { 565 | font-size: 20px; 566 | color: #fefefe; 567 | 568 | a { 569 | @include static-link-color($accent-color); 570 | } 571 | .cta { 572 | margin-top: 30px; 573 | margin-bottom: 30px; 574 | .button { 575 | @include cta-button($primary-color, white); 576 | border: 1px solid $accent-color; 577 | } 578 | } 579 | p:first-child:first-letter { 580 | color: $accent-color; 581 | float: left; 582 | font-size: 75px; 583 | line-height: 60px; 584 | padding-right: 8px; 585 | margin-left: -5px; 586 | } 587 | @media screen and (min-width: $bigscreen-breakpoint) { 588 | p:first-child { 589 | padding-right: 20vw; 590 | } 591 | } 592 | } 593 | } 594 | } 595 | 596 | &.site--project--one-software.layout--home > main { 597 | // On single-software project sites, the only software item on landing 598 | // is made part of the page rather than being constrained to a card widget. 599 | // No own background means it’ll appear on landing page’s overall dark background. 600 | 601 | .custom-intro { 602 | .summary { 603 | a { 604 | @include static-link-color(white); 605 | } 606 | } 607 | } 608 | 609 | .item { 610 | background: none; 611 | padding: 0; 612 | 613 | .docs-nav { 614 | ul.nav-items > li { 615 | > .item-title { 616 | font-size: 24px; 617 | 618 | a { 619 | @include static-link-color(white); 620 | } 621 | } 622 | } 623 | } 624 | .external-links { 625 | @include item-external-links(true); 626 | margin-left: 0; 627 | margin-right: 0; 628 | } 629 | } 630 | } 631 | 632 | &.layout--home > main > .software, 633 | &.layout--home > main > .specs, 634 | &.layout--software-index > main, 635 | &.layout--spec-index > main { 636 | > .items { 637 | > hr { 638 | // Separates featured items, listed initially, from the rest 639 | width: 10em; 640 | margin: 40px auto; 641 | border-style: solid; 642 | border-color: $primary-color; 643 | background-color: $primary-color; 644 | color: $primary-color; 645 | box-shadow: 2px 2px 0 3px $primary-color; 646 | } 647 | 648 | .item { 649 | flex: 1; 650 | text-align: left; 651 | 652 | header > .title { 653 | margin: 0; 654 | } 655 | .body { 656 | font-size: 16px; 657 | } 658 | } 659 | } 660 | } 661 | 662 | &.layout--software-index > main, 663 | &.layout--spec-index > main { 664 | > .items .item { 665 | display: block; 666 | } 667 | } 668 | 669 | &.layout--software-index > main, 670 | &.layout--spec-index > main { 671 | > .items .item { 672 | @extend .item-card; 673 | @include hoverable-card(2px, 10px, rgba(desaturate($primary-color, 50), 0.08)); 674 | 675 | padding: 30px 32px; 676 | flex: unset; 677 | } 678 | } 679 | 680 | &.layout--home > main > .software { 681 | > .items { 682 | .item { 683 | $logo-space: 64px; 684 | $logo-side: 32px; 685 | 686 | header { 687 | display: flex; 688 | flex-flow: row nowrap; 689 | align-items: center; 690 | flex-shrink: 0; 691 | 692 | .title { 693 | flex: 1; 694 | } 695 | .logo-container { 696 | width: $logo-space; 697 | flex: 0; 698 | padding: 4px ($logo-space - $logo-side) 4px 0; 699 | 700 | .logo > :only-child { 701 | width: $logo-side; 702 | height: $logo-side; 703 | vertical-align: middle; 704 | } 705 | } 706 | } 707 | } 708 | } 709 | } 710 | 711 | &.layout--software-index > main { 712 | > .items { 713 | .item { 714 | $logo-space: 132px; 715 | $logo-side: 48px; 716 | 717 | .logo-container { 718 | .logo > :only-child { 719 | width: $logo-side; 720 | height: $logo-side; 721 | } 722 | } 723 | 724 | @media screen and (min-width: $bigscreen-breakpoint) { 725 | padding-left: $logo-space; 726 | 727 | .logo-container { 728 | float: left; 729 | margin-left: -$logo-space; 730 | padding: 8px calc(($logo-space - $logo-side) / 2); 731 | } 732 | } 733 | } 734 | } 735 | } 736 | 737 | &.layout--home > main > .software, 738 | &.layout--home > main > .specs { 739 | @extend .main-section; 740 | 741 | > .title { 742 | padding: .4em 1.5em; 743 | background: rgba(white, 0.9); 744 | font-size: 110%; 745 | font-weight: normal; 746 | align-self: flex-start; 747 | color: lighten($main-font-color, 20); 748 | margin-bottom: $gutter; 749 | 750 | a { 751 | @include static-link-color($primary-dark-color); 752 | } 753 | } 754 | 755 | .items { 756 | @extend .item-grid; 757 | justify-content: center; 758 | 759 | > .item { 760 | @media screen and (min-width: $bigscreen-breakpoint) { 761 | box-sizing: border-box; 762 | flex-basis: calc( 100%/#{$featured-cols-narrow} - #{$gutter} ); 763 | 764 | // Hide third element (there’re at most 3) 765 | &:nth-child(3) { 766 | opacity: 0; 767 | display: none; 768 | } 769 | } 770 | 771 | @media screen and (min-width: $widescreen-breakpoint) { 772 | box-sizing: border-box; 773 | flex-basis: calc( 100%/#{$featured-cols} - #{$gutter} ); 774 | 775 | // Show third element 776 | &:nth-child(3) { 777 | opacity: 1; 778 | display: flex; 779 | } 780 | } 781 | } 782 | } 783 | } 784 | 785 | &.layout--software-index > main, 786 | &.layout--spec-index > main { 787 | > .items { 788 | @extend .index-item-grid; 789 | } 790 | } 791 | 792 | &.layout--spec > main > article { 793 | @extend .main-article; 794 | } 795 | &.docs-page > main { 796 | @include docs-page($primary-dark-color); 797 | } 798 | } 799 | -------------------------------------------------------------------------------- /_sass/normalize.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | box-sizing: content-box; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Contain overflow in all browsers. 218 | */ 219 | 220 | pre { 221 | overflow: auto; 222 | } 223 | 224 | /** 225 | * Address odd `em`-unit font size rendering in all browsers. 226 | */ 227 | 228 | code, 229 | kbd, 230 | pre, 231 | samp { 232 | font-family: monospace, monospace; 233 | font-size: 1em; 234 | } 235 | 236 | /* Forms 237 | ========================================================================== */ 238 | 239 | /** 240 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 241 | * styling of `select`, unless a `border` property is set. 242 | */ 243 | 244 | /** 245 | * 1. Correct color not being inherited. 246 | * Known issue: affects color of disabled elements. 247 | * 2. Correct font properties not being inherited. 248 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 249 | */ 250 | 251 | button, 252 | input, 253 | optgroup, 254 | select, 255 | textarea { 256 | color: inherit; /* 1 */ 257 | font: inherit; /* 2 */ 258 | margin: 0; /* 3 */ 259 | } 260 | 261 | /** 262 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 263 | */ 264 | 265 | button { 266 | overflow: visible; 267 | } 268 | 269 | /** 270 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 271 | * All other form control elements do not inherit `text-transform` values. 272 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 273 | * Correct `select` style inheritance in Firefox. 274 | */ 275 | 276 | button, 277 | select { 278 | text-transform: none; 279 | } 280 | 281 | /** 282 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 283 | * and `video` controls. 284 | * 2. Correct inability to style clickable `input` types in iOS. 285 | * 3. Improve usability and consistency of cursor style between image-type 286 | * `input` and others. 287 | */ 288 | 289 | button, 290 | html input[type="button"], /* 1 */ 291 | input[type="reset"], 292 | input[type="submit"] { 293 | -webkit-appearance: button; /* 2 */ 294 | cursor: pointer; /* 3 */ 295 | } 296 | 297 | /** 298 | * Re-set default cursor for disabled elements. 299 | */ 300 | 301 | button[disabled], 302 | html input[disabled] { 303 | cursor: default; 304 | } 305 | 306 | /** 307 | * Remove inner padding and border in Firefox 4+. 308 | */ 309 | 310 | button::-moz-focus-inner, 311 | input::-moz-focus-inner { 312 | border: 0; 313 | padding: 0; 314 | } 315 | 316 | /** 317 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 318 | * the UA stylesheet. 319 | */ 320 | 321 | input { 322 | line-height: normal; 323 | } 324 | 325 | /** 326 | * It's recommended that you don't attempt to style these elements. 327 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 328 | * 329 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 330 | * 2. Remove excess padding in IE 8/9/10. 331 | */ 332 | 333 | input[type="checkbox"], 334 | input[type="radio"] { 335 | box-sizing: border-box; /* 1 */ 336 | padding: 0; /* 2 */ 337 | } 338 | 339 | /** 340 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 341 | * `font-size` values of the `input`, it causes the cursor style of the 342 | * decrement button to change from `default` to `text`. 343 | */ 344 | 345 | input[type="number"]::-webkit-inner-spin-button, 346 | input[type="number"]::-webkit-outer-spin-button { 347 | height: auto; 348 | } 349 | 350 | /** 351 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 352 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 353 | * (include `-moz` to future-proof). 354 | */ 355 | 356 | input[type="search"] { 357 | -webkit-appearance: textfield; /* 1 */ /* 2 */ 358 | box-sizing: content-box; 359 | } 360 | 361 | /** 362 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 363 | * Safari (but not Chrome) clips the cancel button when the search input has 364 | * padding (and `textfield` appearance). 365 | */ 366 | 367 | input[type="search"]::-webkit-search-cancel-button, 368 | input[type="search"]::-webkit-search-decoration { 369 | -webkit-appearance: none; 370 | } 371 | 372 | /** 373 | * Define consistent border, margin, and padding. 374 | */ 375 | 376 | fieldset { 377 | border: 1px solid #c0c0c0; 378 | margin: 0 2px; 379 | padding: 0.35em 0.625em 0.75em; 380 | } 381 | 382 | /** 383 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 384 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 385 | */ 386 | 387 | legend { 388 | border: 0; /* 1 */ 389 | padding: 0; /* 2 */ 390 | } 391 | 392 | /** 393 | * Remove default vertical scrollbar in IE 8/9/10/11. 394 | */ 395 | 396 | textarea { 397 | overflow: auto; 398 | } 399 | 400 | /** 401 | * Don't inherit the `font-weight` (applied by a rule above). 402 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 403 | */ 404 | 405 | optgroup { 406 | font-weight: bold; 407 | } 408 | 409 | /* Tables 410 | ========================================================================== */ 411 | 412 | /** 413 | * Remove most spacing between table cells. 414 | */ 415 | 416 | table { 417 | border-collapse: collapse; 418 | border-spacing: 0; 419 | } 420 | 421 | td, 422 | th { 423 | padding: 0; 424 | } 425 | -------------------------------------------------------------------------------- /_sass/rop-base.scss: -------------------------------------------------------------------------------- 1 | @import 'rop-mixins'; 2 | 3 | $easeOutCirc: cubic-bezier(0.075, 0.82, 0.165, 1); 4 | 5 | body { 6 | font-family: $font-family; 7 | font-size: 15px; 8 | line-height: 1.6; 9 | 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | 13 | color: $main-font-color; 14 | } 15 | 16 | abbr { 17 | cursor: help; 18 | } 19 | 20 | .svg-inline--fa { 21 | vertical-align: -.15em; 22 | } 23 | 24 | a { 25 | &:link, &:hover, &:visited { 26 | color: $primary-dark-color; 27 | text-decoration: none; 28 | } 29 | } 30 | 31 | .item-grid { 32 | @media screen and (min-width: $bigscreen-breakpoint) { 33 | margin: 0 -#{$gutter} 0 0; 34 | display: flex; 35 | flex-flow: row wrap; 36 | justify-content: flex-start; 37 | 38 | > .item { 39 | margin-right: $gutter; 40 | 41 | &:only-child { 42 | flex: 1; 43 | } 44 | 45 | &.featured-item::before { 46 | // Reposition featured item label for grid layout 47 | // !important overrides .item-card which ends up with higher specificity 48 | top: 0 !important; 49 | right: 0 !important; 50 | left: auto !important; 51 | bottom: auto !important; 52 | } 53 | } 54 | } 55 | } 56 | 57 | .index-item-grid { 58 | margin-top: 40px; 59 | padding: 0; // Override padding set by main section 60 | 61 | @media screen and (min-width: $bigscreen-breakpoint) { 62 | margin-top: 80px; 63 | } 64 | } 65 | 66 | .main-section { 67 | margin-top: 1em; 68 | margin-bottom: 1em; 69 | 70 | display: flex; 71 | flex-flow: column nowrap; 72 | 73 | > .puny-label { 74 | // DEPRECATED: Used only on hub site, old design 75 | align-self: center; 76 | 77 | text-align: center; 78 | margin: 0; 79 | font-size: 18px; 80 | font-weight: 600; 81 | color: $primary-color; 82 | } 83 | 84 | > .title { 85 | align-self: center; 86 | 87 | text-align: center; 88 | font-weight: 600; 89 | 90 | margin-top: 0; 91 | margin-bottom: 1em; 92 | 93 | position: relative; 94 | 95 | color: white; 96 | 97 | a { 98 | @include static-link-color(white); 99 | } 100 | 101 | .more-link { 102 | margin-left: .5em; 103 | font-size: 70%; 104 | } 105 | 106 | &:after { 107 | // Underlaying border feature can be turned on 108 | // in extending sections by providing border-bottom-color 109 | // on this :after element. 110 | content: " "; 111 | border-bottom-width: 12px; 112 | border-bottom-style: solid; 113 | border-bottom-color: transparent; 114 | position: absolute; 115 | bottom: 8px; 116 | left: -5px; 117 | right: -5px; 118 | z-index: -1; 119 | } 120 | } 121 | 122 | > .items { 123 | align-self: stretch; 124 | } 125 | } 126 | 127 | .with-symbol-background { 128 | position: relative; 129 | 130 | > * { 131 | z-index: 1; 132 | position: relative; 133 | } 134 | > svg { 135 | z-index: 0; 136 | position: absolute; 137 | top: -38px; 138 | right: -60px; 139 | height: 525px; 140 | width: 525px; 141 | path { 142 | fill: rgba($primary-color, 0.08); 143 | } 144 | } 145 | } 146 | 147 | .item-card { 148 | background: white; 149 | 150 | display: flex; 151 | flex-flow: column nowrap; 152 | 153 | position: relative; 154 | overflow: hidden; 155 | 156 | .card-body { 157 | height: 100%; 158 | display: flex; 159 | flex-flow: column nowrap; 160 | } 161 | 162 | .body { 163 | flex: 1; 164 | } 165 | 166 | &:link, &:hover, &:visited { 167 | color: inherit; 168 | text-decoration: none; 169 | } 170 | 171 | &.featured-item::before { 172 | content: "featured"; 173 | 174 | position: absolute; 175 | bottom: 2.5em; 176 | right: 2em; 177 | padding: 2px 6px; 178 | font-size: 12px; 179 | background: linear-gradient(135deg, rgba($primary-color, 0.7) 0%, rgba($primary-dark-color, 0.9) 100%); 180 | color: white; 181 | font-weight: bold; 182 | } 183 | 184 | header { 185 | > .parent-project { 186 | display: flex; 187 | flex-flow: row nowrap; 188 | align-items: center; 189 | justify-content: space-between; 190 | 191 | .project-logo { 192 | width: 32px; 193 | height: 32px; 194 | vertical-align: middle; 195 | margin-right: 10px; 196 | 197 | display: flex; 198 | flex-flow: column nowrap; 199 | justify-content: center; 200 | } 201 | .project-title { 202 | font-size: 14px; 203 | font-weight: 600; 204 | flex: 1; 205 | 206 | color: $primary-color; 207 | .layout--software-index & { 208 | color: $hub-software--primary-color; 209 | } 210 | .layout--spec-index & { 211 | color: $hub-specs--primary-color; 212 | } 213 | } 214 | } 215 | > .title { 216 | font-weight: 600; 217 | font-size: 20px; 218 | margin: 0 0 .5em 0; 219 | } 220 | } 221 | 222 | .body { 223 | margin: 0; 224 | } 225 | 226 | footer { 227 | color: grey; 228 | font-size: 14px; 229 | 230 | .last-update, .tags { 231 | margin: 6px 0 0 0; 232 | } 233 | 234 | .last-update { 235 | padding: 0; 236 | } 237 | 238 | .tags { 239 | list-style: none; 240 | padding: 0; 241 | overflow: hidden; 242 | text-overflow: ellipsis; 243 | 244 | > li { 245 | display: inline; 246 | font-weight: 600; 247 | margin: 0; 248 | padding: 0; 249 | 250 | white-space: nowrap; 251 | 252 | .namespace { 253 | color: lighten($main-font-color, 50%); 254 | font-weight: normal; 255 | } 256 | 257 | &::after { 258 | content: " • "; 259 | margin: 0 4px; 260 | color: grey; 261 | font-weight: normal; 262 | } 263 | &:last-child::after { 264 | content: ""; 265 | margin: 0; 266 | } 267 | 268 | color: $primary-color; 269 | 270 | .site--hub.layout--software-index & { 271 | color: $hub-software--primary-color; 272 | } 273 | .site--hub.layout--spec-index & { 274 | color: $hub-specs--primary-color; 275 | } 276 | } 277 | } 278 | } 279 | } 280 | 281 | .post-meta-row { 282 | color: grey; 283 | font-size: 14px; 284 | 285 | .date { 286 | white-space: nowrap; 287 | } 288 | 289 | .authors { 290 | .author { 291 | white-space: nowrap; 292 | display: inline-block; 293 | margin: .2em 0; 294 | 295 | .author-name { 296 | margin-right: 10px; 297 | white-space: nowrap; 298 | 299 | font-weight: 600; 300 | color: $primary-color; 301 | 302 | text-overflow: ellipsis; 303 | overflow: hidden; 304 | } 305 | 306 | .author-avatar { 307 | margin-right: 10px; 308 | width: 32px; 309 | height: 32px; 310 | border-radius: 50%; 311 | overflow: hidden; 312 | 313 | display: inline-block; 314 | vertical-align: middle; 315 | 316 | img { 317 | width: 100%; 318 | height: 100%; 319 | } 320 | } 321 | } 322 | } 323 | } 324 | 325 | .post-card { 326 | position: relative; 327 | 328 | &.has-parent-project { 329 | padding-top: 20px; 330 | } 331 | &.has-cover-image { 332 | .cover-image { 333 | display: none; 334 | } 335 | @media screen and (min-width: $bigscreen-breakpoint) { 336 | position: relative; 337 | 338 | .card-body { 339 | margin-left: calc(50% + #{$gutter} / 2 + 30px); 340 | } 341 | .cover-image { 342 | display: block; 343 | margin: 0; 344 | position: absolute; 345 | left: 0; 346 | top: 0; 347 | bottom: 0; 348 | right: 50%; 349 | 350 | img { 351 | display: block; 352 | height: 100%; 353 | width: 100%; 354 | object-fit: cover; 355 | } 356 | } 357 | } 358 | } 359 | .hub-symbol { 360 | position: absolute; 361 | top: 10px; 362 | right: 10px; 363 | width: 28px; 364 | height: 28px; 365 | 366 | svg path { 367 | fill: lighten(desaturate($primary-color, 30), 45); 368 | } 369 | } 370 | header { 371 | .title { 372 | font-weight: 600; 373 | font-size: 22px; 374 | } 375 | .external-link-icon { 376 | img { 377 | width: 16px; 378 | height: 16px; 379 | } 380 | } 381 | } 382 | footer { 383 | @extend .post-meta-row; 384 | margin-top: 14px; 385 | } 386 | } 387 | 388 | .tbd { 389 | @include tbd(); 390 | } 391 | 392 | .main-article { 393 | max-width: 750px; 394 | 395 | > header { 396 | .title { 397 | font-size: 36px; 398 | font-weight: 600; 399 | margin-bottom: 36px; 400 | } 401 | } 402 | .body { 403 | font-size: 18px; 404 | line-height: 1.65; 405 | 406 | > p:first-child, > .paragraph:first-child p:only-child { 407 | margin-top: 0; 408 | } 409 | 410 | code { 411 | @include code-snippet(); 412 | } 413 | 414 | a { 415 | &:not(.image) { 416 | border-bottom: 1px solid; 417 | } 418 | 419 | &[rel=external] { 420 | border-bottom-style: dotted; 421 | &:link, &:hover, &:focus, &:active { 422 | .ico-ext { 423 | font-size: 50%; 424 | vertical-align: text-top; 425 | position: relative; 426 | left: .15em; 427 | } 428 | } 429 | } 430 | } 431 | 432 | pre { 433 | @include code-snippet-container(); 434 | } 435 | 436 | dl { 437 | dd { 438 | margin-left: 1.25em; 439 | } 440 | } 441 | ul, ol { 442 | padding-left: 1.25em; 443 | 444 | li { 445 | margin: .25em 0; 446 | 447 | > p:first-child { 448 | margin-top: 0; 449 | } 450 | > p:last-child { 451 | margin-bottom: 0; 452 | } 453 | } 454 | } 455 | dl { 456 | dd { 457 | table, 458 | p { 459 | margin-top: .5em; 460 | margin-bottom: .5em; 461 | font-size: 90%; 462 | } 463 | } 464 | } 465 | blockquote { 466 | margin-left: 1.25em; 467 | } 468 | 469 | @media screen and (min-width: $bigscreen-breakpoint) { 470 | dl dd { 471 | margin-left: 2em; 472 | } 473 | blockquote { 474 | margin-left: 2em; 475 | } 476 | ul, ol { 477 | padding-left: 2em; 478 | } 479 | } 480 | 481 | table { 482 | $border-color: lighten($main-font-color, 80); 483 | 484 | border-collapse: collapse; 485 | width: 100%; 486 | 487 | margin-top: 1em; 488 | margin-bottom: 1em; 489 | 490 | p { 491 | margin: 0; 492 | } 493 | 494 | th, td { 495 | text-align: left; 496 | padding: .5em; 497 | } 498 | tr { 499 | border-bottom: 1px solid $border-color; 500 | &:last-child { 501 | border-bottom-width: 0; 502 | } 503 | } 504 | } 505 | 506 | @include asciidoc-markup($primary-dark-color); 507 | } 508 | } 509 | 510 | 511 | html, body { 512 | margin: 0; 513 | padding: 0; 514 | } 515 | 516 | .underlay, 517 | section, 518 | header, 519 | footer, 520 | article { 521 | body > &, 522 | body > main > & { 523 | padding: 0 2em; 524 | @media screen and (min-width: $bigscreen-breakpoint) { 525 | padding: 0; 526 | } 527 | } 528 | } 529 | 530 | body { 531 | display: flex; 532 | flex-flow: column nowrap; 533 | min-height: 100vh; 534 | align-items: stretch; 535 | 536 | > main { 537 | flex: 1; 538 | overflow: hidden; 539 | } 540 | } 541 | body > .underlay, 542 | body > main, 543 | body > main > .underlay, 544 | .item-filter { 545 | display: flex; 546 | flex-flow: column nowrap; 547 | @media screen and (min-width: $bigscreen-breakpoint) { 548 | align-items: center; 549 | } 550 | } 551 | .underlay { 552 | @media screen and (min-width: $bigscreen-breakpoint) { 553 | width: 100%; 554 | } 555 | } 556 | 557 | nav.item-filter > * { 558 | @include wide-container(); 559 | } 560 | 561 | header, 562 | footer, 563 | section, 564 | .hero, 565 | article { 566 | body > &, 567 | body > .underlay > &, 568 | body > main > &, 569 | body > main > .underlay > & { 570 | @include wide-container(); 571 | } 572 | } 573 | -------------------------------------------------------------------------------- /_sass/rop-header-footer.scss: -------------------------------------------------------------------------------- 1 | body > .underlay > header, 2 | body > .underlay > footer { 3 | display: flex; 4 | 5 | .site-logo { 6 | margin: 0; 7 | padding: 0; 8 | line-height: .5; 9 | font-size: 24px; 10 | font-weight: 600; 11 | white-space: nowrap; 12 | color: white; 13 | 14 | :link, :hover, :visited { 15 | color: inherit; 16 | } 17 | 18 | svg { 19 | height: 30px; 20 | vertical-align: middle; 21 | } 22 | 23 | @media screen and (min-width: $bigscreen-breakpoint) { 24 | margin-right: 100px; 25 | } 26 | } 27 | .social-links { 28 | > a { 29 | margin-left: 14px; 30 | font-size: 18px; 31 | 32 | &:first-child { 33 | margin-left: 0; 34 | } 35 | } 36 | } 37 | } 38 | 39 | 40 | .underlay.header { 41 | body > & { 42 | background: $header-background; 43 | 44 | > .hero { 45 | padding-top: 20px; 46 | color: white; 47 | 48 | > .text { 49 | position: relative; 50 | 51 | > .title { 52 | font-size: 44px; 53 | font-weight: 700; 54 | margin: 0 0 20px 0; 55 | line-height: 1.2; 56 | } 57 | > .desc { 58 | font-size: 20px; 59 | margin: 0 0 20px 0; 60 | } 61 | > .cta { // Call to action. 62 | margin-top: 40px; 63 | 64 | .button { 65 | &:not(:first-child) { 66 | @include cta-button(rgba(white, 0.32), white); 67 | } 68 | &:first-child { 69 | @include cta-button(white, $primary-dark-color); 70 | } 71 | &:last-child { 72 | margin-right: 0; 73 | } 74 | &:only-child { 75 | @include cta-button($primary-dark-color, white); 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | .site--hub.layout--software-index > & { 83 | padding-bottom: 2em; 84 | background: $hub-software--hero-background; 85 | } 86 | .site--hub.layout--blog-index > &, 87 | .site--hub.layout--project-index > & { 88 | padding-bottom: 2em; 89 | } 90 | .site--hub.layout--spec-index > & { 91 | padding-bottom: 2em; 92 | background: $hub-specs--hero-background; 93 | } 94 | .site--hub.layout--home > & { 95 | padding-bottom: 2em; 96 | background: $main-background; 97 | } 98 | .site--project.layout--software-index > &, 99 | .site--project.layout--spec-index > &, 100 | .site--project.layout--blog-index > & { 101 | padding-bottom: 2em; 102 | } 103 | .site--project.layout--home > & { 104 | background: none; 105 | } 106 | 107 | .site--project.layout--home > & { 108 | > .hero { 109 | .text { 110 | margin-top: 1.5em; 111 | margin-bottom: 2em; 112 | } 113 | } 114 | } 115 | 116 | .site--hub.layout--home > & { 117 | > .hero { 118 | text-align: left; 119 | 120 | @media screen and (min-width: $bigscreen-breakpoint) { 121 | padding-bottom: 50px; 122 | } 123 | } 124 | } 125 | } 126 | 127 | body > .underlay.footer { 128 | background: rgba(black, 0.4); 129 | } 130 | 131 | body > .underlay > header { 132 | padding-top: 26px; 133 | padding-bottom: 26px; 134 | z-index: 5; 135 | // Higher than hero, otherwise Algolia search pop-up might have stuff over it 136 | 137 | align-items: center; 138 | flex-flow: row nowrap; 139 | justify-content: space-between; 140 | 141 | > button.hamburger { 142 | border: 0; 143 | background: transparent; 144 | font-size: inherit; 145 | z-index: 20; 146 | color: white; 147 | } 148 | 149 | > .hamburger-menu { 150 | position: absolute; 151 | top: 0; 152 | left: 0; 153 | right: 0; 154 | transform: translateY(-100%); 155 | transition: transform .8s cubic-bezier(0.23, 1, 0.32, 1); 156 | color: white; 157 | 158 | height: 100vh; 159 | overflow: hidden; 160 | z-index: 10; 161 | background: rgba($primary-dark-color, 0.95); 162 | 163 | display: flex; 164 | flex-flow: column nowrap; 165 | align-items: center; 166 | justify-content: flex-start; 167 | 168 | .site-logo-container { 169 | margin-left: 2em; 170 | margin-top: 26px; 171 | align-self: flex-start; 172 | } 173 | 174 | > nav, 175 | > .social-links { 176 | a { 177 | &:link, &:visited, &:hover { 178 | font-size: 1.3em; 179 | color: white; 180 | } 181 | } 182 | } 183 | 184 | > nav { 185 | flex: 1; 186 | display: flex; 187 | flex-flow: column nowrap; 188 | align-items: flex-start; 189 | justify-content: flex-start; 190 | align-self: stretch; 191 | 192 | a.search { 193 | display: none; 194 | } 195 | .search-widget { 196 | margin-top: 2em; 197 | margin-bottom: 1em; 198 | } 199 | 200 | > * { 201 | margin: .25em; 202 | margin-left: 2em; 203 | } 204 | > .active { 205 | font-weight: bold; 206 | } 207 | } 208 | 209 | .social-links { 210 | margin-top: 1em; 211 | margin-bottom: 2em; 212 | } 213 | 214 | &.expanded { 215 | transform: translateY(0); 216 | } 217 | } 218 | 219 | > .top-menu > .search-widget, 220 | > .hamburger-menu > nav > .search-widget { 221 | input[type=search] { 222 | padding: 6px 10px 6px 10px; 223 | border-radius: 1em; 224 | font-size: inherit; 225 | line-height: inherit; 226 | border: 0; 227 | color: white; 228 | } 229 | } 230 | 231 | > .top-menu { 232 | flex: 1; 233 | 234 | > :not(.search-widget) { 235 | display: inline-block; 236 | font-weight: 600; 237 | margin-right: 20px; 238 | padding: 6px 10px 6px 10px; 239 | white-space: nowrap; 240 | } 241 | > .search-widget { 242 | width: 0; 243 | display: none; 244 | position: relative; 245 | 246 | > * { 247 | flex: 1; 248 | } 249 | } 250 | &.with-expanded-search { 251 | > a { 252 | display: none; 253 | } 254 | > .search-widget { 255 | width: 90%; 256 | display: inline-flex; 257 | } 258 | } 259 | } 260 | 261 | > .top-menu, 262 | > .social-links { 263 | color: white; 264 | display: none; 265 | white-space: nowrap; 266 | 267 | .active { 268 | background-color: rgba(black, 0.1); 269 | } 270 | a:link, a:visited, a:hover { 271 | color: white; 272 | } 273 | } 274 | 275 | @media screen and (min-width: $bigscreen-breakpoint) { 276 | justify-content: unset; 277 | 278 | > button.hamburger { 279 | display: none; 280 | } 281 | > .top-menu, > .social-links { 282 | display: block; 283 | } 284 | } 285 | } 286 | 287 | body > .underlay > footer { 288 | padding-top: 50px; 289 | padding-bottom: 50px; 290 | 291 | align-items: flex-start; 292 | flex-flow: column nowrap; 293 | 294 | color: white; 295 | 296 | a:link, a:visited, a:hover { 297 | color: white; 298 | } 299 | 300 | .parent-hub-plug { 301 | .logo { 302 | display: block; 303 | } 304 | 305 | display: flex; 306 | flex-flow: row nowrap; 307 | align-items: center; 308 | white-space: nowrap; 309 | line-height: .5; 310 | opacity: 0.8; 311 | color: white; 312 | 313 | @media screen and (min-width: $bigscreen-breakpoint) { 314 | margin-right: 50px; 315 | } 316 | 317 | .label { 318 | margin-right: 20px; 319 | font-weight: 500; 320 | } 321 | } 322 | 323 | nav { 324 | display: flex; 325 | flex-flow: row wrap; 326 | 327 | > * { 328 | margin-right: 40px; 329 | } 330 | } 331 | 332 | .links { 333 | font-weight: bold; 334 | opacity: 0.8; 335 | margin-bottom: 1em; 336 | } 337 | 338 | .legal { 339 | font-size: 14px; 340 | 341 | flex: 1; 342 | display: flex; 343 | flex-flow: column nowrap; 344 | justify-content: space-around; 345 | 346 | margin-top: 1em; 347 | margin-bottom: 1em; 348 | 349 | .copyright { 350 | .copyright-head, .copyright-tail { 351 | white-space: nowrap; 352 | } 353 | } 354 | 355 | @media screen and (min-width: $widescreen-breakpoint) { 356 | flex-flow: row nowrap; 357 | 358 | nav { 359 | display: block; 360 | } 361 | .copyright { 362 | margin-right: 40px; 363 | } 364 | } 365 | } 366 | } 367 | -------------------------------------------------------------------------------- /_sass/rop-mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin tbd($color: red) { 2 | position: relative; 3 | padding: 0 .3em; 4 | border: 1px dashed lighten($main-font-color, 70); 5 | 6 | &:after { 7 | position: absolute; 8 | left: 100%; 9 | content: "TBD"; 10 | color: lighten($main-font-color, 70); 11 | font-size: .6em; 12 | line-height: 1; 13 | padding: .05em .4em; 14 | } 15 | } 16 | 17 | @mixin wide-container() { 18 | @media screen and (min-width: $bigscreen-breakpoint) { 19 | padding: 0 2em; 20 | width: $bigscreen-breakpoint - $gutter * 8; 21 | } 22 | @media screen and (min-width: $widescreen-breakpoint) { 23 | width: $widescreen-breakpoint - $gutter * 8; 24 | } 25 | } 26 | 27 | @mixin padded-code-snippet() { 28 | padding: .2em .5em; 29 | margin: 0 .2em; 30 | 31 | font-size: 15px; 32 | 33 | background: $code-listing-background-color; 34 | 35 | border-color: $code-listing-border-color; 36 | border-width: 0 1px 0 1px; 37 | border-style: dashed; 38 | border-radius: 0; 39 | } 40 | 41 | @mixin padded-code-snippet--reset() { 42 | padding: 0; 43 | margin: 0; 44 | background: transparent; 45 | border: 0; 46 | border-radius: 0; 47 | } 48 | 49 | @mixin code-snippet-container() { 50 | overflow-x: scroll; 51 | overflow-y: hidden; 52 | line-height: 1.2; 53 | 54 | @include padded-code-snippet(); 55 | padding-top: .5em; 56 | padding-bottom: .5em; 57 | 58 | border-width: 0 0 0 1px; 59 | border-radius: 0 .25em .25em 0; 60 | 61 | margin-top: 1em; 62 | margin-bottom: 1em; 63 | 64 | margin-left: -.1em; 65 | 66 | > code { 67 | // Avoid bad formatting in case of element nested 68 | // inside a
 69 |     @include padded-code-snippet--reset();
 70 |   }
 71 | }
 72 | 
 73 | @mixin code-snippet() {
 74 |   color: lighten($main-font-color, 24);
 75 | 
 76 |   @include padded-code-snippet();
 77 |   margin-top: -1px;
 78 |   margin-bottom: -1px;
 79 | 
 80 |   font-family: $font-family-source;
 81 | 
 82 |   code {
 83 |     // Avoid bad formatting in case of  elements nested
 84 |     // into each other (possible with adoc output)
 85 |     @include padded-code-snippet--reset();
 86 |   }
 87 | }
 88 | 
 89 | @mixin cta-button($bgcolor, $color) {
 90 |   font-weight: 800;
 91 |   font-size: 18px;
 92 |   padding: 12px 32px;
 93 |   display: inline-block;
 94 |   margin-right: 10px;
 95 |   transition: box-shadow .2s ease-out;
 96 | 
 97 |   .icon {
 98 |     margin-right: 10px;
 99 |     font-weight: 400;
100 |     position: relative;
101 |     top: 2px;
102 |     font-size: 120%;
103 |   }
104 | 
105 |   &, &:link, &:visited {
106 |     color: $color;
107 |     background-color: $bgcolor;
108 |   }
109 | 
110 |   &:hover {
111 |     box-shadow: 0 0 0 4px rgba(black, 0.2);
112 |   }
113 | }
114 | 
115 | @mixin cta-button-mini($bgcolor, $color) {
116 |   @include cta-button($bgcolor, $color);
117 |   font-size: 14px;
118 |   padding: 6px 16px;
119 | }
120 | 
121 | @mixin hoverable-card($base-y, $base-blur, $color) {
122 |   $hovered-y: $base-y * 2;
123 |   $hovered-blur: $base-blur * 2;
124 | 
125 |   box-shadow: 0px $base-y $base-blur $color;
126 | 
127 |   transition: box-shadow .17s ease, transform .17s ease;
128 | 
129 |   &:hover {
130 |     transform: translateY(-1px);
131 |     box-shadow: 0px $hovered-y $hovered-blur $color;
132 |   }
133 | }
134 | 
135 | @mixin reset-list() {
136 |   list-style: none;
137 |   margin: 0;
138 |   padding: 0;
139 | }
140 | 
141 | @mixin static-link-color($color) {
142 |   &:link, &:hover, &:visited {
143 |     color: $color;
144 |   }
145 | }
146 | 
147 | @mixin asciidoc-markup($highlight-color) {
148 | 
149 |   h1, h2, h3, h4, h5, h6 {
150 |     // Header highlight when in-page navigation links are used
151 |     &.highlighted {
152 |       &:before {
153 |         content: "→";
154 |         margin-right: .5em;
155 |       }
156 |     }
157 |   }
158 | 
159 |   // Small text
160 |   span.small {
161 |     font-size: 80%;
162 |   }
163 | 
164 |   // Callouts
165 |   .conum {
166 |     color: $primary-dark-color;
167 |     font-family: $font-family;
168 |     opacity: 0.7;
169 |     transition: opacity .4s ease-out;
170 | 
171 |     &:hover {
172 |       opacity: 1;
173 |     }
174 |   }
175 |   .colist {
176 |     ol {
177 |       list-style: none;
178 |       counter-reset: item;
179 |       padding-left: 1.5em;
180 | 
181 |       li {
182 |         counter-increment: item;
183 |         display: flex;
184 |         flex-flow: row nowrap;
185 |         align-items: flex-start;
186 | 
187 |         &:before {
188 |           margin-left: -1.5em;
189 |           flex-shrink: 0;
190 |           width: 1.75em;
191 |           height: 1.75em;
192 |           margin-right: .25em;
193 |           margin-top: -.1em;
194 | 
195 |           border-radius: 100%;
196 |           padding: .1em;
197 |           line-height: 1.8;
198 | 
199 |           content: counter(item);
200 |           font-size: 100%;
201 |           font-weight: bold;
202 |           text-align: center;
203 |           background-color: $primary-dark-color;
204 |           font-family: monospace;
205 |           color: white;
206 |           transform: scale(0.8);
207 |         }
208 |       }
209 |     }
210 |   }
211 | 
212 |   // Generic title
213 |   // Used for e.g. code listing headings and tip block labels
214 |   .title {
215 |     text-transform: uppercase;
216 |     font-size: 12px;
217 |     border-radius: .25em;
218 |     background-color: $main-font-color;
219 |     color: white;
220 |     font-weight: bold;
221 |     padding: .3em .6em;
222 |   }
223 | 
224 |   // Blocks
225 | 
226 |   .admonitionblock {
227 |     > table {
228 |       display: flex;
229 |       flex-flow: column nowrap;
230 | 
231 |       tbody {
232 |         display: flex;
233 |         flex-flow: column nowrap;
234 | 
235 |         tr {
236 |           display: flex;
237 |           flex-flow: column nowrap;
238 | 
239 |           @media screen and (min-width: $bigscreen-breakpoint) {
240 |             flex-flow: row nowrap;
241 |           }
242 | 
243 |           td.content {
244 |             overflow-x: hidden;
245 |           }
246 |         }
247 |       }
248 |     }
249 |   }
250 | 
251 |   .admonitionblock,
252 |   .listingblock {
253 |     margin: 1em 0;
254 |   }
255 | 
256 |   .admonitionblock.warning {
257 |     td.icon .title {
258 |       background-color: $warning-color;
259 |     }
260 |   }
261 |   .admonitionblock.important {
262 |     td.icon .title {
263 |       background-color: $important-color;
264 |     }
265 |   }
266 | 
267 |   .imageblock {
268 |     .title {
269 |       background-color: $accent-color;
270 |       color: white;
271 |     }
272 |   }
273 | 
274 |   .listingblock {
275 |     display: flex;
276 |     flex-flow: column nowrap;
277 | 
278 |     .title {
279 |       align-self: flex-start;
280 |       background-color: $code-listing-border-color;
281 |       color: white;
282 |       border-radius: 0;
283 |     }
284 | 
285 |     .content {
286 |       align-self: stretch;
287 | 
288 |       position: relative;
289 |       button.listing-clipboard-button {
290 |         position: absolute;
291 |         right: 0;
292 |         top: .25em;
293 |         padding: .3em .3em;
294 |         font-size: 80%;
295 |         transform: translateX(100%);
296 |         color: $code-listing-border-color;
297 |         background: $code-listing-background-color;
298 |         border: 0;
299 |         cursor: pointer;
300 |       }
301 | 
302 |       pre {
303 |         margin: 0;
304 |       }
305 |     }
306 |   }
307 | 
308 |   .admonitionblock {
309 |     padding-left: .5em;
310 |     background-color: rgba(black, 0.03);
311 | 
312 |     @media screen and (min-width: $bigscreen-breakpoint) {
313 |       overflow-x: scroll;
314 |     }
315 | 
316 |     > table:first-child {
317 |       margin-top: 0;
318 |     }
319 |     > table:last-child {
320 |       margin-bottom: 0;
321 |     }
322 | 
323 |     td.icon {
324 |       vertical-align: top;
325 |       padding-left: 0;
326 |       font-size: 90%;
327 |     }
328 | 
329 |     .title {
330 |       background-color: $primary-dark-color;
331 |       color: white;
332 |     }
333 | 
334 |     .content {
335 |       font-size: 90%;
336 | 
337 |       .title {
338 |         background: transparent;
339 |         color: $main-font-color;
340 |         padding-left: 0;
341 |       }
342 | 
343 |       .listingblock pre {
344 |         font-size: 100%;
345 |       }
346 | 
347 |       > div:first-child {
348 |         > :first-child {
349 |           margin-top: 0;
350 |         }
351 |       }
352 |       > div:last-child {
353 |         > :last-child {
354 |           margin-bottom: 0;
355 |         }
356 |         &.ulist {
357 |           li:first-child > :first-child {
358 |             margin-top: 0;
359 |           }
360 |           li:last-child > :last-child {
361 |             margin-bottom: 0;
362 |           }
363 |         }
364 |       }
365 |     }
366 |   }
367 | }
368 | 
369 | @mixin item-external-links($onDark: false) {
370 |   ul.nav-items {
371 |     @include reset-list();
372 |   }
373 | 
374 |   > .nav-items > li {
375 |     flex-basis: 50%;
376 |     width: 50%;
377 |     max-width: 200px;
378 | 
379 |     &:first-child {
380 |       a {
381 |         margin-left: 1px;
382 |       }
383 |     }
384 | 
385 |     > a {
386 |       @if $onDark == true {
387 |         @include static-link-color(white);
388 |         background-color: rgba(black, 0.7);
389 |       } @else {
390 |         @include static-link-color(#444);
391 |         background-color: rgba(black, 0.08);
392 |       }
393 | 
394 |       display: block;
395 |       font-weight: bold;
396 |       padding: .5em 1em .5em 1.5em;
397 | 
398 |       margin: 1px 1px 1px 0;
399 | 
400 |       display: flex;
401 |       flex-flow: row nowrap;
402 | 
403 |       .lbl {
404 |         white-space: nowrap;
405 |         text-overflow: ellipsis;
406 |         overflow: hidden;
407 |         flex: 1;
408 |       }
409 |       .ico {
410 |         flex-shrink: 0;
411 |         width: 32px;
412 |       }
413 |       .ico-ext {
414 |         flex-shrink: 0;
415 |         text-align: right;
416 |         width: 32px;
417 |       }
418 |     }
419 | 
420 |     &.featured {
421 |       > a {
422 |         @if $onDark == true {
423 |           @include static-link-color($primary-color);
424 |           background-color: white;
425 |         } @else {
426 |           @include static-link-color(white);
427 |           background-color: $primary-dark-color;
428 |         }
429 |       }
430 |     }
431 |   }
432 | }
433 | 
434 | @mixin item-nav-toc() {
435 |   // Used for ToC on software item’s landing and elsewhere,
436 |   // (though not in docs sidebar)
437 | 
438 |   ul.nav-items {
439 |     @include reset-list;
440 |     font-size: 15px;
441 |   }
442 | 
443 |   > ul.nav-items > li {
444 |     > .item-title {
445 |       font-size: 18px;
446 |       font-weight: bold;
447 |       margin: 0;
448 |       line-height: 1.8;
449 |     }
450 |     ul {
451 |       line-height: 2;
452 |     }
453 |   }
454 | }
455 | 
456 | @mixin docs-page($primary-dark-color) {
457 |   .leaflet-pane {
458 |     // To ensure leaflet does not obscure navigation sidebar
459 |     z-index: 3;
460 |   }
461 |   .leaflet-top, .leaflet-bottom {
462 |     // To ensure leaflet buttons get covered by expandable top menu
463 |     z-index: 5;
464 |   }
465 | 
466 |   > header.documentation-header,
467 |   > section.documentation {
468 |     align-self: stretch;
469 |     width: auto;
470 |   }
471 | 
472 |   > header.documentation-header {
473 |     display: flex;
474 |     flex-flow: row nowrap;
475 |     align-items: center;
476 |     padding: 0 0 0 2em;
477 |     position: fixed;
478 |     right: 0;
479 |     z-index: 4;
480 | 
481 |     transition: background .1s linear, border-bottom .1s linear, transform .1s linear;
482 | 
483 |     .nav-header {
484 |       padding: 10px 2em 10px 2em;
485 |       display: flex;
486 |       flex-flow: row nowrap;
487 |       align-items: center;
488 |       transition: background .6s $easeOutCirc;
489 | 
490 |       .title {
491 |         white-space: nowrap;
492 |         line-height: 1;
493 |         font-weight: normal;
494 |         font-size: 15px;
495 |         text-transform: uppercase;
496 |         letter-spacing: 0.08em;
497 | 
498 |         a {
499 |           @include static-link-color(#444);
500 |         }
501 | 
502 |         .nav-toggle-icon {
503 |           cursor: pointer;
504 |         }
505 |       }
506 | 
507 |       .logo-container {
508 |         $logoSize: 32px;
509 | 
510 |         margin-right: 10px;
511 |         height: $logoSize;
512 |         width: $logoSize;
513 | 
514 |         .logo > :only-child {
515 |           width: $logoSize;
516 |           height: $logoSize;
517 |         }
518 |       }
519 | 
520 |       .nav-toggle-icon {
521 |         margin-left: 1em;
522 | 
523 |         > .close { display: none; }
524 |         > .open { display: block; }
525 |       }
526 |     }
527 | 
528 |     &.nav-expanded {
529 |       .nav-header {
530 |         background-color: #f7f7f7;
531 |       }
532 |       .nav-header .nav-toggle-icon {
533 |         > .open { display: none; }
534 |         > .close { display: block; }
535 |       }
536 |     }
537 | 
538 |     .item-type {
539 |       display: none;
540 |       margin-right: 10px;
541 |     }
542 | 
543 |     &.headroom--not-top {
544 |       background: rgba(white, 0.9);
545 |       box-shadow: rbga(white, 0.9) 0 20px 30px;
546 |     }
547 | 
548 |     &.unpinned {
549 |       .item-type, .subsection {
550 |         display: inline-block;
551 |       }
552 |     }
553 |   }
554 | 
555 |   > section.documentation {
556 |     flex: 1;
557 | 
558 |     @media screen and (min-width: $bigscreen-breakpoint) {
559 |       display: flex;
560 |       flex-flow: column nowrap;
561 |     }
562 | 
563 |     overflow-x: auto; // on narrow screens, code snippets & tables may overflow width
564 | 
565 |     .docs-nav {
566 |       $navFlexShare: 20%;
567 | 
568 |       background: transparent;
569 |       flex-basis: 20%;
570 | 
571 |       transition: flex-basis .6s $easeOutCirc;
572 | 
573 |       > section {
574 |         margin-bottom: 15px;
575 |       }
576 | 
577 |       // New style: Nav with nested items
578 |       > ul.nav-items {
579 |         $sidePadding: 1em;
580 | 
581 |         @include reset-list;
582 | 
583 |         position: fixed;
584 |         overflow-y: auto;
585 |         bottom: 0;
586 |         right: 0;
587 |         left: 0;
588 | 
589 |         @media screen and (min-width: $bigscreen-breakpoint) {
590 |           left: unset;
591 |         }
592 | 
593 |         padding: .75em $sidePadding;
594 | 
595 |         z-index: 5;
596 |         background: #f7f7f7;
597 |         box-shadow: rgba(black, 0.7) -30px 0px 60px -60px;
598 | 
599 |         transition:
600 |           // Collapsing of header when scrolling (w/headroom):
601 |           top .1s linear,
602 |           // Toggling sidebar open/closed
603 |           transform .6s $easeOutCirc,
604 |           opacity .6s $easeOutCirc,
605 |           box-shadow .6s $easeOutCirc;
606 | 
607 |         @media screen and (min-width: $bigscreen-breakpoint) {
608 |           max-width: calc(#{$navFlexShare} - #{$sidePadding});
609 |         }
610 | 
611 |         li {
612 |           font-size: 15px;
613 |           font-weight: normal;
614 | 
615 |           > .item-title {
616 |             white-space: nowrap;
617 |             overflow: hidden;
618 |             text-overflow: ellipsis;
619 |           }
620 | 
621 |           &.selected {
622 |             > .item-title {
623 |               background-color: #f0f0f0;
624 |               margin-left: -2em;
625 |               padding-left: 2em;
626 |             }
627 | 
628 |             span {
629 |               font-weight: bold;
630 |             }
631 |           }
632 |           a { @include static-link-color(#444); }
633 |         }
634 | 
635 |         > li {
636 |           > .item-title {
637 |             font-size: 20px;
638 |             margin: 0;
639 |             line-height: 1.8;
640 |           }
641 |           > ul {
642 |             margin-left: .75em;
643 |             padding-left: 0;
644 |             line-height: 2;
645 |             margin-bottom: .5em;
646 |           }
647 | 
648 |           ul {
649 |             margin-left: 1.25em;
650 |             padding-left: 0;
651 |           }
652 | 
653 |           ul.in-page-toc {
654 |             padding: .25em .25em .25em0;
655 |             margin-left: 0;
656 |             margin-bottom: .5em;
657 |             border-radius: 0 0 0 1em;
658 | 
659 |             &, ul {
660 |               list-style: none;
661 |             }
662 |             ul {
663 |               padding: 0;
664 |             }
665 |             li {
666 |               font-size: 13px;
667 |               line-height: 1.5;
668 | 
669 |               &.highlighted > .item-title {
670 |                 a:link, a:visited {
671 |                   font-weight: bold;
672 |                 }
673 |               }
674 |             }
675 |           }
676 |         }
677 |       }
678 |     }
679 | 
680 |     > article {
681 |       @extend .main-article;
682 | 
683 |       .body {
684 |         font-size: 17px;
685 |         line-height: 1.6;
686 |       }
687 | 
688 |       margin: 0 auto;
689 |       flex: 1;
690 | 
691 |       background: white;
692 |       z-index: 1;
693 | 
694 |       > header, > footer {
695 |         [role=toolbar] {
696 |           line-height: 1;
697 | 
698 |           button, a {
699 |             border: 0;
700 |             padding: 0;
701 |             margin-right: 1em;
702 | 
703 |             font-family: inherit;
704 |             font-size: 80%;
705 |             font-weight: bold;
706 | 
707 |             background: white;
708 |             color: $primary-dark-color;
709 |             cursor: pointer;
710 | 
711 |             text-decoration: none;
712 | 
713 |             &:last-child {
714 |               margin-right: 0;
715 |             }
716 | 
717 |             .ico-ext {
718 |               margin-left: .5em;
719 |             }
720 |           }
721 |         }
722 |       }
723 | 
724 |       > header {
725 |         > [role=toolbar] {
726 |           margin-top: -2em;
727 |           margin-bottom: 4em;
728 |         }
729 |         > .title {
730 |           @media screen and (min-width: $bigscreen-breakpoint) {
731 |             display: flex;
732 |             flex-flow: row nowrap;
733 |           }
734 | 
735 |           padding-top: 70px;
736 | 
737 |           > .logo-container {
738 |             margin-right: 22px;
739 | 
740 |             > :only-child {
741 |               width: 58px;
742 |               height: 58px;
743 |             }
744 |           }
745 | 
746 |           .text {
747 |             flex: 1;
748 |             font-size: 36px;
749 | 
750 |             margin: 0;
751 |             font-weight: 500;
752 |           }
753 |         }
754 |         .lead {
755 |           font-weight: normal;
756 |           font-size: 20px;
757 |         }
758 |       }
759 | 
760 |       > .body {
761 |         @include asciidoc-markup($primary-dark-color);
762 |       }
763 |     }
764 | 
765 |     .docs-nav,
766 |     &.docs-landing > article > header {
767 |       .external-links {
768 |         @include item-external-links();
769 |       }
770 |     }
771 | 
772 |     .docs-nav {
773 |       .external-links {
774 |         margin-bottom: .5em;
775 | 
776 |         > .nav-items > li {
777 |           flex-basis: unset;
778 |           width: 100%;
779 |           a {
780 |             padding: 0;
781 |             background: none;
782 |           }
783 |           &.featured {
784 |             a {
785 |               background: none;
786 |               @include static-link-color($main-font-color);
787 |             }
788 |           }
789 |         }
790 |       }
791 |     }
792 | 
793 |     &.docs-landing > article {
794 |       > header {
795 |         .external-links {
796 |           margin-bottom: 2em;
797 | 
798 |           > .nav-items > li {
799 |             width: unset;
800 |           }
801 |         }
802 |         > .title {
803 |           border-bottom-width: 0;
804 |           padding-bottom: 0;
805 |         }
806 |       }
807 | 
808 |       @include item-nav-toc();
809 |     }
810 | 
811 |     @media screen and (min-width: $bigscreen-breakpoint) {
812 |       flex-flow: row nowrap;
813 |       flex-direction: row-reverse;
814 | 
815 |       > article {
816 |         flex: 2;
817 |       }
818 | 
819 |       > .docs-nav {
820 |         padding: 70px 0 0 0;
821 |       }
822 | 
823 |       &.docs-landing {
824 |         flex-direction: column-reverse;
825 | 
826 |         > article {
827 |           border-left-width: 0;
828 | 
829 |           .external-links {
830 |             > .nav-items {
831 |               display: flex;
832 |               flex-flow: row wrap;
833 |             }
834 |           }
835 | 
836 |           > header,
837 |           > .body {
838 |             margin-left: 0;
839 |           }
840 | 
841 |           @media screen and (min-width: $bigscreen-breakpoint) {
842 |             > .body {
843 |               padding-top: 20px;
844 |             }
845 |           }
846 |         }
847 |       }
848 | 
849 |       &.with-collapsed-toc {
850 |         > article {
851 |           > header, > .body {
852 |             margin-right: 0;
853 |           }
854 |         }
855 |       }
856 |     }
857 | 
858 |     &.with-collapsed-toc {
859 |       position: relative;
860 | 
861 |       > .docs-nav {
862 |         flex-basis: 0;
863 | 
864 |         .nav-items {
865 |           transform: translateX(100%);
866 |           opacity: 0;
867 |         }
868 |       }
869 |     }
870 |   }
871 | }
872 | 


--------------------------------------------------------------------------------
/assets/css/style.scss:
--------------------------------------------------------------------------------
 1 | ---
 2 | ---
 3 | 
 4 | $primary-color: #05C7DF;
 5 | $accent-color: #FF6357;
 6 | 
 7 | $main-background: linear-gradient(135deg, #0446CC 0%, #2864DD 100%);
 8 | 
 9 | @import 'jekyll-theme-rop';
10 | 
11 | .site-logo svg path {
12 |   fill: white;
13 | }
14 | 


--------------------------------------------------------------------------------
/assets/img/external-link.svg:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 


--------------------------------------------------------------------------------
/assets/js/adoc-toc.js:
--------------------------------------------------------------------------------
  1 | (function () {
  2 | 
  3 |   const HEADER_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
  4 |   const IN_PAGE_NAV_HTML_CLASS = 'in-page-toc';
  5 |   const SCROLLABLE_NAV_CONTAINER_SELECTOR = 'ul.nav-items';
  6 | 
  7 |   /* Given a container of AsciiDoc .sectN elementss,
  8 |    * returns an object containing navigation structure like this:
  9 |    * { items: [ { title: "Some title", path: "./#some-title", items: [ ...subitems ] }, ... }
 10 |    * Works recursively through nested sections.
 11 |    */
 12 |   function getAdocTocItems(containerEl, sectLvl) {
 13 |     sectLvl = sectLvl || 1;
 14 |     var items = [];
 15 | 
 16 |     const topLevelSections = Array.from(containerEl.children).filter((el) => {
 17 |       return el.matches(`div.sect${sectLvl}`);
 18 |     });
 19 | 
 20 |     for (let sectionEl of topLevelSections) {
 21 |       const headerEl = Array.from(sectionEl.children).filter((el) => {
 22 |         for (let hTagName of HEADER_TAGS) {
 23 |           if (el.matches(hTagName)) { return true; }
 24 |         }
 25 |         return false;
 26 |       })[0];
 27 |       const headerId = headerEl.getAttribute('id');
 28 | 
 29 |       var subItems = [];
 30 |       const sectionBody = sectionEl.querySelector('div.sectionbody');
 31 |       if (sectionBody) {
 32 |         subItems = getAdocTocItems(sectionBody, sectLvl + 1);
 33 |       } else {
 34 |         subItems = getAdocTocItems(sectionEl, sectLvl + 1);
 35 |       }
 36 | 
 37 |       items.push({
 38 |         title: headerEl.innerText,
 39 |         description: headerEl.innerText,
 40 |         path: `./#${headerId}`,
 41 |         items: subItems,
 42 | 
 43 |         id: headerId,
 44 |       });
 45 |     }
 46 | 
 47 |     return items;
 48 |   }
 49 | 
 50 |   function highlightSelected(headerId, itemPath) {
 51 |     let selectedItemEl;
 52 | 
 53 |     for (const itemEl of document.querySelectorAll(`.${IN_PAGE_NAV_HTML_CLASS} li`)) {
 54 |       const link = (itemEl.firstChild || {}).firstChild;
 55 |       if (link && link.getAttribute('href') == itemPath) {
 56 |         itemEl.classList.add('highlighted');
 57 |         selectedItemEl = itemEl;
 58 |       } else {
 59 |         itemEl.classList.remove('highlighted');
 60 |       }
 61 |     }
 62 |     for (const hTag of HEADER_TAGS) {
 63 |       for (const headerEl of document.querySelectorAll(hTag)) {
 64 |         headerEl.classList.remove('highlighted');
 65 |       }
 66 |     }
 67 |     const selectedHeaderEl = document.getElementById(headerId);
 68 |     selectedHeaderEl.classList.add('highlighted');
 69 | 
 70 |     return selectedItemEl;
 71 |   }
 72 | 
 73 |   /* Given a list of navigation items, returns an