├── .github ├── actions │ └── run-via-ssh │ │ └── action.yml └── workflows │ ├── deploy.yml │ ├── licences.yml │ └── renew.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── LICENSE-CONTENT ├── README.md ├── app ├── api │ └── v1 │ │ └── index.ts ├── components │ ├── Link.tsx │ ├── Localised.tsx │ ├── Script.tsx │ ├── assets │ │ └── BrowserWireframe.tsx │ ├── common │ │ ├── A11y │ │ │ └── index.tsx │ │ ├── Footer │ │ │ ├── index.tsx │ │ │ ├── language.tsx │ │ │ ├── section.tsx │ │ │ ├── sitemap.tsx │ │ │ └── socials.tsx │ │ ├── Header │ │ │ ├── Drawer.tsx │ │ │ ├── Item.tsx │ │ │ ├── Items.tsx │ │ │ └── index.tsx │ │ ├── L10nBanner │ │ │ └── index.tsx │ │ └── Meta │ │ │ ├── OGMeta.tsx │ │ │ └── index.tsx │ ├── icons │ │ ├── ArrowRight.tsx │ │ ├── ChevronDown.tsx │ │ ├── ChevronRight.tsx │ │ ├── Close.tsx │ │ ├── Giving.tsx │ │ ├── Institution.tsx │ │ ├── JavaScript.tsx │ │ ├── Menu.tsx │ │ ├── News.tsx │ │ ├── Note.tsx │ │ ├── OpenInNew.tsx │ │ ├── PaymentCard.tsx │ │ ├── Search.tsx │ │ ├── animated │ │ │ └── ArrowRightAnimated.tsx │ │ ├── brands │ │ │ ├── Cargo.tsx │ │ │ ├── Discord.tsx │ │ │ ├── Mastodon.tsx │ │ │ ├── Matrix.tsx │ │ │ ├── NPM.tsx │ │ │ └── Twitter.tsx │ │ ├── cards │ │ │ ├── Amex.tsx │ │ │ ├── Discover.tsx │ │ │ ├── Mastercard.tsx │ │ │ └── Visa.tsx │ │ └── index.tsx │ ├── index.tsx │ ├── marketing │ │ ├── browser │ │ │ └── browser-landing-intro-block.tsx │ │ ├── index.tsx │ │ └── sponsors-block.tsx │ ├── pages │ │ ├── donate │ │ │ └── index.tsx │ │ └── third-party-licenses │ │ │ ├── Dependency.tsx │ │ │ ├── DependencyItem.tsx │ │ │ ├── Reference.tsx │ │ │ ├── Repository.tsx │ │ │ └── index.tsx │ └── ui │ │ ├── Aside │ │ └── index.tsx │ │ ├── Banner │ │ └── index.tsx │ │ ├── Button │ │ └── index.tsx │ │ ├── Card │ │ └── index.tsx │ │ ├── Checkbox │ │ └── index.tsx │ │ ├── ClientData.tsx │ │ ├── ConstrainedChildren.tsx │ │ ├── Field.tsx │ │ ├── HTMLComment.tsx │ │ ├── Hero │ │ └── index.tsx │ │ ├── ItemList │ │ └── index.tsx │ │ ├── Logo │ │ └── index.tsx │ │ ├── Menu │ │ ├── Item.tsx │ │ └── index.tsx │ │ ├── ProductLockup │ │ └── index.tsx │ │ ├── Radio │ │ └── index.tsx │ │ ├── Select │ │ └── index.tsx │ │ ├── Separator.tsx │ │ ├── Stack.tsx │ │ ├── Tabs │ │ └── index.tsx │ │ └── TextField │ │ └── index.tsx ├── flags.ts ├── l10n.ts ├── main.ts ├── og.ts ├── pages │ ├── 404.tsx │ ├── @layout.tsx │ ├── about │ │ └── third-party-licenses.tsx │ ├── contribute │ │ └── donate.tsx │ ├── index.tsx │ └── select-language.ts ├── redirects.ts ├── router.ts ├── server.ts ├── ssr.ts ├── types.d.ts └── utils │ ├── cache.ts │ ├── data.ts │ ├── error.ts │ ├── flags.ts │ ├── html.ts │ ├── icons.tsx │ ├── path.ts │ ├── router.ts │ └── ua.ts ├── data ├── donations.yml ├── footer.yml ├── header.yml └── sponsors.yml ├── docker-compose.yml ├── docker ├── config │ ├── compression.conf │ ├── nginx.conf │ ├── sites │ │ └── www.conf │ └── ssl.conf ├── create-stub-certificates.sh ├── generate-certificates.sh ├── nginx-entrypoint.sh ├── nginx.dockerfile └── www.dockerfile ├── generated └── generated.tsx ├── jest.config.js ├── l10n ├── en-GB │ ├── a11y.ftl │ ├── brand.ftl │ ├── domain-migration.ftl │ ├── errors │ │ └── 404.ftl │ ├── footer.ftl │ ├── header.ftl │ ├── marketing │ │ ├── browser │ │ │ └── LandingIntroBlock.ftl │ │ └── sponsors-block.ftl │ ├── meta.ftl │ └── pages │ │ ├── about │ │ └── third-party-licenses.ftl │ │ ├── donate.ftl │ │ └── index.ftl ├── en-US │ ├── README.md │ └── overrides.ftl └── es-ES │ ├── a11y.ftl │ ├── brand.ftl │ ├── domain-migration.ftl │ ├── errors │ └── 404.ftl │ ├── footer.ftl │ ├── header.ftl │ ├── marketing │ ├── browser │ │ └── LandingIntroBlock.ftl │ └── sponsors-block.ftl │ ├── meta.ftl │ └── pages │ ├── about │ └── third-party-licenses.ftl │ ├── donate.ftl │ └── index.ftl ├── package.json ├── public ├── .well-known │ ├── keys │ │ ├── dothq_code_signing.asc │ │ └── dothq_general.asc │ └── security.txt ├── errors │ └── 500.html ├── favicon.ico ├── favicon.png ├── favicon.svg ├── media │ ├── fonts │ │ ├── inter │ │ │ ├── Inter-Black.woff │ │ │ ├── Inter-Black.woff2 │ │ │ ├── Inter-BlackItalic.woff │ │ │ ├── Inter-BlackItalic.woff2 │ │ │ ├── Inter-Bold.woff │ │ │ ├── Inter-Bold.woff2 │ │ │ ├── Inter-BoldItalic.woff │ │ │ ├── Inter-BoldItalic.woff2 │ │ │ ├── Inter-ExtraBold.woff │ │ │ ├── Inter-ExtraBold.woff2 │ │ │ ├── Inter-ExtraBoldItalic.woff │ │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ │ ├── Inter-ExtraLight.woff │ │ │ ├── Inter-ExtraLight.woff2 │ │ │ ├── Inter-ExtraLightItalic.woff │ │ │ ├── Inter-ExtraLightItalic.woff2 │ │ │ ├── Inter-Italic.var.woff2 │ │ │ ├── Inter-Italic.woff │ │ │ ├── Inter-Italic.woff2 │ │ │ ├── Inter-Light.woff │ │ │ ├── Inter-Light.woff2 │ │ │ ├── Inter-LightItalic.woff │ │ │ ├── Inter-LightItalic.woff2 │ │ │ ├── Inter-Medium.woff │ │ │ ├── Inter-Medium.woff2 │ │ │ ├── Inter-MediumItalic.woff │ │ │ ├── Inter-MediumItalic.woff2 │ │ │ ├── Inter-Regular.woff │ │ │ ├── Inter-Regular.woff2 │ │ │ ├── Inter-SemiBold.woff │ │ │ ├── Inter-SemiBold.woff2 │ │ │ ├── Inter-SemiBoldItalic.woff │ │ │ ├── Inter-SemiBoldItalic.woff2 │ │ │ ├── Inter-Thin.woff │ │ │ ├── Inter-Thin.woff2 │ │ │ ├── Inter-ThinItalic.woff │ │ │ ├── Inter-ThinItalic.woff2 │ │ │ ├── Inter-roman.var.woff2 │ │ │ └── Inter.var.woff2 │ │ └── satoshi │ │ │ ├── Satoshi-Black.woff │ │ │ ├── Satoshi-Black.woff2 │ │ │ ├── Satoshi-BlackItalic.woff │ │ │ ├── Satoshi-BlackItalic.woff2 │ │ │ ├── Satoshi-Bold.woff │ │ │ ├── Satoshi-Bold.woff2 │ │ │ ├── Satoshi-BoldItalic.woff │ │ │ ├── Satoshi-BoldItalic.woff2 │ │ │ ├── Satoshi-Italic.var.woff │ │ │ ├── Satoshi-Italic.var.woff2 │ │ │ ├── Satoshi-Italic.woff │ │ │ ├── Satoshi-Italic.woff2 │ │ │ ├── Satoshi-Light.woff │ │ │ ├── Satoshi-Light.woff2 │ │ │ ├── Satoshi-LightItalic.woff │ │ │ ├── Satoshi-LightItalic.woff2 │ │ │ ├── Satoshi-Medium.woff │ │ │ ├── Satoshi-Medium.woff2 │ │ │ ├── Satoshi-MediumItalic.woff │ │ │ ├── Satoshi-MediumItalic.woff2 │ │ │ ├── Satoshi-Regular.woff │ │ │ ├── Satoshi-Regular.woff2 │ │ │ ├── Satoshi.var.woff │ │ │ └── Satoshi.var.woff2 │ ├── icons │ │ ├── 114x114.png │ │ ├── 120x120.png │ │ ├── 128x128.png │ │ ├── 144x144.png │ │ ├── 150x150.png │ │ ├── 152x152.png │ │ ├── 160x160.png │ │ ├── 16x16.png │ │ ├── 192x192.png │ │ ├── 196x196.png │ │ ├── 256x256.png │ │ ├── 310x150.png │ │ ├── 310x310.png │ │ ├── 32x32.png │ │ ├── 36x36.png │ │ ├── 384x384.png │ │ ├── 48x48.png │ │ ├── 512x512.png │ │ ├── 57x57.png │ │ ├── 70x70.png │ │ ├── 72x72.png │ │ ├── 76x76.png │ │ ├── 96x96.png │ │ └── ui │ │ │ └── lock.svg │ ├── images │ │ ├── dothq_colour_space.jpg │ │ ├── logo.jpg │ │ ├── logo@small.jpg │ │ ├── og │ │ │ ├── donate.jpg │ │ │ ├── logo.jpg │ │ │ └── logo_with_browser_wireframe.jpg │ │ └── sponsors │ │ │ └── tuta_logo.svg │ └── js │ │ ├── donations │ │ └── index.js │ │ ├── flags.js │ │ └── scalar.js └── robots.txt ├── scripts ├── build.js ├── inject-vars.js ├── l10n.js ├── licences.js ├── rebuild_docker.sh └── renew_certificates_docker.sh ├── tests ├── renders-landing-page.test.ts └── utils.ts ├── tsconfig.json ├── ui ├── blocks │ ├── browser-landing-intro-block.scss │ └── sponsors-block.scss ├── foundation │ ├── components │ │ ├── aside │ │ │ └── index.scss │ │ ├── banner │ │ │ ├── helpers.scss │ │ │ └── index.scss │ │ ├── browser-wireframe.scss │ │ ├── button │ │ │ ├── helpers.scss │ │ │ └── index.scss │ │ ├── card │ │ │ └── index.scss │ │ ├── code │ │ │ └── index.scss │ │ ├── domain-migration.scss │ │ ├── error.scss │ │ ├── flex │ │ │ ├── helpers.scss │ │ │ └── index.scss │ │ ├── footer │ │ │ ├── index.scss │ │ │ ├── items.scss │ │ │ ├── logo.scss │ │ │ └── subfooter.scss │ │ ├── form │ │ │ ├── helpers.scss │ │ │ ├── index.scss │ │ │ └── input │ │ │ │ └── index.scss │ │ ├── header │ │ │ ├── a11y.scss │ │ │ ├── drawer.scss │ │ │ ├── index.scss │ │ │ ├── items.scss │ │ │ ├── logo.scss │ │ │ └── menu.scss │ │ ├── hero │ │ │ ├── helpers.scss │ │ │ └── index.scss │ │ ├── icons.scss │ │ ├── itemlist │ │ │ └── index.scss │ │ ├── logo.scss │ │ ├── main.scss │ │ ├── menu │ │ │ ├── helpers.scss │ │ │ ├── index.scss │ │ │ └── item.scss │ │ ├── tabs │ │ │ └── index.scss │ │ └── typography.scss │ ├── scalar.scss │ └── utils │ │ ├── a11y.scss │ │ ├── fonts.scss │ │ └── reset.scss └── pages │ ├── donate.scss │ └── third-party-licenses.scss └── yarn.lock /.github/actions/run-via-ssh/action.yml: -------------------------------------------------------------------------------- 1 | name: "Run via SSH" 2 | description: "Connects securely to a server over Tailscale and runs a shell script." 3 | inputs: 4 | ts_hostname: 5 | description: "Tailscale server hostname to use" 6 | required: true 7 | ts_oauth_client_id: 8 | description: "Tailscale OAuth2 client ID to use" 9 | required: true 10 | ts_oauth_secret: 11 | description: "Tailscale OAuth2 secret to use" 12 | required: true 13 | ts_tags: 14 | description: "Tailscale tags to use." 15 | default: "" 16 | required: false 17 | ssh_username: 18 | description: "SSH username to use." 19 | required: true 20 | ssh_private_key: 21 | description: "SSH private key to use." 22 | required: true 23 | run: 24 | description: "Shell script to execute" 25 | required: true 26 | 27 | runs: 28 | using: "composite" 29 | steps: 30 | - name: Connect to Tailscale network 31 | uses: tailscale/github-action@v2 32 | with: 33 | oauth-client-id: ${{ inputs.ts_oauth_client_id }} 34 | oauth-secret: ${{ inputs.ts_oauth_secret }} 35 | tags: ${{ inputs.ts_tags }} 36 | 37 | - name: Install SSH key 38 | shell: bash --noprofile --norc -eo pipefail {0} 39 | run: | 40 | mkdir -p ~/.ssh 41 | install -m 600 -D /dev/null ~/.ssh/id_rsa 42 | install -m 600 -D /dev/null ~/.ssh/known_hosts 43 | 44 | echo "${{ inputs.ssh_private_key }}" > ~/.ssh/id_rsa 45 | 46 | SERVER_IP="$(tailscale ip -6 ${{ inputs.ts_hostname }})" 47 | ping -c 3 $SERVER_IP 48 | 49 | ssh-keyscan $SERVER_IP > ~/.ssh/known_hosts 50 | 51 | - name: Run script 52 | shell: bash --noprofile --norc -eo pipefail {0} 53 | run: | 54 | SERVER_IP="$(tailscale ip -6 ${{ inputs.ts_hostname }})" 55 | 56 | echo "Connecting to server over SSH on ${{ inputs.ssh_username }}@$SERVER_IP..." 57 | ssh -t ${{ inputs.ssh_username }}@$SERVER_IP "${{ inputs.run }}" 58 | 59 | - name: Nuke SSH keys 60 | shell: bash --noprofile --norc -eo pipefail {0} 61 | run: rm -rf ~/.ssh 62 | -------------------------------------------------------------------------------- /.github/workflows/licences.yml: -------------------------------------------------------------------------------- 1 | name: Generate licences 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "0 0 * * *" # Runs everyday at 00:00 7 | 8 | jobs: 9 | generate: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Use Node.js 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: 18.x 19 | 20 | - name: Install dependencies 21 | run: | 22 | yarn 23 | 24 | - name: Generate licences 25 | env: 26 | TOKEN: ${{ secrets.ROBOT_TOKEN }} 27 | run: | 28 | node scripts/licences.js 29 | git add generated/ 30 | 31 | - name: Commit and push changes 32 | uses: actions-js/push@master 33 | with: 34 | github_token: ${{ secrets.ROBOT_TOKEN }} 35 | branch: staging 36 | author_email: dothq-robot@users.noreply.github.com 37 | author_name: dothq-robot 38 | message: "📄 Generate licence page data" 39 | -------------------------------------------------------------------------------- /.github/workflows/renew.yml: -------------------------------------------------------------------------------- 1 | name: Renew production certificates 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "0 5 * * *" # every day at 5am 7 | 8 | jobs: 9 | renew: 10 | runs-on: ubuntu-latest 11 | environment: 12 | name: Production 13 | permissions: 14 | contents: read 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Renew production certificates 21 | uses: ./.github/actions/run-via-ssh 22 | with: 23 | ts_hostname: ${{ vars.SERVER_HOSTNAME }} 24 | ts_oauth_client_id: ${{ secrets.TS_OAUTH_CLIENT_ID }} 25 | ts_oauth_secret: ${{ secrets.TS_OAUTH_SECRET }} 26 | ts_tags: tag:ci 27 | ssh_username: ci 28 | ssh_private_key: ${{ secrets.SERVER_CI_PRIVATE_KEY }} 29 | run: | 30 | cd /app 31 | ./scripts/renew_certificates_docker.sh 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # production 9 | /build 10 | 11 | # misc 12 | .DS_Store 13 | *.pem 14 | 15 | # debug 16 | npm-debug.log* 17 | yarn-debug.log* 18 | yarn-error.log* 19 | .pnpm-debug.log* 20 | 21 | # local env files 22 | .env*.local 23 | 24 | # typescript 25 | *.tsbuildinfo 26 | 27 | # swc 28 | .swc 29 | 30 | # Added by cargo 31 | target 32 | 33 | .scalar 34 | 35 | .env 36 | 37 | hs_ed25519_secret_key 38 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .env 4 | .env.* 5 | !.env.example 6 | /.next 7 | 8 | # Ignore files for PNPM, NPM and YARN 9 | pnpm-lock.yaml 10 | package-lock.json 11 | yarn.lock 12 | 13 | # Ignore _head.html template 14 | templates/_head.html 15 | 16 | # Ignore error pages 17 | public/errors/500.html -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": false, 4 | "trailingComma": "none", 5 | "printWidth": 70, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "macabeus.vscode-fluent", 5 | "bungcip.better-toml", 6 | "rust-lang.rust-analyzer" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.organizeImports": true, 4 | "source.fixAll": true 5 | }, 6 | "explorer.excludeGitIgnore": false, 7 | "files.exclude": { 8 | "**/.git": true, 9 | "**/.svn": true, 10 | "**/.hg": true, 11 | "**/CVS": true, 12 | "**/.DS_Store": true, 13 | "**/Thumbs.db": true 14 | }, 15 | "editor.formatOnSave": true, 16 | "editor.formatOnType": true, 17 | "editor.defaultFormatter": "esbenp.prettier-vscode", 18 | "files.associations": { 19 | "*.mdx": "markdown", 20 | "*.svg": "html" 21 | }, 22 | "macros.list": { 23 | "license": [ 24 | { 25 | "command": "type", 26 | "args": { 27 | "text": "/* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n* file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n\n" 28 | } 29 | }, 30 | "insertSnippet" 31 | ] 32 | }, 33 | "[rust]": { 34 | "editor.defaultFormatter": "rust-lang.rust-analyzer" 35 | }, 36 | "[html]": { 37 | "editor.defaultFormatter": "esbenp.prettier-vscode" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scalar 2 | 3 | [![Build](https://github.com/dothq/scalar/actions/workflows/deploy.yml/badge.svg)](https://github.com/dothq/scalar/actions/workflows/deploy.yml) 4 | 5 | The Dot HQ Website 6 | 7 | - [Production](https://www.dothq.org) (dothq.org) ![Production](https://img.shields.io/github/deployments/dothq/scalar/Production) 8 | - [Staging](http://dothq.local) (dothq.local) ![Staging](https://img.shields.io/github/deployments/dothq/scalar/Staging) 9 | 10 | ## Licenses 11 | 12 | The Dot HQ Website (Scalar) codebase is licensed under [Mozilla Public License 2.0](LICENSE). 13 | Content published to the Dot HQ Website is licensed under [CC BY-SA 4.0](LICENSE-CONTENT). 14 | -------------------------------------------------------------------------------- /app/api/v1/index.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { FastifyPluginCallback } from "fastify"; 6 | 7 | export const v1: FastifyPluginCallback = (server, opts, done) => { 8 | done(); 9 | }; 10 | -------------------------------------------------------------------------------- /app/components/Link.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { JSXInternal } from "preact/src/jsx"; 6 | import { getLocale } from "../l10n"; 7 | 8 | export const localisedHref = (href: string) => { 9 | if (href && !href.startsWith("http")) { 10 | const currentURI = (global as any).SCALAR_URL; 11 | 12 | let localelessURI = currentURI 13 | .substring(1) 14 | .split("/") 15 | .slice(1) 16 | .join("/"); 17 | 18 | // add preceding slash if we aren't blank 19 | if (localelessURI.trim().length) { 20 | localelessURI = "/" + localelessURI; 21 | } 22 | 23 | // remove preceding slash from href if we're loading / 24 | if (href.charAt(0) == "/" && href.trim().length == 1) { 25 | href = href.substring(1); 26 | } 27 | 28 | let newURI = ""; 29 | 30 | // handle hashes 31 | if (href.charAt(0) == "#") { 32 | newURI = `/${getLocale()}${localelessURI}${href}`; 33 | } else if (href.charAt(0) == "/" || href == "") { 34 | // handle root 35 | newURI = `/${getLocale()}${href}`; 36 | } else { 37 | // handle appended page 38 | newURI = `/${getLocale()}${localelessURI}/${href}`; 39 | } 40 | 41 | return newURI; 42 | } else { 43 | return href; 44 | } 45 | }; 46 | 47 | const Link = ( 48 | props: JSXInternal.HTMLAttributes & { 49 | href?: any; 50 | } 51 | ) => { 52 | props.href = localisedHref(props.href); 53 | 54 | return {props.children}; 55 | }; 56 | 57 | export default Link; 58 | -------------------------------------------------------------------------------- /app/components/Localised.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { parse } from "node-html-parser"; 6 | import { ComponentType, createElement, Fragment } from "preact"; 7 | import { JSXInternal } from "preact/src/jsx"; 8 | import { l } from "../l10n"; 9 | 10 | export const createLocalisedComponent = ( 11 | translateFunction?: typeof l 12 | ) => { 13 | return ({ 14 | id, 15 | ...rest 16 | }: { id: string } & Record< 17 | string, 18 | | ComponentType 19 | | string 20 | | number 21 | | boolean 22 | | JSXInternal.Element 23 | >) => { 24 | const ctx: any = {}; 25 | const elements = new Map(); 26 | 27 | for (const [key, value] of Object.entries(rest)) { 28 | const v = value as any; 29 | 30 | if ( 31 | typeof v == "object" && 32 | "type" in v && 33 | "props" in v && 34 | typeof v.props == "object" && 35 | "key" in v && 36 | "ref" in v 37 | ) { 38 | elements.set(key, value); 39 | } else { 40 | ctx[key] = v; 41 | } 42 | } 43 | 44 | const fn = translateFunction ? translateFunction : l; 45 | const str = fn(id, ctx); 46 | 47 | const parsed = parse(str.replace(/(?:\r\n|\r|\n)/g, "
"), { 48 | lowerCaseTagName: true, 49 | comment: false 50 | }); 51 | 52 | const localised = []; 53 | 54 | for (const node of parsed.childNodes) { 55 | if (node.nodeType == 1) { 56 | /* element */ 57 | const tagName = (node as any).rawTagName; 58 | 59 | if (elements.get(tagName)) { 60 | const elementData = elements.get(tagName); 61 | 62 | const jsxElement = createElement( 63 | elementData.type, 64 | elementData.props, 65 | node.textContent.trim() 66 | ); 67 | 68 | localised.push(jsxElement); 69 | } else if (tagName == "br") { 70 | const jsxElement = createElement("br", {}); 71 | 72 | localised.push(jsxElement); 73 | } 74 | } else if (node.nodeType == 3) { 75 | /* text */ 76 | localised.push(node.textContent); 77 | } 78 | } 79 | 80 | return createElement(Fragment, {}, localised); 81 | }; 82 | }; 83 | 84 | const Localised = createLocalisedComponent(); 85 | export default Localised; 86 | -------------------------------------------------------------------------------- /app/components/Script.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { withCacheBuster } from "../utils/cache"; 6 | 7 | const Script = ({ src, defer }: { src: string; defer?: boolean }) => { 8 | return ( 9 | 15 | ); 16 | }; 17 | 18 | export default Script; 19 | -------------------------------------------------------------------------------- /app/components/common/A11y/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { l } from "../../../l10n"; 6 | import Link from "../../Link"; 7 | 8 | const A11y = () => { 9 | return ( 10 | 28 | ); 29 | }; 30 | 31 | export default A11y; 32 | -------------------------------------------------------------------------------- /app/components/common/Footer/language.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { l } from "../../../l10n"; 6 | import { localisedHref } from "../../Link"; 7 | import Button from "../../ui/Button"; 8 | import Select from "../../ui/Select"; 9 | import FooterSection from "./section"; 10 | 11 | const FooterLanguage = () => { 12 | let go = 13 | "/" + 14 | ((global as any).SCALAR_URL.split("/").splice(2).join("/") || 15 | ""); 16 | 17 | return ( 18 | 19 |
25 | 39 | 40 | 43 |
44 |
45 | ); 46 | }; 47 | 48 | export default FooterLanguage; 49 | -------------------------------------------------------------------------------- /app/components/common/Footer/section.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { JSXInternal } from "preact/src/jsx"; 6 | import Link from "../../Link"; 7 | 8 | const FooterSection = ({ 9 | title, 10 | items, 11 | children 12 | }: { 13 | title: string; 14 | items?: JSXInternal.HTMLAttributes[]; 15 | children?: any; 16 | }) => { 17 | return ( 18 |
19 |

{title}

20 | {children ? ( 21 | children 22 | ) : items ? ( 23 |
    24 | {items.map((i) => ( 25 |
  • 26 | {i.children} 27 |
  • 28 | ))} 29 |
30 | ) : ( 31 | <> 32 | )} 33 |
34 | ); 35 | }; 36 | 37 | export default FooterSection; 38 | -------------------------------------------------------------------------------- /app/components/common/Footer/sitemap.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { JSXInternal } from "preact/src/jsx"; 6 | import { getComponentConfig } from "../../../utils/data"; 7 | import FooterSection from "./section"; 8 | 9 | const FooterSitemap = () => { 10 | const config = getComponentConfig<{ 11 | name: string; 12 | items: { 13 | id: string; 14 | title: string; 15 | items: JSXInternal.HTMLAttributes[]; 16 | }[]; 17 | }>("footer"); 18 | 19 | return ( 20 |
21 | {config.items.map((i) => ( 22 | 23 | ))} 24 |
25 | ); 26 | }; 27 | 28 | export default FooterSitemap; 29 | -------------------------------------------------------------------------------- /app/components/common/Footer/socials.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { l } from "../../../l10n"; 6 | import { getComponentConfig } from "../../../utils/data"; 7 | import { Discord } from "../../icons/brands/Discord"; 8 | import { Mastodon } from "../../icons/brands/Mastodon"; 9 | import { Matrix } from "../../icons/brands/Matrix"; 10 | import { Twitter } from "../../icons/brands/Twitter"; 11 | import FooterSection from "./section"; 12 | 13 | const socialIcons = { 14 | twitter: , 15 | mastodon: , 16 | matrix: , 17 | discord: 18 | }; 19 | 20 | const FooterSocials = () => { 21 | const config = getComponentConfig<{ 22 | name: string; 23 | socials: { 24 | id: string; 25 | title: string; 26 | href: string; 27 | }[]; 28 | }>("footer"); 29 | 30 | return ( 31 |
32 | { 35 | const icon = (socialIcons as any)[s.id]; 36 | 37 | delete s.id; 38 | 39 | return { 40 | ...s, 41 | children: icon 42 | }; 43 | })} 44 | /> 45 |
46 | ); 47 | }; 48 | 49 | export default FooterSocials; 50 | -------------------------------------------------------------------------------- /app/components/common/Header/Drawer.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { HeaderConfig, renderHeaderElement } from "."; 6 | import { Close } from "../../icons/Close"; 7 | import Button from "../../ui/Button"; 8 | import NavItems from "./Items"; 9 | 10 | const HeaderDrawer = ({ config }: { config: HeaderConfig }) => { 11 | return ( 12 |
17 |
18 |
    19 | 20 | 21 | <> 22 | {config.end.map((i: any) => { 23 | i.fullwidth = true; 24 | 25 | return
  • {renderHeaderElement(i)}
  • ; 26 | })} 27 | 28 |
29 | 30 | 40 |
41 |
42 | ); 43 | }; 44 | 45 | export default HeaderDrawer; 46 | -------------------------------------------------------------------------------- /app/components/common/Header/Item.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { HeaderConfigElementChildItem } from "."; 6 | import Link from "../../Link"; 7 | import Menu from "../../ui/Menu"; 8 | import MenuItem from "../../ui/Menu/Item"; 9 | 10 | const HeaderItemLink = ({ 11 | href, 12 | children 13 | }: { 14 | href: string; 15 | children: string; 16 | }) => ( 17 | 18 | {children} 19 | 20 | ); 21 | 22 | const HeaderItem = ({ 23 | children, 24 | href, 25 | menuItems 26 | }: { 27 | children: string; 28 | href: string; 29 | menuItems?: HeaderConfigElementChildItem[]; 30 | }) => { 31 | return ( 32 |
  • 33 | {children} 34 | 35 | {menuItems && !!menuItems.length && ( 36 | 41 | {menuItems.map((i) => { 42 | const Icon = i.icon; 43 | 44 | if (i.element == "menu_item") { 45 | return ( 46 | 47 |
    52 | {i.title && ( 53 |
    54 | {i.title} 55 |
    56 | )} 57 | {i.subtitle && ( 58 | 61 | {i.subtitle} 62 | 63 | )} 64 |
    65 |
    66 | ); 67 | } else if (i.element == "link") { 68 | return ( 69 | 73 | {i.children} 74 | 75 | ); 76 | } 77 | })} 78 |
    79 | )} 80 |
  • 81 | ); 82 | }; 83 | 84 | export default HeaderItem; 85 | -------------------------------------------------------------------------------- /app/components/common/Header/Items.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { HeaderConfig, renderHeaderElement } from "."; 6 | 7 | const HeaderItems = ({ config }: { config: HeaderConfig }) => { 8 | return ( 9 | <>{config.items.map((i: any) => renderHeaderElement(i))} 10 | ); 11 | }; 12 | 13 | export default HeaderItems; 14 | -------------------------------------------------------------------------------- /app/components/common/L10nBanner/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { getPercentTranslated, getTranslation } from "../../../l10n"; 6 | import Localised from "../../Localised"; 7 | import Banner from "../../ui/Banner"; 8 | import Button from "../../ui/Button"; 9 | import Stack from "../../ui/Stack"; 10 | 11 | const L10nBanner = () => { 12 | return ( 13 | <> 14 | {getPercentTranslated() < 100 && ( 15 | 16 | 26 | 39 | } 40 | /> 41 | 42 | 43 | )} 44 | 45 | ); 46 | }; 47 | 48 | export default L10nBanner; 49 | -------------------------------------------------------------------------------- /app/components/common/Meta/OGMeta.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import imageSize from "image-size"; 6 | import { resolve } from "path"; 7 | import { PageMetadata } from "../../../types"; 8 | import { withCacheBuster } from "../../../utils/cache"; 9 | import { unixifyPath } from "../../../utils/path"; 10 | 11 | export const OGMeta = ({ 12 | data, 13 | host 14 | }: { 15 | data: Exclude; 16 | host: string; 17 | }) => { 18 | const { width, height, type } = imageSize( 19 | unixifyPath( 20 | resolve( 21 | process.cwd(), 22 | ".scalar", 23 | "public", 24 | "media", 25 | "images", 26 | "og", 27 | data.url 28 | ) 29 | ) 30 | ); 31 | 32 | return ( 33 | <> 34 | 41 | 45 | 46 | 47 | 51 | 55 | 56 | ); 57 | }; 58 | -------------------------------------------------------------------------------- /app/components/icons/ArrowRight.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const ArrowRight = (props: IconProps) => { 8 | return ( 9 | 10 | 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /app/components/icons/ChevronDown.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const ChevronDown = (props: IconProps) => { 8 | return ( 9 | 10 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /app/components/icons/ChevronRight.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const ChevronRight = (props: IconProps) => { 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /app/components/icons/Close.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Close = (props: IconProps) => { 8 | return ( 9 | 10 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /app/components/icons/Giving.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Giving = (props: IconProps) => { 8 | return ( 9 | 10 | 16 | 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /app/components/icons/Institution.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Institution = (props: IconProps) => { 8 | return ( 9 | 13 | 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /app/components/icons/JavaScript.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const JavaScript = (props: IconProps) => { 8 | return ( 9 | 10 | 14 | 18 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /app/components/icons/Menu.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Menu = (props: IconProps) => { 8 | return ( 9 | 10 | 17 | 24 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /app/components/icons/News.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const News = (props: IconProps) => { 8 | return ( 9 | 10 | 14 | 18 | 22 | 26 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /app/components/icons/Note.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Note = (props: IconProps) => { 8 | return ( 9 | 10 | 16 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /app/components/icons/OpenInNew.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const OpenInNew = (props: IconProps) => { 8 | return ( 9 | 10 | 11 | 15 | 19 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /app/components/icons/PaymentCard.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const PaymentCard = (props: IconProps) => { 8 | return ( 9 | 10 | 14 | 18 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /app/components/icons/Search.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from "."; 6 | 7 | export const Search = (props: IconProps) => { 8 | return ( 9 | 10 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /app/components/icons/animated/ArrowRightAnimated.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const ArrowRightAnimated = (props: IconProps) => { 8 | return ( 9 | 14 | 21 | 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /app/components/icons/brands/Mastodon.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Mastodon = (props: IconProps) => { 8 | return ( 9 | 10 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /app/components/icons/brands/Matrix.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Matrix = (props: IconProps) => { 8 | return ( 9 | 10 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /app/components/icons/brands/NPM.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const NPM = (props: IconProps) => { 8 | return ( 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /app/components/icons/brands/Twitter.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Twitter = (props: IconProps) => { 8 | return ( 9 | 10 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /app/components/icons/cards/Amex.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Amex = (props: IconProps) => { 8 | return ( 9 | 14 | 18 | 24 | 30 | 36 | 42 | 48 | 54 | 55 | ); 56 | }; 57 | -------------------------------------------------------------------------------- /app/components/icons/cards/Mastercard.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Mastercard = (props: IconProps) => { 8 | return ( 9 | 10 | 14 | 18 | 22 | 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /app/components/icons/cards/Visa.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Icon, IconProps } from ".."; 6 | 7 | export const Visa = (props: IconProps) => { 8 | return ( 9 | 10 | 17 | 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /app/components/icons/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { Menu } from "./Menu"; 7 | 8 | export interface IconProps { 9 | size?: number; 10 | colour?: FDNColour | "current-color"; 11 | ariaLabel?: string; 12 | className?: string; 13 | } 14 | 15 | export const Icon = ({ 16 | children, 17 | size, 18 | colour, 19 | ariaLabel, 20 | viewBox, 21 | ...rest 22 | }: { 23 | children: any; 24 | viewBox?: any; 25 | className?: string; 26 | } & IconProps) => { 27 | const className = clsx( 28 | "fdn-icon", 29 | { 30 | [colour || "black"]: true 31 | }, 32 | rest.className || "" 33 | ); 34 | 35 | const s = size || 1; 36 | 37 | return ( 38 | 48 | {children} 49 | 50 | ); 51 | }; 52 | 53 | export { Menu }; 54 | -------------------------------------------------------------------------------- /app/components/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | type FDNColour = 6 | | "red" 7 | | "orange" 8 | | "yellow" 9 | | "green" 10 | | "blue" 11 | | "purple" 12 | | "pink" 13 | | "black" 14 | | "white"; 15 | 16 | type FDNSize = "sm" | "md" | "lg"; 17 | type FDNSizeExtended = 18 | | FDNSize 19 | | "xl" 20 | | "xxl" 21 | | "xxxl" 22 | | "4xl" 23 | | "fw" 24 | | "fh"; 25 | 26 | type FDNStateType = "info" | "warn" | "success" | "error"; 27 | 28 | type FDNOrientation = "h" | "v"; 29 | 30 | type FDNOverflow = "hidden" | "scroll" | "clip" | "visible"; 31 | -------------------------------------------------------------------------------- /app/components/marketing/browser/browser-landing-intro-block.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Block } from ".."; 6 | import { useTranslations } from "../../../l10n"; 7 | import BrowserWireframe from "../../assets/BrowserWireframe"; 8 | import { ArrowRightAnimated } from "../../icons/animated/ArrowRightAnimated"; 9 | import Button from "../../ui/Button"; 10 | import ConstrainedChildren from "../../ui/ConstrainedChildren"; 11 | import { Hero, HeroBody } from "../../ui/Hero"; 12 | import ProductLockup from "../../ui/ProductLockup"; 13 | import Stack from "../../ui/Stack"; 14 | 15 | const BLOCK_ID = "browser-landing-intro-block"; 16 | 17 | const BrowserLandingIntroBlock = () => { 18 | const [l, Localised] = useTranslations(BLOCK_ID); 19 | 20 | return ( 21 | 22 | 28 | 29 | 30 | 31 | 36 | 42 | 43 |

    44 | 45 |

    46 |
    47 | 48 | 53 |

    54 | 55 |

    56 | 57 | 74 |
    75 |
    76 |
    77 |
    78 | 79 | 80 |
    81 |
    82 | ); 83 | }; 84 | 85 | export default BrowserLandingIntroBlock; 86 | -------------------------------------------------------------------------------- /app/components/marketing/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { cloneElement } from "preact"; 6 | import { withCacheBuster } from "../../utils/cache"; 7 | import HTMLComment from "../ui/HTMLComment"; 8 | 9 | export const Block = ({ 10 | id, 11 | children 12 | }: { 13 | id: string; 14 | children?: any; 15 | }) => { 16 | return ( 17 | <> 18 | @{id} 19 | 23 | {cloneElement(children, { 24 | ...children.props, 25 | className: [`block-${id}`] 26 | .concat( 27 | children.props.className 28 | ? children.props.className.split(" ") 29 | : [] 30 | ) 31 | .join(" ") 32 | })} 33 | 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /app/components/marketing/sponsors-block.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Block } from "."; 6 | import { useTranslations } from "../../l10n"; 7 | import { getComponentConfig } from "../../utils/data"; 8 | import Button from "../ui/Button"; 9 | import { Hero, HeroBody } from "../ui/Hero"; 10 | import Stack from "../ui/Stack"; 11 | 12 | const BLOCK_ID = "sponsors-block"; 13 | 14 | interface SponsorItem { 15 | id: string; 16 | name: string; 17 | url: string; 18 | logo_url: string; 19 | description: string; 20 | } 21 | 22 | interface SponsorsConfig { 23 | items: SponsorItem[]; 24 | } 25 | 26 | const SponsorsBlock = () => { 27 | const [l, Localised] = useTranslations(BLOCK_ID); 28 | 29 | const data = getComponentConfig("sponsors"); 30 | 31 | if (!data.items.length) return <>; 32 | 33 | return ( 34 | 35 | 36 | 37 | 38 | 39 |

    {l("title")}

    40 |

    {l("subtitle")}

    41 |
    42 | 43 | 44 | {data.items.map((i) => ( 45 | 63 | ))} 64 | 65 |
    66 |
    67 |
    68 |
    69 | ); 70 | }; 71 | 72 | export default SponsorsBlock; 73 | -------------------------------------------------------------------------------- /app/components/pages/third-party-licenses/Dependency.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { getPackageURL, getSourceIcon, sources } from "."; 6 | import { OpenInNew } from "../../icons/OpenInNew"; 7 | import Button from "../../ui/Button"; 8 | import { ItemList } from "../../ui/ItemList"; 9 | import { Reference } from "./Reference"; 10 | 11 | export interface DependencyReference { 12 | owner: string; 13 | repo: string; 14 | path: string; 15 | branch: string; 16 | line?: string; 17 | } 18 | 19 | export const Dependency = ({ 20 | name, 21 | source, 22 | license, 23 | references 24 | }: { 25 | name: string; 26 | source: string; 27 | license: string; 28 | references: DependencyReference[]; 29 | }) => { 30 | const SourceIcon = getSourceIcon(source); 31 | const pkgURL = getPackageURL(source, name); 32 | 33 | return ( 34 |
    38 |
    39 | 43 |

    {name}

    44 |
    45 | 46 |
    47 | {SourceIcon ? ( 48 |

    49 | {SourceIcon} 50 | {sources[source].title} 51 |

    52 | ) : ( 53 | <> 54 | )} 55 | 56 | {pkgURL && ( 57 | 66 | )} 67 |
    68 |
    69 | 70 | 71 | {references.map((ref) => ( 72 | 73 | ))} 74 | 75 | 76 | 77 |
  • 78 | 79 |
    80 | 							{license.split("\n").map((ln) => (
    81 | 								{ln}
    82 | 							))}
    83 | 						
    84 |
    85 |
  • 86 |
    87 |
    88 | ); 89 | }; 90 | -------------------------------------------------------------------------------- /app/components/pages/third-party-licenses/DependencyItem.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | import { getSourceIcon } from "."; 8 | import { ArrowRightAnimated } from "../../icons/animated/ArrowRightAnimated"; 9 | 10 | export const DependencyItem = ({ 11 | name, 12 | source, 13 | license, 14 | ...rest 15 | }: { 16 | name: string; 17 | source: string; 18 | license: string; 19 | } & JSXInternal.HTMLAttributes) => { 20 | const className = clsx( 21 | "fdn-stack h x-space-between fdn-icon-arrow-right-animated-parent", 22 | rest.className || "" 23 | ); 24 | 25 | return ( 26 | 31 |

    {name}

    32 | 33 |
    34 | {getSourceIcon(source)} 35 | 36 |
    37 |

    43 | {license} 44 |

    45 | 46 | 47 |
    48 |
    49 |
    50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /app/components/pages/third-party-licenses/Reference.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | import { OpenInNew } from "../../icons/OpenInNew"; 8 | import Button from "../../ui/Button"; 9 | 10 | export const Reference = ({ 11 | owner, 12 | repo, 13 | path, 14 | branch, 15 | line, 16 | ...rest 17 | }: { 18 | owner: string; 19 | repo: string; 20 | path: string; 21 | branch: string; 22 | line?: string; 23 | } & JSXInternal.HTMLAttributes) => { 24 | const className = clsx( 25 | "fdn-stack h x-space-between", 26 | rest.className || "" 27 | ); 28 | 29 | return ( 30 |
  • 31 |
    32 | 37 | 38 |
    39 |

    40 | 41 | {owner}/{repo} 42 | 43 |

    44 | {path.substring(1)} 45 |
    46 |
    47 | 48 | 58 |
  • 59 | ); 60 | }; 61 | -------------------------------------------------------------------------------- /app/components/pages/third-party-licenses/Repository.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import Link from "../../Link"; 6 | import { ItemList } from "../../ui/ItemList"; 7 | import { DependencyItem } from "./DependencyItem"; 8 | 9 | export const Repository = ({ 10 | repository, 11 | dependencies 12 | }: { 13 | repository: string; 14 | dependencies: { name: string; source: string; license: string }[]; 15 | }) => { 16 | return ( 17 |
    18 | 23 |

    {repository}

    24 | 25 | 26 | {dependencies.map((dep) => ( 27 | 32 | ))} 33 | 34 |
    35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /app/components/pages/third-party-licenses/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { createElement } from "preact"; 6 | import { Cargo } from "../../icons/brands/Cargo"; 7 | import { NPM } from "../../icons/brands/NPM"; 8 | 9 | export const sources: any = { 10 | NodeService: { 11 | icon: NPM, 12 | title: "npm", 13 | packageURL: (pkg: string) => 14 | `https://npmjs.com/package/${pkg}` 15 | }, 16 | CargoService: { 17 | icon: Cargo, 18 | title: "crates.io", 19 | packageURL: (pkg: string) => `https://crates.io/crates/${pkg}` 20 | } 21 | }; 22 | 23 | export const getSourceIcon = (source: keyof typeof sources) => { 24 | if (source in sources) { 25 | return createElement(sources[source].icon, { 26 | title: sources[source].title, 27 | size: 1.25 28 | }); 29 | } else { 30 | return <>; 31 | } 32 | }; 33 | 34 | export const getPackageURL = ( 35 | source: keyof typeof sources, 36 | pkg: string 37 | ) => { 38 | if (source in sources) { 39 | return sources[source].packageURL(pkg); 40 | } else { 41 | return null; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /app/components/ui/Aside/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | 8 | const Aside = ({ 9 | header, 10 | children, 11 | ...rest 12 | }: { 13 | header?: any; 14 | children?: any; 15 | } & JSXInternal.HTMLAttributes) => { 16 | const className = clsx("fdn-aside", rest.className); 17 | 18 | return ( 19 | 32 | ); 33 | }; 34 | 35 | export default Aside; 36 | -------------------------------------------------------------------------------- /app/components/ui/Banner/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { cloneElement } from "preact"; 7 | import { JSXInternal } from "preact/src/jsx"; 8 | 9 | const Banner = ({ 10 | type, 11 | size, 12 | icon, 13 | children, 14 | ...rest 15 | }: { 16 | type?: FDNStateType; 17 | size?: FDNSizeExtended; 18 | icon?: any; 19 | children: any; 20 | } & Omit< 21 | JSXInternal.HTMLAttributes, 22 | "size" | "icon" 23 | >) => { 24 | size = size ? size : "md"; 25 | 26 | const className = clsx( 27 | "fdn-banner", 28 | { 29 | [type as string]: !!type, 30 | [size as string]: true 31 | }, 32 | rest.className || "" 33 | ); 34 | 35 | return ( 36 | 45 | ); 46 | }; 47 | 48 | export default Banner; 49 | -------------------------------------------------------------------------------- /app/components/ui/Button/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { createElement } from "preact"; 7 | import { JSXInternal } from "preact/src/jsx"; 8 | import { localisedHref } from "../../Link"; 9 | 10 | export interface ButtonProps { 11 | colour?: FDNColour; 12 | size?: FDNSize; 13 | children?: any; 14 | fullwidth?: boolean; 15 | href?: any; 16 | noJS?: boolean; 17 | type?: "primary" | "secondary" | "text"; 18 | hasIcon?: boolean; 19 | } 20 | 21 | const Button = ({ 22 | children, 23 | size, 24 | colour, 25 | fullwidth, 26 | href, 27 | type, 28 | noJS, 29 | hasIcon, 30 | as, 31 | ...rest 32 | }: JSXInternal.HTMLAttributes & ButtonProps) => { 33 | type = type ? type : "primary"; 34 | size = size ? size : ("md" as any); 35 | href = href ? localisedHref(href) : undefined; 36 | 37 | const className = clsx( 38 | "fdn-button", 39 | { 40 | [size as string]: true, 41 | [colour as string]: true, 42 | [type as string]: true, 43 | "no-js": noJS, 44 | "full-width": fullwidth, 45 | "has-icon": hasIcon 46 | }, 47 | (rest as any).className || "" 48 | ); 49 | 50 | return createElement( 51 | as ? (as as any) : noJS ? "input" : href ? "a" : "button", 52 | { 53 | ...rest, 54 | href, 55 | className, 56 | ...(noJS 57 | ? { type: "submit", value: children.toString() } 58 | : {}) 59 | }, 60 | noJS ? [] : children 61 | ); 62 | }; 63 | 64 | export default Button; 65 | -------------------------------------------------------------------------------- /app/components/ui/Card/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | 8 | const Card = ({ 9 | header, 10 | footer, 11 | children, 12 | ...rest 13 | }: { 14 | header?: any; 15 | footer?: any; 16 | children?: any; 17 | } & JSXInternal.HTMLAttributes) => { 18 | const className = clsx("fdn-card", rest.className); 19 | 20 | return ( 21 |
    22 | {header && ( 23 |
    24 | {header} 25 |
    26 | )} 27 | 28 | {children && ( 29 |
    {children}
    30 | )} 31 | 32 | {footer && ( 33 |
    {footer}
    34 | )} 35 |
    36 | ); 37 | }; 38 | 39 | export default Card; 40 | -------------------------------------------------------------------------------- /app/components/ui/Checkbox/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import Field, { FieldProps } from "../Field"; 6 | 7 | const Checkbox = ({ ...rest }: FieldProps) => { 8 | return ( 9 | 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default Checkbox; 16 | -------------------------------------------------------------------------------- /app/components/ui/ClientData.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | const ClientData = ({ id, data }: { id: string; data: any }) => { 6 | return ( 7 | 15 | ); 16 | }; 17 | 18 | export default ClientData; 19 | -------------------------------------------------------------------------------- /app/components/ui/ConstrainedChildren.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | const ConstrainedChildren = ({ children }: { children?: any }) => { 6 | return
    {children}
    ; 7 | }; 8 | 9 | export default ConstrainedChildren; 10 | -------------------------------------------------------------------------------- /app/components/ui/HTMLComment.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | const HTMLComment = ({ 6 | children 7 | }: { 8 | children: string | string[]; 9 | }) => { 10 | return ( 11 | ` 21 | }} 22 | > 23 | ); 24 | }; 25 | 26 | export default HTMLComment; 27 | -------------------------------------------------------------------------------- /app/components/ui/Hero/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | 8 | const HeroBody = ({ 9 | children, 10 | ...rest 11 | }: JSXInternal.HTMLAttributes) => { 12 | const className = clsx("fdn-hero-body", rest.className || ""); 13 | 14 | return ( 15 |
    16 | {children} 17 |
    18 | ); 19 | }; 20 | 21 | const Hero = ({ 22 | colour, 23 | size, 24 | detatched, 25 | children, 26 | overflow, 27 | ...rest 28 | }: { 29 | colour?: FDNColour; 30 | size?: FDNSizeExtended; 31 | detatched?: boolean; 32 | overflow?: FDNOverflow; 33 | } & Omit, "size">) => { 34 | size = size ? size : ("md" as any); 35 | 36 | const className = clsx( 37 | "fdn-hero", 38 | { 39 | [colour as string]: !!colour, 40 | [size as string]: !!size, 41 | detatched: !!detatched, 42 | [`overflow-${overflow}`]: !!overflow 43 | }, 44 | rest.className || "" 45 | ); 46 | 47 | return
    {children}
    ; 48 | }; 49 | 50 | export { 51 | Hero, 52 | HeroBody, 53 | // 54 | HeroBody as Body 55 | }; 56 | -------------------------------------------------------------------------------- /app/components/ui/ItemList/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { cloneElement } from "preact"; 7 | import { JSXInternal } from "preact/src/jsx"; 8 | 9 | export const ItemList = ({ 10 | children, 11 | ...rest 12 | }: { 13 | children?: any; 14 | } & JSXInternal.HTMLAttributes) => { 15 | const className = clsx("fdn-item-list", rest.className || ""); 16 | 17 | if (!Array.isArray(children)) { 18 | children = [children]; 19 | } 20 | 21 | return ( 22 |
      23 | {children.map((c: any) => 24 | cloneElement(c, { 25 | className: clsx( 26 | "fdn-list-item", 27 | c.props.className || "" 28 | ) 29 | }) 30 | )} 31 |
    32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /app/components/ui/Menu/Item.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | import Button, { ButtonProps } from "../Button"; 8 | 9 | const MenuItem = ({ 10 | icon, 11 | children, 12 | ...rest 13 | }: Omit, "icon"> & 14 | ButtonProps & { 15 | icon?: any; 16 | }) => { 17 | const Icon = icon; 18 | 19 | const className = clsx( 20 | "fdn-menu-item", 21 | { 22 | secondary: true 23 | }, 24 | rest.className || "" 25 | ); 26 | 27 | return ( 28 | 33 | ); 34 | }; 35 | 36 | export default MenuItem; 37 | -------------------------------------------------------------------------------- /app/components/ui/Menu/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { JSXInternal } from "preact/src/jsx"; 7 | 8 | const Menu = ({ 9 | hasArrow, 10 | children, 11 | arrowPosition, 12 | ...rest 13 | }: { 14 | hasArrow?: boolean; 15 | arrowPosition?: "center" | "start" | "end" | string; 16 | } & JSXInternal.HTMLAttributes) => { 17 | const className = clsx( 18 | "fdn-menu", 19 | { 20 | ["has-arrow" as string]: !!hasArrow 21 | }, 22 | rest.className || "" 23 | ); 24 | 25 | if (!arrowPosition) arrowPosition = "start"; 26 | if (arrowPosition == "center") arrowPosition = "50%"; 27 | if (arrowPosition == "start") arrowPosition = "1rem"; 28 | if (arrowPosition == "end") arrowPosition = "calc(100% - 1rem)"; 29 | 30 | return ( 31 | 36 | {hasArrow && ( 37 | 45 | 49 | 50 | )} 51 | 52 |
    {children}
    53 |
    54 | ); 55 | }; 56 | 57 | export default Menu; 58 | -------------------------------------------------------------------------------- /app/components/ui/Radio/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import Field, { FieldProps } from "../Field"; 6 | 7 | const Radio = ({ ...rest }: FieldProps) => { 8 | return ( 9 | 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default Radio; 16 | -------------------------------------------------------------------------------- /app/components/ui/Select/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { JSXInternal } from "preact/src/jsx"; 6 | import { ChevronDown } from "../../icons/ChevronDown"; 7 | import Field, { FieldProps } from "../Field"; 8 | 9 | const Select = ({ 10 | items, 11 | ...rest 12 | }: FieldProps & { 13 | items: 14 | | JSXInternal.HTMLAttributes[] 15 | | (() => JSXInternal.HTMLAttributes[]); 16 | }) => { 17 | items = typeof items == "function" ? items() : items; 18 | 19 | return ( 20 | } {...rest}> 21 | 26 | 27 | ); 28 | }; 29 | 30 | export default Select; 31 | -------------------------------------------------------------------------------- /app/components/ui/Separator.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | 7 | const Separator = ({ orientation }: { orientation: "h" | "v" }) => { 8 | const className = clsx("fdn-separator", { 9 | [orientation]: true 10 | }); 11 | 12 | return
    ; 13 | }; 14 | 15 | export default Separator; 16 | -------------------------------------------------------------------------------- /app/components/ui/Stack.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import clsx from "clsx"; 6 | import { createElement } from "preact"; 7 | import { JSXInternal } from "preact/src/jsx"; 8 | 9 | const Stack = ({ 10 | orientation, 11 | gap, 12 | as, 13 | flex, 14 | x, 15 | y, 16 | xy, 17 | wrap, 18 | w, 19 | h, 20 | children, 21 | ...rest 22 | }: { 23 | orientation?: FDNOrientation; 24 | gap?: FDNSizeExtended; 25 | as?: keyof JSXInternal.IntrinsicElements; 26 | flex?: string; 27 | x?: string; 28 | y?: string; 29 | xy?: string; 30 | wrap?: boolean; 31 | w?: string; 32 | h?: string; 33 | className?: string; 34 | children?: any; 35 | }) => { 36 | as = as ? as : "div"; 37 | 38 | if (xy) { 39 | if (xy.includes(" ") && xy.split(" ").length == 2) { 40 | x = xy.split(" ")[0]; 41 | y = xy.split(" ")[1]; 42 | } else { 43 | x = xy; 44 | y = xy; 45 | } 46 | } 47 | 48 | const className = clsx( 49 | "fdn-stack", 50 | { 51 | [orientation as string]: !!orientation, 52 | [`gap-${gap}`]: !!gap, 53 | [`flex-${flex}`]: !!flex, 54 | [`x-${x}`]: !!x, 55 | [`y-${y}`]: !!y, 56 | [`w-${w}`]: !!w, 57 | [`h-${h}`]: !!h, 58 | wrap: !!wrap 59 | }, 60 | rest.className || "" 61 | ); 62 | 63 | return createElement(as, { ...rest, className }, children); 64 | }; 65 | 66 | export default Stack; 67 | -------------------------------------------------------------------------------- /app/components/ui/Tabs/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import Button, { ButtonProps } from "../Button"; 6 | 7 | export interface Tab { 8 | value: string; 9 | label: string; 10 | disabled?: boolean; 11 | children?: any; 12 | } 13 | 14 | export const Tabs = ({ 15 | tabs, 16 | id, 17 | selected, 18 | ...rest 19 | }: ButtonProps & { 20 | id: string; 21 | selected: string; 22 | tabs: () => Tab[] | Tab[]; 23 | }) => { 24 | const evaluatedTabs = typeof tabs == "function" ? tabs() : tabs; 25 | 26 | return ( 27 |
    28 | {evaluatedTabs.map((tab, i) => ( 29 | <> 30 | 37 | 56 | 61 | 62 | ))} 63 |
    64 | ); 65 | }; 66 | -------------------------------------------------------------------------------- /app/components/ui/TextField/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import Field, { FieldProps } from "../Field"; 6 | 7 | const TextField = ({ ...rest }: FieldProps) => { 8 | return ( 9 | 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default TextField; 16 | -------------------------------------------------------------------------------- /app/flags.ts: -------------------------------------------------------------------------------- 1 | export const flags = { 2 | base: 0, 3 | new_donations_experience: 1 4 | }; 5 | -------------------------------------------------------------------------------- /app/main.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { config } from "dotenv"; 6 | import { DEFAULT_LOCALE, getL10nBundle } from "./l10n"; 7 | import { createHttpServer } from "./server"; 8 | 9 | config(); 10 | 11 | const main = async () => { 12 | (global as any).SCALAR_LANG_DEFAULT_BUNDLE = await getL10nBundle( 13 | DEFAULT_LOCALE 14 | ); 15 | 16 | const server = createHttpServer(); 17 | 18 | const host = process.env.HOST ? process.env.HOST : "127.0.0.1"; 19 | const port = process.env.PORT ? +process.env.PORT : 3000; 20 | 21 | server.listen({ 22 | host, 23 | port 24 | }); 25 | }; 26 | 27 | process.on("uncaughtException", (e) => { 28 | console.error(e); 29 | }); 30 | 31 | main(); 32 | -------------------------------------------------------------------------------- /app/og.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | const ogImages = { 6 | _: { 7 | url: "logo.jpg", 8 | alt: "A picture of the Dot HQ logo positioned in the center." 9 | }, 10 | 11 | logo_with_browser_wireframe: { 12 | url: "logo_with_browser_wireframe.jpg", 13 | alt: "A picture of the Dot HQ logo placed above a wireframe drawing of Dot Browser." 14 | }, 15 | 16 | donate: { 17 | url: "donate.jpg", 18 | alt: "A picture of a red hand holding a red heart placed above the Dot HQ logo and donate as a title." 19 | } 20 | }; 21 | 22 | export default ogImages; 23 | -------------------------------------------------------------------------------- /app/pages/404.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Hero, HeroBody } from "../components/ui/Hero"; 6 | import { l } from "../l10n"; 7 | 8 | export const meta = { 9 | title: () => l("error-not-found-page-title"), 10 | titleSuffix: false, 11 | description: () => l("error-not-found-title") 12 | }; 13 | 14 | const NotFound = () => { 15 | return ( 16 | <> 17 | 18 | 19 |

    {l("error-not-found-title")}

    20 | 21 |

    {l("error-not-found-subtitle")}

    22 |
    23 |
    24 | 25 | ); 26 | }; 27 | 28 | export default NotFound; 29 | -------------------------------------------------------------------------------- /app/pages/about/third-party-licenses.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { resolve } from "path"; 6 | import Localised from "../../components/Localised"; 7 | import { Hero, HeroBody } from "../../components/ui/Hero"; 8 | import Separator from "../../components/ui/Separator"; 9 | import { l } from "../../l10n"; 10 | import ogImages from "../../og"; 11 | import { PageProps } from "../../types"; 12 | 13 | export const meta = { 14 | title: () => l("page-third-party-licenses-title"), 15 | description: () => l("page-third-party-licenses-description"), 16 | css: ["third-party-licenses.css"], 17 | ogImage: ogImages._ 18 | }; 19 | 20 | const windowsPrefix = process.platform == "win32" ? "file:///" : ""; 21 | 22 | const ThirdPartyLicensesPage = async ({ req, res }: PageProps) => { 23 | const { DependenciesSection, RepositoriesSection } = await import( 24 | windowsPrefix + 25 | resolve( 26 | process.cwd(), 27 | ".scalar", 28 | "generated", 29 | "generated.js" 30 | ) 31 | ); 32 | 33 | return ( 34 | <> 35 | 36 | 37 |

    {l("page-third-party-licenses-title")}

    38 |

    {l("page-third-party-licenses-subtitle")}

    39 |
    40 |
    41 | 42 | 43 | 44 |
    45 | {/* } 47 | placeholder={ 48 | "Search third-party licenses..." 49 | } 50 | /> */} 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 |
    59 | 60 |

    61 | } 66 | /> 67 |

    68 |
    69 |
    70 |
    71 | 72 | ); 73 | }; 74 | 75 | export default ThirdPartyLicensesPage; 76 | -------------------------------------------------------------------------------- /app/pages/index.tsx: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import BrowserLandingIntroBlock from "../components/marketing/browser/browser-landing-intro-block"; 6 | import SponsorsBlock from "../components/marketing/sponsors-block"; 7 | import { l } from "../l10n"; 8 | import ogImages from "../og"; 9 | import { PageProps } from "../types"; 10 | 11 | export const meta = { 12 | title: () => l("page-index-title"), 13 | description: () => l("page-index-description"), 14 | 15 | ogImage: ogImages.logo_with_browser_wireframe 16 | }; 17 | 18 | const Index = ({ lang }: PageProps) => { 19 | return ( 20 | <> 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default Index; 29 | -------------------------------------------------------------------------------- /app/pages/select-language.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { FastifyReply, FastifyRequest } from "fastify"; 6 | import { isValidLocale } from "../l10n"; 7 | 8 | export default ( 9 | req: FastifyRequest<{ 10 | Querystring: { new_locale: string; go: string }; 11 | }>, 12 | res: FastifyReply 13 | ) => { 14 | if ( 15 | !req.query.new_locale || 16 | !req.query.go || 17 | (req.query.new_locale && !isValidLocale(req.query.new_locale)) 18 | ) { 19 | return res.redirect(307, "/"); 20 | } 21 | 22 | const filteredPath = req.query.go.split("?")[0]; 23 | const pathQueries = req.query.go.split("?")[1]; 24 | 25 | const trimmedPath = filteredPath.endsWith("/") 26 | ? filteredPath.substring(0, filteredPath.length - 1) 27 | : filteredPath; 28 | 29 | res.redirect( 30 | 307, 31 | `/${req.query.new_locale}${trimmedPath}${ 32 | pathQueries ? `?${pathQueries}` : "" 33 | }` 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /app/redirects.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | type RedirectItemOptions = { statusCode: number }; 6 | type RedirectItemLonghand = [string, RedirectItemOptions]; 7 | type RedirectItem = string | [string] | RedirectItemLonghand; 8 | 9 | // Default status code is 307 10 | const redirects: Record = { 11 | "/browser": "https://github.com/dothq/browser", 12 | 13 | "/browser/desktop": "https://github.com/dothq/browser-desktop", 14 | "/browser/android": "https://github.com/dothq/browser-android", 15 | 16 | "/translate": "https://github.com/dothq/lexicon", 17 | "/one": "https://github.com/dothq/one", 18 | 19 | "/donate": "/contribute/donate" 20 | }; 21 | 22 | const formatRedirects = () => { 23 | let allRedirects: Record = { 24 | ...(redirects as any) 25 | }; 26 | 27 | const defaultOptions: RedirectItemOptions = { 28 | statusCode: 307 29 | }; 30 | 31 | for (const [key, value] of Object.entries(redirects)) { 32 | if (typeof value == "string") { 33 | allRedirects[key] = [value, defaultOptions]; 34 | } else if (Array.isArray(value)) { 35 | if (value.length == 1) { 36 | allRedirects[key] = [value[0], defaultOptions]; 37 | } else if (value.length == 2) { 38 | allRedirects[key] = value; 39 | } 40 | } 41 | } 42 | 43 | return allRedirects; 44 | }; 45 | 46 | export default formatRedirects(); 47 | -------------------------------------------------------------------------------- /app/types.d.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { FastifyReply, FastifyRequest } from "fastify"; 6 | 7 | export interface PageMetadata { 8 | title?: string; 9 | titleSuffix?: boolean; 10 | description?: string; 11 | js?: string[]; 12 | css?: string[]; 13 | 14 | ogImage?: { 15 | url: string; 16 | alt: string; 17 | }; 18 | } 19 | 20 | interface PageProps< 21 | Params = Record 22 | > { 23 | params: Params; 24 | query: Params; 25 | meta: PageMetadata; 26 | formData: URLSearchParams; 27 | url: URL; 28 | schema: any; 29 | req: FastifyRequest; 30 | res: FastifyReply; 31 | lang: string; 32 | cache: FastifyRequest["cache"]; 33 | } 34 | 35 | declare module "fastify" { 36 | export interface FastifyRequest { 37 | cache: Map< 38 | string, 39 | { 40 | data: any; 41 | ttl?: number; 42 | } 43 | >; 44 | } 45 | } 46 | 47 | declare var __scalar_js: any[]; 48 | -------------------------------------------------------------------------------- /app/utils/cache.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | export const withCacheBuster = (path: string) => { 6 | const uri = new URL(path, "http://localhost"); 7 | 8 | uri.searchParams.set("r", process.env.SCALAR_GIT_REVISION || "_"); 9 | 10 | return uri.href.split("localhost")[1]; 11 | }; 12 | -------------------------------------------------------------------------------- /app/utils/data.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { readFileSync } from "fs"; 6 | import { traverse } from "object-traversal"; 7 | import { resolve } from "path"; 8 | import { createElement, Fragment } from "preact"; 9 | import vm from "vm"; 10 | import yaml from "yaml"; 11 | import * as l10n from "../l10n"; 12 | import Icons from "./icons"; 13 | import { unixifyPath } from "./path"; 14 | 15 | export const getComponentConfig = (name: string): T => { 16 | const path = unixifyPath( 17 | resolve(process.cwd(), "data", `${name}.yml`) 18 | ); 19 | 20 | const data = readFileSync(path, "utf-8"); 21 | 22 | var parsed = yaml.parse(data); 23 | 24 | traverse(parsed, ({ parent, key, value }: any) => { 25 | if (key == "icon") { 26 | let data: any = { 27 | name: value 28 | }; 29 | 30 | if (typeof value == "object") { 31 | data = value; 32 | } 33 | 34 | if (!(data.name in Icons)) { 35 | console.warn( 36 | `Invalid icon name '${data.name}' in icons list.` 37 | ); 38 | return () => createElement(Fragment, {}); 39 | } 40 | 41 | const I = (props: any) => 42 | createElement((Icons as any)[data.name], { 43 | size: data.size 44 | ? parseInt( 45 | data.size.toString().replace(/x/g, "") 46 | ) 47 | : null, 48 | colour: data.colour ? data.colour : null 49 | }); 50 | 51 | parent[key] = I; 52 | 53 | return I; 54 | } 55 | 56 | if (typeof value == "string") { 57 | parent[key] = value.replace( 58 | /\${{(.*)}}/g, 59 | (_: any, fnData: string) => { 60 | const encoded = encodeURI(fnData); 61 | 62 | const ctx = { 63 | l: l10n.l, 64 | result: null 65 | }; 66 | 67 | vm.runInNewContext( 68 | `result=eval(decodeURI("` + encoded + `"))`, 69 | ctx 70 | ); 71 | 72 | return ctx.result as any; 73 | } 74 | ); 75 | } 76 | }); 77 | 78 | return parsed; 79 | }; 80 | -------------------------------------------------------------------------------- /app/utils/error.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import createFastifyError from "@fastify/error"; 6 | 7 | export const createError = (code: number): void => { 8 | const Error = createFastifyError("ERROR", "", code); 9 | new Error(); 10 | }; 11 | -------------------------------------------------------------------------------- /app/utils/flags.ts: -------------------------------------------------------------------------------- 1 | import { FastifyRequest } from "fastify"; 2 | import { flags } from "../flags"; 3 | 4 | export const isFlagActive = ( 5 | req: FastifyRequest, 6 | flag: keyof typeof flags 7 | ) => { 8 | const flagCookie = req.cookies["web_flags"]; 9 | 10 | if (!flagCookie) return false; 11 | 12 | try { 13 | const bits = parseInt(flagCookie); 14 | 15 | const val = flags[flag]; 16 | if (!val) return false; 17 | 18 | return Boolean(bits & (1 << val)); 19 | } catch (e) { 20 | console.error(e); 21 | return false; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /app/utils/html.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | export const addMPLLicenseHeader = (html: string) => { 6 | return ` 7 | 8 | 11 | ${html}`; 12 | }; 13 | -------------------------------------------------------------------------------- /app/utils/path.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { posix, sep } from "path"; 6 | 7 | export const unixifyPath = (path: string) => 8 | path.split(sep).join(posix.sep); 9 | -------------------------------------------------------------------------------- /app/utils/ua.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import UAParser from "ua-parser-js"; 6 | 7 | export const getBrowserId = (userAgent: string) => { 8 | const parser = new UAParser(); 9 | parser.setUA(userAgent); 10 | 11 | const engine = parser.getEngine(); 12 | 13 | switch (engine.name) { 14 | case "WebKit": 15 | case "Blink": 16 | return "webkit"; 17 | case "Gecko": 18 | return "gecko"; 19 | case "EdgeHTML": 20 | return "edgehtml"; 21 | case "Trident": 22 | return "trident"; 23 | default: 24 | return ""; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /data/sponsors.yml: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | name: Sponsors 6 | items: 7 | - id: tuta 8 | name: ${{ l("sponsors-block-item-tuta-name") }} 9 | description: ${{ l("sponsors-block-item-tuta-description") }} 10 | url: https://tuta.com/ 11 | logo_url: /media/images/sponsors/tuta_logo.svg 12 | -------------------------------------------------------------------------------- /docker/config/compression.conf: -------------------------------------------------------------------------------- 1 | # Enables gzip 2 | gzip on; 3 | gzip_proxied any; 4 | gzip_buffers 16 8k; 5 | gzip_http_version 1.1; 6 | gzip_min_length 256; 7 | gzip_types 8 | application/atom+xml 9 | application/javascript 10 | application/x-javascript 11 | application/json 12 | application/ld+json 13 | font/eot 14 | font/otf 15 | font/ttf 16 | font/woff 17 | font/woff2 18 | image/svg+xml 19 | image/png 20 | image/jpeg 21 | text/css 22 | text/javascript 23 | text/plain 24 | text/xml 25 | text/html; -------------------------------------------------------------------------------- /docker/config/nginx.conf: -------------------------------------------------------------------------------- 1 | events { 2 | worker_connections 1024; 3 | } 4 | 5 | http { 6 | include mime.types; 7 | default_type application/octet-stream; 8 | 9 | error_log /var/log/nginx/error.log; 10 | access_log /dev/null; 11 | 12 | server_name_in_redirect off; 13 | server_tokens off; 14 | port_in_redirect off; 15 | 16 | client_body_buffer_size 1k; 17 | client_header_buffer_size 1k; 18 | client_max_body_size 1k; 19 | large_client_header_buffers 2 1k; 20 | 21 | server_names_hash_bucket_size 128; 22 | 23 | server { 24 | listen 80; 25 | server_name localhost; 26 | } 27 | 28 | include sites/*; 29 | } -------------------------------------------------------------------------------- /docker/config/sites/www.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | listen [::]:80 default_server; 4 | server_name www.dothq.co www.dothq.org dothq.co dothq.org; 5 | 6 | include compression.conf; 7 | 8 | location / { 9 | return 301 https://$http_host$request_uri; 10 | } 11 | 12 | location ^~ /.well-known/acme-challenge { 13 | default_type "text/plain"; 14 | root /var/www/letsencrypt; 15 | break; 16 | } 17 | 18 | location = /.well-known/acme-challenge/ { 19 | return 404; 20 | } 21 | } 22 | 23 | server { 24 | listen 443 ssl; 25 | listen [::]:443 ssl; 26 | 27 | server_name _; 28 | 29 | include ssl.conf; 30 | include compression.conf; 31 | 32 | location / { 33 | proxy_http_version 1.1; 34 | proxy_cache_bypass $http_upgrade; 35 | 36 | proxy_set_header Upgrade $http_upgrade; 37 | proxy_set_header Connection "upgrade"; 38 | proxy_set_header Host $http_host; 39 | 40 | proxy_pass http://scalar:80; 41 | } 42 | } 43 | 44 | server { 45 | listen 80; 46 | listen [::]:80; 47 | 48 | server_name dothqaaaxerjhwh6ovuvvgypv5khivfxpd7zpdvcr3ssemrjdhcvniyd.onion; 49 | 50 | include compression.conf; 51 | 52 | location / { 53 | proxy_http_version 1.1; 54 | proxy_cache_bypass $http_upgrade; 55 | 56 | proxy_set_header Upgrade $http_upgrade; 57 | proxy_set_header Connection "upgrade"; 58 | proxy_set_header Host $http_host; 59 | 60 | proxy_pass http://scalar:80; 61 | } 62 | } -------------------------------------------------------------------------------- /docker/config/ssl.conf: -------------------------------------------------------------------------------- 1 | # SSL Configuration 2 | ssl_certificate /etc/letsencrypt/live/dothq.org/fullchain.pem; 3 | ssl_certificate_key /etc/letsencrypt/live/dothq.org/privkey.pem; 4 | ssl_trusted_certificate /etc/letsencrypt/live/dothq.org/chain.pem; 5 | 6 | ssl_session_timeout 1d; 7 | ssl_session_cache shared:MozSSL:10m; # about 40000 sessions 8 | ssl_session_tickets off; 9 | 10 | ssl_dhparam /etc/ssl/dhparam.pem; 11 | 12 | ssl_protocols TLSv1.2 TLSv1.3; 13 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 14 | ssl_prefer_server_ciphers off; 15 | 16 | ssl_stapling on; 17 | ssl_stapling_verify on; -------------------------------------------------------------------------------- /docker/create-stub-certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | docker restart certbot 3 | docker exec certbot mkdir -p /etc/letsencrypt/live/www.dothq.org 4 | docker exec certbot openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ 5 | -keyout /etc/letsencrypt/live/www.dothq.org/privkey.pem \ 6 | -out /etc/letsencrypt/live/www.dothq.org/fullchain.pem \ 7 | -subj /CN=dothq.org -------------------------------------------------------------------------------- /docker/generate-certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | docker exec certbot certbot certonly --webroot -w /var/www/letsencrypt \ 5 | --email contact+letsencrypt@dothq.org \ 6 | --agree-tos \ 7 | -n \ 8 | -d dothq.org \ 9 | -d www.dothq.org 10 | 11 | echo "Run docker restart nginx certbot to load the certificate." -------------------------------------------------------------------------------- /docker/nginx-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | chown -R nginx:nginx /etc/letsencrypt 4 | exec runuser -u appuser "$@" -------------------------------------------------------------------------------- /docker/nginx.dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:alpine 2 | 3 | RUN curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/ssl/dhparam.pem 4 | -------------------------------------------------------------------------------- /docker/www.dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | 3 | WORKDIR /worker/scalar 4 | 5 | COPY . . 6 | 7 | RUN apk add git 8 | 9 | RUN yarn 10 | RUN yarn build 11 | 12 | ENTRYPOINT ["node", ".scalar/main.js"] -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | }; -------------------------------------------------------------------------------- /l10n/en-GB/a11y.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | a11y-skip-to-content = Skip to content 6 | a11y-skip-to-end = Skip to end 7 | -------------------------------------------------------------------------------- /l10n/en-GB/brand.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | -brand-full-name = Dot HQ 6 | -brand-short-name = Dot 7 | 8 | -brand-browser-short-text = Browser 9 | -brand-browser-long-text = Dot Browser 10 | -brand-browser-desktop-short-text = Dot Browser (Desktop) 11 | -brand-browser-android-short-text = Dot Browser (Android) 12 | -brand-browser-desktop-long-text = Dot Browser for Desktop 13 | -brand-browser-android-long-text = Dot Browser for Android 14 | 15 | -brand-translate-short-text = Translate 16 | -brand-translate-long-text = Dot Translate 17 | 18 | -brand-one-short-text = One 19 | -brand-one-long-text = Dot One 20 | 21 | -brand-shield-short-text = Shield 22 | -brand-shield-long-text = Dot Shield 23 | 24 | -brand-windows = Windows 25 | -brand-macos = macOS 26 | -brand-linux = Linux 27 | -brand-ubuntu = Ubuntu 28 | -brand-fedora = Fedora 29 | -brand-arch-linux = Arch Linux 30 | -brand-android = Android -------------------------------------------------------------------------------- /l10n/en-GB/domain-migration.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | domain-migration-banner = We've moved domains from dothq.co to dothq.org! Welcome back. -------------------------------------------------------------------------------- /l10n/en-GB/errors/404.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | error-not-found-page-title = 404: Page Not Found 6 | 7 | error-not-found-title = Sorry, we can't find that page. 8 | error-not-found-subtitle = Please check the address and try again. -------------------------------------------------------------------------------- /l10n/en-GB/footer.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | # Products 6 | 7 | footer-products-section = Products 8 | 9 | footer-products-section-browser = { -brand-browser-short-text } 10 | footer-products-section-translate = { -brand-translate-short-text } 11 | footer-products-section-one = { -brand-one-short-text } 12 | footer-products-section-shield = { -brand-shield-short-text } 13 | 14 | # Community 15 | 16 | footer-community-section = Community 17 | 18 | footer-community-section-contribute = Contribute 19 | footer-community-section-donate = Donate 20 | footer-community-section-blog = Blog 21 | 22 | # Support 23 | 24 | footer-support-section = Support 25 | 26 | footer-support-section-get-help = Get help 27 | footer-support-section-bugs = Bugs 28 | footer-support-section-ideas = Ideas 29 | 30 | # Resources 31 | 32 | footer-resources-section = Resources 33 | 34 | footer-resources-section-branding = Branding 35 | footer-resources-section-developers = Developers 36 | footer-resources-section-open-source = Open-source 37 | 38 | # About 39 | 40 | footer-about-section = About 41 | 42 | footer-about-section-us = { -brand-full-name } 43 | footer-about-section-privacy = Privacy 44 | footer-about-section-terms = Terms 45 | footer-about-section-environment = Environment 46 | footer-about-section-charter = Charter 47 | footer-about-section-third-party-licences = Third-party licences 48 | 49 | # Socials 50 | 51 | footer-socials-section = Follow us 52 | 53 | # Language Switcher 54 | 55 | footer-language-section = Language 56 | footer-language-switcher-initial-prompt = Select a language 57 | 58 | footer-view-source = View page source 59 | footer-edit-page = Edit this page 60 | 61 | footer-copyright-text = 62 | © 2019–{ $year } { -brand-full-name }. 63 | Content on this page is licensed under CC BY-SA 4.0. -------------------------------------------------------------------------------- /l10n/en-GB/header.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | # Browser Item 6 | header-browser-item = { -brand-browser-short-text } 7 | header-browser-item-desktop-title = { -brand-browser-desktop-long-text } 8 | header-browser-item-desktop-subtitle = Get the web browser that protects your privacy on Windows, macOS and Linux. 9 | header-browser-item-android-title = { -brand-browser-android-long-text } 10 | header-browser-item-android-subtitle = Get the web browser that protects for your privacy on your Android phone. 11 | 12 | # Products Item 13 | header-products-item = Products 14 | 15 | header-products-item-translate-title = { -brand-translate-long-text } 16 | header-products-item-translate-subtitle = A fast translation service with hundreds of languages - all built without compromising privacy. 17 | 18 | header-products-item-one-title = { -brand-one-long-text } 19 | header-products-item-one-subtitle = The next-generation accounts and sync system that stays secure. 20 | 21 | header-products-item-shield-title = { -brand-shield-long-text } 22 | header-products-item-shield-subtitle = Our powerful and lightweight ad-blocking shield that won't block up your system resources. 23 | 24 | header-products-item-view-all-link = View all products 25 | 26 | # Community Item 27 | header-community-item = Community 28 | 29 | header-community-item-blog-title = Blog 30 | header-community-item-blog-subtitle = Keep to date on the newest information from { -brand-full-name }. 31 | 32 | header-community-item-help-title = Help and support 33 | header-community-item-help-subtitle = Get help with using our products and get your questions answered. 34 | 35 | header-community-item-discord-title = Discord 36 | header-community-item-discord-subtitle = Join our Discord server to stay up to date with the latest updates. 37 | 38 | header-community-item-matrix-title = Matrix 39 | header-community-item-matrix-subtitle = Join our Matrix server to stay up to date with the latest updates. 40 | 41 | # Community Item 42 | header-about-item = About 43 | 44 | # CTA 45 | header-cta-button-text = Contribute 46 | -------------------------------------------------------------------------------- /l10n/en-GB/marketing/browser/LandingIntroBlock.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | browser-landing-intro-block-title = 6 | A safer way to 7 | surf the web. 8 | 9 | browser-landing-intro-block-description = 10 | A next-generation web browser with rugged 11 | privacy features out-of-the-box. 12 | 13 | browser-landing-intro-block-cta-btn-text = Coming soon -------------------------------------------------------------------------------- /l10n/en-GB/marketing/sponsors-block.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | sponsors-block-title = Our sponsors 6 | sponsors-block-subtitle = The following organisations have generously provided their support to us: 7 | 8 | sponsors-block-item-tuta-name = Tuta 9 | sponsors-block-item-tuta-description = Providing email services -------------------------------------------------------------------------------- /l10n/en-GB/meta.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | -language-full-name = English (United Kingdom) 6 | -language-short-name = English (UK) 7 | -language-short-code = UK 8 | 9 | language-select-format = { $percent -> 10 | [100] { $name } 11 | *[other] { $name } - { $percent }% 12 | } 13 | 14 | language-not-localised = 15 | This language is only { $percent }% translated. 16 | Some parts of the page will appear in { $fallback-lang }. 17 | 18 | Contribute to { -language-short-name } 19 | 20 | page-title-format = { $title } ― { -brand-full-name } ({ -language-short-code }) -------------------------------------------------------------------------------- /l10n/en-GB/pages/about/third-party-licenses.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-third-party-licenses-title = Third-party licences 6 | page-third-party-licenses-subtitle = 7 | Dot HQ would like to thank everyone involved with the 8 | creation and development of the following 9 | libraries and software. 10 | 11 | page-third-party-licenses-description = 12 | Third-party licences of open-source software we 13 | depend on across all Dot products and services. 14 | 15 | page-third-party-licenses-reached-bottom = 16 | You've reached the bottom, go back to the top? -------------------------------------------------------------------------------- /l10n/en-GB/pages/donate.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-donate-title = Donate 6 | page-donate-description = Help support us and our mission by contributing financially. -------------------------------------------------------------------------------- /l10n/en-GB/pages/index.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-index-title = Privacy for all 6 | page-index-description = At Dot HQ, we're committed to defending and advocating for online privacy through our flagship products and services, like Dot Browser. -------------------------------------------------------------------------------- /l10n/en-US/README.md: -------------------------------------------------------------------------------- 1 | # English (United States) 2 | 3 | This language is a stub language and should not be edited. 4 | 5 | Instead, you should edit the base en-GB language as all locale data is generated and British-spellings are converted to their Americanized forms. 6 | -------------------------------------------------------------------------------- /l10n/en-US/overrides.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | -language-full-name = English (United States) 6 | -language-short-name = English (US) 7 | -language-short-code = US -------------------------------------------------------------------------------- /l10n/es-ES/a11y.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | a11y-skip-to-content = Saltar al contenido 6 | a11y-skip-to-end = Saltar al final 7 | -------------------------------------------------------------------------------- /l10n/es-ES/brand.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | -brand-full-name = Dot HQ 6 | -brand-short-name = Dot 7 | 8 | -brand-browser-short-text = Navegador 9 | -brand-browser-long-text = Dot Browser 10 | -brand-browser-desktop-short-text = Dot Browser (Desktop) 11 | -brand-browser-android-short-text = Dot Browser (Android) 12 | -brand-browser-desktop-long-text = Dot Browser para Desktop 13 | -brand-browser-android-long-text = Dot Browser para Android 14 | 15 | -brand-translate-short-text = Translate 16 | -brand-translate-long-text = Dot Translate 17 | 18 | -brand-one-short-text = One 19 | -brand-one-long-text = Dot One 20 | 21 | -brand-shield-short-text = Shield 22 | -brand-shield-long-text = Dot Shield 23 | 24 | -brand-windows = Windows 25 | -brand-macos = macOS 26 | -brand-linux = Linux 27 | -brand-ubuntu = Ubuntu 28 | -brand-fedora = Fedora 29 | -brand-arch-linux = Arch Linux 30 | -brand-android = Android -------------------------------------------------------------------------------- /l10n/es-ES/domain-migration.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | domain-migration-banner = ¡Hemos movido dominios de dothq.co a dothq.org! Bienvenido de nuevo. -------------------------------------------------------------------------------- /l10n/es-ES/errors/404.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | error-not-found-page-title = 404: Pagina no encontrada 6 | 7 | error-not-found-title = Lo sentimos, no podemos encontrar esa página. 8 | error-not-found-subtitle = Comprueba la dirección y vuelve a intentarlo. -------------------------------------------------------------------------------- /l10n/es-ES/footer.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | # Products 6 | 7 | footer-products-section = Productos 8 | 9 | footer-products-section-browser = { -brand-browser-short-text } 10 | footer-products-section-translate = { -brand-translate-short-text } 11 | footer-products-section-one = { -brand-one-short-text } 12 | footer-products-section-shield = { -brand-shield-short-text } 13 | 14 | # Community 15 | 16 | footer-community-section = Comunidad 17 | 18 | footer-community-section-contribute = Contribuir 19 | footer-community-section-donate = Donar 20 | footer-community-section-blog = Blog 21 | 22 | # Support 23 | 24 | footer-support-section = Apoyo 25 | 26 | footer-support-section-get-help = Consigue ayuda 27 | footer-support-section-bugs = Bugs 28 | footer-support-section-ideas = Ideas 29 | 30 | # Resources 31 | 32 | footer-resources-section = Recursos 33 | 34 | footer-resources-section-branding = Marca 35 | footer-resources-section-developers = Desarrolladores 36 | footer-resources-section-open-source = Fuente abierta 37 | 38 | # About 39 | 40 | footer-about-section = Sobre 41 | 42 | footer-about-section-us = { -brand-full-name } 43 | footer-about-section-privacy = Privacidad 44 | footer-about-section-terms = Términos 45 | footer-about-section-environment = Medio ambiente 46 | footer-about-section-charter = Carta 47 | footer-about-section-third-party-licences = Licencias de terceros 48 | 49 | # Socials 50 | 51 | footer-socials-section = Síguenos 52 | 53 | # Language Switcher 54 | 55 | footer-language-section = Idioma 56 | footer-language-switcher-initial-prompt = Selecciona un idioma 57 | 58 | footer-view-source = Ver fuente de página 59 | footer-edit-page = Edita esta página 60 | 61 | footer-copyright-text = 62 | © 2019–{ $year } { -brand-full-name }. 63 | El contenido de esta página está licenciado bajo la licencia CC BY-SA 4.0. -------------------------------------------------------------------------------- /l10n/es-ES/header.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | # Browser Item 6 | header-browser-item = { -brand-browser-short-text } 7 | header-browser-item-desktop-title = { -brand-browser-desktop-long-text } 8 | header-browser-item-desktop-subtitle = Obtenga el navegador web que proteja su privacidad para { -brand-windows }, { -brand-macos } y { -brand-linux }. 9 | header-browser-item-android-title = { -brand-browser-android-long-text } 10 | header-browser-item-android-subtitle = Obtenga el navegador web que proteja su privacidad en su teléfono { -brand-android }. 11 | 12 | # Products Item 13 | header-products-item = Productos 14 | 15 | header-products-item-translate-title = { -brand-translate-long-text } 16 | header-products-item-translate-subtitle = Un servicio de traducción rápido con cientos de idiomas - todo construido sin comprometer la privacidad. 17 | 18 | header-products-item-one-title = { -brand-one-long-text } 19 | header-products-item-one-subtitle = El sistema de cuentas y sincronización de próxima generación que se mantiene seguro. 20 | 21 | header-products-item-shield-title = { -brand-shield-long-text } 22 | header-products-item-shield-subtitle = Nuestro poderoso y liviano escudo de bloqueo de anuncios que no bloqueará los recursos de su sistema. 23 | 24 | header-products-item-view-all-link = Ver todos los productos 25 | 26 | # Community Item 27 | header-community-item = Comunidad 28 | 29 | # Community Item 30 | header-about-item = Sobre 31 | 32 | # CTA 33 | header-cta-button-text = Contribuir 34 | -------------------------------------------------------------------------------- /l10n/es-ES/marketing/browser/LandingIntroBlock.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | browser-landing-intro-block-title = 6 | Una forma más segura de 7 | explorar la web. 8 | 9 | browser-landing-intro-block-description = 10 | Un navegador web de próxima generación 11 | con características de privacidad robustas. 12 | 13 | browser-landing-intro-block-cta-btn-text = Próximamente -------------------------------------------------------------------------------- /l10n/es-ES/marketing/sponsors-block.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | sponsors-block-title = Nuestros patrocinadores 6 | sponsors-block-subtitle = Las siguientes organizaciones nos han brindado generosamente su apoyo: 7 | 8 | sponsors-block-item-tuta-name = Tuta 9 | sponsors-block-item-tuta-description = Brindando servicios de correo electrónico -------------------------------------------------------------------------------- /l10n/es-ES/meta.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | -language-full-name = Español (España) 6 | -language-short-name = Español (España) 7 | -language-short-code = ES 8 | 9 | language-select-format = { $percent -> 10 | [100] { $name } 11 | *[other] { $name } - { $percent }% 12 | } 13 | 14 | language-not-localised = 15 | Este idioma está solo del { $percent }% traducido. 16 | Algunas partes de la página aparecerán en { $fallback-lang }. 17 | 18 | Contribuir al { -language-short-name } 19 | 20 | page-title-format = { $title } ― { -brand-full-name } ({ -language-short-code }) -------------------------------------------------------------------------------- /l10n/es-ES/pages/about/third-party-licenses.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-third-party-licenses-title = Licencias de terceros 6 | page-third-party-licenses-subtitle = 7 | Dot HQ quisiera agradecer a todos los involucrados con el 8 | creación y desarrollo de los siguientes 9 | bibliotecas y software. 10 | 11 | page-third-party-licenses-description = 12 | Licencias de software open source de terceros que 13 | dependemos en todos los productos y servicios de Dot. 14 | 15 | page-third-party-licenses-reached-bottom = 16 | Has llegado al final de la página, ¿volver a la parte superior? -------------------------------------------------------------------------------- /l10n/es-ES/pages/donate.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-donate-title = Donar 6 | page-donate-description = Apóyanos a nosotros y a nuestra misión contribuyendo financieramente. -------------------------------------------------------------------------------- /l10n/es-ES/pages/index.ftl: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | page-index-title = Privacidad para todos 6 | page-index-description = En Dot HQ, nos comprometemos a defender y promover la privacidad a través de nuestros productos y servicios emblemáticos, como Dot Browser. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scalar", 3 | "version": "0.0.0", 4 | "description": "Dot HQ Website", 5 | "main": "app/main.ts", 6 | "repository": "https://github.com/dothq/scalar.git", 7 | "author": "Dot HQ ", 8 | "license": "MPL-2.0", 9 | "private": true, 10 | "scripts": { 11 | "start": "node --enable-source-maps .scalar/main.js", 12 | "build": "node scripts/build", 13 | "dev": "cross-env NODE_ENV=develop yarn build && cross-env NODE_ENV=develop yarn start", 14 | "watch": "nodemon -e js,ts,tsx,scss,ftl,yml --exec \"yarn dev\"", 15 | "generate:l10n": "node scripts/l10n", 16 | "test:firefox": "BROWSER=firefox jest --detectOpenHandles", 17 | "test:chrome": "BROWSER=chrome jest --detectOpenHandles", 18 | "test": "yarn test:firefox && yarn test:chrome" 19 | }, 20 | "dependencies": { 21 | "@dothq/id": "^1.0.1", 22 | "@fastify/compress": "^6.2.0", 23 | "@fastify/cookie": "^8.3.0", 24 | "@fastify/error": "^3.0.0", 25 | "@fastify/formbody": "^7.3.0", 26 | "@fastify/static": "^6.5.0", 27 | "@fluent/bundle": "^0.17.1", 28 | "@fluent/langneg": "^0.6.2", 29 | "@fluent/sequence": "^0.7.0", 30 | "@fluent/syntax": "^0.18.1", 31 | "american-british-english-translator": "^0.2.1", 32 | "axios": "^1.1.3", 33 | "clsx": "^1.2.1", 34 | "dotenv": "^16.0.3", 35 | "ejs": "^3.1.8", 36 | "extract-stack": "^3.0.0", 37 | "fastify": "^4.9.2", 38 | "glob": "^8.0.3", 39 | "image-size": "^1.0.2", 40 | "intl-parse-accept-language": "^1.0.0", 41 | "node-html-parser": "^6.1.1", 42 | "object-traversal": "^1.0.1", 43 | "preact": "^10.11.2", 44 | "preact-render-to-string": "^5.2.6", 45 | "prettier": "^3.0.0", 46 | "stripe": "^10.15.0", 47 | "ua-parser-js": "^0.7.33", 48 | "yaml": "^2.1.3" 49 | }, 50 | "devDependencies": { 51 | "@types/ejs": "^3.1.1", 52 | "@types/glob": "^8.0.0", 53 | "@types/jest": "^29.5.3", 54 | "@types/node": "^18.11.7", 55 | "@types/tcp-port-used": "^1.0.1", 56 | "@types/ua-parser-js": "^0.7.36", 57 | "broken-link-checker": "^0.7.8", 58 | "chalk": "^5.1.2", 59 | "compare-versions": "^6.0.0", 60 | "concurrently": "^8.2.0", 61 | "cross-env": "^7.0.3", 62 | "esbuild": "^0.15.12", 63 | "fs-extra": "^10.1.0", 64 | "html-prettify": "^1.0.7", 65 | "jest": "^29.6.1", 66 | "locate-app": "^2.0.0", 67 | "nodemon": "^2.0.22", 68 | "puppeteer": "^20.9.0", 69 | "rimraf": "^3.0.2", 70 | "sass": "^1.55.0", 71 | "tcp-port-used": "^1.0.2", 72 | "ts-jest": "^29.1.1", 73 | "typescript": "^4.8.4" 74 | } 75 | } -------------------------------------------------------------------------------- /public/.well-known/keys/dothq_code_signing.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mDMEYx+XbhYJKwYBBAHaRw8BAQdAS/xmp8rzrDkOqWZJ/x7zEtN95Ld3eFPXx7M0 4 | FXTMV120MERvdCBIUSBDb2RlIFNpZ25pbmcgPGNvbnRhY3QrY29kZXNpZ25AZG90 5 | aHEub3JnPoiaBBMWCgBCFiEEKsIYiw/QAqDNL1n+Kzj53DU/PcAFAmMfl24CGwMF 6 | CQHhM4AFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJECs4+dw1Pz3AamwB 7 | AP7CH307cu+sDvOK6offe3pF/z0Yxgjet+IBGXKTFk9bAQCb8tWpDN2jBA7aHHIi 8 | niKxxlmy6fz0as9yFRL2ztqiCLg4BGMfl24SCisGAQQBl1UBBQEBB0AkB3UEqUi8 9 | e2je8VGkjuuhYOrmG2jdMnjceKR78mSSUAMBCAeIfgQYFgoAJhYhBCrCGIsP0AKg 10 | zS9Z/is4+dw1Pz3ABQJjH5duAhsMBQkB4TOAAAoJECs4+dw1Pz3AYpsBAOnnCqAu 11 | obyEYTtRB5Tv+qLVIR9TMaG0COiI0/5H5uXHAQDjWYrq9ZZBoMfdywKklYgSjde/ 12 | +89ZePbROLMNcCaSAg== 13 | =b2bt 14 | -----END PGP PUBLIC KEY BLOCK----- 15 | -------------------------------------------------------------------------------- /public/.well-known/keys/dothq_general.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mDMEYxtqehYJKwYBBAHaRw8BAQdAZss0JeyHH0TnEj1XRt2KHR0nC846CvuTiE5F 4 | 5HqUVcK0HkRvdCBIUSA8Y29udGFjdCtwZ3BAZG90aHEub3JnPoiaBBMWCgBCFiEE 5 | DOvjEyvyecgcOyhRWMFBfUQ0G3IFAmMbanoCGwMFCQHhM4AFCwkIBwIDIgIBBhUK 6 | CQgLAgQWAgMBAh4HAheAAAoJEFjBQX1ENBty39wBAMNdlA7xeoK0rdIsMairjAyk 7 | SYpwtqWMZE9GdMt0XCtpAQDq3m46W4x+oFNP2EaiOczFqJfdRvDnKmrW/EuNKPEd 8 | A7g4BGMbanoSCisGAQQBl1UBBQEBB0DZIy/mVVjrcU+nu+EU2vKwgeScay72Mkzr 9 | r+zS76OcaQMBCAeIfgQYFgoAJhYhBAzr4xMr8nnIHDsoUVjBQX1ENBtyBQJjG2p6 10 | AhsMBQkB4TOAAAoJEFjBQX1ENBtywO0A/ivy+JVy/j/2arDv1AY9N/Sz0nrBGCvM 11 | EgU9m90bdvW8APwPQcjRvF3LmUqPyauxlC4zqif4stRoYnXd/StokZrIBQ== 12 | =BB5B 13 | -----END PGP PUBLIC KEY BLOCK----- 14 | -------------------------------------------------------------------------------- /public/.well-known/security.txt: -------------------------------------------------------------------------------- 1 | Contact: https://www.dothq.org/security 2 | 3 | Acknowledgments: https://www.dothq.org/security/thanks 4 | 5 | Canonical: https://www.dothq.org/.well-known/security.txt 6 | 7 | Preferred-Languages: en 8 | Expires: 2024-01-01T15:00:00.000Z -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/favicon.png -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Black.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Black.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-BlackItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-BlackItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Bold.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Bold.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-BoldItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraBold.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraBold.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraLight.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraLight.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraLightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraLightItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Italic.var.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Italic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Italic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Light.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Light.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-LightItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-LightItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Medium.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Medium.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-MediumItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-MediumItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Regular.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Regular.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-SemiBold.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-SemiBoldItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Thin.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-Thin.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ThinItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-ThinItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /public/media/fonts/inter/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/inter/Inter.var.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Black.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Black.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-BlackItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-BlackItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Bold.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Bold.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-BoldItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Italic.var.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Italic.var.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Italic.var.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Italic.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Italic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Light.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Light.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-LightItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-LightItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Medium.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Medium.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-MediumItalic.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-MediumItalic.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Regular.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi-Regular.woff2 -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi.var.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi.var.woff -------------------------------------------------------------------------------- /public/media/fonts/satoshi/Satoshi.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/fonts/satoshi/Satoshi.var.woff2 -------------------------------------------------------------------------------- /public/media/icons/114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/114x114.png -------------------------------------------------------------------------------- /public/media/icons/120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/120x120.png -------------------------------------------------------------------------------- /public/media/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/128x128.png -------------------------------------------------------------------------------- /public/media/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/144x144.png -------------------------------------------------------------------------------- /public/media/icons/150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/150x150.png -------------------------------------------------------------------------------- /public/media/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/152x152.png -------------------------------------------------------------------------------- /public/media/icons/160x160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/160x160.png -------------------------------------------------------------------------------- /public/media/icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/16x16.png -------------------------------------------------------------------------------- /public/media/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/192x192.png -------------------------------------------------------------------------------- /public/media/icons/196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/196x196.png -------------------------------------------------------------------------------- /public/media/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/256x256.png -------------------------------------------------------------------------------- /public/media/icons/310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/310x150.png -------------------------------------------------------------------------------- /public/media/icons/310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/310x310.png -------------------------------------------------------------------------------- /public/media/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/32x32.png -------------------------------------------------------------------------------- /public/media/icons/36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/36x36.png -------------------------------------------------------------------------------- /public/media/icons/384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/384x384.png -------------------------------------------------------------------------------- /public/media/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/48x48.png -------------------------------------------------------------------------------- /public/media/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/512x512.png -------------------------------------------------------------------------------- /public/media/icons/57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/57x57.png -------------------------------------------------------------------------------- /public/media/icons/70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/70x70.png -------------------------------------------------------------------------------- /public/media/icons/72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/72x72.png -------------------------------------------------------------------------------- /public/media/icons/76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/76x76.png -------------------------------------------------------------------------------- /public/media/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/icons/96x96.png -------------------------------------------------------------------------------- /public/media/icons/ui/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/media/images/dothq_colour_space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/dothq_colour_space.jpg -------------------------------------------------------------------------------- /public/media/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/logo.jpg -------------------------------------------------------------------------------- /public/media/images/logo@small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/logo@small.jpg -------------------------------------------------------------------------------- /public/media/images/og/donate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/og/donate.jpg -------------------------------------------------------------------------------- /public/media/images/og/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/og/logo.jpg -------------------------------------------------------------------------------- /public/media/images/og/logo_with_browser_wireframe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dothq/scalar/3c225afd201f8b6fa82893894d1ec19206d7059a/public/media/images/og/logo_with_browser_wireframe.jpg -------------------------------------------------------------------------------- /public/media/images/sponsors/tuta_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/media/js/scalar.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | document.documentElement.classList.remove("no-js"); 6 | 7 | document 8 | .querySelector("#app-language-switcher select") 9 | .addEventListener("change", () => { 10 | document.querySelector("#app-language-switcher").submit(); 11 | }); 12 | 13 | document.addEventListener("scroll", () => { 14 | document.documentElement.classList.toggle( 15 | "header-scroll-threshold", 16 | window.scrollY >= 100 17 | ); 18 | }); 19 | 20 | const updateLanguageSwitcherGoURL = () => { 21 | document.forms["app-language-switcher"].elements.go.value = 22 | "/" + window.location.pathname.split("/").splice(2).join("/") + window.location.search + window.location.hash 23 | } 24 | 25 | updateLanguageSwitcherGoURL(); 26 | 27 | window.addEventListener("hashchange", () => { 28 | updateLanguageSwitcherGoURL(); 29 | }) -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * -------------------------------------------------------------------------------- /scripts/inject-vars.js: -------------------------------------------------------------------------------- 1 | process.env = { 2 | ...process.env, 3 | SCALAR_GIT_REVISION: SCALAR_GIT_REVISION, 4 | SCALAR_GIT_REMOTE: SCALAR_GIT_REMOTE, 5 | SCALAR_GIT_BRANCH: SCALAR_GIT_BRANCH, 6 | SCALAR_GIT_DEFAULT_BRANCH: SCALAR_GIT_DEFAULT_BRANCH 7 | } -------------------------------------------------------------------------------- /scripts/rebuild_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | docker compose build 6 | docker compose up -d -------------------------------------------------------------------------------- /scripts/renew_certificates_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | docker exec -it certbot certbot renew 6 | docker compose down 7 | docker compose up -d -------------------------------------------------------------------------------- /tests/renders-landing-page.test.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Runner, createRunner } from "./utils"; 6 | 7 | let runner: Runner; 8 | 9 | beforeAll(async () => { 10 | runner = await createRunner(); 11 | }, 20000); 12 | 13 | test("renders landing page", async () => { 14 | await runner.page.waitForSelector("#main-content"); 15 | 16 | const title = await runner.page.$eval( 17 | "#main-content > section:first-of-type .fdn-hero-body h1", 18 | (e) => e.innerText?.trim().replace(/\n/g, " ") 19 | ); 20 | expect(title).toBe("A safer way to surf the web."); 21 | }); 22 | 23 | afterAll(async () => { 24 | await runner.browser.close(); 25 | }); 26 | -------------------------------------------------------------------------------- /tests/utils.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | import { locateApp, locateChrome, locateFirefox } from "locate-app"; 6 | import puppeteer, { Browser, Page, Product } from "puppeteer"; 7 | import { check } from "tcp-port-used"; 8 | 9 | export interface Runner { 10 | page: Page; 11 | browser: Browser; 12 | } 13 | 14 | const browsers: any = { 15 | // For Firefox, we want to see if Nightly is installed also 16 | firefox: async () => { 17 | try { 18 | return await locateFirefox(); 19 | } catch (e) { 20 | try { 21 | return await locateApp({ 22 | appName: "Firefox Nightly", 23 | linuxWhich: "firefox-nightly", 24 | windowsSuffix: "\\Mozilla Firefox\\firefox.exe", 25 | macOsName: "Firefox Nightly" 26 | }); 27 | } catch (e) { 28 | throw e; 29 | } 30 | } 31 | }, 32 | chrome: locateChrome 33 | }; 34 | 35 | export const createRunner = async () => { 36 | if (!((process.env.BROWSER as string) in browsers)) { 37 | throw new Error(`Unknown browser '${process.env.BROWSER}'`); 38 | } 39 | 40 | if (!(await check(3000))) { 41 | throw new Error(`Server needs to be running first!`); 42 | } 43 | 44 | const executablePath = await browsers[ 45 | process.env.BROWSER as string 46 | ](); 47 | 48 | const browser = await puppeteer.launch({ 49 | headless: process.env.BROWSER == "chrome" ? "new" : true, 50 | product: process.env.BROWSER as Product, 51 | executablePath 52 | }); 53 | 54 | const page = await browser.newPage(); 55 | await page.goto("http://localhost:3000/"); 56 | 57 | return { 58 | page, 59 | browser 60 | }; 61 | }; 62 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "jsx": "react-jsx", 10 | "jsxImportSource": "preact" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ui/blocks/browser-landing-intro-block.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @media (max-width: 1160px) { 6 | .block-browser-landing-intro-block { 7 | --padding-y: 3.75rem !important; 8 | } 9 | 10 | .block-browser-landing-intro-block 11 | .fdn-hero-body 12 | .fdn-page-constrain 13 | > .fdn-stack { 14 | flex-direction: column; 15 | 16 | & > .fdn-stack { 17 | --x: center; 18 | text-align: center; 19 | } 20 | 21 | & > .fdn-stack:last-of-type p.text-right { 22 | text-align: center; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ui/blocks/sponsors-block.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .sponsor-item { 6 | max-width: 250px; 7 | align-items: flex-start; 8 | flex-direction: column; 9 | --spacing-y: 0 !important; 10 | --spacing-x: 0 !important; 11 | --max-height: unset !important; 12 | --border-radii: 4px !important; 13 | gap: 1rem; 14 | } 15 | 16 | .sponsor-item img { 17 | max-width: 200px; 18 | } 19 | -------------------------------------------------------------------------------- /ui/foundation/components/aside/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-aside { 6 | display: flex; 7 | flex-direction: column; 8 | height: 100%; 9 | background-color: var(--fdn-colours-white); 10 | } 11 | -------------------------------------------------------------------------------- /ui/foundation/components/banner/helpers.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* Types */ 6 | 7 | .fdn-banner.info { 8 | --bg-colour: var(--fdn-info-colour); 9 | --text-colour: var(--fdn-colours-white); 10 | --link-colour: var(--fdn-colours-white); 11 | } 12 | 13 | .fdn-banner.warn { 14 | --bg-colour: repeating-linear-gradient( 15 | -45deg, 16 | rgba(0, 0, 0, 0.05), 17 | rgba(0, 0, 0, 0.05) 20px, 18 | var(--fdn-warn-colour) 20px, 19 | var(--fdn-warn-colour) 40px 20 | ), 21 | var(--fdn-warn-colour); 22 | --text-colour: var(--fdn-colours-black); 23 | --link-colour: var(--fdn-colours-black); 24 | } 25 | 26 | .fdn-banner.error { 27 | --bg-colour: var(--fdn-error-colour); 28 | --text-colour: var(--fdn-colours-white); 29 | --link-colour: var(--fdn-colours-white); 30 | } 31 | 32 | .fdn-banner.success { 33 | --bg-colour: var(--fdn-success-colour); 34 | --text-colour: var(--fdn-colours-white); 35 | --link-colour: var(--fdn-colours-white); 36 | } 37 | 38 | /* Sizes */ 39 | 40 | .fdn-banner.sm { 41 | --padding: 1.25rem; 42 | } 43 | 44 | .fdn-banner.md { 45 | --padding: 2rem; 46 | } 47 | 48 | .fdn-banner.lg { 49 | --padding: 4rem; 50 | } 51 | 52 | .fdn-banner.fw { 53 | --padding: 2rem; 54 | } 55 | -------------------------------------------------------------------------------- /ui/foundation/components/banner/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "helpers"; 6 | 7 | .fdn-banner { 8 | display: flex; 9 | align-items: flex-start; 10 | justify-content: center; 11 | flex-direction: row; 12 | background: var(--bg-colour, var(--fdn-colours-gray-secondary)); 13 | color: var(--text-colour, var(--fdn-colours-black)); 14 | padding: var(--padding); 15 | gap: 1.5rem; 16 | border-radius: var(--border-radius, 1rem); 17 | } 18 | 19 | .fdn-banner p { 20 | display: flex; 21 | align-items: center; 22 | min-height: var(--padding); 23 | color: inherit; 24 | flex: 1; 25 | } 26 | 27 | .fdn-banner a:not(.fdn-button) { 28 | color: var(--link-colour, var(--fdn-colours-link)); 29 | } 30 | 31 | @media (min-width: 15rem) { 32 | .fdn-banner.full-width { 33 | --padding: 0 2rem; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ui/foundation/components/browser-wireframe.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-browser-wireframe { 6 | max-width: 1280px; 7 | width: 100%; 8 | height: 100%; 9 | } 10 | -------------------------------------------------------------------------------- /ui/foundation/components/button/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "helpers"; 6 | 7 | :root { 8 | --default-btn-spacing-x: 1.25rem; 9 | --default-btn-spacing-y: 0.8rem; 10 | --default-btn-font-size: 1rem; 11 | } 12 | 13 | .fdn-button { 14 | --btn-spacing-x: var(--spacing-x, var(--default-btn-spacing-x)); 15 | --btn-spacing-y: var(--spacing-y, var(--default-btn-spacing-y)); 16 | --btn-font-size: var(--font-size, var(--default-btn-font-size)); 17 | 18 | display: flex; 19 | width: fit-content; 20 | gap: 0.5rem; 21 | 22 | align-items: center; 23 | justify-content: center; 24 | 25 | position: relative; 26 | 27 | padding-inline-start: var(--btn-spacing-x); 28 | padding-inline-end: var(--btn-spacing-x); 29 | padding-block-start: var(--btn-spacing-y); 30 | padding-block-end: var(--btn-spacing-y); 31 | 32 | font-size: var(--btn-font-size); 33 | font-weight: 600; 34 | 35 | background-color: var(--bg-colour); 36 | color: var(--text-colour); 37 | border: 2px solid var(--border-colour, var(--bg-colour)); 38 | 39 | border-radius: var(--border-radii, 1rem); 40 | 41 | text-decoration: none; 42 | 43 | transition: 0.2s background-color ease, 0.2s color ease, 44 | 0.2s border ease; 45 | 46 | max-height: var(--max-height); 47 | } 48 | 49 | .fdn-button:hover, 50 | .fdn-button:active { 51 | background-color: var(--bg-action-colour, transparent); 52 | color: var(--text-hover-colour, var(--bg-colour)); 53 | } 54 | 55 | .fdn-button::before { 56 | content: ""; 57 | 58 | position: absolute; 59 | inset: 0px; 60 | 61 | width: 100%; 62 | height: 100%; 63 | 64 | background-color: var( 65 | --bg-before-colour, 66 | var(--bg-action-colour, var(--bg-colour)) 67 | ); 68 | 69 | border-radius: calc(1rem - 4px); 70 | 71 | transition: opacity 0.05s linear 0s; 72 | 73 | opacity: 0; 74 | } 75 | 76 | .fdn-button:active::before { 77 | opacity: var(--bg-active-colour-intensity, 0.1); 78 | } 79 | 80 | :root:not(.no-js) .fdn-button.no-js, 81 | :root.no-js .fdn-button.no-js + .fdn-button:not(.no-js) { 82 | display: none; 83 | } 84 | 85 | .fdn-button[disabled] { 86 | opacity: 0.5; 87 | pointer-events: none; 88 | } 89 | -------------------------------------------------------------------------------- /ui/foundation/components/card/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-card { 6 | display: flex; 7 | background-color: var(--fdn-colours-white); 8 | border-radius: 1rem; 9 | flex-direction: column; 10 | height: fit-content; 11 | } 12 | 13 | .fdn-card-header, 14 | .fdn-card-footer { 15 | display: flex; 16 | padding: 2.375rem; 17 | gap: 1.5rem; 18 | } 19 | 20 | .fdn-card-container { 21 | padding: 0 2.375rem; 22 | } 23 | -------------------------------------------------------------------------------- /ui/foundation/components/code/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-code { 6 | background-color: var(--fdn-bg-default); 7 | border-radius: 0.5rem; 8 | padding: 2.25rem; 9 | width: 100%; 10 | max-height: 500px; 11 | overflow: scroll; 12 | mask-image: linear-gradient(black 90%, #0000 100%); 13 | } 14 | 15 | .fdn-code pre { 16 | display: flex; 17 | flex-direction: column; 18 | } 19 | 20 | .fdn-code pre span { 21 | display: block; 22 | line-height: 1.5rem; 23 | counter-increment: ln; 24 | } 25 | 26 | .fdn-code pre span::before { 27 | content: counter(ln); 28 | margin-inline-end: 2rem; 29 | display: inline-block; 30 | width: 1.5rem; 31 | text-align: right; 32 | opacity: 0.5; 33 | } 34 | -------------------------------------------------------------------------------- /ui/foundation/components/domain-migration.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .domain-migration-banner .fdn-p { 6 | text-align: center; 7 | justify-content: center; 8 | } 9 | -------------------------------------------------------------------------------- /ui/foundation/components/error.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-error-container { 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: center; 9 | align-items: center; 10 | gap: 0.5rem; 11 | height: 50rem; 12 | } 13 | -------------------------------------------------------------------------------- /ui/foundation/components/flex/helpers.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* Orientation */ 6 | 7 | .fdn-stack.h, 8 | .fdn-stack.horiz, 9 | .fdn-stack.horizontal { 10 | display: flex; 11 | flex-direction: row; 12 | } 13 | 14 | .fdn-stack.v, 15 | .fdn-stack.vert, 16 | .fdn-stack.vertical { 17 | display: flex; 18 | flex-direction: column; 19 | } 20 | 21 | /* Flex */ 22 | 23 | .fdn-stack.flex-1 { 24 | flex: 1; 25 | } 26 | 27 | /* Gap */ 28 | 29 | .fdn-stack.gap-sm { 30 | gap: 0.5rem; 31 | } 32 | 33 | .fdn-stack.gap-md { 34 | gap: 1rem; 35 | } 36 | 37 | .fdn-stack.gap-lg { 38 | gap: 1.5rem; 39 | } 40 | 41 | .fdn-stack.gap-xl { 42 | gap: 2.5rem; 43 | } 44 | 45 | .fdn-stack.gap-xxl { 46 | gap: 4rem; 47 | } 48 | 49 | .fdn-stack.gap-xxxl { 50 | gap: 6rem; 51 | } 52 | 53 | .fdn-stack.gap-4xl { 54 | gap: 8rem; 55 | } 56 | 57 | /* X axis */ 58 | 59 | .fdn-stack.x-start, 60 | .fdn-stack.x-flex-start { 61 | --x: flex-start; 62 | } 63 | 64 | .fdn-stack.x-center { 65 | --x: center; 66 | } 67 | 68 | .fdn-stack.x-end, 69 | .fdn-stack.x-flex-end { 70 | --x: flex-end; 71 | } 72 | 73 | .fdn-stack.x-between, 74 | .fdn-stack.x-space-between { 75 | --x: space-between; 76 | } 77 | 78 | /* Y axis */ 79 | 80 | .fdn-stack.y-start, 81 | .fdn-stack.y-flex-start { 82 | --y: flex-start; 83 | } 84 | 85 | .fdn-stack.y-center { 86 | --y: center; 87 | } 88 | 89 | .fdn-stack.y-end, 90 | .fdn-stack.y-flex-end { 91 | --y: flex-end; 92 | } 93 | 94 | .fdn-stack.y-between, 95 | .fdn-stack.y-space-between { 96 | --y: space-between; 97 | } 98 | 99 | /* Sizing */ 100 | 101 | .fdn-stack.w-full { 102 | width: 100%; 103 | } 104 | 105 | .fdn-stack.h-full { 106 | height: 100%; 107 | } 108 | 109 | /* Wrap */ 110 | 111 | .fdn-stack.wrap { 112 | flex-wrap: wrap; 113 | } 114 | -------------------------------------------------------------------------------- /ui/foundation/components/flex/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "helpers"; 6 | 7 | .fdn-stack { 8 | display: flex; 9 | } 10 | 11 | .fdn-stack.v { 12 | align-items: var(--x); 13 | justify-content: var(--y); 14 | } 15 | 16 | .fdn-stack.h { 17 | align-items: var(--y); 18 | justify-content: var(--x); 19 | } 20 | -------------------------------------------------------------------------------- /ui/foundation/components/footer/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "logo"; 6 | @use "items"; 7 | @use "subfooter"; 8 | 9 | .fdn-footer { 10 | width: 100%; 11 | background-color: var(--fdn-colours-white); 12 | border-top: 1px solid var(--fdn-border-colour); 13 | padding: 0 0.5rem; 14 | } 15 | 16 | .fdn-footer-container { 17 | display: flex; 18 | flex-direction: column; 19 | gap: 4rem; 20 | margin: 0 auto; 21 | max-width: var(--fdn-content-width); 22 | padding: 4rem 0; 23 | } 24 | 25 | .fdn-footer-content { 26 | display: flex; 27 | justify-content: space-between; 28 | gap: 2rem; 29 | } 30 | 31 | @media (min-width: 25rem) { 32 | .fdn-footer { 33 | padding: 0 1rem; 34 | } 35 | } 36 | 37 | @media (min-width: 15rem) { 38 | .fdn-footer { 39 | padding: 0 2rem; 40 | } 41 | } 42 | 43 | @media (max-width: 52rem) { 44 | .fdn-footer-content { 45 | flex-direction: column; 46 | } 47 | } 48 | 49 | .fdn-footer-langage-switcher { 50 | display: flex; 51 | gap: 1rem; 52 | flex-direction: column; 53 | align-items: flex-end; 54 | } 55 | -------------------------------------------------------------------------------- /ui/foundation/components/footer/items.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-footer-item { 6 | display: flex; 7 | flex-wrap: wrap; 8 | justify-content: flex-end; 9 | gap: 2.5rem; 10 | } 11 | 12 | .fdn-footer-section { 13 | display: flex; 14 | flex-direction: column; 15 | gap: 1.15rem; 16 | min-width: 9.5rem; 17 | } 18 | 19 | .fdn-footer-section-list { 20 | display: flex; 21 | flex-direction: column; 22 | gap: 0.75rem; 23 | } 24 | 25 | .fdn-footer-section-title { 26 | color: var(--fdn-text-colour); 27 | font-weight: 700; 28 | } 29 | 30 | .fdn-footer-section-list-item { 31 | font-weight: 500; 32 | } 33 | 34 | .fdn-footer-section-list-item a { 35 | display: flex; 36 | color: var(--fdn-text-secondary-colour); 37 | text-decoration: none; 38 | transition: 0.2s color ease; 39 | } 40 | 41 | .fdn-footer-section-list-item a:hover, 42 | .fdn-footer-section-list-item a:focus { 43 | color: var(--fdn-colours-link); 44 | } 45 | 46 | @media (max-width: 52rem) { 47 | .fdn-footer-item { 48 | justify-content: flex-start; 49 | } 50 | } 51 | 52 | .fdn-footer-sitemap { 53 | flex: 2; 54 | } 55 | 56 | .fdn-footer-socials .fdn-footer-section-list { 57 | flex-direction: row; 58 | } 59 | -------------------------------------------------------------------------------- /ui/foundation/components/footer/logo.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-footer .fdn-footer-logo-container { 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: space-between; 9 | flex: 1; 10 | gap: 2rem; 11 | } 12 | 13 | .fdn-footer-extras-container { 14 | display: flex; 15 | flex-direction: column; 16 | align-items: flex-start; 17 | gap: 2rem; 18 | } 19 | 20 | .fdn-footer-extras-container .fdn-footer-section { 21 | width: 100%; 22 | } 23 | 24 | .fdn-footer .fdn-logo { 25 | width: 2.5rem; 26 | height: 2.5rem; 27 | } 28 | -------------------------------------------------------------------------------- /ui/foundation/components/footer/subfooter.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-footer-copying { 6 | font-weight: 500; 7 | line-height: 1.5; 8 | } 9 | 10 | .fdn-footer-editing { 11 | font-weight: 500; 12 | line-height: 1.5; 13 | } 14 | 15 | .fdn-footer-editing pre { 16 | text-align: right; 17 | font-size: 0.9rem; 18 | color: var(--fdn-text-secondary-colour); 19 | } 20 | 21 | .fdn-footer-editing .fdn-footer-editing-links { 22 | display: flex; 23 | justify-content: flex-end; 24 | gap: 1rem; 25 | } 26 | 27 | @media (max-width: 52rem) { 28 | .fdn-footer-copying { 29 | margin-block-end: 1.5rem; 30 | } 31 | 32 | .fdn-footer-editing pre { 33 | text-align: left; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ui/foundation/components/form/helpers.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* Sizes */ 6 | 7 | .fdn-field.sm { 8 | --font-size: 0.8rem; 9 | --max-height: 1.85rem; /* Calculated height from padding + font-sise */ 10 | } 11 | 12 | .fdn-field.md { 13 | --font-size: var(--default-btn-font-size); 14 | --max-height: 2.85rem; /* Calculated height from padding + font-sise */ 15 | } 16 | 17 | .fdn-field.lg { 18 | --font-size: 1.5rem; 19 | --max-height: 3.85rem; /* Calculated height from padding + font-sise */ 20 | } 21 | 22 | /* Has* */ 23 | 24 | .fdn-field.has-prefix .fdn-input .fdn-internal-input:not(select) { 25 | border-top-left-radius: 0; 26 | border-bottom-left-radius: 0; 27 | } 28 | 29 | .fdn-field.has-suffix .fdn-input .fdn-internal-input:not(select) { 30 | border-top-right-radius: 0; 31 | border-bottom-right-radius: 0; 32 | } 33 | 34 | .fdn-field:not(.has-prefix) .fdn-internal-input:not(select) { 35 | padding-inline-start: 1rem; 36 | } 37 | 38 | .fdn-field.has-error .fdn-input .fdn-internal-input { 39 | outline: 2px solid var(--fdn-error-colour); 40 | } 41 | 42 | .fdn-field.has-error .fdn-input-error { 43 | display: flex; 44 | visibility: visible; 45 | } 46 | 47 | /* Width */ 48 | 49 | .fdn-field.full-width { 50 | width: 100%; 51 | text-align: center; 52 | justify-content: center; 53 | } 54 | -------------------------------------------------------------------------------- /ui/foundation/components/form/input/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-input .fdn-internal-input { 6 | appearance: none; 7 | 8 | display: flex; 9 | width: 100%; 10 | height: 100%; 11 | flex: 1; 12 | 13 | margin: 0; 14 | padding-inline-start: var(--padding-start, 0.75rem); 15 | padding-inline-end: var(--padding-end, 0); 16 | 17 | background-color: transparent; 18 | color: var(--fdn-colours-black); 19 | 20 | font-family: inherit; 21 | font-size: var(--font-size); 22 | font-weight: 600; 23 | 24 | border-radius: 1rem; 25 | border: none; 26 | outline: none; 27 | 28 | --focus-outline-offset: 2px; 29 | transition: 0.05s outline ease; 30 | 31 | z-index: 1; 32 | 33 | position: relative; 34 | 35 | text-overflow: ellipsis; 36 | } 37 | -------------------------------------------------------------------------------- /ui/foundation/components/header/a11y.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-header-a11y { 6 | position: absolute; 7 | left: 0; 8 | right: 0; 9 | top: 6rem; 10 | z-index: 999999; 11 | } 12 | 13 | .fdn-header-a11y-link:focus { 14 | padding: 1rem; 15 | background-color: var(--fdn-colours-white); 16 | color: var(--fdn-colours-blue); 17 | position: relative; 18 | clip-path: none; 19 | clip: none; 20 | width: auto; 21 | height: auto; 22 | font-weight: 600; 23 | text-decoration: none; 24 | } 25 | -------------------------------------------------------------------------------- /ui/foundation/components/header/drawer.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-header-drawer { 6 | display: flex; 7 | justify-content: space-between; 8 | position: relative; 9 | height: inherit; 10 | overflow: hidden; 11 | transition: var(--drawer-animation-length) height; 12 | transition-timing-function: cubic-bezier(0.86, 0, 0.07, 1); 13 | padding: 0 0.5rem; 14 | box-shadow: 0px 1px 0px 0px var(--fdn-border-colour); 15 | } 16 | 17 | .fdn-header-drawer { 18 | height: 0px; 19 | outline: none; 20 | } 21 | 22 | @media (min-width: 52rem) { 23 | .fdn-header-drawer { 24 | display: none; 25 | } 26 | } 27 | 28 | .fdn-header-drawer:target { 29 | height: var(--drawer-height); 30 | scroll-margin-top: 4.5rem; 31 | overflow: visible; 32 | } 33 | 34 | .fdn-header-drawer-container { 35 | display: flex; 36 | width: 100%; 37 | } 38 | 39 | .fdn-header-drawer-container .fdn-header-items { 40 | flex-direction: column; 41 | align-items: flex-start; 42 | gap: 0; 43 | justify-content: flex-start; 44 | transition: 0s visibility var(--drawer-animation-length); 45 | visibility: hidden; 46 | overflow: hidden; 47 | } 48 | 49 | .fdn-header-drawer:target .fdn-header-items { 50 | transition: 0s visibility 0s; 51 | visibility: visible; 52 | } 53 | 54 | .fdn-header-drawer-container .fdn-header-items li { 55 | width: 100%; 56 | } 57 | 58 | .fdn-header-drawer-container .fdn-header-item { 59 | width: 100%; 60 | height: 4rem; 61 | align-items: center; 62 | justify-content: flex-start; 63 | text-align: left; 64 | --spacing-x: 0; 65 | } 66 | 67 | .fdn-header-drawer-container .fdn-header-item::after { 68 | content: none; 69 | } 70 | 71 | .fdn-header-drawer:target #menu-close { 72 | display: flex; 73 | position: absolute; 74 | right: var(--close-right, 0.5rem); 75 | top: calc(-4.5rem - 3px); 76 | } 77 | 78 | #menu-close { 79 | height: fit-content; 80 | margin-block-start: 1rem; 81 | display: none; 82 | background-color: var(--fdn-colours-white); 83 | } 84 | 85 | .fdn-header-drawer-container #donate-button { 86 | margin-block-start: 0.5rem; 87 | } 88 | -------------------------------------------------------------------------------- /ui/foundation/components/header/items.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-header-items { 6 | display: flex; 7 | align-items: center; 8 | justify-content: center; 9 | order: 0; 10 | flex: 1; 11 | width: 100%; 12 | } 13 | 14 | @media (max-width: 52rem) { 15 | .fdn-header-content .fdn-header-items { 16 | display: none; 17 | } 18 | } 19 | 20 | @media (max-width: 40rem) { 21 | .fdn-header-content .fdn-header-end > :not(#menu-button) { 22 | display: none; 23 | } 24 | } 25 | 26 | .fdn-header-item-container { 27 | display: flex; 28 | flex-direction: column; 29 | justify-content: center; 30 | align-items: center; 31 | } 32 | 33 | .fdn-header-item { 34 | align-items: center; 35 | height: 4.5rem; 36 | --border-radii: 0; 37 | --spacing-x: 1.25rem; 38 | --text-colour: var(--fdn-colours-black); 39 | --text-hover-colour: var(--fdn-colours-black); 40 | border-bottom: 2px solid transparent !important; 41 | } 42 | 43 | .fdn-header-content .fdn-header-item:hover, 44 | .fdn-header-content 45 | .fdn-header-item-container:hover 46 | .fdn-header-item { 47 | border-bottom: 2px solid currentColor !important; 48 | } 49 | 50 | .fdn-header-content 51 | .fdn-header-item:hover:not(:target) 52 | + .fdn-header-menu, 53 | .fdn-header-content 54 | .fdn-header-item:focus-within:not(:target) 55 | + .fdn-header-menu, 56 | .fdn-header-content .fdn-header-menu:hover, 57 | .fdn-header-content .fdn-header-menu:focus-within { 58 | --opacity: 1; 59 | --pointer-events: all; 60 | } 61 | 62 | .fdn-header-item:target { 63 | pointer-events: none; 64 | } 65 | -------------------------------------------------------------------------------- /ui/foundation/components/header/logo.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-header .fdn-logo svg { 6 | height: 2rem; 7 | width: auto; 8 | } 9 | 10 | .fdn-header .fdn-logo a { 11 | width: fit-content; 12 | } 13 | -------------------------------------------------------------------------------- /ui/foundation/components/header/menu.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-header-menu { 6 | position: absolute; 7 | top: 4.5rem; 8 | --visible: 0; 9 | --pointer-events: none; 10 | } 11 | 12 | .fdn-header-menu-item-content { 13 | display: flex; 14 | flex-direction: column; 15 | gap: 0.5rem; 16 | flex: 1; 17 | } 18 | 19 | .fdn-header-menu > .fdn-menu-container { 20 | width: 0; 21 | } 22 | -------------------------------------------------------------------------------- /ui/foundation/components/hero/helpers.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* Sizes */ 6 | 7 | .fdn-hero.sm { 8 | --padding-y: 1rem; 9 | } 10 | 11 | .fdn-hero.md { 12 | --padding-y: 2rem; 13 | } 14 | 15 | .fdn-hero.lg { 16 | --padding-y: 4rem; 17 | } 18 | 19 | .fdn-hero.xl { 20 | --padding-y: 8rem; 21 | } 22 | 23 | .fdn-hero.fh { 24 | --height: 100vh; 25 | } 26 | 27 | /* Colours */ 28 | 29 | .fdn-hero.red { 30 | --bg-colour: var(--fdn-colours-red); 31 | --text-colour: var(--fdn-colours-white); 32 | } 33 | 34 | .fdn-hero.orange { 35 | --bg-colour: var(--fdn-colours-orange); 36 | --text-colour: var(--fdn-colours-white); 37 | } 38 | 39 | .fdn-hero.yellow { 40 | --bg-colour: var(--fdn-colours-yellow); 41 | --text-colour: var(--fdn-colours-black); 42 | } 43 | 44 | .fdn-hero.green { 45 | --bg-colour: var(--fdn-colours-green); 46 | --text-colour: var(--fdn-colours-white); 47 | } 48 | 49 | .fdn-hero.blue { 50 | --bg-colour: var(--fdn-colours-blue); 51 | --text-colour: var(--fdn-colours-white); 52 | } 53 | 54 | .fdn-hero.purple { 55 | --bg-colour: var(--fdn-colours-purple); 56 | --text-colour: var(--fdn-colours-white); 57 | } 58 | 59 | .fdn-hero.pink { 60 | --bg-colour: var(--fdn-colours-pink); 61 | --text-colour: var(--fdn-colours-white); 62 | } 63 | 64 | .fdn-hero.black { 65 | --bg-colour: var(--fdn-colours-black); 66 | --text-colour: var(--fdn-colours-white); 67 | } 68 | 69 | .fdn-hero.white { 70 | --bg-colour: var(--fdn-colours-white); 71 | --text-colour: var(--fdn-colours-black); 72 | } 73 | 74 | /* States */ 75 | 76 | .fdn-hero.detatched { 77 | --hero-body-width: 100%; 78 | } 79 | -------------------------------------------------------------------------------- /ui/foundation/components/hero/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "helpers"; 6 | 7 | .fdn-hero { 8 | display: flex; 9 | flex-direction: column; 10 | justify-content: space-between; 11 | align-items: center; 12 | 13 | background-color: var(--bg-colour); 14 | color: var(--text-colour); 15 | 16 | height: var(--height); 17 | } 18 | 19 | .fdn-hero .fdn-hero-body { 20 | display: flex; 21 | flex-direction: column; 22 | justify-content: center; 23 | 24 | width: 100%; 25 | max-width: var(--hero-body-width, var(--fdn-content-width)); 26 | height: 100%; 27 | 28 | gap: 0.5rem; 29 | 30 | padding: var(--padding-y, 0) 0; 31 | } 32 | 33 | @media (min-width: 15rem) { 34 | .fdn-hero { 35 | padding: 0 2rem; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ui/foundation/components/icons.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-icon { 6 | display: flex; 7 | color: var(--bg-colour); 8 | } 9 | 10 | .fdn-icon.red { 11 | --bg-colour: var(--fdn-colours-red); 12 | } 13 | 14 | .fdn-icon.orange { 15 | --bg-colour: var(--fdn-colours-orange); 16 | } 17 | 18 | .fdn-icon.yellow { 19 | --bg-colour: var(--fdn-colours-yellow); 20 | } 21 | 22 | .fdn-icon.green { 23 | --bg-colour: var(--fdn-colours-green); 24 | } 25 | 26 | .fdn-icon.blue { 27 | --bg-colour: var(--fdn-colours-blue); 28 | } 29 | 30 | .fdn-icon.purple { 31 | --bg-colour: var(--fdn-colours-purple); 32 | } 33 | 34 | .fdn-icon.pink { 35 | --bg-colour: var(--fdn-colours-pink); 36 | } 37 | 38 | .fdn-icon.black { 39 | --bg-colour: var(--fdn-colours-black); 40 | } 41 | 42 | .fdn-icon.current-color { 43 | --bg-colour: currentColor; 44 | } 45 | 46 | .fdn-icon.fdn-icon-arrow-right-animated { 47 | .arrow-head { 48 | opacity: 0; 49 | transition: 0.2s opacity ease; 50 | } 51 | 52 | .arrow-arm { 53 | transform: translateX(-4px); 54 | transition: 0.2s transform ease; 55 | } 56 | } 57 | 58 | *:hover > .fdn-icon.fdn-icon-arrow-right-animated, 59 | .fdn-icon-arrow-right-animated-parent:hover 60 | .fdn-icon.fdn-icon-arrow-right-animated { 61 | .arrow-head { 62 | opacity: 1; 63 | } 64 | 65 | .arrow-arm { 66 | transform: translateX(0px); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ui/foundation/components/itemlist/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-item-list { 6 | display: flex; 7 | flex-direction: column; 8 | gap: 2px; 9 | border-radius: 1rem; 10 | overflow: hidden; 11 | background-color: var(--fdn-bg-default); 12 | } 13 | 14 | .fdn-item-list .fdn-list-item { 15 | display: flex; 16 | background-color: var(--fdn-colours-white); 17 | padding: 1.5rem; 18 | border-radius: 0.25rem; 19 | text-decoration: none; 20 | } 21 | -------------------------------------------------------------------------------- /ui/foundation/components/logo.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-logo { 6 | width: fit-content; 7 | color: var(--fdn-colours-black); 8 | } 9 | 10 | .fdn-logo a { 11 | color: var(--fdn-text-colour); 12 | display: flex; 13 | align-items: center; 14 | } 15 | -------------------------------------------------------------------------------- /ui/foundation/components/main.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "typography"; 6 | 7 | .fdn-main-content { 8 | display: flex; 9 | flex-direction: column; 10 | scroll-margin-top: 4.5rem; 11 | flex: 1; 12 | width: 100%; 13 | } 14 | 15 | .fdn-content > .fdn-content-container { 16 | padding: 0 0.5rem; 17 | max-width: var(--fdn-content-width); 18 | margin: 0 auto; 19 | } 20 | 21 | @media (min-width: 25rem) { 22 | .fdn-content > .fdn-content-container { 23 | padding: 0 1rem; 24 | } 25 | } 26 | 27 | @media (min-width: 15rem) { 28 | .fdn-content > .fdn-content-container { 29 | padding: 0 2rem; 30 | } 31 | } 32 | 33 | @media (min-width: 80rem) { 34 | .fdn-content > .fdn-content-container { 35 | max-width: 80rem; 36 | } 37 | } 38 | 39 | .text-left { 40 | text-align: left; 41 | } 42 | 43 | .text-center { 44 | text-align: center; 45 | } 46 | 47 | .text-right { 48 | text-align: right; 49 | } 50 | -------------------------------------------------------------------------------- /ui/foundation/components/menu/helpers.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* States */ 6 | 7 | .fdn-menu.has-arrow .fdn-menu-container { 8 | margin-top: 1rem; 9 | } 10 | -------------------------------------------------------------------------------- /ui/foundation/components/menu/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | @use "helpers"; 6 | @use "item"; 7 | 8 | .fdn-menu { 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | 14 | opacity: var(--opacity); 15 | pointer-events: var(--pointer-events); 16 | 17 | transition: 0.15s opacity; 18 | 19 | --opacity: 0; 20 | --pointer-events: none; 21 | } 22 | 23 | .fdn-menu-container { 24 | display: flex; 25 | gap: 0.25rem; 26 | flex-direction: column; 27 | 28 | max-width: min-content; 29 | min-width: fit-content; 30 | 31 | background-color: var(--fdn-colours-white); 32 | 33 | border: 1px solid var(--fdn-border-colour); 34 | border-radius: 1rem; 35 | 36 | box-shadow: 37 | 0 50px 100px -20px rgba(50, 50, 93, 0.25), 38 | 0 30px 60px -30px rgba(0, 0, 0, 0.3); 39 | 40 | padding: 1rem; 41 | 42 | margin-top: 1rem; 43 | } 44 | 45 | .fdn-menu-arrow { 46 | position: absolute; 47 | 48 | top: 0.5rem; 49 | left: calc(var(--arrow-position) - 0.5rem); 50 | 51 | color: var(--fdn-colours-white); 52 | 53 | filter: drop-shadow(1px 0px 0px var(--fdn-border-colour)) 54 | drop-shadow(-1px 0px 0px var(--fdn-border-colour)) 55 | drop-shadow(0px -0.5px 0px var(--fdn-border-colour)); 56 | 57 | margin-top: 0.0625rem; /* 1px */ 58 | } 59 | -------------------------------------------------------------------------------- /ui/foundation/components/menu/item.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* @todo use of !important here is not really a good idea */ 6 | .fdn-menu-item { 7 | --border-radii: 0.5rem; 8 | --max-height: auto !important; 9 | --spacing-y: var(--spacing-x) !important; 10 | min-width: 350px !important; 11 | justify-content: flex-start; 12 | gap: 1.25rem !important; 13 | align-items: flex-start; 14 | } 15 | 16 | .fdn-menu-link { 17 | font-weight: 500; 18 | width: fit-content; 19 | margin: 0 auto; 20 | margin-block: 1rem; 21 | } 22 | -------------------------------------------------------------------------------- /ui/foundation/components/tabs/index.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-tabs { 6 | display: flex; 7 | position: relative; 8 | 9 | .fdn-tab:hover { 10 | --tab-border-bottom: 2px solid var(--fdn-colours-gray); 11 | } 12 | 13 | .fdn-tab[disabled] { 14 | background-color: var(--fdn-colours-black-secondary); 15 | } 16 | } 17 | 18 | :root:not(.no-js) .fdn-tabs { 19 | input[type="radio"] { 20 | display: none; 21 | visibility: hidden; 22 | } 23 | } 24 | 25 | :root.no-js .fdn-tabs { 26 | flex-direction: column; 27 | 28 | input[type="radio"] { 29 | position: absolute; 30 | appearance: none; 31 | width: 100%; 32 | height: 45px; 33 | padding: 0; 34 | margin: 0; 35 | pointer-events: none; 36 | } 37 | 38 | .fdn-tab { 39 | order: -1; 40 | position: var(--no-js-pos); 41 | width: var(--no-js-width); 42 | left: var(--no-js-left); 43 | } 44 | } 45 | 46 | .fdn-tabs input[type="radio"] { 47 | + .fdn-tab { 48 | --bg-colour: transparent; 49 | --text-colour: var(--fdn-colours-black); 50 | --text-hover-colour: var(--fdn-colours-black); 51 | --border-radii: 0; 52 | border: none; 53 | border-top: 2px solid transparent; 54 | border-bottom: var( 55 | --tab-border-bottom, 56 | 2px solid transparent 57 | ); 58 | box-shadow: 0px 1px 0px 0px var(--fdn-colours-gray); 59 | } 60 | 61 | &:checked + .fdn-tab { 62 | --text-colour: var(--primary-bg-colour); 63 | --text-hover-colour: var(--primary-bg-colour); 64 | border-bottom: 2px solid var(--primary-bg-colour); 65 | } 66 | 67 | :root.no-js &:checked + .fdn-tab + div { 68 | display: flex !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ui/foundation/components/typography.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-main-content h1, 6 | .fdn-h1 { 7 | --default-font-size: 5rem; 8 | font-size: min(var(--default-font-size), 10dvw); 9 | font-weight: 700; 10 | line-height: 1.25; 11 | } 12 | 13 | .fdn-main-content h2, 14 | .fdn-h2 { 15 | --default-font-size: 3rem; 16 | font-size: min(var(--default-font-size), 6dvw); 17 | font-weight: 700; 18 | line-height: 1.25; 19 | } 20 | 21 | .fdn-main-content h3, 22 | .fdn-h3 { 23 | --default-font-size: 2.5rem; 24 | font-size: min(var(--default-font-size), 5dvw); 25 | font-weight: 600; 26 | line-height: 1.25; 27 | } 28 | 29 | .fdn-main-content h4, 30 | .fdn-h4 { 31 | --default-font-size: 2rem; 32 | font-size: min(var(--default-font-size), 4dvw); 33 | font-weight: 600; 34 | line-height: 1.1; 35 | } 36 | 37 | .fdn-main-content h5, 38 | .fdn-h5 { 39 | --default-font-size: 1.5rem; 40 | font-size: min(var(--default-font-size), 3dvw); 41 | font-weight: 600; 42 | line-height: 1.1; 43 | } 44 | 45 | .fdn-main-content h6, 46 | .fdn-h6 { 47 | --default-font-size: 1.15rem; 48 | font-size: min(var(--default-font-size), 2.3dvw); 49 | font-weight: 600; 50 | line-height: 1.1; 51 | } 52 | 53 | .fdn-main-content p, 54 | .fdn-p { 55 | --default-font-size: 1.125rem; 56 | font-size: min(var(--default-font-size), 4dvw); 57 | font-weight: 500; 58 | line-height: 1.375; 59 | color: var(--fdn-text-secondary-colour); 60 | } 61 | 62 | .fdn-main-content span, 63 | .fdn-span { 64 | --default-font-size: 1rem; 65 | font-size: min(var(--default-font-size), 3.5dvw); 66 | font-weight: 500; 67 | line-height: 1.375; 68 | color: var(--fdn-text-secondary-colour); 69 | } 70 | 71 | .fdn-main-content pre, 72 | .fdn-main-content code { 73 | --default-font-size: 1.125rem; 74 | font-size: min(var(--default-font-size), 4dvw); 75 | } 76 | 77 | .fdn-main-content strong, 78 | .fdn-main-content b, 79 | .fdn-bold { 80 | --default-font-size: 1.125rem; 81 | font-size: min(var(--default-font-size), 4dvw); 82 | font-weight: 500; 83 | } 84 | 85 | .fdn-main-content p strong, 86 | .fdn-main-content p b { 87 | color: var(--fdn-colours-black); 88 | } 89 | -------------------------------------------------------------------------------- /ui/foundation/utils/a11y.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .fdn-visually-hidden { 6 | position: absolute; 7 | overflow: hidden; 8 | margin: 0; 9 | width: 1px; 10 | height: 1px; 11 | clip-path: inset(100%); 12 | clip: rect(1px, 1px, 1px, 1px); 13 | white-space: nowrap; 14 | } 15 | -------------------------------------------------------------------------------- /ui/pages/donate.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .donate-app { 6 | width: 100%; 7 | --donate-app-gutters: calc((100% - var(--fdn-content-width)) / 2); 8 | scroll-behavior: smooth; 9 | } 10 | 11 | .donate-aside { 12 | max-width: 25rem; 13 | padding-inline-end: 1.5rem; 14 | } 15 | 16 | .donate-aside, 17 | .fdn-aside-container { 18 | display: flex; 19 | flex-direction: column; 20 | gap: 10rem; 21 | } 22 | 23 | .donate-aside .fdn-aside-header { 24 | display: flex; 25 | flex-direction: column; 26 | gap: 1.5rem; 27 | } 28 | 29 | .donate-aside-container { 30 | display: flex; 31 | background-color: var(--fdn-colours-white); 32 | padding-inline-start: var(--donate-app-gutters); 33 | padding-block: 4rem; 34 | } 35 | 36 | .donate-flow-container { 37 | display: flex; 38 | background-color: var(--fdn-bg-default); 39 | flex: 1; 40 | width: 100%; 41 | padding-inline-end: var(--donate-app-gutters); 42 | padding-block: 4rem; 43 | padding-inline-start: 3rem; 44 | flex-direction: column; 45 | gap: 3rem; 46 | } 47 | 48 | .donate-card-container { 49 | padding-inline-start: calc(42px + 26px); 50 | } 51 | 52 | .donate-amounts-grid { 53 | display: grid; 54 | grid-template-columns: repeat(var(--grid-cols, 4), 1fr); 55 | gap: 1rem; 56 | } 57 | 58 | .donate-amounts-grid.large { 59 | --grid-cols: 3; 60 | } 61 | 62 | .donate-amounts-grid #custom_amount { 63 | grid-column: span var(--grid-cols, 2); 64 | } 65 | 66 | .donate-aside-text-container { 67 | display: flex; 68 | gap: 0.75rem; 69 | flex-direction: column; 70 | } 71 | 72 | .donate-aside-text-container h3 { 73 | line-height: 1.25; 74 | } 75 | 76 | .donate-aside-text-container p { 77 | line-height: 1.75; 78 | } 79 | 80 | .donate-flow-container .fdn-card { 81 | scroll-margin-top: 25rem; 82 | } 83 | 84 | .no-js .donate-amounts-grid .fdn-button { 85 | display: none; 86 | } 87 | 88 | .donate-amounts-grid .fdn-button.primary, 89 | #donate-pay-methods .fdn-button.primary { 90 | pointer-events: none; 91 | } 92 | 93 | .donate-payment-method-container { 94 | display: flex; 95 | flex-direction: column; 96 | gap: 0.5rem; 97 | } 98 | -------------------------------------------------------------------------------- /ui/pages/third-party-licenses.scss: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | .tpl-deps-list { 6 | .fdn-list-item:not(:hover) { 7 | color: var(--fdn-text-secondary-colour) !important; 8 | } 9 | 10 | .fdn-list-item:hover { 11 | color: var(--fdn-text-colour) !important; 12 | 13 | & .fdn-icon.chevron-right { 14 | transform: translateX(4px); 15 | } 16 | } 17 | 18 | .fdn-list-item .fdn-icon { 19 | transition: 0.1s transform; 20 | } 21 | 22 | .fdn-list-item > p { 23 | color: var(--fdn-text-colour); 24 | } 25 | } 26 | 27 | .tpl-dep-reference-list { 28 | .fdn-list-item img { 29 | border-radius: 0.5rem; 30 | } 31 | } 32 | 33 | .tpl-dep-info { 34 | scroll-margin-top: 7.2em; 35 | 36 | .tpl-dep-name { 37 | position: relative; 38 | color: var(--fdn-text-colour); 39 | 40 | &:hover { 41 | color: var(--fdn-colours-link); 42 | } 43 | 44 | &:hover::before { 45 | content: "#"; 46 | position: absolute; 47 | font-size: inherit; 48 | left: -2rem; 49 | font-family: inherit; 50 | font-weight: inherit; 51 | } 52 | } 53 | } 54 | 55 | .tpl-repo-info { 56 | .tpl-repo-name { 57 | color: var(--fdn-text-colour); 58 | 59 | &:hover { 60 | color: var(--fdn-colours-link); 61 | } 62 | } 63 | } 64 | --------------------------------------------------------------------------------