diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f89a867
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+root = true
+
+[*]
+charset = utf-8
+insert_final_newline = true
+indent_size = 4
+indent_style = tab
+
+[{package,package-lock}.json]
+indent_size = 2
+indent_style = space
+
+[*.yml]
+indent_size = 2
+indent_style = space
+
+[*.svg]
+insert_final_newline = false
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 0000000..a294f63
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,72 @@
+name: Pages
+
+on: push
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Use Node.js 13.2
+ uses: actions/setup-node@v1
+ with:
+ node-version: 13.2
+
+ - name: npm install, build, and test
+ run: |
+ npm ci
+ npm run build-docs
+
+ env:
+ CI: true
+
+ - name: Deploy
+ uses: JamesIves/github-pages-deploy-action@releases/v3
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ BRANCH: gh-pages
+ FOLDER: build
+
+ - name: Create Release
+ id: create_release
+ uses: actions/create-release@latest
+ if: startsWith(github.ref, 'refs/tags/v')
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ release_name: Release ${{ github.ref }}
+ draft: false
+ prerelease: false
+
+ - name: Upload minified CSS
+ uses: actions/upload-release-asset@v1
+ if: startsWith(github.ref, 'refs/tags/v')
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: build/pr0gramm.min.css
+ asset_name: pr0gramm.min.css
+ asset_content_type: text/css
+
+ - name: Upload CSS
+ uses: actions/upload-release-asset@v1
+ if: startsWith(github.ref, 'refs/tags/v')
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: build/pr0gramm.css
+ asset_name: pr0gramm.css
+ asset_content_type: text/css
+
+ - name: Publish Package
+ if: startsWith(github.ref, 'refs/tags/v')
+ run: |
+ npm ci
+ npm publish --access public
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..667a564
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+build/
+node_modules/
+*.css
+*.map
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..1393853
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,9 @@
+*.js
+*.scss
+*.html
+*.map
+.*ignore
+.github
+.editorconfig
+build
+src
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12cdedd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# pr0gramm.css
+
+Ein Stylesheet für pr0gramm-esque Seiten.
+
+Dieses Stylesheet hat nichts mit dem offiziellen Stylesheet von pr0gramm zu tun.
+
+### [Dokumentation](https://holzmaster.github.io/pr0gramm.css)
diff --git a/build-docs.js b/build-docs.js
new file mode 100644
index 0000000..665ec44
--- /dev/null
+++ b/build-docs.js
@@ -0,0 +1,32 @@
+const fs = require("fs");
+const hljs = require("highlightjs");
+const child_process = require("child_process");
+const outdent = require("outdent");
+
+console.log("Bundling CSS...");
+const npmOutput = child_process.execSync("npm run compile:prod", { encoding: "utf-8" });
+console.log(npmOutput);
+
+const indexTemplate = fs.readFileSync("index.html", { encoding: "utf-8" });
+
+console.log("Replacing variables...");
+
+const correctedCss = indexTemplate
+ .replace("build/pr0gramm.css", "pr0gramm.min.css")
+ .replace("node_modules/highlightjs/styles/vs2015.css", "vs2015.css");
+
+console.log("Highlighting code...");
+
+const demoPattern = /\{\{(.+?);\n*(.+?)\n*\}\}/gis;
+
+const withDemoCode = correctedCss.replace(demoPattern, (_, language, codeToHighlight) => {
+ const normalizedCode = outdent.string(codeToHighlight).trim();
+ return hljs.highlight(language, normalizedCode).value;
+});
+
+console.log("Writing out files...");
+
+fs.copyFileSync("node_modules/highlightjs/styles/vs2015.css", "build/vs2015.css");
+fs.writeFileSync("build/index.html", withDemoCode);
+
+console.log("...done!");
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..842dd88
--- /dev/null
+++ b/index.html
@@ -0,0 +1,496 @@
+
+
+
+
+
+
+
+
pr0gramm.css
+
+
+
+
+
+
+
+
+
+
+
+ pr0gramm.css
+
+ Ein Stylesheet für pr0gramm-esque Seiten.
+
Hat bis auf das Aussehen nichts mit dem pr0gramm.min.css zu tun, das auf pr0gramm verwendet wird.
+
+
+ Zuerst ein paar Schmuser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Verwendung / Installation
+
+ {{bash;
+ npm install pr0gramm.css
+ # CSS liegt in node_modules/pr0gramm.css/pr0gramm.min.css
+ # import "pr0gramm.css"; // bei einem CSS-in-JS-Bundler (z. B. create-react-app)
+ }}
+ oder
+ {{html; }}
+
+
+
+ Standard-Styles für Controls
+
+
+
+
+
Ein Button
+
Abbrechen
+
Deaktiviert
+
+
+
+
+
+
+
+
+ Tolle
+
+
+
+ Radio-Buttons
+
+
+
+ Hier ist noch ein Range-Slider:
+
+
+
+
+ Hier klicken zum Ausklappen
+ Wer das liest ist doof. Hihi
+
+
Krass abspeichern
+
+
+
+ Code Anzeigen
+ {{html;
+
+
+
+
+ Ein Button
+ Abbrechen
+ Deaktiviert
+
+
+
+
+
+ Tolle
+
+
+
+ Radio-Buttons
+
+
+
+
+
+
+
+
+ Hier klicken zum Ausklappen
+ Wer das liest ist doof. Hihi
+
+
+ Krass abspeichern
+ }}
+
+
+
+
+ Links
+
+
+
+
+ Code Anzeigen
+ {{html;
+ Ein Link ,
+ eine Aktion ,
+ mit Klammern ,
+ ein Navigationslink und
+ ein aktiver Navigationslink
+ }}
+
+
+
+
+ Komponente: Nutzerränge
+
+
+
+ EinUser
+ IchBinNeuHier
+ Benutzer
+ cha0s
+ Blauschwuchtel
+ froschler
+ Marina
+ Keith
+ Wichtel
+ EdlerSpender
+ KeineAltschwuchtel
+ Seglormeister
+ RundesBalli
+ NutzerBot
+ SystemBot
+
+
+
Mit OP-Tag:
+ holzmaster
+
Als Link: Gamb
+
+
+
+ Code Anzeigen
+ {{html;
+
+ EinUser
+ IchBinNeuHier
+ Benutzer
+ cha0s
+ Blauschwuchtel
+ froschler
+ Marina
+ Keith
+ Wichtel
+ EdlerSpender
+ KeineAltschwuchtel
+ Seglormeister
+ RundesBalli
+ NutzerBot
+ SystemBot
+
+
+ cha0s
+
+
+ holzmaster
+
+ Gamb
+ }}
+
+
+
+
+ Komponente: Tags
+
+
+
+
+ Code Anzeigen
+ {{html;
+ gute nudel
+ Falsche Zielgruppe
+
+
+ auch mit votes
+ +
+ -
+
+
+ und mit Verlinkung
+
+
+ mit votes und Verlinkung
+ +
+ -
+
+ }}
+
+
+
+
+ Komponente: Navbar
+
+
+
Siehe diese Seite
+
+
+
+ Code Anzeigen
+ Strg+U
+
+
+
+
+ Farbschema Ändern
+
+
+
+
+ bewährtes Orange
+
+
+
+ angenehmes Grün
+
+
+
+ Olivgrün des Friedens
+
+
+
+ episches Blau
+
+
+
+ altes Pink
+
+
+
+
+ Code Anzeigen
+ {{css;
+ /*
+ * 0: bewährtes Orange
+ * 1: angenehmes Grün
+ * 2: Olivgrün des Friedens
+ * 3: episches Blau
+ * 4: altes Pink
+ */
+ :root {
+ --primary-color: var(--theme-color-primary-0);
+ --secondary-color: var(--theme-color-secondary-0);
+ }
+ }}
+
+
+
+
+ Komponente: Separator
+
+
+ Das hier ist ein ganz toller Text. Vielleicht gibt es hier sogar Controls. Wer weiß!
+ oder
+ Vielleicht möchtest du ja auch das tun, was unter diesem tollen "oder"-Teiler steht.
+
+
+
+ Code Anzeigen
+ {{html;
+
+ Inhalt über dem Teiler
+ oder
+ Inhalt unter dem Teiler
+
+ }}
+
+
+
+
+ Komponente: Plus/Minus
+
+
+
+ Statische plus/minus:
+
+
+
+ Interaktiv (mit hover):
+
+
+
+ Mit a- oder button-Tag und anderer Größe:
+
+
+
+
+
+ Code Anzeigen
+ {{html;
+
+
+
+
+
+
+
+
+
+
+
+
+ }}
+
+
+
+
+ CSS-Variablen
+
+ Die aktuelle Primärfarbe (diese hier )
+ und die Linkfarbe (diese hier )
+ sind über CSS-Variablen verfügbar.
+ Dies gilt auch für das richtige Grau und die passenden Schriftarten.
+
+ {{css;
+ .rule {
+ color: var(--primary-color); /* Primärarbe des aktuellen Themes */
+ color: var(--secondary-color); /* Linkfarbe */
+ background-color: var(--pr0gramm-background-color); /* richtiges Grau */
+ font-family: var(--pr0gramm-font-family); /* passende Schriftart */
+ }
+ }}
+
+
+
+ Statische plus/minus:
+
+
+
+ Interaktiv (mit hover):
+
+
+
+ Mit a- oder button-Tag und anderer Größe:
+
+
+
+
+
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..1ea3c69
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,258 @@
+{
+ "name": "pr0gramm.css",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "chokidar": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
+ "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.3.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "highlightjs": {
+ "version": "9.16.2",
+ "resolved": "https://registry.npmjs.org/highlightjs/-/highlightjs-9.16.2.tgz",
+ "integrity": "sha512-FK1vmMj8BbEipEy8DLIvp71t5UsC7n2D6En/UfM/91PCwmOpj6f2iu0Y0coRC62KSRHHC+dquM2xMULV/X7NFg==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "outdent": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.7.1.tgz",
+ "integrity": "sha512-VjIzdUHunL74DdhcwMDt5FhNDQ8NYmTkuW0B+usIV2afS9aWT/1c9z1TsnFW349TP3nxmYeUl7Z++XpJRByvgg==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
+ "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.0.7"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "sass": {
+ "version": "1.26.5",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.5.tgz",
+ "integrity": "sha512-FG2swzaZUiX53YzZSjSakzvGtlds0lcbF+URuU9mxOv7WBh7NhXEVDa4kPKN4hN6fC2TkOTOKqiqp6d53N9X5Q==",
+ "dev": true,
+ "requires": {
+ "chokidar": ">=2.0.0 <4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c12a249
--- /dev/null
+++ b/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "pr0gramm.css",
+ "version": "1.0.0",
+ "author": "holzmaster",
+ "description": "Ein Stylesheet für pr0gramm-esque Seiten.",
+ "license": "ISC",
+ "main": "pr0gramm.min.css",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/holzmaster/pr0gramm.css"
+ },
+ "scripts": {
+ "watch": "mkdirp build && sass --watch src/pr0gramm.scss:build/pr0gramm.css",
+ "clean": "mkdirp build && rimraf build/*",
+ "compile": "mkdirp build && sass src/pr0gramm.scss:build/pr0gramm.css",
+ "compile:prod": "mkdirp build && npm run compile:plain && npm run compile:compressed",
+ "compile:plain": "sass --no-source-map src/pr0gramm.scss:build/pr0gramm.css",
+ "compile:compressed": "sass --no-source-map --style compressed src/pr0gramm.scss:build/pr0gramm.min.css",
+ "build-docs": "node build-docs.js",
+ "prepublishOnly": "npm run compile:prod && mv build/pr0gramm*.css ."
+ },
+ "keywords": [
+ "pr0gramm",
+ "css"
+ ],
+ "devDependencies": {
+ "highlightjs": "^9.16.2",
+ "mkdirp": "^1.0.4",
+ "outdent": "^0.7.1",
+ "rimraf": "^3.0.2",
+ "sass": "^1.26.5"
+ }
+}
diff --git a/src/_constants.scss b/src/_constants.scss
new file mode 100644
index 0000000..9720a50
--- /dev/null
+++ b/src/_constants.scss
@@ -0,0 +1,94 @@
+
+$richtiges-grau: #161618;
+$pr0gramm-primary: #ee4d2e;
+$pr0gramm-secondary: #fc8833;
+$link-color: #75c0c7;
+$cha0s-grau: #212121;
+$tag-background: #2a2e31;
+
+$placeholder-color: #666;
+
+$input-background: #1b1e1f;
+$input-color: #bbb;
+
+$input-focused-background: #212425;
+$input-focused-color: #f5f7f6;
+
+$divider-color: #252525;
+
+$text-primary: #f2f5f4;
+$text-muted: #888;
+
+$sfw: #5cb85c;
+$nsfw: #f0ad4e;
+$nsfl: #d9534f;
+
+$ordentliche-schrift: "Helvetica Neue", "Helvetica", "Bitstream Vera Sans", "DejaVu Sans", sans-serif; // KEIN Arial. :)
+
+$vs-dark-background-color: #1e1e1e; // Color not available on pr0gramm, but we need something darker for the code listings
+
+$code-background-color: $vs-dark-background-color;
+
+/*
+// Unused colors
+#f2f5f4 Standard-Schriftfarbe #f2f5f4 Formate
+#f7c516 Gelb vom pr0mium-Post #f7c516 Formate
+#222222 pr0mium-Auswahlteile #222222 Formate
+#ff0082 Altes pr0gramm <3 #ff0082 Formate
+*/
+
+$mark-banned:#444;
+$mark-ftb: #6c432b;
+$mark-neuschwuchtel: #e108e9;
+$mark-schwuchtel: #fff;
+$mark-mittelaltschwuchtel: #addc8d;
+$mark-altschwuchtel: #5bb91c;
+$mark-spender: #1cb992;
+$mark-wichtel: $pr0gramm-primary;
+$mark-mod: #008fff;
+$mark-altmod: #7fc7ff;
+$mark-admin: #ff9900;
+$mark-system-bot: #ffc166;
+$mark-user-bot: #10366f;
+$mark-legende: #1cb992;
+$mark-helfer: #c52b2f;
+
+$marks: (
+ "0": $mark-schwuchtel,
+ "1": $mark-neuschwuchtel,
+ "2": $mark-altschwuchtel,
+ "3": $mark-admin,
+ "4": $mark-banned,
+ "5": $mark-mod,
+ "6": $mark-ftb,
+ "7": $mark-legende,
+ "8": $mark-wichtel,
+ "9": $mark-spender,
+ "10": $mark-mittelaltschwuchtel,
+ "11": $mark-altmod,
+ "12": $mark-helfer,
+ "13": $mark-user-bot,
+ "14": $mark-system-bot,
+);
+
+$special-shapes: (
+ "7": "\25C6", // Legende
+ "8": "\25A7", // Wichtel
+ "12": "\2764", // Helfer
+);
+
+$theme-primaries: (
+ "0": $pr0gramm-primary,
+ "1": #1db992,
+ "2": #bfbc06,
+ "3": $mark-mod,
+ "4": #ff0082,
+);
+
+$theme-secondaries: (
+ "0": $link-color,
+ "1": #1b9677,
+ "2": #b0ad05,
+ "3": #36a7ff,
+ "4": #f90081,
+);
diff --git a/src/_controls.scss b/src/_controls.scss
new file mode 100644
index 0000000..fa8d4e4
--- /dev/null
+++ b/src/_controls.scss
@@ -0,0 +1,248 @@
+::placeholder {
+ color: $placeholder-color;
+}
+
+button, input, textarea {
+ font-family: sans-serif;
+
+ background-color: $input-background;
+ color: $input-color;
+
+ border: 0;
+ border-radius: 0;
+
+ padding: 5px;
+
+ appearance: none;
+ outline: none;
+
+ &:disabled {
+ background-color: $placeholder-color !important;
+ color: $text-muted !important;
+ cursor: default;
+ }
+
+ &:focus, &:focus-within {
+ background-color: $input-focused-background;
+ color: $input-focused-color;
+ }
+
+ // https://github.com/necolas/normalize.css/issues/393#issue-52309010
+ &::-moz-focus-inner { border: 0; }
+}
+
+textarea {
+ width: 100%;
+
+ margin-bottom: 12px;
+
+ &:invalid {
+ outline: none;
+ box-shadow: none;
+ }
+}
+
+button,
+input[type=button],
+input[type=submit] {
+ $lage-button-width: 300px;
+
+ background-color: var(--primary-color);
+
+ padding: 8px 8px 6px 8px;
+ margin: 0;
+
+ color: $input-focused-color;
+ text-align: center;
+
+ cursor: pointer;
+ font-size: 12px;
+
+ &.large {
+ margin: 32px 0 0 0;
+ width: $lage-button-width;
+ padding: 12px;
+ font-size: 16px;
+ }
+
+ &.secondary {
+ background-color: $input-focused-background;
+ color: $text-muted;
+ }
+
+ &:hover, &:focus {
+ outline: none;
+ text-shadow: none;
+ color: #555;
+ background-color: $input-focused-color;
+ }
+}
+
+// This style was entirely copied from the original pr0gramm.min.css
+input[type=range] {
+ background-color: transparent;
+ -webkit-appearance: none;
+ appearance: none;
+ // width: 100%;
+
+ &:focus {
+ outline: none;
+
+ &::-webkit-slider-runnable-track {
+ background: #ffffff;
+ }
+ }
+
+ &::-moz-range-thumb {
+ cursor: pointer;
+
+ width: 3px;
+ height: 14px;
+
+ box-shadow: none;
+ border: none;
+ border-radius: 7px;
+
+ background: #fff;
+ }
+
+ &::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ cursor: pointer;
+
+ width: 3px;
+ height: 14px;
+ margin-top: -6px;
+
+ box-shadow: none;
+ border: none;
+ border-radius: 7px;
+
+ background: #fff;
+ }
+
+ &::-moz-range-track {
+ cursor: pointer;
+
+ width: 100%;
+ height: 2px;
+
+ box-shadow: none;
+ border: none;
+ border-radius: 0px;
+
+ background: #fff;
+ }
+ &::-webkit-slider-runnable-track {
+ cursor: pointer;
+
+ width: 100%;
+ height: 2px;
+
+ box-shadow: none;
+ border: none;
+ border-radius: 0px;
+
+ background: #fff;
+ }
+}
+
+label {
+ cursor: pointer;
+
+ $radio-size: 11px;
+
+ & > input[type="checkbox"], // Checkboxes use the same style as radio buttons. This is not good UX.
+ & > input[type="radio"] {
+ display: none;
+ }
+ & > input[type="checkbox"] + span, // Checkboxes use the same style as radio buttons. This is not good UX.
+ & > input[type="radio"] + span {
+ position: relative;
+ padding-left: $radio-size + 7px;
+ margin: 4px 4px;
+ }
+ & > input[type="checkbox"] + span::before, // Checkboxes use the same style as radio buttons. This is not good UX.
+ & > input[type="radio"] + span::before {
+ content: "";
+
+ width: $radio-size;
+ height: $radio-size;
+
+ position: absolute;
+ top: 2px;
+ left: 0;
+
+ display: inline-block;
+
+ background-color: transparent;
+ border: 1px solid $input-focused-color;
+ }
+ & > input[type="checkbox"]:checked + span::before, // Checkboxes use the same style as radio buttons. This is not good UX.
+ & > input[type="radio"]:checked + span::before {
+ background-color: $input-focused-color;
+ }
+}
+
+hr {
+ border: none;
+ border-top: 1px solid $divider-color;
+}
+
+code {
+ padding: 16px;
+ display: block;
+ background-color: $code-background-color;
+}
+
+
+details {
+ $summary-icon-width: 18px;
+ $summary-icon-margin: 6px;
+
+ padding-left: $summary-icon-width + $summary-icon-margin;
+
+ summary {
+ margin-left: -($summary-icon-width + $summary-icon-margin);
+
+ cursor: pointer;
+
+ // Hide default arrow because we want our own
+ list-style-type: none; // Firefox
+ &::-webkit-details-marker { display: none; } // Chrome
+ &::marker { display: none; }
+ }
+
+ & summary::before {
+ color: var(--primary-color);
+
+ display: inline-block;
+ width: $summary-icon-width;
+ margin-right: $summary-icon-margin;
+
+ text-align: center;
+
+ content: "[+]";
+ }
+ &[open] {
+
+ summary::before {
+ content: "[-]";
+ }
+
+ summary ~ * {
+ animation: open .25s ease;
+ }
+ }
+}
+
+@keyframes open {
+ 0% {
+ opacity: 0;
+ transform: translateX(-30px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
diff --git a/src/_link.scss b/src/_link.scss
new file mode 100644
index 0000000..ba586b9
--- /dev/null
+++ b/src/_link.scss
@@ -0,0 +1,39 @@
+a {
+ color: var(--secondary-color);
+
+ text-decoration: none;
+
+ &.action {
+ color: var(--primary-color);
+ // Font size should be set by the outer container
+ // font-size: 12px;
+
+ &.serious {
+ &::before {
+ content: "[";
+ color: $placeholder-color;
+ }
+ &::after {
+ content: "]";
+ color: $placeholder-color;
+ }
+ }
+ }
+
+ &:hover {
+ cursor: pointer;
+ color: $input-focused-color;
+ }
+
+ &.nav-link {
+ color: #fff;
+
+ &:hover, &.active {
+ color: var(--primary-color);
+ }
+ }
+
+ &.user:hover, &.user.active {
+ color: var(--secondary-color);
+ }
+}
diff --git a/src/components/_navbar.scss b/src/components/_navbar.scss
new file mode 100644
index 0000000..710263d
--- /dev/null
+++ b/src/components/_navbar.scss
@@ -0,0 +1,39 @@
+$navbar-height: 52px;
+$backdrop-blur: 30px;
+$backdrop-color: rgba(0, 0, 0, 0.5);
+$nav-shadow-color: $backdrop-color;
+
+.navbar {
+ height: $navbar-height;
+ z-index: 100;
+
+ &.fixed {
+ margin: 0 auto;
+ position: fixed;
+ top: 0;
+ left: 0px;
+ right: 0px;
+ }
+
+ padding: 0 16px;
+
+ & .brand {
+ margin-right: 16px;
+ }
+}
+
+@supports(backdrop-filter: blur()) {
+ .navbar {
+ background-color: $backdrop-color;
+ backdrop-filter: blur($backdrop-blur);
+ }
+}
+@media only screen and (min-width: 600px) {
+ .navbar {
+ box-shadow: $nav-shadow-color 0px 20px 20px -10px;
+ }
+}
+
+.adjust-for-fixed-navbar {
+ margin-top: $navbar-height;
+}
diff --git a/src/components/_separator.scss b/src/components/_separator.scss
new file mode 100644
index 0000000..3838a76
--- /dev/null
+++ b/src/components/_separator.scss
@@ -0,0 +1,17 @@
+// Mostly taken from: https://stackoverflow.com/a/26634224
+.separator {
+ display: flex;
+ align-items: center;
+ text-align: center;
+
+ margin-top: 10px;
+ margin-bottom: 10px;
+
+ &::before, &::after {
+ content: "";
+ flex: 1;
+ border-bottom: 1px solid $divider-color;
+ }
+ &::before { margin-right: .3em; }
+ &::after { margin-left: .3em; }
+}
diff --git a/src/components/_tag.scss b/src/components/_tag.scss
new file mode 100644
index 0000000..694dd61
--- /dev/null
+++ b/src/components/_tag.scss
@@ -0,0 +1,30 @@
+
+.tag {
+ font-size: 12px;
+ background-color: $tag-background;
+
+ display: inline-block;
+ padding: 2px 10px;
+ margin: 0px 6px 6px 0;
+
+ border-radius: 10px;
+
+ color: $input-focused-color;
+
+ a {
+ color: $input-focused-color;
+
+ &[class|="vote"] {
+ padding: 0 2px;
+ color: $text-muted;
+
+ &:hover {
+ color: var(--primary-color)
+ }
+ }
+
+ }
+ a:hover, a:focus {
+ color: var(--secondary-color);
+ }
+}
diff --git a/src/components/_user.scss b/src/components/_user.scss
new file mode 100644
index 0000000..8512c34
--- /dev/null
+++ b/src/components/_user.scss
@@ -0,0 +1,54 @@
+@mixin user-dot {
+ content: "\25CF";
+ margin-left: 0.4em;
+}
+
+.user {
+ &.op {
+
+ &::before {
+ content: "OP";
+
+ background-color: var(--primary-color);
+
+ padding: 0px 6px;
+ margin-right: 4px;
+
+ vertical-align: baseline;
+ text-align: center;
+ font-weight: bold;
+ border-radius: 0.25em;
+ }
+ }
+
+ // Setting the mark via data attribue
+ &[data-mark] {
+ color: $input-focused-color;
+
+ &::after { @include user-dot; }
+
+ @each $mark, $color in $marks {
+ &[data-mark="#{$mark}"]::after {
+ color: $color;
+ @if map-has-key($special-shapes, $mark) {
+ content: map-get($special-shapes, $mark);
+ }
+ }
+ }
+ }
+
+ // Alternative mark, the way pr0gramm does it
+ &[class*="um"] {
+ color: $input-focused-color;
+ &[class*="um"]::after { @include user-dot; }
+ }
+
+ @each $mark, $color in $marks {
+ &.um#{$mark}::after {
+ color: $color;
+ @if map-has-key($special-shapes, $mark) {
+ content: map-get($special-shapes, $mark);
+ }
+ }
+ }
+}
diff --git a/src/components/_vote.scss b/src/components/_vote.scss
new file mode 100644
index 0000000..58ccbdb
--- /dev/null
+++ b/src/components/_vote.scss
@@ -0,0 +1,38 @@
+.vote {
+ --plus-image: url('data:image/svg+xml;utf8, ');
+ --minus-image: url('data:image/svg+xml;utf8, ');
+
+ $default-vote-icon-size: 20px;
+
+ display: inline-block;
+ width: $default-vote-icon-size;
+ height: $default-vote-icon-size;
+
+ background: $text-muted;
+ border: none;
+ padding: 0;
+ line-height: normal;
+ vertical-align: middle;
+
+ &.interactive:hover, &.interactive:focus {
+ cursor: pointer;
+
+ background: var(--primary-color);
+ }
+
+ &.plus {
+ -webkit-mask: var(--plus-image);
+ mask: var(--plus-image);
+
+ -webkit-mask-size: contain;
+ mask-size: contain;
+ }
+
+ &.minus {
+ -webkit-mask: var(--minus-image);
+ mask: var(--minus-image);
+
+ -webkit-mask-size: contain;
+ mask-size: contain;
+ }
+}
diff --git a/src/components/assets/minus.svg b/src/components/assets/minus.svg
new file mode 100644
index 0000000..da90279
--- /dev/null
+++ b/src/components/assets/minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/assets/plus.svg b/src/components/assets/plus.svg
new file mode 100644
index 0000000..b916507
--- /dev/null
+++ b/src/components/assets/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/pr0gramm.scss b/src/pr0gramm.scss
new file mode 100644
index 0000000..31caf68
--- /dev/null
+++ b/src/pr0gramm.scss
@@ -0,0 +1,37 @@
+@import "_constants";
+@import "_controls";
+@import "_link";
+@import "components/_navbar";
+@import "components/_separator";
+@import "components/_vote";
+@import "components/_tag";
+@import "components/_user";
+
+:root {
+ // Keep this as a CSS variable to be able to change it via JS
+ --primary-color: #{$pr0gramm-primary};
+ --secondary-color: #{$link-color};
+ --pr0gramm-background-color: #{$richtiges-grau};
+ --pr0gramm-font-family: #{$ordentliche-schrift};
+
+ @each $theme-key, $theme-color in $theme-primaries {
+ --theme-color-primary-#{$theme-key}: #{$theme-color};
+ }
+ @each $theme-key, $theme-color in $theme-secondaries {
+ --theme-color-secondary-#{$theme-key}: #{$theme-color};
+ }
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: var(--pr0gramm-font-family);
+
+ background-color: var(--pr0gramm-background-color);
+ color: $text-primary;
+
+ line-height: 1.3;
+ font-size: 14px;
+}