├── src ├── data │ ├── .gitkeep │ ├── .gitignore │ ├── index.json │ ├── index_de.json │ ├── imprint_de.json │ ├── imprint.json │ └── english-texts.json ├── assets │ ├── img │ │ ├── .gitkeep │ │ ├── spacer.gif │ │ ├── favicon.png │ │ ├── spinner.gif │ │ ├── app-mockup.png │ │ ├── favicon_64.png │ │ ├── icons │ │ │ ├── close.png │ │ │ ├── next.png │ │ │ ├── prev.png │ │ │ ├── loading.gif │ │ │ ├── preview-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-180x180.png │ │ │ ├── favicon-192x192.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ ├── twitter_white.png │ │ │ ├── minus.svg │ │ │ ├── arrow-right-light.svg │ │ │ ├── down.svg │ │ │ ├── plus.svg │ │ │ ├── cross_close.svg │ │ │ ├── burger_menu.svg │ │ │ ├── arrow-down.svg │ │ │ ├── collapse.svg │ │ │ ├── burger_menu_close.svg │ │ │ ├── arrow-right.svg │ │ │ ├── expand.svg │ │ │ ├── external.svg │ │ │ ├── info.svg │ │ │ ├── Close.svg │ │ │ ├── security.svg │ │ │ ├── issue.svg │ │ │ ├── open-source.svg │ │ │ ├── github_white.svg │ │ │ ├── github.svg │ │ │ ├── github_white32x32.svg │ │ │ ├── lock.svg │ │ │ ├── questions.svg │ │ │ ├── info_faq.svg │ │ │ ├── bug.svg │ │ │ ├── documentation.svg │ │ │ ├── code.svg │ │ │ ├── download.svg │ │ │ ├── arrow-left.svg │ │ │ ├── smartphone.svg │ │ │ ├── improvement.svg │ │ │ ├── decentralized.svg │ │ │ ├── virus.svg │ │ │ └── schnelltest-partner.svg │ │ ├── thanks-de.png │ │ ├── thanks-en.png │ │ ├── app-mockup@2x.png │ │ ├── pt-poster-1.0.0.png │ │ ├── partner │ │ │ ├── TUViT_logo@1x.png │ │ │ ├── TUViT_logo@2x.png │ │ │ ├── cispa_logo@1x.png │ │ │ ├── cispa_logo@2x.png │ │ │ ├── logo_msg@1x.png │ │ │ ├── logo_msg@2x.png │ │ │ ├── rki-logo@1x.png │ │ │ ├── rki-logo@2x.png │ │ │ ├── sap_logo@1x.png │ │ │ ├── sap_logo@2x.png │ │ │ ├── detecon-logo@1x.png │ │ │ ├── detecon-logo@2x.png │ │ │ ├── logo_edelman@1x.png │ │ │ ├── logo_edelman@2x.png │ │ │ └── T_Logo.svg │ │ ├── rat-partner-option-1.png │ │ ├── rat-partner-option-2.png │ │ ├── pt-poster-1.0.0-multiqr.png │ │ ├── rat-partner-option-1_en.png │ │ ├── rat-partner-option-2_en.png │ │ ├── pt-poster-withtext-1.0.0.png │ │ ├── screenshots │ │ │ └── dummy_yellow.png │ │ ├── pt-poster-1.0.0-placeholder.png │ │ ├── pt-poster-1.0.0-placeholder_en.png │ │ ├── arrow_left.svg │ │ ├── arrow_right.svg │ │ ├── faq.svg │ │ ├── ideas.svg │ │ ├── news-blog.svg │ │ ├── error.svg │ │ └── how-it-works-2.svg │ ├── scss │ │ ├── helpers │ │ │ ├── _clearfix.scss │ │ │ ├── _text-truncation.scss │ │ │ ├── _screenreaders.scss │ │ │ ├── _background.scss │ │ │ ├── _stretched-link.scss │ │ │ ├── _colored-links.scss │ │ │ ├── _position.scss │ │ │ └── _embed.scss │ │ ├── mixins │ │ │ ├── _clearfix.scss │ │ │ ├── _lists.scss │ │ │ ├── _text-truncate.scss │ │ │ ├── _resize.scss │ │ │ ├── _alert.scss │ │ │ ├── _background-variant.scss │ │ │ ├── _image.scss │ │ │ ├── _list-group.scss │ │ │ ├── _reset-text.scss │ │ │ ├── _box-shadow.scss │ │ │ ├── _container.scss │ │ │ ├── _deprecate.scss │ │ │ ├── _transition.scss │ │ │ ├── _pagination.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _table-variants.scss │ │ │ ├── _caret.scss │ │ │ ├── _utilities.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _gradients.scss │ │ │ └── _buttons.scss │ │ ├── forms │ │ │ ├── _form-text.scss │ │ │ ├── _validation.scss │ │ │ ├── _labels.scss │ │ │ ├── _layout.scss │ │ │ ├── _form-file.scss │ │ │ ├── _form-select.scss │ │ │ ├── _form-control.scss │ │ │ └── _input-group.scss │ │ ├── _sticky-panel.scss │ │ ├── _grid.scss │ │ ├── _images.scss │ │ ├── _modal.scss │ │ ├── vendor │ │ │ ├── _utilities.scss │ │ │ └── _slick.scss │ │ ├── _root.scss │ │ ├── _icon.scss │ │ ├── _custom-variables.scss │ │ ├── _progress.scss │ │ ├── _mixins.scss │ │ ├── utilities │ │ │ └── _api.scss │ │ ├── _footer.scss │ │ ├── _containers.scss │ │ ├── style.scss │ │ ├── _type.scss │ │ ├── _nav.scss │ │ └── _list.scss │ ├── fonts │ │ ├── icon-font │ │ │ ├── icon-font.eot │ │ │ ├── icon-font.ttf │ │ │ ├── icon-font.woff │ │ │ ├── styles.css │ │ │ └── icon-font.svg │ │ ├── roboto-v20-latin-700.eot │ │ ├── roboto-v20-latin-700.ttf │ │ ├── roboto-v20-latin-700.woff │ │ ├── roboto-v20-latin-900.eot │ │ ├── roboto-v20-latin-900.ttf │ │ ├── roboto-v20-latin-900.woff │ │ ├── roboto-v20-latin-700.woff2 │ │ ├── roboto-v20-latin-900.woff2 │ │ ├── roboto-v20-latin-italic.eot │ │ ├── roboto-v20-latin-italic.ttf │ │ ├── roboto-v20-latin-italic.woff │ │ ├── roboto-v20-latin-regular.eot │ │ ├── roboto-v20-latin-regular.ttf │ │ ├── roboto-v20-latin-700italic.eot │ │ ├── roboto-v20-latin-700italic.ttf │ │ ├── roboto-v20-latin-900italic.eot │ │ ├── roboto-v20-latin-900italic.ttf │ │ ├── roboto-v20-latin-italic.woff2 │ │ ├── roboto-v20-latin-regular.woff │ │ ├── roboto-v20-latin-regular.woff2 │ │ ├── roboto-v20-latin-700italic.woff │ │ ├── roboto-v20-latin-700italic.woff2 │ │ ├── roboto-v20-latin-900italic.woff │ │ └── roboto-v20-latin-900italic.woff2 │ └── js │ │ ├── static │ │ ├── redirect.js │ │ ├── store-redirect.js │ │ └── page-redirect.js │ │ └── lazyload.js ├── partials │ ├── enum-text-section.html │ ├── page-redirect.html │ ├── text-plain-component.html │ ├── button-back-component.html │ ├── headline-plain-component.html │ ├── header.html │ ├── header-for-error-pages.html │ ├── button-icon-component.html │ ├── image-ticker.html │ ├── button-component.html │ ├── button-link-component.html │ ├── headline-small-component.html │ ├── icon-list-component.html │ ├── news-text-component.html │ ├── headline-component.html │ ├── slider-component.html │ ├── text-component.html │ ├── image-component.html │ ├── two-column.html │ ├── page-index.html │ ├── favicon.html │ ├── participants.html │ ├── section-get-app.html │ ├── footer.html │ ├── navlist-item.html │ ├── page-imprint.html │ ├── page-privacy.html │ ├── error-page-content.html │ └── global-nav.html ├── helpers │ ├── toJSON.js │ └── limit.js ├── root-assets │ └── robots.txt ├── pages │ ├── error.html │ ├── de │ │ ├── imprint │ │ │ └── index.html │ │ ├── privacy │ │ │ └── index.html │ │ └── index.html │ ├── en │ │ ├── imprint │ │ │ └── index.html │ │ ├── privacy │ │ │ └── index.html │ │ └── index.html │ └── index.html ├── well-known │ └── apple-app-site-association └── layouts │ ├── error-pages.html │ ├── redirect.html │ └── default.html ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 03_other.md │ ├── 02_questions.md │ ├── 01_site_issue.md │ └── 04_feature_request.md └── workflows │ ├── build-and-test.yml │ └── deploy-master.yml ├── images └── CWA_title.png ├── .browserslistrc ├── NOTICE ├── .editorconfig ├── .vscode └── settings.json ├── CODEOWNERS ├── config.yml ├── docs ├── CREATE_BLOG_REDIRECTS.md ├── FAQ_SEARCH_SUMMARY.md └── CHANGE_WEBSITE_CONTENT.md ├── SECURITY.md ├── .gitignore └── package.json /src/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | src/assets/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /src/partials/enum-text-section.html: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

{{text}}

3 | -------------------------------------------------------------------------------- /src/assets/scss/helpers/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /src/helpers/toJSON.js: -------------------------------------------------------------------------------- 1 | module.exports = (object) => { 2 | return JSON.stringify(object); 3 | } 4 | -------------------------------------------------------------------------------- /images/CWA_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/images/CWA_title.png -------------------------------------------------------------------------------- /src/root-assets/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | Sitemap: https://coronawarn.app/sitemap.xml 4 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # Browsers that we support 2 | last 2 versions 3 | ie >= 11 4 | ios >= 12 5 | android >= 5 6 | -------------------------------------------------------------------------------- /src/assets/img/spacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/spacer.gif -------------------------------------------------------------------------------- /src/assets/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/favicon.png -------------------------------------------------------------------------------- /src/assets/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/spinner.gif -------------------------------------------------------------------------------- /src/pages/error.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: error-pages 3 | lang_de: false 4 | --- 5 | 6 | {{> error-page-content}} 7 | -------------------------------------------------------------------------------- /src/assets/img/app-mockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/app-mockup.png -------------------------------------------------------------------------------- /src/assets/img/favicon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/favicon_64.png -------------------------------------------------------------------------------- /src/assets/img/icons/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/close.png -------------------------------------------------------------------------------- /src/assets/img/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/next.png -------------------------------------------------------------------------------- /src/assets/img/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/prev.png -------------------------------------------------------------------------------- /src/assets/img/thanks-de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/thanks-de.png -------------------------------------------------------------------------------- /src/assets/img/thanks-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/thanks-en.png -------------------------------------------------------------------------------- /src/assets/img/app-mockup@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/app-mockup@2x.png -------------------------------------------------------------------------------- /src/assets/img/icons/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/loading.gif -------------------------------------------------------------------------------- /src/data/.gitignore: -------------------------------------------------------------------------------- 1 | # generated assets 2 | blogentries*.json 3 | scienceblogentries*.json 4 | searchable_blogentries*.json 5 | -------------------------------------------------------------------------------- /src/assets/img/pt-poster-1.0.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/pt-poster-1.0.0.png -------------------------------------------------------------------------------- /src/assets/img/icons/preview-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/preview-icon.png -------------------------------------------------------------------------------- /src/assets/fonts/icon-font/icon-font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/icon-font/icon-font.eot -------------------------------------------------------------------------------- /src/assets/fonts/icon-font/icon-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/icon-font/icon-font.ttf -------------------------------------------------------------------------------- /src/assets/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/img/icons/favicon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/favicon-180x180.png -------------------------------------------------------------------------------- /src/assets/img/icons/favicon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/favicon-192x192.png -------------------------------------------------------------------------------- /src/assets/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/img/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/favicon-96x96.png -------------------------------------------------------------------------------- /src/assets/img/icons/twitter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/icons/twitter_white.png -------------------------------------------------------------------------------- /src/assets/img/partner/TUViT_logo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/TUViT_logo@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/TUViT_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/TUViT_logo@2x.png -------------------------------------------------------------------------------- /src/assets/img/partner/cispa_logo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/cispa_logo@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/cispa_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/cispa_logo@2x.png -------------------------------------------------------------------------------- /src/assets/img/partner/logo_msg@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/logo_msg@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/logo_msg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/logo_msg@2x.png -------------------------------------------------------------------------------- /src/assets/img/partner/rki-logo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/rki-logo@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/rki-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/rki-logo@2x.png -------------------------------------------------------------------------------- /src/assets/img/partner/sap_logo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/sap_logo@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/sap_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/sap_logo@2x.png -------------------------------------------------------------------------------- /src/assets/img/rat-partner-option-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/rat-partner-option-1.png -------------------------------------------------------------------------------- /src/assets/img/rat-partner-option-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/rat-partner-option-2.png -------------------------------------------------------------------------------- /src/assets/fonts/icon-font/icon-font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/icon-font/icon-font.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700.ttf -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900.ttf -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900.woff -------------------------------------------------------------------------------- /src/assets/img/partner/detecon-logo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/detecon-logo@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/detecon-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/detecon-logo@2x.png -------------------------------------------------------------------------------- /src/assets/img/partner/logo_edelman@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/logo_edelman@1x.png -------------------------------------------------------------------------------- /src/assets/img/partner/logo_edelman@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/partner/logo_edelman@2x.png -------------------------------------------------------------------------------- /src/assets/img/pt-poster-1.0.0-multiqr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/pt-poster-1.0.0-multiqr.png -------------------------------------------------------------------------------- /src/assets/img/rat-partner-option-1_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/rat-partner-option-1_en.png -------------------------------------------------------------------------------- /src/assets/img/rat-partner-option-2_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/rat-partner-option-2_en.png -------------------------------------------------------------------------------- /src/assets/scss/helpers/_text-truncation.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Text truncation 3 | // 4 | 5 | .text-truncate { 6 | @include text-truncate(); 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-italic.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-italic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-italic.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-regular.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-regular.ttf -------------------------------------------------------------------------------- /src/assets/img/pt-poster-withtext-1.0.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/pt-poster-withtext-1.0.0.png -------------------------------------------------------------------------------- /src/assets/img/screenshots/dummy_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/screenshots/dummy_yellow.png -------------------------------------------------------------------------------- /src/helpers/limit.js: -------------------------------------------------------------------------------- 1 | module.exports = function(arr, limit) { 2 | if (!Array.isArray(arr)) { return []; } 3 | return arr.slice(0, limit); 4 | } -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700italic.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700italic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900italic.eot -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900italic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-regular.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-regular.woff2 -------------------------------------------------------------------------------- /src/assets/img/pt-poster-1.0.0-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/pt-poster-1.0.0-placeholder.png -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700italic.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-700italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900italic.woff -------------------------------------------------------------------------------- /src/assets/fonts/roboto-v20-latin-900italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/fonts/roboto-v20-latin-900italic.woff2 -------------------------------------------------------------------------------- /src/assets/img/pt-poster-1.0.0-placeholder_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corona-warn-app/cwa-website/HEAD/src/assets/img/pt-poster-1.0.0-placeholder_en.png -------------------------------------------------------------------------------- /src/assets/scss/helpers/_screenreaders.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Screenreaders 3 | // 4 | 5 | .sr-only, 6 | .sr-only-focusable:not(:focus) { 7 | @include sr-only(); 8 | } 9 | -------------------------------------------------------------------------------- /src/partials/page-redirect.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/partials/text-plain-component.html: -------------------------------------------------------------------------------- 1 | {{#if text}} 2 |

{{{text}}}

3 | {{/if}} 4 | {{#if textblock}} 5 | {{#each textblock}} 6 |

{{{.}}}

7 | {{/each}} 8 | {{/if}} -------------------------------------------------------------------------------- /src/assets/img/icons/minus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/helpers/_background.scss: -------------------------------------------------------------------------------- 1 | @if $enable-gradients { 2 | @each $color, $value in $theme-colors { 3 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Deutsche Telekom AG and SAP SE or an SAP affiliate company. 2 | 3 | This project is licensed under Apache License, Version 2.0; 4 | you may not use them except in compliance with the License. -------------------------------------------------------------------------------- /src/assets/scss/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start clearfix 2 | @mixin clearfix() { 3 | &::after { 4 | display: block; 5 | clear: both; 6 | content: ""; 7 | } 8 | } 9 | // scss-docs-end clearfix 10 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | # top-most EditorConfig file 3 | root = true 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | quote_type = single 8 | max_line_length = 120 9 | [*.json] 10 | indent_style = space 11 | indent_size = 4 -------------------------------------------------------------------------------- /src/assets/img/icons/arrow-right-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/assets/img/icons/down.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/img/icons/plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/cross_close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /src/pages/de/imprint/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_de: true 3 | page-title: Open-Source-Projekt Corona-Warn-App – Impressum 4 | page-description: Impressum der Webseite coronawarn.app. 5 | page-name: imprint 6 | --- 7 | {{> page-imprint page-contents=imprint_de}} 8 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | @mixin alert-variant($background, $border, $color) { 2 | color: $color; 3 | @include gradient-bg($background); 4 | border-color: $border; 5 | 6 | .alert-link { 7 | color: darken($color, 10%); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/en/imprint/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_en: true 3 | page-title: Open-Source Project Corona-Warn-App – Legal Notice 4 | page-description: Legal notice of the website coronawarn.app. 5 | page-name: imprint 6 | --- 7 | {{> page-imprint page-contents=imprint}} 8 | -------------------------------------------------------------------------------- /src/pages/en/privacy/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_en: true 3 | page-title: Open-Source Project Corona-Warn-App – Privacy Statement 4 | page-description: The privacy statement of the Corona-Warn-App. 5 | page-name: privacy 6 | --- 7 | {{> page-privacy page-contents=privacy}} -------------------------------------------------------------------------------- /src/partials/button-back-component.html: -------------------------------------------------------------------------------- 1 | {{#if button}} 2 | 4 |   {{button.title}} 5 | {{/if}} -------------------------------------------------------------------------------- /src/assets/img/icons/burger_menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/de/privacy/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_de: true 3 | page-title: Open-Source-Projekt Corona-Warn-App – Datenschutzerklärung 4 | page-description: Datenschutzerklärung der Corona-Warn-App. 5 | page-name: privacy 6 | --- 7 | {{> page-privacy page-contents=privacy_de}} -------------------------------------------------------------------------------- /src/assets/scss/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @mixin bg-gradient-variant($parent, $color) { 4 | #{$parent} { 5 | background-image: linear-gradient(180deg, mix($body-bg, $color, 15%), $color) !important; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/partials/headline-plain-component.html: -------------------------------------------------------------------------------- 1 | {{#if titlecaption }} 2 |
{{titlecaption}}
3 | {{/if}} 4 | {{#if title}} 5 |

{{title}}

6 | {{/if}} 7 | {{#if subtitle}} 8 |

{{subtitle}}

9 | {{/if}} -------------------------------------------------------------------------------- /src/partials/header.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{#unless lang_de}} 4 | {{> global-nav language=global.lang.en}} 5 | {{/unless}} 6 | {{#if lang_de}} 7 | {{> global-nav language=global.lang.de}} 8 | {{/if}} 9 |
10 |
11 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_form-text.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Form text 3 | // 4 | 5 | .form-text { 6 | margin-top: $form-text-margin-top; 7 | @include font-size($form-text-font-size); 8 | font-style: $form-text-font-style; 9 | font-weight: $form-text-font-weight; 10 | color: $form-text-color; 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_de: true 3 | layout: redirect 4 | page-title: Open-Source-Projekt Corona-Warn-App 5 | page-description: Website des Open-Source-Projekts für die Corona-Warn-App. Die Corona-Warn-App ist eine App, die hilft, Infektionsketten des Coronavirus in Deutschland nachzuverfolgen. 6 | --- 7 | -------------------------------------------------------------------------------- /src/partials/header-for-error-pages.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{#unless lang_de}} 4 | {{> global-nav language=global.lang.en}} 5 | {{/unless}} 6 | {{#if lang_de}} 7 | {{> global-nav language=global.lang.de}} 8 | {{/if}} 9 |
10 |
11 | -------------------------------------------------------------------------------- /src/assets/scss/helpers/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::#{$stretched-link-pseudo-element} { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: $stretched-link-z-index; 13 | content: ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/scss/_sticky-panel.scss: -------------------------------------------------------------------------------- 1 | .sticky-panel { 2 | position: fixed; 3 | background-color: #999; 4 | width: 100%; 5 | overflow: hidden; 6 | box-sizing: border-box; 7 | line-height: 0; 8 | padding: 15px; 9 | &_bottom { 10 | bottom: 0; 11 | } 12 | &.hidden { 13 | display: none; 14 | } 15 | } -------------------------------------------------------------------------------- /src/assets/scss/helpers/_colored-links.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $theme-colors { 2 | .link-#{$color} { 3 | color: $value; 4 | 5 | @if $emphasized-link-hover-darken-percentage != 0 { 6 | &:hover, 7 | &:focus { 8 | color: darken($value, $emphasized-link-hover-darken-percentage); 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/en/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_en: true 3 | get-app-enabled: true 4 | homepage: true 5 | page-title: Open-Source Project Corona-Warn-App 6 | page-description: The website of the open-source project for the Corona-Warn-App. The Corona-Warn-App is an app that helps trace infection chains of COVID-19 in Germany. 7 | --- 8 | {{> page-index page-contents=index}} 9 | -------------------------------------------------------------------------------- /src/pages/de/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | lang_de: true 3 | get-app-enabled: true 4 | homepage: true 5 | page-title: Open-Source-Projekt Corona-Warn-App 6 | page-description: Website des Open-Source-Projekts für die Corona-Warn-App. Die Corona-Warn-App ist eine App, die hilft, Infektionsketten des Coronavirus in Deutschland nachzuverfolgen. 7 | --- 8 | {{> page-index page-contents=index_de}} 9 | -------------------------------------------------------------------------------- /src/partials/button-icon-component.html: -------------------------------------------------------------------------------- 1 | {{#if button}} 2 | {{button.title}} 3 | {{/if}} -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[html]": { 3 | "editor.formatOnSave": false 4 | }, 5 | "[json]": { 6 | "editor.detectIndentation": false, 7 | "editor.tabSize": 4, 8 | "editor.insertSpaces": true, 9 | "editor.trimAutoWhitespace": true, 10 | "files.trimTrailingWhitespace": true, 11 | "files.insertFinalNewline": true, 12 | "files.trimFinalNewlines": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/assets/scss/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | @if $enable-grid-classes { 6 | .row { 7 | @include make-row(); 8 | 9 | > * { 10 | @include make-col-ready(); 11 | } 12 | } 13 | } 14 | 15 | 16 | // Columns 17 | // 18 | // Common styles for small and large grid columns 19 | 20 | @if $enable-grid-classes { 21 | @include make-grid-columns(); 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/scss/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive image 2 | // 3 | // Keep images from scaling beyond the width of their parents. 4 | 5 | .img-fluid { 6 | // Part 1: Set a maximum relative to the parent 7 | max-width: 100%; 8 | // Part 2: Override the height to auto, otherwise images will be stretched 9 | // when setting a width and height attribute on the img element. 10 | height: auto; 11 | } 12 | 13 | .img-shadow { 14 | box-shadow: 0 8px 24px -17px #000101; 15 | } -------------------------------------------------------------------------------- /src/assets/scss/_modal.scss: -------------------------------------------------------------------------------- 1 | .modal { 2 | display: block; 3 | position: fixed; 4 | z-index: 1; 5 | left: 0; 6 | top: 0; 7 | width: 100%; 8 | height: 100%; 9 | overflow: auto; 10 | background-color: rgb(0,0,0); 11 | background-color: rgba(0,0,0,0.4); 12 | } 13 | 14 | 15 | .modal-content { 16 | text-align: center; 17 | background-color: #fefefe; 18 | margin: 15% auto; 19 | padding: 20px; 20 | border: 1px solid #888; 21 | width: 30%; 22 | } -------------------------------------------------------------------------------- /src/assets/scss/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | 10 | @mixin img-fluid { 11 | // Part 1: Set a maximum relative to the parent 12 | max-width: 100%; 13 | // Part 2: Override the height to auto, otherwise images will be stretched 14 | // when setting a width and height attribute on the img element. 15 | height: auto; 16 | } 17 | -------------------------------------------------------------------------------- /src/partials/image-ticker.html: -------------------------------------------------------------------------------- 1 | {{#unless image.right}}
{{> image-component image=image }}
{{/unless}} 2 |
{{#if index}}{{index}}{{/if}}{{#unless index}}{{@index}}{{/unless}}{{> text-component this=. linksblock='true'}}
3 | {{#if image.right}}
{{> image-component image=image }}
{{/if}} -------------------------------------------------------------------------------- /src/assets/img/arrow_left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/vendor/_utilities.scss: -------------------------------------------------------------------------------- 1 | .w-100 { 2 | width: 100%; 3 | } 4 | 5 | .h-100 { 6 | height: 100%; 7 | } 8 | 9 | // add responsive position utilities 10 | @each $breakpoint in map-keys($grid-breakpoints) { 11 | @include media-breakpoint-up($breakpoint) { 12 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 13 | // Common values 14 | @each $position in (relative, absolute) { 15 | .position#{$infix}-#{$position} { position: $position !important; } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/assets/img/arrow_right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This file provides an overview of code owners in this repository. 2 | 3 | # Each line is a file pattern followed by one or more owners. 4 | # The last matching pattern has the most precedence. 5 | # For more details, read the following article on GitHub: https://help.github.com/articles/about-codeowners/. 6 | 7 | # These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file. 8 | * @corona-warn-app/cwa-moderators 9 | -------------------------------------------------------------------------------- /src/assets/img/icons/collapse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | @mixin list-group-item-variant($state, $background, $color) { 4 | .list-group-item-#{$state} { 5 | color: $color; 6 | background-color: $background; 7 | 8 | &.list-group-item-action { 9 | &:hover, 10 | &:focus { 11 | color: $color; 12 | background-color: darken($background, 5%); 13 | } 14 | 15 | &.active { 16 | color: $white; 17 | background-color: $color; 18 | border-color: $color; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/img/icons/burger_menu_close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Custom variable values only support SassScript inside `#{}`. 3 | @each $color, $value in $colors { 4 | --bs-#{$color}: #{$value}; 5 | } 6 | 7 | @each $color, $value in $theme-colors { 8 | --bs-#{$color}: #{$value}; 9 | } 10 | 11 | // Use `inspect` for lists so that quoted items keep the quotes. 12 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 13 | --bs-font-sans-serif: #{inspect($font-family-sans-serif)}; 14 | --bs-font-monospace: #{inspect($font-family-monospace)}; 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/img/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/expand.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/js/static/redirect.js: -------------------------------------------------------------------------------- 1 | var lang = "en"; 2 | 3 | if ( 4 | typeof navigator.languages !== "undefined" && 5 | navigator.languages.length > 0 6 | ) { 7 | for (var i = 0; i < navigator.languages.length; ++i) { 8 | var tag = navigator.languages[i].slice(0, 2).toLowerCase(); 9 | if (tag === "de" || tag === "en") { 10 | lang = tag; 11 | break; 12 | } 13 | } 14 | } else if ( 15 | (navigator.language || navigator.userLanguage).slice(0, 2).toLowerCase() === 16 | "de" 17 | ) { 18 | lang = "de"; 19 | } 20 | 21 | window.location.href = "./" + lang + "/"; 22 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_validation.scss: -------------------------------------------------------------------------------- 1 | // Form validation 2 | // 3 | // Provide feedback to users when form field values are valid or invalid. Works 4 | // primarily for client-side validation via scoped `:invalid` and `:valid` 5 | // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for 6 | // server-side validation. 7 | 8 | // scss-docs-start form-validation-states-loop 9 | @each $state, $data in $form-validation-states { 10 | @include form-validation-state($state, map-get($data, color), map-get($data, icon)); 11 | } 12 | // scss-docs-end form-validation-states-loop 13 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | word-spacing: normal; 15 | white-space: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /src/partials/button-component.html: -------------------------------------------------------------------------------- 1 | {{#if button}} 2 | {{#if titleprefix}}{{titleprefix}} {{/if}}{{button.title}}{{#if button.icon}}{{/if}}{{#unless button.icon}}{{#if icon}}{{/if}}{{/unless}} 3 | {{/if}} -------------------------------------------------------------------------------- /src/partials/button-link-component.html: -------------------------------------------------------------------------------- 1 | {{#if button}} 2 | {{#if titleprefix}}{{titleprefix}} {{/if}}{{button.title}} 5 | {{/if}} -------------------------------------------------------------------------------- /src/partials/headline-small-component.html: -------------------------------------------------------------------------------- 1 | {{#if titlecaption }} 2 |
{{titlecaption}}
3 | {{/if}} 4 | {{#if title}} 5 |

{{title}}

6 | {{/if}} 7 | {{#if subtitle}} 8 |

{{subtitle}}

9 | {{/if}} 10 | {{#if text}} 11 |

{{{text}}}

12 | {{/if}} 13 | 14 | {{#if button}} 15 | {{button.title}} 16 | {{/if}} 17 | {{#if links}} 18 | {{#each links}} 19 | {{> button-link-component button=.}} 20 | {{/each}} 21 | {{/if}} -------------------------------------------------------------------------------- /src/partials/icon-list-component.html: -------------------------------------------------------------------------------- 1 | {{#if icon-list}} 2 | 17 | {{/if}} 18 | -------------------------------------------------------------------------------- /src/partials/news-text-component.html: -------------------------------------------------------------------------------- 1 |
2 | {{#unless lang_de}} 3 | {{#if date}} 4 |

{{date}} {{#if author}}| by {{{author}}}{{/if}}

5 | {{/if}} 6 |

{{{title}}}

7 | {{> button-link-component button=source direction='right' titleprefix='Read the'}} 8 | {{/unless}} 9 | {{#if lang_de}} 10 | {{#if date_de}} 11 |

{{date_de}} {{#if author}}| von {{{author}}}{{/if}}

12 | {{/if}} 13 |

{{{title}}}

14 | {{> button-link-component button=source direction='right' titleprefix='Zum'}} 15 | {{/if}} 16 |
17 | -------------------------------------------------------------------------------- /src/well-known/apple-app-site-association: -------------------------------------------------------------------------------- 1 | { 2 | "applinks": { 3 | "apps": [], 4 | "details": [ 5 | { 6 | "appID": "523TP53AQF.de.rki.corona-warn-app", 7 | "paths": [ 8 | "/e1/*", 9 | "/E1/*" 10 | ] 11 | }, 12 | { 13 | "appID": "523TP53AQF.de.rki.coronawarnapp-dev", 14 | "paths": [ 15 | "/e1/*", 16 | "/E1/*" 17 | ] 18 | }, 19 | { 20 | "appID": "523TP53AQF.de.rki.coronawarnapp", 21 | "paths": [ 22 | "/e1/*", 23 | "/E1/*" 24 | ] 25 | } 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/03_other.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F4AC Anything else?" 3 | about: For implementation specific issues (e.g., bug in the iOS app), please consider to open an issue in the respective repository. 4 | 5 | --- 6 | 11 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | 5 | @if (length($shadow) == 1) { 6 | // We can pass `@include box-shadow(none);` 7 | $result: $shadow; 8 | } @else { 9 | // Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;` 10 | @for $i from 1 through length($shadow) { 11 | @if nth($shadow, $i) != "none" { 12 | $result: append($result, nth($shadow, $i), "comma"); 13 | } 14 | } 15 | } 16 | @if (length($result) > 0) { 17 | box-shadow: $result; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/assets/img/icons/external.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/scss/helpers/_position.scss: -------------------------------------------------------------------------------- 1 | // Shorthand 2 | 3 | .fixed-top { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | left: 0; 8 | z-index: $zindex-fixed; 9 | } 10 | 11 | .fixed-bottom { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: $zindex-fixed; 17 | } 18 | 19 | // Responsive sticky top 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | @include media-breakpoint-up($breakpoint) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | .sticky#{$infix}-top { 25 | position: sticky; 26 | top: 0; 27 | z-index: $zindex-sticky; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_container.scss: -------------------------------------------------------------------------------- 1 | // Container mixins 2 | 3 | @mixin make-container($padding-x: $container-padding-x) { 4 | width: 100%; 5 | padding-right: $padding-x; 6 | padding-left: $padding-x; 7 | margin-right: auto; 8 | margin-left: auto; 9 | } 10 | 11 | 12 | // For each breakpoint, define the maximum width of the container in a media query 13 | @mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) { 14 | @each $breakpoint, $container-max-width in $max-widths { 15 | @include media-breakpoint-up($breakpoint, $breakpoints) { 16 | max-width: $container-max-width; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/assets/img/icons/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/img/icons/Close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/scss/helpers/_embed.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | @use "sass:math"; 4 | 5 | .embed-responsive { 6 | position: relative; 7 | width: 100%; 8 | 9 | &::before { 10 | display: block; 11 | content: ""; 12 | } 13 | 14 | .embed-responsive-item, 15 | iframe, 16 | embed, 17 | object, 18 | video { 19 | position: absolute; 20 | top: 0; 21 | left: 0; 22 | width: 100%; 23 | height: 100%; 24 | } 25 | } 26 | 27 | @each $key, $ratio in $embed-responsive-aspect-ratios { 28 | .embed-responsive-#{$key} { 29 | &::before { 30 | padding-top: percentage(math.div(map-get($ratio, y), map-get($ratio, x))); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/partials/headline-component.html: -------------------------------------------------------------------------------- 1 | {{#if titlecaption }} 2 |
{{titlecaption}}
3 | {{/if}} 4 | {{#if title}} 5 |

{{title}}

6 | {{/if}} 7 | {{#if subtitle}} 8 |

{{subtitle}}

9 | {{/if}} 10 | {{#if text}} 11 |

{{{text}}}

12 | {{/if}} 13 | 14 | {{#if button}} 15 | {{button.title}}{{#if button.icon}}{{/if}}{{#unless button.icon}}{{#if icon}}{{/if}}{{/unless}} 16 | 17 | {{/if}} -------------------------------------------------------------------------------- /src/assets/js/static/store-redirect.js: -------------------------------------------------------------------------------- 1 | 2 | document.addEventListener("DOMContentLoaded", function(event) { 3 | if(navigator.userAgent.toLowerCase().indexOf("android") > -1){ 4 | console.log("redirect android"); 5 | window.location = 'market://details?id=de.rki.coronawarnapp'; 6 | document.getElementById("store_apple").classList.add("d-none"); 7 | } 8 | else if(navigator.userAgent.toLowerCase().indexOf("iphone") > -1){ 9 | console.log("redirect apple"); 10 | window.location.href = 'https://apps.apple.com/de/app/corona-warn-app/id1512595757'; 11 | document.getElementById("store_android").classList.add("d-none"); 12 | } 13 | else { 14 | console.log("no redirect"); 15 | } 16 | }); -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_questions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U00002753 Questions?" 3 | about: If you have *specific* questions about the website, please post them here. 4 | labels: question 5 | 6 | --- 7 | 12 | 13 | ## Your Question 14 | 15 | * Website URL Path: 16 | * Line / Paragraph: 17 | * Question: 18 | -------------------------------------------------------------------------------- /src/assets/img/icons/security.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/partials/slider-component.html: -------------------------------------------------------------------------------- 1 |
2 | {{#if type}} 3 | {{#ifequal type 'blog'}} 4 | {{#unless lang_de}} 5 | {{#each (limit slides amount)}} 6 |
7 | {{> news-text-component this=.}} 8 |
9 | {{/each}} 10 | {{/unless}} 11 | {{#if lang_de}} 12 | {{#each (limit slides amount)}} 13 |
14 | {{> news-text-component this=. lang_de=true}} 15 |
16 | {{/each}} 17 | {{/if}} 18 | {{/ifequal}} 19 | {{else}} 20 | {{#each (limit slides amount)}} 21 |
22 | {{.}} 23 |
24 | {{/each}} 25 | {{/if}} 26 |
27 | -------------------------------------------------------------------------------- /src/data/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "section-main": { 3 | "image": { 4 | "url": "/assets/img/thanks-en.png", 5 | "title": "Community", 6 | "alt": "Thank you" 7 | }, 8 | "headline": { 9 | "title": "Thank you for your interest in the Corona-Warn-App.", 10 | "textblock": [ 11 | "Following the end of the app's development on 31 May 2023, its website has now also been discontinued.", 12 | "Some of the content has been moved to the website of the Robert Koch Institute, where it is still available (most of it German only) at https://www.rki.de/cwa." 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/data/index_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "section-main": { 3 | "image": { 4 | "url": "/assets/img/thanks-de.png", 5 | "title": "Community", 6 | "alt": "Vielen Dank" 7 | }, 8 | "headline": { 9 | "title": "Vielen Dank für Ihr Interesse an der Corona-Warn-App.", 10 | "textblock": [ 11 | "Nach dem Entwicklungsende der App am 31.05.2023 wird nun auch ihre Website nicht mehr weitergeführt.", 12 | "Einige der Inhalte sind zum Internetauftritt des Robert Koch-Instituts umgezogen, wo sie Ihnen unter https://www.rki.de/cwa weiterhin zur Verfügung stehen." 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-blacklist 2 | @mixin transition($transition...) { 3 | @if length($transition) == 0 { 4 | $transition: $transition-base; 5 | } 6 | 7 | @if length($transition) > 1 { 8 | @each $value in $transition { 9 | @if $value == null or $value == none { 10 | @warn "The keyword 'none' or 'null' must be used as a single argument."; 11 | } 12 | } 13 | } 14 | 15 | @if $enable-transitions { 16 | @if nth($transition, 1) != null { 17 | transition: $transition; 18 | } 19 | 20 | @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { 21 | @media (prefers-reduced-motion: reduce) { 22 | transition: none; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/partials/text-component.html: -------------------------------------------------------------------------------- 1 | {{#if title}} 2 | {{#if large-title}} 3 |

{{{title}}}

4 | {{else}} 5 |

{{{title}}}

6 | {{/if}} 7 | {{/if}} 8 | {{#if text}} 9 |

{{{text}}}

10 | {{/if}} 11 | {{#if textblock}} 12 | {{#each textblock}} 13 |

{{{.}}}

14 | {{/each}} 15 | {{/if}} 16 | {{#if textcaption}} 17 |

{{textcaption}}

18 | {{/if}} 19 | {{#if button}} 20 | {{> button-component button=button}} 21 | {{/if}} 22 | {{#if links}} 23 | {{#if linksblock}}
{{/if}} 24 | {{#each links}} 25 | {{> button-link-component button=.}} 26 | {{/each}} 27 | {{#if linksblock}}
{{/if}} 28 | {{/if}} 29 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | @mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { 4 | .page-link { 5 | padding: $padding-y $padding-x; 6 | @include font-size($font-size); 7 | } 8 | 9 | .page-item { 10 | @if $pagination-margin-left == (-$pagination-border-width) { 11 | &:first-child { 12 | .page-link { 13 | @include border-left-radius($border-radius); 14 | } 15 | } 16 | 17 | &:last-child { 18 | .page-link { 19 | @include border-right-radius($border-radius); 20 | } 21 | } 22 | } @else { 23 | //Add border-radius to all pageLinks in case they have left margin 24 | .page-link { 25 | @include border-radius($border-radius); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/partials/image-component.html: -------------------------------------------------------------------------------- 1 |
2 | {{#if image.url-webp}} 3 | 4 | 5 | {{image.title}} 6 | 7 | {{else}} 8 | {{image.title}} 9 | {{/if}} 10 |
11 | -------------------------------------------------------------------------------- /src/assets/scss/_icon.scss: -------------------------------------------------------------------------------- 1 | @mixin image-icon($value) { 2 | &_#{$value}:before { 3 | background-image: url("../img/icons/#{$value}.svg"); 4 | } 5 | } 6 | 7 | .icon { 8 | overflow: visible; 9 | position: relative; 10 | &:before { 11 | content: ""; 12 | background-position: center; 13 | background-repeat: no-repeat; 14 | position: absolute; 15 | width: 100%; 16 | height: 100%; 17 | top: 50%; 18 | left: 50%; 19 | transform: translate3d(-50%,-50%,0); 20 | } 21 | @include image-icon('github'); 22 | @include image-icon('schnelltest-partner'); 23 | @include image-icon('arrow-down'); 24 | @include image-icon('arrow-right'); 25 | @include image-icon('arrow-left'); 26 | &_img { 27 | &:before { 28 | content: normal; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/assets/img/icons/issue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/open-source.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | pull_request: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Setup Node.js 18 environment 15 | uses: actions/setup-node@v3 16 | with: 17 | node-version: 'lts/hydrogen' 18 | 19 | - name: Install root dependencies 20 | uses: bahmutov/npm-install@v1 21 | 22 | - name: Check if the page builds 23 | run: npm run-script build 24 | 25 | - name: Zip build 26 | run: zip -r public.zip public -x "public/assets/screenshots/*" "public/assets/img/blog/*" "public/assets/img/science/*" 27 | 28 | - name: Upload artifact 29 | uses: actions/upload-artifact@v3 30 | with: 31 | name: public 32 | retention-days: 1 33 | path: public.zip -------------------------------------------------------------------------------- /src/partials/two-column.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

How does the app work?

5 |
6 |
7 |
8 |
Corona-Warn-App Open Source Project
9 |

Help us improve the COVID-19 10 | exposure notification app

11 |

12 | The Corona-Warn-App open-source project develops a tracking app based on technology with a decentralized approach that 13 | notifies users if they have been exposed to COVID-19. It maintains the highest security and data privacy standards to 14 | protect the end-users and encourage adoption. 15 |

16 |
17 |
18 |
19 |
20 |
21 |
22 |
-------------------------------------------------------------------------------- /src/partials/page-index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |
6 | 7 |
8 | 9 | 10 | 11 |
12 | 13 |
14 | {{> headline-component title=page-contents.section-main.headline.title}} 15 |
16 | 17 |
18 | {{> text-component 19 | textblock=page-contents.section-main.headline.textblock 20 | button=page-contents.section-main.headline.button}} 21 |
22 | 23 |
24 |
25 |
-------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/01_site_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F6A8 Website Issue" 3 | about: Did you come across parts of our website that should be fixed? 4 | labels: content, bug 5 | 6 | --- 7 | 12 | 13 | ## Where to find the issue 14 | 15 | 16 | ## Describe the issue 17 | 18 | 19 | ## Suggested change 20 | 21 | -------------------------------------------------------------------------------- /src/partials/favicon.html: -------------------------------------------------------------------------------- 1 | {{#if favicon}} 2 | {{#if favicon.include}} 3 | {{#ifequal favicon.include "all"}} 4 | 5 | 6 | 7 | 8 | 9 | {{/ifequal}} 10 | {{/if}} 11 | {{else}} 12 | 18 | {{/if}} -------------------------------------------------------------------------------- /src/assets/scss/mixins/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Only display content to screen readers 4 | // 5 | // See: https://a11yproject.com/posts/how-to-hide-content/ 6 | // See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/ 7 | 8 | @mixin sr-only { 9 | position: absolute !important; 10 | width: 1px !important; 11 | height: 1px !important; 12 | padding: 0 !important; 13 | margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 14 | overflow: hidden !important; 15 | clip: rect(0, 0, 0, 0) !important; 16 | white-space: nowrap !important; 17 | border: 0 !important; 18 | } 19 | 20 | // Use to only display content when it's focused. 21 | // 22 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 23 | 24 | @mixin sr-only-focusable { 25 | &:not(:focus) { 26 | @include sr-only(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/assets/img/icons/github_white.svg: -------------------------------------------------------------------------------- 1 | GithubCreated with Sketch. -------------------------------------------------------------------------------- /src/assets/img/icons/github.svg: -------------------------------------------------------------------------------- 1 | icon/GithubCreated with Sketch. -------------------------------------------------------------------------------- /src/assets/img/icons/github_white32x32.svg: -------------------------------------------------------------------------------- 1 | GithubCreated with Sketch. -------------------------------------------------------------------------------- /src/partials/participants.html: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant($state, $background) { 3 | .table-#{$state} { 4 | $color: color-contrast(opaque($body-bg, $background)); 5 | $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); 6 | $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); 7 | $active-bg: mix($color, $background, percentage($table-active-bg-factor)); 8 | 9 | --bs-table-bg: #{$background}; 10 | --bs-table-striped-bg: #{$striped-bg}; 11 | --bs-table-striped-color: #{color-contrast($striped-bg)}; 12 | --bs-table-active-bg: #{$active-bg}; 13 | --bs-table-active-color: #{color-contrast($active-bg)}; 14 | --bs-table-hover-bg: #{$hover-bg}; 15 | --bs-table-hover-color: #{color-contrast($hover-bg)}; 16 | 17 | color: $color; 18 | border-color: mix($color, $background, percentage($table-border-factor)); 19 | } 20 | } 21 | // scss-docs-end table-variant 22 | -------------------------------------------------------------------------------- /src/assets/img/icons/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/questions.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/info_faq.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /src/data/imprint_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "title": "Impressum", 4 | "description": "" 5 | }, 6 | "section-main": { 7 | "headline": { 8 | "title": "Impressum" 9 | }, 10 | "content": { 11 | "title": "Robert Koch-Institut", 12 | "textblock": [ 13 | "Herausgeber", 14 | "(verantwortlich nach § 5 Abs. 1 TMG, § 18 Abs. 1 MStV, DSGVO, BDSG)", 15 | "Robert Koch-Institut
Nordufer 20
13353 Berlin
", 16 | "Vertreten durch den Präsidenten

", 17 | "Kontakt
E-Mail: info...rki...de
Kontaktformular
", 18 | "Telefon: 030 18754 0 (Zentrale)

", 19 | "Umsatzsteuer-Identifikationsnummer
DE 165 893 430" 20 | ] 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/data/imprint.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "title": "Legal notice", 4 | "description": "" 5 | }, 6 | "section-main": { 7 | "headline": { 8 | "title": "Legal notice" 9 | }, 10 | "content": { 11 | "title": "Robert Koch Institute", 12 | "textblock": [ 13 | "Published by", 14 | "(responsible in accordance with Art. 5 (1) TMG, Art. 18 (1) MStV, GDPR, BDSG)", 15 | "Robert Koch Institute
Nordufer 20
13353 Berlin
", 16 | "Represented by its president

", 17 | "Contact
E-Mail: info...rki...de
Contact Form
", 18 | "Phone: +49 30 18754 0 (switchboard)

", 19 | "VAT identification number
DE 165 893 430" 20 | ] 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/assets/img/icons/bug.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/04_feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F381 Feature Request" 3 | about: Do you have an idea for a new feature? 4 | labels: enhancement 5 | 6 | --- 7 | 12 | 13 | ## Feature description 14 | 15 | 20 | 21 | ## Problem and motivation 22 | 25 | 26 | ## Is this something you're interested in working on 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/assets/img/icons/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/layouts/error-pages.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{#if global.favicon}} 10 | {{> favicon favicon=global.favicon}} 11 | {{/if}} 12 | 13 | 14 | 15 | 16 | {{page-title}} 17 | 18 | 19 | {{!-- Pages you create in the src/pages/ folder are inserted here when the 20 | flattened page is created. --}} 21 | 22 | {{> header-for-error-pages}} 23 |
24 | {{> body}} 25 |
26 | {{> footer language=global.lang.en}} 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/assets/img/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/scss/_custom-variables.scss: -------------------------------------------------------------------------------- 1 | $theme-button-colors: ( 2 | "primary": $primary, 3 | "secondary": $secondary 4 | ) !default; 5 | $theme-button-shadow-color: $charcoal-black; 6 | 7 | $background-image_gradient: linear-gradient(to right, #54b3e1 20%, #943749 100%, #943749 126%); 8 | $background-image_shape-wave: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='1440' height='272' viewBox='0 0 1440 272'%3e%3cpath fill='%23fff' d='M1428.979 207.361c-178.674 81.041-501.519 81.266-718.176 6.004-266.515-92.581-562.398-106.589-710.803-106.974v165.609h1440v-70.02c-3.941 2.036-7.636 3.846-11.021 5.381z'/%3e%3c/svg%3e"); 9 | $background-image_shape-wave-xs: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1' xmlns='http://www.w3.org/2000/svg' width='375' height='36' viewBox='0 0 375 36'%3e%3cpath fill='%23fff' d='M5.18 22.209c-1.775-.189-3.5-.409-5.18-.656v14.447h375v-25.712c-111.343 21.507-244.559 25.302-369.82 11.921z'/%3e%3c/svg%3e"); 10 | 11 | $accordion-header-padding: ($spacer * 1.25) 44px ($spacer * 1.25) ($spacer * 1.25); 12 | $according-header-bg: $body-bg; 13 | $according-header-active-bg: $secondary; 14 | $accordion-border-color: $border-color; 15 | 16 | $header-mobile-sticky: false; -------------------------------------------------------------------------------- /src/partials/section-get-app.html: -------------------------------------------------------------------------------- 1 | {{#if @root.get-app-enabled}} 2 |
3 |
4 | {{#if section-contents}} 5 | {{#if section-cancelable}} 6 |
7 | 8 |
9 | {{/if}} 10 |
11 | {{#if section-contents.icon-list}} 12 |
13 | {{#each section-contents.icon-list}} 14 | 15 | {{title}} Icon 16 | 17 | {{/each}} 18 |
19 | {{/if}} 20 | {{#if section-contents.headline}} 21 |
22 | {{> headline-component section-contents.headline}} 23 |
24 | {{/if}} 25 |
26 | {{/if}} 27 |
28 |
29 | {{/if}} -------------------------------------------------------------------------------- /src/partials/footer.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | # Your project's server will run on localhost:xxxx at this port 2 | PORT: 8000 3 | 4 | # Autoprefixer will make sure your CSS works with these browsers 5 | COMPATIBILITY: 6 | - "last 2 versions" 7 | - "ie >= 9" 8 | - "ios >= 7" 9 | 10 | # UnCSS will use these settings 11 | UNCSS_OPTIONS: 12 | html: 13 | # Search for used CSS classes in generated HTML files 14 | - "dist/**/*.html" 15 | ignore: 16 | - !!js/regexp .foundation-mq 17 | - !!js/regexp ^\.is-.* 18 | 19 | # Gulp will reference these paths when it copies files 20 | PATHS: 21 | # Path to dist folder 22 | dist: "./public" 23 | # Paths to static assets that aren't images, CSS, or JavaScript 24 | assets: 25 | - "src/assets/**/*" 26 | - "!src/assets/js/app.js" 27 | - "!src/assets/js/lib/**/*" 28 | - "!src/assets/{img,scss}/**/*" 29 | # Paths to Sass libraries, which can then be loaded with @import 30 | sass: 31 | # - "node_modules/foundation-sites/scss" 32 | # - "node_modules/motion-ui/src" 33 | # Paths to JavaScript entry points for webpack to bundle modules 34 | entries: 35 | - "src/assets/js/app.js" 36 | # Paths to root assets 37 | rootAssets: 38 | - "src/root-assets/*" 39 | wellKnown: 40 | - "src/well-known/*" 41 | -------------------------------------------------------------------------------- /docs/CREATE_BLOG_REDIRECTS.md: -------------------------------------------------------------------------------- 1 | # Creating Blog Redirects 2 | 3 | If you plan to replace an old blog post with an updated version and make sure that the old links still work, use the following process 4 | 5 | ## Create a new blogpost 6 | 7 | Just copy the old `index.md` and `index_de.md` files to a new folder with the right date (e.g., today). 8 | Rewrite the blog post as needed. 9 | 10 | ## Update the old blog post 11 | 12 | Your old blog post will still have the following structure at the top of the md files: 13 | 14 | ```md 15 | --- 16 | page-title: "QR Code scanned but no test result in the Corona-Warn-App" 17 | page-description: "QR Code scanned but no test result in the Corona-Warn-App" 18 | page-name: notes-qr-codes 19 | page-name_de: notes-qr-codes 20 | author: Janina Hoerdt 21 | layout: blog 22 | --- 23 | ``` 24 | 25 | replace this with the following: 26 | 27 | ```md 28 | --- 29 | redirect: {date of new blogpost}-{page-name of new blogpost} 30 | page-name: {page-name-of-old-blogpost} 31 | --- 32 | ``` 33 | 34 | For an example, see [here](../blog/2020-08-11-hinweise-qr-code/index.md). 35 | 36 | It is important to keep the page name of the old blogpost (you can use the same one for the new post, though), otherwise the links will not be properly generated. 37 | -------------------------------------------------------------------------------- /src/layouts/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{#if global.favicon}} 10 | 16 | {{/if}} 17 | 18 | 19 | 20 | {{page-title}} 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/assets/js/static/page-redirect.js: -------------------------------------------------------------------------------- 1 | // get the target faq anchor from the script attributes 2 | const targetAnchor = document.currentScript.getAttribute('target-anchor'); 3 | const targetPath = document.currentScript.getAttribute('target-path'); 4 | // get the current url 5 | const curPage = window.location.href; 6 | const endsWithSlash = curPage.substr(-1) === "/"; 7 | let targetPage = curPage; 8 | 9 | // if we have a target path, replace the existing last part of the url 10 | if(targetPath){ 11 | // Replace the last part of the string with the new path 12 | if(endsWithSlash){ 13 | targetPage = curPage.replace(/\/[^\/]*\/$/, "/" + targetPath + "/"); 14 | } else { 15 | targetPage = curPage.replace(/\/[^\/]*$/, "/" + targetPath + "/"); 16 | } 17 | } 18 | 19 | // replace the part from the last slash to the end of the string with the proper hash 20 | if(targetAnchor){ 21 | if(endsWithSlash) { 22 | // if the page already ends with a slash, we only append the anchor 23 | targetPage += "#" + targetAnchor; 24 | } else { 25 | // otherwhise, we replace the last part of the url with the anchor 26 | targetPage = curPage.replace(/\/[^\/]*$/, '/#' + targetAnchor); 27 | } 28 | } 29 | 30 | // redirect to target 31 | window.location.href = targetPage; 32 | -------------------------------------------------------------------------------- /src/assets/scss/_progress.scss: -------------------------------------------------------------------------------- 1 | // Disable animation if transitions are disabled 2 | @if $enable-transitions { 3 | @keyframes progress-bar-stripes { 4 | 0% { background-position-x: $progress-height; } 5 | } 6 | } 7 | 8 | .progress { 9 | display: flex; 10 | height: $progress-height; 11 | overflow: hidden; // force rounded corners by cropping it 12 | @include font-size($progress-font-size); 13 | background-color: $progress-bg; 14 | @include border-radius($progress-border-radius); 15 | @include box-shadow($progress-box-shadow); 16 | } 17 | 18 | .progress-bar { 19 | display: flex; 20 | flex-direction: column; 21 | justify-content: center; 22 | overflow: hidden; 23 | color: $progress-bar-color; 24 | text-align: center; 25 | white-space: nowrap; 26 | background-color: $progress-bar-bg; 27 | @include transition($progress-bar-transition); 28 | } 29 | 30 | .progress-bar-striped { 31 | @include gradient-striped(); 32 | background-size: $progress-height $progress-height; 33 | } 34 | 35 | @if $enable-transitions { 36 | .progress-bar-animated { 37 | animation: progress-bar-stripes $progress-bar-animation-timing; 38 | 39 | @if $enable-reduced-motion { 40 | @media (prefers-reduced-motion: reduce) { 41 | animation: none; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/assets/img/faq.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/fonts/icon-font/styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @font-face { 4 | font-family: "icon-font"; 5 | src:url("fonts/icon-font.eot"); 6 | src:url("fonts/icon-font.eot?#iefix") format("embedded-opentype"), 7 | url("fonts/icon-font.woff") format("woff"), 8 | url("fonts/icon-font.ttf") format("truetype"), 9 | url("fonts/icon-font.svg#icon-font") format("svg"); 10 | font-weight: normal; 11 | font-style: normal; 12 | 13 | } 14 | 15 | [data-icon]:before { 16 | font-family: "icon-font" !important; 17 | content: attr(data-icon); 18 | font-style: normal !important; 19 | font-weight: normal !important; 20 | font-variant: normal !important; 21 | text-transform: none !important; 22 | speak: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | [class^="icon-"]:before, 29 | [class*=" icon-"]:before { 30 | font-family: "icon-font" !important; 31 | font-style: normal !important; 32 | font-weight: normal !important; 33 | font-variant: normal !important; 34 | text-transform: none !important; 35 | speak: none; 36 | line-height: 1; 37 | -webkit-font-smoothing: antialiased; 38 | -moz-osx-font-smoothing: grayscale; 39 | } 40 | 41 | .icon-github-icon:before { 42 | content: "\61"; 43 | } 44 | .icon-twitter-icon:before { 45 | content: "\62"; 46 | } 47 | .icon-slack-icon:before { 48 | content: "\63"; 49 | } 50 | -------------------------------------------------------------------------------- /src/partials/navlist-item.html: -------------------------------------------------------------------------------- 1 | {{#unless item.deactivated}} 2 | 30 | {{/unless}} 31 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // 4 | 5 | .form-label { 6 | margin-bottom: $form-label-margin-bottom; 7 | @include font-size($form-label-font-size); 8 | font-style: $form-label-font-style; 9 | font-weight: $form-label-font-weight; 10 | color: $form-label-color; 11 | } 12 | 13 | // For use with horizontal and inline forms, when you need the label (or legend) 14 | // text to align with the form controls. 15 | .col-form-label { 16 | padding-top: add($input-padding-y, $input-border-width); 17 | padding-bottom: add($input-padding-y, $input-border-width); 18 | margin-bottom: 0; // Override the `` default 19 | @include font-size(inherit); // Override the `` default 20 | font-style: $form-label-font-style; 21 | font-weight: $form-label-font-weight; 22 | line-height: $input-line-height; 23 | color: $form-label-color; 24 | } 25 | 26 | .col-form-label-lg { 27 | padding-top: add($input-padding-y-lg, $input-border-width); 28 | padding-bottom: add($input-padding-y-lg, $input-border-width); 29 | @include font-size($input-font-size-lg); 30 | } 31 | 32 | .col-form-label-sm { 33 | padding-top: add($input-padding-y-sm, $input-border-width); 34 | padding-bottom: add($input-padding-y-sm, $input-border-width); 35 | @include font-size($input-font-size-sm); 36 | } 37 | 38 | .col-form-label-fieldset { 39 | padding-top: 0; 40 | padding-bottom: 0; 41 | } 42 | 43 | .col-form-label-fieldset-container { 44 | padding-top: add($input-padding-y, $input-border-width); 45 | } -------------------------------------------------------------------------------- /src/assets/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import "vendor/rfs"; 7 | 8 | // Deprecate 9 | @import "mixins/deprecate"; 10 | 11 | // Helpers 12 | @import "mixins/breakpoints"; 13 | @import "mixins/image"; 14 | @import "mixins/resize"; 15 | @import "mixins/screen-reader"; 16 | @import "mixins/reset-text"; 17 | @import "mixins/text-truncate"; 18 | 19 | // Utilities 20 | @import "mixins/utilities"; 21 | 22 | // Components 23 | @import "mixins/alert"; 24 | @import "mixins/buttons"; 25 | @import "mixins/caret"; 26 | @import "mixins/pagination"; 27 | @import "mixins/lists"; 28 | @import "mixins/list-group"; 29 | @import "mixins/forms"; 30 | @import "mixins/table-variants"; 31 | 32 | // Skins 33 | @import "mixins/background-variant"; 34 | @import "mixins/border-radius"; 35 | @import "mixins/box-shadow"; 36 | @import "mixins/gradients"; 37 | @import "mixins/transition"; 38 | 39 | // Layout 40 | @import "mixins/clearfix"; 41 | @import "mixins/container"; 42 | @import "mixins/grid"; 43 | 44 | 45 | //Slider 46 | @function slick-image-url($url) { 47 | @if function-exists(image-url) { 48 | @return image-url($url); 49 | } 50 | @else { 51 | @return url($slick-loader-path + $url); 52 | } 53 | } 54 | 55 | @function slick-font-url($url) { 56 | @if function-exists(font-url) { 57 | @return font-url($url); 58 | } 59 | @else { 60 | @return url($slick-font-path + $url); 61 | } 62 | } -------------------------------------------------------------------------------- /src/assets/js/lazyload.js: -------------------------------------------------------------------------------- 1 | function lazyload() { 2 | const images = Array.prototype.slice.call(document.querySelectorAll(".lazy")); 3 | 4 | if ('IntersectionObserver' in window && 5 | 'IntersectionObserverEntry' in window && 6 | 'intersectionRatio' in window.IntersectionObserverEntry.prototype) { 7 | var imageObserver = new IntersectionObserver(function (entries, observer) { 8 | for (let i=0; i { 11 | if (entry.isIntersecting) { 12 | const lazyImage = entry.target; 13 | if(lazyImage.hasAttribute("data-src")) { 14 | lazyImage.src = lazyImage.dataset.src; 15 | } else { 16 | lazyImage.srcset = lazyImage.dataset.srcset; 17 | } 18 | lazyImage.classList.remove("lazy"); 19 | imageObserver.unobserve(lazyImage); 20 | } 21 | } 22 | }); 23 | 24 | for (let i=0; i { 31 | for (let i=0; i 3 |
4 |
5 | 10 |
11 |
12 |

{{page-contents.section-main.headline.title}}

13 |

{{page-contents.section-main.content.title}}

14 |
15 | {{#each page-contents.section-main.content.textblock}} 16 |

{{{.}}}

17 | {{/each}} 18 |
19 |
20 |
21 | 26 |
27 |
28 | 29 | {{/if}} 30 | -------------------------------------------------------------------------------- /src/assets/img/icons/smartphone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/partials/page-privacy.html: -------------------------------------------------------------------------------- 1 | {{#if page-contents}} 2 |
3 |
4 |
5 | 10 |
11 |

{{page-contents.section-main.headline.title}}

12 |
13 |
14 |
15 |

{{page-contents.section-main.website-headline.title}}

16 |
17 | {{#each page-contents.section-main.website-content.textblock}} 18 |

{{{.}}}

19 | {{/each}} 20 |
21 |
22 |
23 | 28 |
29 |
30 |
31 | {{/if}} 32 | -------------------------------------------------------------------------------- /src/partials/error-page-content.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |

{{global.error.title}}

7 |

{{global.error.titlecaption}}

8 |
9 |
10 | {{>image-component image=global.error.image }} 11 |
12 |
13 | {{#if global.error.boxes}} 14 |
15 | {{#each global.error.boxes}} 16 |
17 |
18 | {{#if image}} 19 | {{> image-component this=.}} 20 | {{/if}} 21 |
22 | {{#if title}} 23 |

{{title}}

24 | {{/if}} 25 | {{#if button}} 26 | {{button.title}} 28 | {{/if}} 29 |
30 |
31 |
32 | {{/each}} 33 |
34 | {{/if}} 35 |
36 |
37 |
38 | -------------------------------------------------------------------------------- /src/assets/img/icons/improvement.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_caret.scss: -------------------------------------------------------------------------------- 1 | @mixin caret-down { 2 | border-top: $caret-width solid; 3 | border-right: $caret-width solid transparent; 4 | border-bottom: 0; 5 | border-left: $caret-width solid transparent; 6 | } 7 | 8 | @mixin caret-up { 9 | border-top: 0; 10 | border-right: $caret-width solid transparent; 11 | border-bottom: $caret-width solid; 12 | border-left: $caret-width solid transparent; 13 | } 14 | 15 | @mixin caret-right { 16 | border-top: $caret-width solid transparent; 17 | border-right: 0; 18 | border-bottom: $caret-width solid transparent; 19 | border-left: $caret-width solid; 20 | } 21 | 22 | @mixin caret-left { 23 | border-top: $caret-width solid transparent; 24 | border-right: $caret-width solid; 25 | border-bottom: $caret-width solid transparent; 26 | } 27 | 28 | @mixin caret($direction: down) { 29 | @if $enable-caret { 30 | &::after { 31 | display: inline-block; 32 | margin-left: $caret-spacing; 33 | vertical-align: $caret-vertical-align; 34 | content: ""; 35 | @if $direction == down { 36 | @include caret-down(); 37 | } @else if $direction == up { 38 | @include caret-up(); 39 | } @else if $direction == right { 40 | @include caret-right(); 41 | } 42 | } 43 | 44 | @if $direction == left { 45 | &::after { 46 | display: none; 47 | } 48 | 49 | &::before { 50 | display: inline-block; 51 | margin-right: $caret-spacing; 52 | vertical-align: $caret-vertical-align; 53 | content: ""; 54 | @include caret-left(); 55 | } 56 | } 57 | 58 | &:empty::after { 59 | margin-left: 0; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/assets/img/icons/decentralized.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Vulnerabilities 2 | 3 | The Corona-Warn-App is built with security and data privacy in mind to ensure your data is safe. 4 | 5 | ## Reporting 6 | 7 | We are grateful for security researchers and users reporting a vulnerability to us, first. To ensure that your request is handled in a timely manner and non-disclosure of vulnerabilities can be assured, please follow the below guideline. 8 | 9 | **Please do not report security vulnerabilities directly on GitHub. GitHub Issues can be publicly seen and therefore would result in a direct disclosure.** 10 | 11 | **Important:** From June 1, 2023 onwards, please report a vulnerability, address questions about data privacy, security concepts, and other media requests by contacting [CoronaWarnApp@rki.de](mailto:CoronaWarnApp@rki.de)! For transparency reasons, you can find the reporting procedure that was in place until May 31, 2023 below. 12 | 13 | * For reporting a vulnerability, please use the Vulnerability Report Form for Security Researchers on [SAP Trust Center](https://www.sap.com/about/trust-center/security/incident-management.html). 14 | * Please select "Corona-Warn-App" in the _product_ list. 15 | * In the _versions_ field, either note the specific [release version](https://github.com/corona-warn-app/cwa-website/releases) or commit id of the master branch you investigated. 16 | * The affected repository should be mentioned in the _vulnerability description_. 17 | * Please use this channel only for reporting vulnerabilities of the _cwa-website_ component and check the security of the respective repositories for other components. 18 | 19 | ## Disclosure Handling 20 | The CWA-Team is committed to timely review and respond to your request. The project will inform the public about resolved security vulnerabilities. -------------------------------------------------------------------------------- /src/assets/scss/utilities/_api.scss: -------------------------------------------------------------------------------- 1 | // Loop over each breakpoint 2 | @each $breakpoint in map-keys($grid-breakpoints) { 3 | 4 | // Generate media query if needed 5 | @include media-breakpoint-up($breakpoint) { 6 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 7 | 8 | // Loop over each utility property 9 | @each $key, $utility in $utilities { 10 | // The utility can be disabled with `false`, thus check if the utility is a map first 11 | // Only proceed if responsive media queries are enabled or if it's the base media query 12 | @if type-of($utility) == "map" and (map-get($utility, responsive) or $infix == "") { 13 | @include generate-utility($utility, $infix); 14 | } 15 | } 16 | } 17 | } 18 | 19 | // RFS rescaling 20 | @media (min-width: $rfs-mq-value) { 21 | @each $breakpoint in map-keys($grid-breakpoints) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { 25 | // Loop over each utility property 26 | @each $key, $utility in $utilities { 27 | // The utility can be disabled with `false`, thus check if the utility is a map first 28 | // Only proceed if responsive media queries are enabled or if it's the base media query 29 | @if type-of($utility) == "map" and map-get($utility, rfs) { 30 | @include generate-utility($utility, $infix, true); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | 37 | 38 | // Print utilities 39 | @media print { 40 | @each $key, $utility in $utilities { 41 | // The utility can be disabled with `false`, thus check if the utility is a map first 42 | // Then check if the utility needs print styles 43 | @if type-of($utility) == "map" and map-get($utility, print) == true { 44 | @include generate-utility($utility, "-print"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docs/FAQ_SEARCH_SUMMARY.md: -------------------------------------------------------------------------------- 1 | # FAQ Search 2 | 3 | FAQ search was introduced to allow users navigate the 80+ questions we collected over the last weeks. 4 | It comprises two main parts that you need to alter, if you want to optimize or change the way the search behaves. 5 | 6 | ## Gulp Function 7 | 8 | The `gulp build` tasks in the [gulpfile](../gulpfile.mjs) performs a step called `copyFAQs`. This takes the faq files ([en](../src/data/faq.json), [de](../src/data/faq_de.json)) and transforms them into a searchable structure. 9 | 10 | Text blocks are merged into a single string and HTML tags are removed. Additionally, the question text is added. Indexes of the structure are the FAQ anchors. The resulting very straightforward JavaScript objects (one per language) are copied to the `{lang}/faq/faq.json` folders of the distribution. 11 | 12 | ## JavaScript 13 | 14 | In [app.js](../src/assets/js/app.js), the file is loaded via an Ajax get call. 15 | If the user enters something (that is longer than 2 characters) into the search field, a callback function runs through the loaded strings and checks whether the given words (split by space) are contained in an FAQ answer. 16 | 17 | All anchors are returned, whose FAQ entry matches the search query. 18 | All FAQs that do not match are hidden. 19 | 20 | ## URL parameters 21 | 22 | If you search and press enter (i.e., submit the search form), you see that an URL parameter called `search` is added. 23 | This way, you can also link to search results instead of just the entire FAQ list or a single entry. 24 | 25 | If, in addition to the search parameter, a hash (e.g., #ios_136) is part of the url to address one entry directly, the search parameter is ignored. 26 | 27 | If the hash cannot be found in the list of available FAQs (e.g., though an outdated, manually altered, or wrong link from the app), a search is performed instead of navigating to the respective FAQ entry. 28 | -------------------------------------------------------------------------------- /src/assets/img/ideas.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icons/virus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_utilities.scss: -------------------------------------------------------------------------------- 1 | // Utility generator 2 | // Used to generate utilities & print utilities 3 | @mixin generate-utility($utility, $infix, $is-rfs-media-query: false) { 4 | $values: map-get($utility, values); 5 | 6 | // If the values are a list or string, convert it into a map 7 | @if type-of($values) == "string" or type-of(nth($values, 1)) != "list" { 8 | $values: zip($values, $values); 9 | } 10 | 11 | @each $key, $value in $values { 12 | $properties: map-get($utility, property); 13 | 14 | // Multiple properties are possible, for example with vertical or horizontal margins or paddings 15 | @if type-of($properties) == "string" { 16 | $properties: append((), $properties); 17 | } 18 | 19 | // Use custom class if present 20 | $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1)); 21 | $property-class: if($property-class == null, "", $property-class); 22 | 23 | $infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix); 24 | 25 | // Don't prefix if value key is null (eg. with shadow class) 26 | $property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, ""); 27 | 28 | @if map-get($utility, rfs) { 29 | // Inside the media query 30 | @if $is-rfs-media-query { 31 | $val: rfs-value($value); 32 | 33 | // Do not render anything if fluid and non fluid values are the same 34 | $value: if($val == rfs-fluid-value($value), null, $val); 35 | } 36 | @else { 37 | $value: rfs-fluid-value($value); 38 | } 39 | } 40 | 41 | @if $value != null { 42 | .#{$property-class + $infix + $property-class-modifier} { 43 | @each $property in $properties { 44 | #{$property}: $value if($enable-important-utilities, !important, null); 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/assets/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | position: relative; 3 | background-position: center; 4 | @extend .section_bg-gradient; 5 | color: $white; 6 | padding-top: 3rem; 7 | padding-bottom: 1rem; 8 | 9 | a:not(.btn), 10 | .copyright, 11 | .small { 12 | color: inherit; 13 | text-decoration: none; 14 | } 15 | a:not(.btn) { 16 | &:hover { 17 | text-decoration: underline; 18 | } 19 | } 20 | .link-item { 21 | padding-left: ($grid-gutter-width *0.5); 22 | padding-right: ($grid-gutter-width *0.5); 23 | margin-bottom: 1.2rem; 24 | 25 | strong, 26 | a { 27 | display: block; 28 | // white-space: nowrap; 29 | fill: white; 30 | } 31 | &:focus { 32 | //outline: none; 33 | } 34 | &:focus-visible { 35 | outline: none; 36 | border: 2px solid white!important; 37 | box-shadow: 0 0 0 2px black!important; 38 | } 39 | } 40 | .logo img { 41 | height: 48px; 42 | } 43 | .logo { 44 | margin-bottom: 1.6rem; 45 | 46 | } 47 | } 48 | 49 | .copyright-bar { 50 | @extend .small; 51 | @extend .d-flex; 52 | margin-top: 1.5rem; 53 | flex-wrap: wrap; 54 | margin-left: ($grid-gutter-width *0.5) * -1; 55 | margin-right: ($grid-gutter-width *0.5) * -1; 56 | 57 | div { 58 | flex: 1 0 auto; 59 | padding-left: ($grid-gutter-width *0.5); 60 | padding-right: ($grid-gutter-width *0.5); 61 | max-width: 100%; 62 | } 63 | 64 | @media (min-width: $screen-sm){ 65 | flex-wrap: nowrap; 66 | justify-content: space-between; 67 | margin-top: 2rem; 68 | div { 69 | flex: 1 1 auto; 70 | } 71 | } 72 | @media (min-width: $screen-md){ 73 | margin-top: 3.2rem; 74 | } 75 | .privacy a { 76 | white-space: nowrap; 77 | } 78 | } -------------------------------------------------------------------------------- /src/assets/fonts/icon-font/icon-font.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/scss/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-grid-classes { 6 | // Single container class with breakpoint max-widths 7 | .container { 8 | @include make-container(); 9 | @include make-container-max-widths(); 10 | &-inner { 11 | max-width: 860px; 12 | margin-left: auto; 13 | margin-right: auto; 14 | padding-left: 0; 15 | padding-right: 0; 16 | &_lg { 17 | max-width: 980px; 18 | } 19 | &_sm { 20 | max-width: 680px; 21 | } 22 | } 23 | @media (max-width: 360px){ 24 | padding-left: 1rem; 25 | padding-right: 1rem; 26 | } 27 | } 28 | 29 | video { 30 | display: block; 31 | width: 100%; 32 | max-height: 100%; 33 | } 34 | 35 | #player-overlay { 36 | background-color: #000; 37 | z-index: 999; 38 | } 39 | 40 | // 100% wide container at all breakpoints 41 | .container-fluid { 42 | @include make-container(); 43 | } 44 | 45 | // Responsive containers that are 100% wide until a breakpoint 46 | @each $breakpoint, $container-max-width in $container-max-widths { 47 | .container-#{$breakpoint} { 48 | @extend .container-fluid; 49 | } 50 | 51 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 52 | %responsive-container-#{$breakpoint} { 53 | max-width: $container-max-width; 54 | } 55 | 56 | // Extend each breakpoint which is smaller or equal to the current breakpoint 57 | $extend-breakpoint: true; 58 | 59 | @each $name, $width in $grid-breakpoints { 60 | @if ($extend-breakpoint) { 61 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 62 | @extend %responsive-container-#{$breakpoint}; 63 | } 64 | 65 | // Once the current breakpoint is reached, stop extending 66 | @if ($breakpoint == $name) { 67 | $extend-breakpoint: false; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/partials/global-nav.html: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /src/assets/img/news-blog.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/partner/T_Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | T_Logo_3c_p_DE 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-blacklist 2 | // Single side border-radius 3 | 4 | // Helper function to replace negative values with 0 5 | @function valid-radius($radius) { 6 | $return: (); 7 | @each $value in $radius { 8 | @if type-of($value) == number { 9 | $return: append($return, max($value, 0)); 10 | } @else { 11 | $return: append($return, $value); 12 | } 13 | } 14 | @return $return; 15 | } 16 | 17 | @mixin border-radius($radius: $border-radius, $fallback-border-radius: false) { 18 | @if $enable-rounded { 19 | border-radius: valid-radius($radius); 20 | } 21 | @else if $fallback-border-radius != false { 22 | border-radius: $fallback-border-radius; 23 | } 24 | } 25 | 26 | @mixin border-top-radius($radius) { 27 | @if $enable-rounded { 28 | border-top-left-radius: valid-radius($radius); 29 | border-top-right-radius: valid-radius($radius); 30 | } 31 | } 32 | 33 | @mixin border-right-radius($radius) { 34 | @if $enable-rounded { 35 | border-top-right-radius: valid-radius($radius); 36 | border-bottom-right-radius: valid-radius($radius); 37 | } 38 | } 39 | 40 | @mixin border-bottom-radius($radius) { 41 | @if $enable-rounded { 42 | border-bottom-right-radius: valid-radius($radius); 43 | border-bottom-left-radius: valid-radius($radius); 44 | } 45 | } 46 | 47 | @mixin border-left-radius($radius) { 48 | @if $enable-rounded { 49 | border-top-left-radius: valid-radius($radius); 50 | border-bottom-left-radius: valid-radius($radius); 51 | } 52 | } 53 | 54 | @mixin border-top-left-radius($radius) { 55 | @if $enable-rounded { 56 | border-top-left-radius: valid-radius($radius); 57 | } 58 | } 59 | 60 | @mixin border-top-right-radius($radius) { 61 | @if $enable-rounded { 62 | border-top-right-radius: valid-radius($radius); 63 | } 64 | } 65 | 66 | @mixin border-bottom-right-radius($radius) { 67 | @if $enable-rounded { 68 | border-bottom-right-radius: valid-radius($radius); 69 | } 70 | } 71 | 72 | @mixin border-bottom-left-radius($radius) { 73 | @if $enable-rounded { 74 | border-bottom-left-radius: valid-radius($radius); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/assets/scss/mixins/_gradients.scss: -------------------------------------------------------------------------------- 1 | // Gradients 2 | 3 | @mixin gradient-bg($color, $foreground: null) { 4 | @if $enable-gradients { 5 | @if $foreground { 6 | background-image: $foreground, linear-gradient(180deg, mix($body-bg, $color, 15%), $color); 7 | } @else { 8 | background-image: linear-gradient(180deg, mix($body-bg, $color, 15%), $color); 9 | } 10 | } @else { 11 | background-color: $color; 12 | } 13 | } 14 | 15 | // Horizontal gradient, from left to right 16 | // 17 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 18 | @mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) { 19 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); 20 | } 21 | 22 | // Vertical gradient, from top to bottom 23 | // 24 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 25 | @mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) { 26 | background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); 27 | } 28 | 29 | @mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) { 30 | background-image: linear-gradient($deg, $start-color, $end-color); 31 | } 32 | 33 | @mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { 34 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); 35 | } 36 | 37 | @mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { 38 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); 39 | } 40 | 41 | @mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) { 42 | background-image: radial-gradient(circle, $inner-color, $outer-color); 43 | } 44 | 45 | @mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) { 46 | background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); 47 | } 48 | -------------------------------------------------------------------------------- /src/layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{#ifequal page-name 'analysis'}} 9 | 10 | {{else}} 11 | 12 | {{/ifequal}} 13 | 14 | {{#if global.favicon}} 15 | {{> favicon favicon=global.favicon}} 16 | {{/if}} 17 | 18 | 19 | 20 | 21 | {{page-title}} 22 | 23 | 24 | {{!-- Pages you create in the src/pages/ folder are inserted here when the 25 | flattened page is created. --}} 26 | 27 | Skip to main content 28 | {{> header}} 29 | 30 |
31 | {{> body}} 32 |
33 | {{#unless lang_de}} 34 | {{> footer language=global.lang.en}} 35 | {{/unless}} 36 | {{#if lang_de}} 37 | {{> footer language=global.lang.de}} 38 | {{/if}} 39 | 40 | {{#if lightbox}} 41 | 42 | {{/if}} 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/assets/scss/style.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2020 The Bootstrap Authors 4 | * Copyright 2011-2020 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | $include-column-box-sizing: true !default; 9 | $form-grid-gutter-width: 30 !default; 10 | $form-check-input-margin-x: 0 !default; 11 | 12 | @import "functions"; 13 | @import "variables"; 14 | @import "custom-variables"; 15 | @import "mixins"; 16 | 17 | 18 | // @import "vendor/rfs"; 19 | @import "fonts"; 20 | @import "containers"; 21 | @import "grid"; 22 | @import "utilities"; 23 | 24 | // Only use the utilities we need 25 | // stylelint-disable-next-line scss/dollar-variable-default 26 | $utilities: map-get-multiple( 27 | $utilities, 28 | ( 29 | "display", 30 | "order", 31 | "flex", 32 | "flex-direction", 33 | "flex-grow", 34 | "flex-shrink" 35 | "flex-wrap", 36 | "justify-content", 37 | "align-items", 38 | "align-content", 39 | "align-self", 40 | "margin", 41 | "margin-x", 42 | "margin-y", 43 | "margin-top", 44 | "margin-right", 45 | "margin-bottom", 46 | "margin-left", 47 | // "negative-margin", 48 | // "negative-margin-x", 49 | // "negative-margin-y", 50 | // "negative-margin-top", 51 | // "negative-margin-right", 52 | // "negative-margin-bottom", 53 | // "negative-margin-left", 54 | "padding", 55 | "padding-x", 56 | "padding-y", 57 | "padding-top", 58 | "padding-right", 59 | "padding-bottom", 60 | "padding-left", 61 | "text-align", 62 | "visibility", 63 | "align", 64 | "position", 65 | "width" 66 | ) 67 | ); 68 | 69 | @import "utilities/api"; 70 | @import "reboot"; 71 | @import "forms"; 72 | @import "type"; 73 | @import "icon"; 74 | @import "buttons"; 75 | 76 | // @import "navbar"; 77 | @import "nav"; 78 | @import "header"; 79 | @import "footer"; 80 | @import "section"; 81 | @import "sticky-panel"; 82 | @import "list"; 83 | @import "box"; 84 | @import "accordion"; 85 | @import "vendor/slick"; 86 | @import "vendor/lightbox"; 87 | @import "vendor/utilities"; 88 | @import "slider"; 89 | @import "images"; 90 | @import "tables"; 91 | @import "modal"; 92 | @import "helpers/screenreaders"; -------------------------------------------------------------------------------- /.github/workflows/deploy-master.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Website 2 | # Test locally with act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04 -j prod 3 | 4 | # Controls when the action will run. Triggers the workflow on push or pull request 5 | # events but only for the master branch 6 | on: 7 | workflow_dispatch: 8 | push: 9 | branches: ["master"] 10 | # cron jobs are not necessary anymore: 11 | # they were done to update the fallback file for the dashboard, in case the TSI server dwas down 12 | # Dashboard is now using static files on website server 13 | # schedule: 14 | # - cron: '0 11 * * *' 15 | # - cron: '0 17 * * *' 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "prod" 19 | prod: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | if: "github.repository == 'corona-warn-app/cwa-website'" 23 | 24 | # Steps represent a sequence of tasks that will be executed as part of the job 25 | steps: 26 | - name: Install requirements 27 | run: | 28 | curl https://cli-assets.heroku.com/install.sh | sh 29 | sudo apt-get install -y libnode-dev libssl-dev automake npm nodejs libpng-dev libjpeg-dev s3cmd 30 | 31 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 32 | - uses: actions/checkout@v3 33 | 34 | - name: Setup Node.js 18 environment 35 | uses: actions/setup-node@v3 36 | with: 37 | node-version: 'lts/hydrogen' 38 | 39 | - name: npm install 40 | run: npm install 41 | 42 | - name: gulp build 43 | run: npm run build 44 | 45 | - name: keepalive.html 46 | run: echo "OK" > public/keepalive.html 47 | 48 | # https://github.com/s3tools/s3cmd/issues/643 49 | - name: Remove python3-magic due to s3cmd incompatibility 50 | run: sudo dpkg --remove --force-depends python3-magic 51 | 52 | - name: Deployment to Staging 53 | id: deploy-to-webapp 54 | uses: azure/webapps-deploy@v2 55 | with: 56 | app-name: 'cwa-website' 57 | slot-name: 'staging' 58 | publish-profile: ${{ secrets.DIGITAL_CUISINE_DEPLOYMENT }} 59 | package: public 60 | -------------------------------------------------------------------------------- /src/assets/scss/vendor/_slick.scss: -------------------------------------------------------------------------------- 1 | /* Slider */ 2 | 3 | .slick-slider { 4 | position: relative; 5 | display: block; 6 | box-sizing: border-box; 7 | -webkit-touch-callout: none; 8 | -webkit-user-select: none; 9 | -khtml-user-select: none; 10 | -moz-user-select: none; 11 | -ms-user-select: none; 12 | user-select: none; 13 | -ms-touch-action: pan-y; 14 | touch-action: pan-y; 15 | -webkit-tap-highlight-color: transparent; 16 | } 17 | .slick-list { 18 | position: relative; 19 | overflow: hidden; 20 | display: block; 21 | margin: 0; 22 | padding: 0; 23 | 24 | &:focus { 25 | outline: none; 26 | } 27 | 28 | &.dragging { 29 | cursor: pointer; 30 | cursor: hand; 31 | } 32 | } 33 | .slick-slider .slick-track, 34 | .slick-slider .slick-list { 35 | -webkit-transform: translate3d(0, 0, 0); 36 | -moz-transform: translate3d(0, 0, 0); 37 | -ms-transform: translate3d(0, 0, 0); 38 | -o-transform: translate3d(0, 0, 0); 39 | transform: translate3d(0, 0, 0); 40 | } 41 | 42 | .slick-track { 43 | position: relative; 44 | left: 0; 45 | top: 0; 46 | display: block; 47 | margin-left: auto; 48 | margin-right: auto; 49 | 50 | &:before, 51 | &:after { 52 | content: ""; 53 | display: table; 54 | } 55 | 56 | &:after { 57 | clear: both; 58 | } 59 | 60 | .slick-loading & { 61 | visibility: hidden; 62 | } 63 | } 64 | .slick-slide { 65 | float: left; 66 | height: 100%; 67 | min-height: 1px; 68 | [dir="rtl"] & { 69 | float: right; 70 | } 71 | img { 72 | display: block; 73 | } 74 | &.slick-loading img { 75 | display: none; 76 | } 77 | 78 | display: none; 79 | 80 | &.dragging img { 81 | pointer-events: none; 82 | } 83 | 84 | .slick-initialized & { 85 | display: block; 86 | } 87 | 88 | .slick-loading & { 89 | visibility: hidden; 90 | } 91 | 92 | .slick-vertical & { 93 | display: block; 94 | height: auto; 95 | border: 1px solid transparent; 96 | } 97 | } 98 | .slick-arrow.slick-hidden { 99 | display: none; 100 | } 101 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_layout.scss: -------------------------------------------------------------------------------- 1 | // Form grid 2 | // 3 | // Special replacement for our grid system's `.row` for tighter form layouts. 4 | 5 | @if $enable-grid-classes { 6 | .form-row { 7 | display: flex; 8 | flex-wrap: wrap; 9 | margin-right: -$form-grid-gutter-width * 0.5; 10 | margin-left: -$form-grid-gutter-width * 0.5; 11 | 12 | > .col, 13 | > [class*="col-"] { 14 | padding-right: $form-grid-gutter-width * 0.5; 15 | padding-left: $form-grid-gutter-width * 0.5; 16 | } 17 | } 18 | } 19 | 20 | // Inline forms 21 | // 22 | // Make forms appear inline(-block) by adding the `.form-inline` class. Inline 23 | // forms begin stacked on extra small (mobile) devices and then go inline when 24 | // viewports reach <768px. 25 | 26 | .form-inline { 27 | display: flex; 28 | flex-flow: row wrap; 29 | align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height) 30 | 31 | // Because we use flex, the initial sizing of checkboxes is collapsed and 32 | // doesn't occupy the full-width (which is what we want for xs grid tier), 33 | // so we force that here. 34 | .form-check { 35 | width: 100%; 36 | } 37 | 38 | // Kick in the inline 39 | @include media-breakpoint-up(sm) { 40 | label { 41 | display: flex; 42 | align-items: center; 43 | justify-content: center; 44 | margin-bottom: 0; 45 | } 46 | 47 | .form-control { 48 | display: inline-block; 49 | width: auto; // Prevent labels from stacking above inputs 50 | vertical-align: middle; 51 | } 52 | 53 | // Make static controls behave like regular ones 54 | .form-control-plaintext { 55 | display: inline-block; 56 | } 57 | 58 | .input-group, 59 | .form-select { 60 | width: auto; 61 | } 62 | 63 | // Remove default margin on radios/checkboxes that were used for stacking, and 64 | // then undo the floating of radios and checkboxes to match. 65 | .form-check { 66 | display: flex; 67 | align-items: center; 68 | justify-content: center; 69 | width: auto; 70 | padding-left: 0; 71 | } 72 | .form-check-input { 73 | position: relative; 74 | flex-shrink: 0; 75 | margin-top: 0; 76 | margin-right: $form-check-input-margin-x; 77 | margin-left: 0; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories and files 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Stores VSCode versions used for testing VSCode extensions 107 | .vscode-test 108 | 109 | # yarn v2 110 | .yarn/cache 111 | .yarn/unplugged 112 | .yarn/build-state.yml 113 | .yarn/install-state.gz 114 | .pnp.* 115 | 116 | # cypress 117 | cypress/downloads/ 118 | cypress/screenshots/ 119 | cypress/videos/ 120 | 121 | src/pages/de/science/** 122 | src/pages/en/science/** 123 | !src/pages/de/science/index.html 124 | !src/pages/en/science/index.html 125 | -------------------------------------------------------------------------------- /src/assets/img/error.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_form-file.scss: -------------------------------------------------------------------------------- 1 | .form-file { 2 | --bs-form-file-height: #{$form-file-height}; 3 | position: relative; 4 | } 5 | 6 | .form-file-input { 7 | position: relative; 8 | z-index: 2; 9 | width: 100%; 10 | height: var(--bs-form-file-height); 11 | margin: 0; 12 | opacity: 0; 13 | 14 | &:focus-within ~ .form-file-label { 15 | border-color: $form-file-focus-border-color; 16 | box-shadow: $form-file-focus-box-shadow; 17 | } 18 | 19 | // Use disabled attribute in addition of :disabled pseudo-class 20 | // See: https://github.com/twbs/bootstrap/issues/28247 21 | &[disabled] ~ .form-file-label .form-file-text, 22 | &:disabled ~ .form-file-label .form-file-text { 23 | background-color: $form-file-disabled-bg; 24 | border-color: $form-file-disabled-border-color; 25 | } 26 | } 27 | 28 | .form-file-label { 29 | position: absolute; 30 | top: 0; 31 | right: 0; 32 | left: 0; 33 | z-index: 1; 34 | display: flex; 35 | height: var(--bs-form-file-height); 36 | border-color: $form-file-border-color; 37 | @include border-radius($form-file-border-radius); 38 | @include box-shadow($form-file-box-shadow); 39 | } 40 | 41 | .form-file-text { 42 | display: block; 43 | flex-grow: 1; 44 | padding: $form-file-padding-y $form-file-padding-x; 45 | overflow: hidden; 46 | font-family: $form-file-font-family; 47 | font-weight: $form-file-font-weight; 48 | line-height: $form-file-line-height; 49 | color: $form-file-color; 50 | text-overflow: ellipsis; 51 | white-space: nowrap; 52 | background-color: $form-file-bg; 53 | border-color: inherit; 54 | border-style: solid; 55 | border-width: $form-file-border-width; 56 | @include border-left-radius(inherit); 57 | } 58 | 59 | .form-file-button { 60 | display: block; 61 | flex-shrink: 0; 62 | padding: $form-file-padding-y $form-file-padding-x; 63 | margin-left: -$form-file-border-width; 64 | line-height: $form-file-line-height; 65 | color: $form-file-button-color; 66 | @include gradient-bg($form-file-button-bg); 67 | border-color: inherit; 68 | border-style: solid; 69 | border-width: $form-file-border-width; 70 | @include border-right-radius(inherit); 71 | } 72 | 73 | .form-file-sm { 74 | --bs-form-file-height: #{$form-file-height-sm}; 75 | @include font-size($form-file-font-size-sm); 76 | 77 | .form-file-text, 78 | .form-file-button { 79 | padding: $form-file-padding-y-sm $form-file-padding-x-sm; 80 | } 81 | } 82 | 83 | .form-file-lg { 84 | --bs-form-file-height: #{$form-file-height-lg}; 85 | @include font-size($form-file-font-size-lg); 86 | 87 | .form-file-text, 88 | .form-file-button { 89 | padding: $form-file-padding-y-lg $form-file-padding-x-lg; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/assets/scss/forms/_form-select.scss: -------------------------------------------------------------------------------- 1 | // Select 2 | // 3 | // Replaces the browser default select with a custom one, mostly pulled from 4 | // https://primer.github.io/. 5 | 6 | .form-select { 7 | display: block; 8 | width: 100%; 9 | height: $form-select-height; 10 | padding: $form-select-padding-y ($form-select-padding-x + $form-select-indicator-padding) $form-select-padding-y $form-select-padding-x; 11 | font-family: $form-select-font-family; 12 | @include font-size($form-select-font-size); 13 | font-weight: $form-select-font-weight; 14 | line-height: $form-select-line-height; 15 | color: $form-select-color; 16 | vertical-align: middle; 17 | background-color: $form-select-bg; 18 | background-image: escape-svg($form-select-indicator); 19 | background-repeat: no-repeat; 20 | background-position: $form-select-bg-position; 21 | background-size: $form-select-bg-size; 22 | border: $form-select-border-width solid $form-select-border-color; 23 | @include border-radius($form-select-border-radius, 0); 24 | @include box-shadow($form-select-box-shadow); 25 | appearance: none; 26 | 27 | &:focus { 28 | border-color: $form-select-focus-border-color; 29 | outline: 0; 30 | @if $enable-shadows { 31 | @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); 32 | } @else { 33 | // Avoid using mixin so we can pass custom focus shadow properly 34 | box-shadow: $form-select-focus-box-shadow; 35 | } 36 | 37 | &::-ms-value { 38 | // For visual consistency with other platforms/browsers, 39 | // suppress the default white text on blue background highlight given to 40 | // the selected option text when the (still closed) s in some browsers, due to the limited stylability of `