├── public
├── img
│ └── .gitignore
├── .gitignore
├── robots.txt
├── sitemap.xml
├── api
│ ├── .htaccess
│ └── index.php
├── site.webmanifest
├── humans.txt
└── addons
│ └── copyable_captcha.php
├── src
├── style
│ ├── Textpattern.css
│ ├── Textpattern
│ │ ├── sass
│ │ │ ├── setup
│ │ │ │ ├── _index.scss
│ │ │ │ ├── _mixins.scss
│ │ │ │ └── _settings.scss
│ │ │ ├── modules
│ │ │ │ ├── _http-errors.scss
│ │ │ │ ├── _accessibility.scss
│ │ │ │ ├── _index.scss
│ │ │ │ ├── _misc.scss
│ │ │ │ ├── fluxbb
│ │ │ │ │ ├── _fluxbb_pagination.scss
│ │ │ │ │ ├── _fluxbb_layout_admin.scss
│ │ │ │ │ ├── _fluxbb_indicators.scss
│ │ │ │ │ ├── _fluxbb_navigation.scss
│ │ │ │ │ ├── _fluxbb_icons.scss
│ │ │ │ │ └── _fluxbb_layout.scss
│ │ │ │ ├── _lists.scss
│ │ │ │ ├── _embedded-content.scss
│ │ │ │ ├── _fonts.scss
│ │ │ │ ├── _alerts.scss
│ │ │ │ ├── _links.scss
│ │ │ │ ├── _tables.scss
│ │ │ │ ├── _code-highlighting.scss
│ │ │ │ ├── _social.scss
│ │ │ │ ├── _buttons.scss
│ │ │ │ ├── _navigation.scss
│ │ │ │ ├── _icons.scss
│ │ │ │ ├── _typography.scss
│ │ │ │ ├── _responsive.scss
│ │ │ │ └── _forms.scss
│ │ │ └── screen.scss
│ │ ├── img
│ │ │ ├── forum-icons.png
│ │ │ ├── forum-icons@2x.png
│ │ │ ├── dark-forum-icons.png
│ │ │ └── dark-forum-icons@2x.png
│ │ ├── fonts
│ │ │ ├── pt-serif-v18-latin-ext-700.woff2
│ │ │ ├── pt-serif-v18-latin-ext-italic.woff2
│ │ │ ├── pt-serif-v18-latin-ext-regular.woff2
│ │ │ ├── pt-serif-v18-latin-ext-700italic.woff2
│ │ │ └── License.txt
│ │ ├── base_admin.css
│ │ ├── maintenance.tpl
│ │ ├── js
│ │ │ └── app.js
│ │ ├── redirect.tpl
│ │ ├── admin.tpl
│ │ └── main.tpl
│ └── .htaccess
├── 503.html
├── 500.html
├── 403.html
└── 404.html
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── ISSUE_TEMPLATE.md
└── CODE_OF_CONDUCT.md
├── composer.json
├── .gitignore
├── .editorconfig
├── LICENSE
├── package.json
├── README.md
└── Gruntfile.js
/public/img/.gitignore:
--------------------------------------------------------------------------------
1 | /*
2 | !/.gitignore
3 | !/.htaccess
--------------------------------------------------------------------------------
/src/style/Textpattern.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Registers FluxBB style.
3 | */
4 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/setup/_index.scss:
--------------------------------------------------------------------------------
1 | @forward "settings";
2 | @forward "mixins";
3 |
--------------------------------------------------------------------------------
/src/style/Textpattern/img/forum-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/img/forum-icons.png
--------------------------------------------------------------------------------
/src/style/Textpattern/img/forum-icons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/img/forum-icons@2x.png
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Changes proposed in this pull request:
2 |
3 | - {Please write here}
4 | - {Please write here}
5 | - {Please write here}
6 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": {
3 | "vendor-dir": "public/vendor"
4 | },
5 | "require": {
6 | "netcarver/textile": "3.8.0"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/style/Textpattern/img/dark-forum-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/img/dark-forum-icons.png
--------------------------------------------------------------------------------
/src/style/Textpattern/img/dark-forum-icons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/img/dark-forum-icons@2x.png
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 |
--------------------------------------------------------------------------------
/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-700.woff2
--------------------------------------------------------------------------------
/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-italic.woff2
--------------------------------------------------------------------------------
/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-regular.woff2
--------------------------------------------------------------------------------
/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-700italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/textpattern/textpattern-forum/HEAD/src/style/Textpattern/fonts/pt-serif-v18-latin-ext-700italic.woff2
--------------------------------------------------------------------------------
/src/style/Textpattern/base_admin.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Disables base admin-panel styles.
3 | *
4 | * This file is hard-linked, and as such, can not be versioned. We
5 | * won't be using this.
6 | */
7 |
--------------------------------------------------------------------------------
/public/.gitignore:
--------------------------------------------------------------------------------
1 | /.htaccess
2 | /cache
3 | /COPYING
4 | /include
5 | /lang
6 | /lib
7 | /style
8 | /tests
9 | /vendor
10 | /*.php
11 | /*.js
12 | /*.md
13 | /.*
14 | !/.gitignore
15 | /*.html
16 | /*.ico
17 | /*.png
18 | /*.svg
19 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /img/
3 | Disallow: /*?*action=
4 | Disallow: /*?*type=
5 | Disallow: /*?*tid=
6 | Disallow: /*?*user_id=
7 | Disallow: /*?*search_id=
8 | Disallow: /*?*username=
9 | Sitemap: https://forum.textpattern.com/sitemap.xml
10 |
--------------------------------------------------------------------------------
/public/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | http://forum.textpattern.com
5 |
6 |
7 | https://forum.textpattern.com/humans.txt
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_http-errors.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* HTTP error pages
4 | ========================================================================== */
5 |
6 | .http-status-code {
7 | font-size: 3em;
8 | }
9 |
10 | .http-status-description {
11 | display: inline-block;
12 | }
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS generated files #
2 | ######################
3 | ._*
4 | .DS_Store
5 | .DS_Store?
6 | .nova
7 | .Spotlight-V100
8 | .Trashes
9 | .vscode
10 | Icon?
11 | ehthumbs.db
12 | Thumbs.db
13 |
14 | # Development files #
15 | ######################
16 | /composer.lock
17 | /node_modules
18 | /package-lock.json
19 | /npm-debug.log
20 | /yarn.lock
21 | /yarn-error.log
22 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_accessibility.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | @media (prefers-reduced-motion: reduce), (update: slow) {
4 | body {
5 | scroll-behavior: auto;
6 | }
7 |
8 | .js #site-navigation,
9 | #site-navigation.site-navigation-open,
10 | .search-form [type="search"] {
11 | transition-duration: 0;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/public/api/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Header unset X-XSS-Protection
3 | Header unset X-Frame-Options
4 | Header unset X-Content-Type-Options
5 | Header unset Expires
6 | Header unset Cache-Control
7 | Header unset Pragma
8 | Header unset Content-Security-Policy
9 |
10 |
11 |
12 | RewriteEngine On
13 | RewriteRule ^topics/([0-9]+) index.php?action=feed&fid=$1 [QSA]
14 | RewriteRule ^posts/([0-9]+) index.php?action=feed&tid=$1 [QSA]
15 |
16 |
--------------------------------------------------------------------------------
/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Textpattern",
3 | "name": "Textpattern CMS Support Forum",
4 | "start_url": "https://forum.textpattern.com",
5 | "scope": "https://forum.textpattern.com",
6 | "icons": [
7 | { "src": "icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable any" },
8 | { "src": "icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable any" }
9 | ],
10 | "background_color": "#ffffff",
11 | "theme_color": "#ffda44",
12 | "display": "minimal-ui"
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # For more information about the properties used in
2 | # this file, please see the EditorConfig documentation:
3 | # https://editorconfig.org/
4 |
5 | root = true
6 |
7 | [*]
8 | charset = utf-8
9 | end_of_line = lf
10 | indent_size = 4
11 | indent_style = space
12 | insert_final_newline = true
13 | trim_trailing_whitespace = true
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
18 | [{*.json,*.yml,humans.txt}]
19 | indent_size = 2
20 | indent_style = space
21 |
22 | [{feature-textpattern-forum.patch}]
23 | indent_style = tab
24 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/setup/_mixins.scss:
--------------------------------------------------------------------------------
1 | @use "settings";
2 |
3 | // Dark Mode shorthand.
4 |
5 | @mixin dark-mode {
6 | @media (prefers-color-scheme: dark) {
7 | @content;
8 | }
9 | }
10 |
11 | // standard gradients
12 |
13 | @mixin gradient-linear($color-gradient-from, $color-gradient-to) {
14 | background-color: $color-gradient-to;
15 | background-image: linear-gradient($color-gradient-from, $color-gradient-to);
16 | }
17 |
18 | // hide text
19 |
20 | @mixin hide-text {
21 | overflow: hidden;
22 | text-indent: 110%;
23 | text-transform: capitalize;
24 | white-space: nowrap;
25 | }
26 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/setup/_settings.scss:
--------------------------------------------------------------------------------
1 | // typography grid
2 | $base-font-size: 16px !default;
3 | $base-line-height: 1.5 !default;
4 | $small-line-height: 1.375 !default;
5 | $code-font-size: 0.875rem !default; // 14px / 16px
6 | $small-font-size: 0.75rem !default; // 12px / 16px
7 |
8 | // layout grid
9 | $container-max-width: 72rem !default; // 1152px / 16px
10 | $breakpoint-3: 60rem !default; // 960px / 16px
11 | $breakpoint-2: 48rem !default; // 768px / 16px
12 | $breakpoint-1: 30rem !default; // 480px / 16px
13 |
14 | // borders
15 | $border-radius: 0.5em !default; // 8px / 16px
16 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_index.scss:
--------------------------------------------------------------------------------
1 | @use "fonts";
2 | @use "layout";
3 | @use "navigation";
4 | @use "links";
5 | @use "typography";
6 | @use "alerts";
7 | @use "embedded-content";
8 | @use "tables";
9 | @use "lists";
10 | @use "forms";
11 | @use "buttons";
12 | @use "code-highlighting";
13 | @use "social";
14 | @use "misc";
15 | @use "http-errors";
16 | @use "icons";
17 | @use "fluxbb/fluxbb_layout";
18 | @use "fluxbb/fluxbb_layout_admin";
19 | @use "fluxbb/fluxbb_navigation";
20 | @use "fluxbb/fluxbb_indicators";
21 | @use "fluxbb/fluxbb_pagination";
22 | @use "fluxbb/fluxbb_icons";
23 | @use "responsive";
24 | @use "accessibility";
25 |
--------------------------------------------------------------------------------
/src/style/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Header unset X-XSS-Protection
3 | Header unset X-Frame-Options
4 | Header unset X-Content-Type-Options
5 | Header unset Content-Security-Policy
6 | Header append Cache-Control "public"
7 |
8 |
9 | Header append Vary "Accept-Encoding"
10 |
11 |
12 |
13 |
14 | ExpiresActive On
15 | ExpiresDefault "access plus 1 year"
16 |
17 |
18 |
19 | RewriteEngine On
20 |
21 | RewriteRule ^(.*?)\.[0-9]+\.(css|js|svg)$ $1.$2 [L]
22 |
23 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_misc.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Miscellaneous
4 | ========================================================================== */
5 |
6 | /**
7 | * Hide text but still allow screen reader access.
8 | *
9 | * Example HTML:
10 | *
11 | *
12 | */
13 |
14 | .accessibility {
15 | position: absolute;
16 | width: 1px;
17 | height: 1px;
18 | margin: -1px;
19 | padding: 0;
20 | overflow: hidden;
21 | clip: rect(0 0 0 0); // TODO: Deprecated - use `clip-path` when browser support is better.
22 | //clip-path: inset(50%); // TODO: Currently causes severe performance issues in Chrome.
23 | border: 0;
24 | white-space: nowrap;
25 | }
26 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_pagination.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 |
3 | /* Forum pagination links
4 | ========================================================================== */
5 |
6 | .pagelink {
7 | strong,
8 | a,
9 | .spacer {
10 | display: inline-block;
11 | min-width: 1.25em;
12 | padding: 0 0.1875em; // 3px / 16px
13 | text-align: center;
14 | }
15 |
16 | strong {
17 | background: var(--clr-text);
18 | color: var(--clr-text-white-enforced);
19 | font-weight: 400;
20 | cursor: default;
21 | }
22 | }
23 |
24 | @include setup.dark-mode {
25 | .pagelink strong {
26 | background: var(--clr-bkgd-form);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_lists.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Lists
4 | ========================================================================== */
5 |
6 | /**
7 | * Address paddings set differently.
8 | */
9 |
10 | menu,
11 | ol,
12 | ul {
13 | padding: 0 0 0 1.75em;
14 | }
15 |
16 | /**
17 | * Remove margins from nested lists.
18 | */
19 |
20 | li {
21 | > ul,
22 | > ol {
23 | margin: 0;
24 | }
25 | }
26 |
27 | /**
28 | * CSS Lists and Counters Module Level 3 list marker styling.
29 | */
30 |
31 | li::marker {
32 | color: var(--clr-text-promoted);
33 | }
34 |
35 | /**
36 | * Style for definition lists.
37 | */
38 |
39 | dd {
40 | margin: 0 0 0 1.75em;
41 | }
42 |
43 | /**
44 | * Visually stronger definition terms.
45 | */
46 |
47 | dt {
48 | color: var(--clr-text-promoted);
49 | font-weight: 700;
50 | }
51 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_embedded-content.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Embedded content
4 | ========================================================================== */
5 |
6 | /**
7 | * Make embedded elements responsive.
8 | */
9 |
10 | img,
11 | video {
12 | max-width: 100%;
13 | height: auto;
14 | }
15 |
16 | /**
17 | * Remove the gap between images and the bottom of their containers.
18 | */
19 |
20 | img {
21 | vertical-align: middle;
22 | }
23 |
24 | /**
25 | * Make embedded videos responsive.
26 | *
27 | * TODO: use `aspect-ratio: var(--aspect-ratio, 16 / 9);` when browser support
28 | * is better.
29 | */
30 |
31 | .embed-video {
32 | position: relative;
33 | padding-top: 56.25%; // TODO: see comment above.
34 |
35 | iframe {
36 | position: absolute;
37 | top: 0;
38 | left: 0;
39 | width: 100%;
40 | height: 100%;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve the Textpattern forum website.
4 | ---
5 |
6 | **Describe the bug**
7 | A clear and concise description of what the bug is.
8 |
9 | **To reproduce**
10 | Steps to reproduce the behaviour:
11 | 1. Go to '...'
12 | 2. Click on '....'
13 | 3. Scroll down to '....'
14 | 4. See error
15 |
16 | **Expected behaviour**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 |
22 | **Desktop (please complete the following information):**
23 | - OS: [e.g. iOS]
24 | - Browser [e.g. chrome, safari]
25 | - Version [e.g. 22]
26 |
27 | **Smartphone (please complete the following information):**
28 | - Device: [e.g. iPhone6]
29 | - OS: [e.g. iOS8.1]
30 | - Browser [e.g. stock browser, safari]
31 | - Version [e.g. 22]
32 |
33 | **Additional context**
34 | Add any other context about the problem here.
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (C) 2024 Team Textpattern
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a
6 | copy of this software and associated documentation files (the "Software"),
7 | to deal in the Software without restriction, including without limitation
8 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 | and/or sell copies of the Software, and to permit persons to whom the
10 | Software is furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "textpattern-forum",
3 | "version": "1.6.4",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/textpattern/textpattern-forum"
7 | },
8 | "bugs": {
9 | "url": "https://github.com/textpattern/textpattern-forum/issues"
10 | },
11 | "devDependencies": {
12 | "@lodder/grunt-postcss": "3.1.1",
13 | "autoprefixer": "10.4.23",
14 | "cssnano": "7.1.2",
15 | "grunt": "1.6.1",
16 | "grunt-cli": "1.5.0",
17 | "grunt-concurrent": "3.0.0",
18 | "grunt-contrib-clean": "2.0.1",
19 | "grunt-contrib-copy": "1.0.0",
20 | "grunt-contrib-jshint": "3.2.0",
21 | "grunt-contrib-watch": "1.1.0",
22 | "grunt-replace-regex": "1.0.3",
23 | "grunt-sass": "4.0.1",
24 | "grunt-stylelint": "0.20.1",
25 | "grunt-terser": "2.0.0",
26 | "load-grunt-tasks": "5.1.0",
27 | "sass": "1.91.0",
28 | "stylelint": "16.26.1",
29 | "stylelint-config-standard-scss": "16.0.0",
30 | "sass": "1.97.0",
31 | "stylelint-order": "7.0.0"
32 | },
33 | "dependencies": {
34 | "jquery": "3.7.1",
35 | "prismjs": "1.30.0",
36 | "textpattern-branding": "0.3.3"
37 | },
38 | "optionalDependencies": {
39 | "fibers": "5.0.3"
40 | },
41 | "browserslist": [
42 | "> 0.5%",
43 | "Firefox ESR",
44 | "not IE 11"
45 | ],
46 | "license": "MIT"
47 | }
48 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_fonts.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Fonts
4 | ========================================================================== */
5 |
6 | /**
7 | * 'PT Serif' font.
8 | */
9 |
10 | // Regular
11 | @font-face {
12 | font-family: "PT Serif";
13 | font-style: normal;
14 | font-weight: 400;
15 | font-display: optional;
16 | src: url("https://forum.textpattern.com/style/Textpattern/fonts/pt-serif-v18-latin-ext-regular.woff2") format("woff2");
17 | }
18 |
19 | // Regular Italic
20 | @font-face {
21 | font-family: "PT Serif";
22 | font-style: italic;
23 | font-weight: 400;
24 | font-display: swap;
25 | src: url("https://forum.textpattern.com/style/Textpattern/fonts/pt-serif-v18-latin-ext-italic.woff2") format("woff2");
26 | }
27 |
28 | // Bold
29 | @font-face {
30 | font-family: "PT Serif";
31 | font-style: normal;
32 | font-weight: 700;
33 | font-display: optional;
34 | src: url("https://forum.textpattern.com/style/Textpattern/fonts/pt-serif-v18-latin-ext-700.woff2") format("woff2");
35 | }
36 |
37 | // Bold Italic
38 | @font-face {
39 | font-family: "PT Serif";
40 | font-style: italic;
41 | font-weight: 700;
42 | font-display: swap;
43 | src: url("https://forum.textpattern.com/style/Textpattern/fonts/pt-serif-v18-latin-ext-700italic.woff2") format("woff2");
44 | }
45 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_alerts.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 | @use "sass:math";
3 |
4 | /* Alert messages
5 | ========================================================================== */
6 |
7 | /**
8 | * Alert labels.
9 | *
10 | * Example HTML:
11 | *
12 | *
13 | *
14 | *
15 | *
16 | */
17 |
18 | .success {
19 | color: var(--clr-success-text);
20 | }
21 |
22 | .warning {
23 | color: var(--clr-warning-text);
24 | }
25 |
26 | .error {
27 | color: var(--clr-error-text);
28 | }
29 |
30 | .information {
31 | color: var(--clr-info-text);
32 | }
33 |
34 | /**
35 | * Alert boxes.
36 | *
37 | * 1. Prevent really, really long words from breaking layout.
38 | *
39 | * Example HTML:
40 | *
41 | *
42 | *
43 | */
44 |
45 | .alert-block {
46 | padding: 0.5em 1em;
47 | border: 1px solid;
48 | border-radius: math.div(setup.$border-radius, 2);
49 | word-wrap: break-word; /* 1 */
50 |
51 | &.success {
52 | border-color: var(--clr-success-brdr);
53 | background: var(--clr-success-bkgd);
54 | }
55 |
56 | &.warning {
57 | border-color: var(--clr-warning-brdr);
58 | background: var(--clr-warning-bkgd);
59 | }
60 |
61 | &.error {
62 | border-color: var(--clr-error-brdr);
63 | background: var(--clr-error-bkgd);
64 | }
65 |
66 | &.information {
67 | border-color: var(--clr-info-brdr);
68 | background: var(--clr-info-bkgd);
69 | }
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_layout_admin.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 |
3 | /* Forum admin layout
4 | ========================================================================== */
5 |
6 | /**
7 | * Hide the duplicate submit button at top.
8 | */
9 |
10 | #adminconsole p.submittop {
11 | display: none;
12 | }
13 |
14 | #adminconsole fieldset {
15 | th[scope="row"] {
16 | width: 30%;
17 | }
18 |
19 | input[type="submit"] {
20 | margin: 1em 0;
21 | }
22 |
23 | td span,
24 | th span {
25 | display: block;
26 | margin-top: 0.5em;
27 | }
28 |
29 | td.location span {
30 | display: inline-block;
31 | }
32 | }
33 |
34 | #forumperms thead th,
35 | #forumperms tbody td {
36 | text-align: center;
37 | }
38 |
39 | /**
40 | * Column widths.
41 | */
42 |
43 | #categoryedit .tcl {
44 | width: 50%;
45 | }
46 |
47 | #edforum .tcl,
48 | #edforum .tc2,
49 | #censoring .tcl,
50 | #censoring .tc2 {
51 | width: 30%;
52 | }
53 |
54 | /**
55 | * User bans table.
56 | */
57 |
58 | #bans1 {
59 | .tcl {
60 | width: 30%;
61 | }
62 |
63 | .tc3 {
64 | width: 9em;
65 | }
66 |
67 | .tc4,
68 | .tc5,
69 | .tc6 {
70 | display: none;
71 | }
72 |
73 | .tcr {
74 | width: 7em;
75 | }
76 | }
77 |
78 | /**
79 | * User search table (admin).
80 | */
81 |
82 | #users2 {
83 | .tcl {
84 | width: 20%;
85 | }
86 |
87 | .tc5 {
88 | display: none;
89 | }
90 | }
91 |
92 | /**
93 | * Hide 'select all' link (we filter out inline JavaScript, so it doesn't work).
94 | */
95 |
96 | .modbuttons a {
97 | display: none;
98 | }
99 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_indicators.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 |
3 | /* Forum indicators
4 | ========================================================================== */
5 |
6 | /**
7 | * `tr` hightlight for new posts.
8 | */
9 |
10 | .inew {
11 | background-color: var(--clr-hilite-box);
12 | }
13 |
14 | /**
15 | * Text highlights.
16 | */
17 |
18 | .warntext,
19 | #page-delete .forminfo p {
20 | display: block;
21 | padding: 0.5em 1em; // 8px / 16px
22 | border: 1px solid;
23 | border-radius: 0.25em; // 4px / 16px
24 | }
25 |
26 | .stickytext,
27 | .closedtext,
28 | .movedtext {
29 | margin-right: 0.3333333em;
30 | padding: 1px 0.25em; // 4px / 16px
31 | border: 1px solid;
32 | border-radius: 0.25em; // 4px / 16px
33 | }
34 |
35 | .warntext {
36 | border-color: var(--clr-warning-brdr);
37 | background: var(--clr-warning-bkgd);
38 | color: var(--clr-warning-text);
39 | }
40 |
41 | .stickytext {
42 | border-color: var(--clr-success-brdr);
43 | background: var(--clr-success-bkgd);
44 | color: var(--clr-success-text);
45 | }
46 |
47 | .closedtext,
48 | #page-delete .forminfo p {
49 | border-color: var(--clr-error-brdr);
50 | background: var(--clr-error-bkgd);
51 | color: var(--clr-error-text);
52 | }
53 |
54 | .movedtext {
55 | border-color: var(--clr-info-brdr);
56 | background: var(--clr-info-bkgd);
57 | color: var(--clr-info-text);
58 | }
59 |
60 | /**
61 | * Indicate posts participated in.
62 | */
63 |
64 | .ipost {
65 | @include setup.hide-text;
66 |
67 | display: inline-block;
68 | width: 0.75em;
69 | height: 0.75em;
70 | margin-right: 0.3333333em;
71 | border-radius: 50%;
72 | background-color: var(--clr-hilite);
73 | }
74 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_links.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Links
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Specify link colour.
8 | * 2. Remove default underline style from non-hover state links.
9 | * 3. Interrupt the decoration line to let the shape of the text show through
10 | * in supported browsers.
11 | * 4. Remove tap delay in modern browsers.
12 | */
13 |
14 | a {
15 | color: var(--clr-a); /* 1 */
16 | text-decoration: none; /* 2 */
17 | text-decoration-skip-ink: auto; /* 3 */
18 | text-underline-offset: 0.125em;
19 | touch-action: manipulation; /* 4 */
20 |
21 | &:hover,
22 | &:active {
23 | color: var(--clr-a-interact);
24 | text-decoration: underline;
25 | }
26 |
27 | &:focus {
28 | outline: 1px solid var(--clr-focus);
29 | }
30 | }
31 |
32 | /**
33 | * Additional styling for heading links.
34 | *
35 | * 1. Expanded CSS level 3 `text-decoration-color` property in supported
36 | * browsers, older browsers ignore this addition.
37 | */
38 |
39 | h1,
40 | h2,
41 | h3,
42 | h4,
43 | h5,
44 | h6 {
45 | a {
46 | color: var(--clr-text-promoted);
47 |
48 | &:hover,
49 | &:active {
50 | color: var(--clr-text-promoted);
51 | text-decoration-color: var(--clr-text-promoted-a50); /* 1 */
52 | }
53 | }
54 | }
55 |
56 | /**
57 | * Additional styling for links within complementary content and site footer.
58 | */
59 |
60 | .complementary-content a:not(.button),
61 | .site-footer a {
62 | color: var(--clr-a-alt);
63 |
64 | &:hover,
65 | &:active {
66 | color: var(--clr-a-alt-interact);
67 | }
68 | }
69 |
70 | /**
71 | * Visually hide unfocussed/inactive ‘skip links’.
72 | *
73 | * Example HTML:
74 | *
75 | *
76 | */
77 |
78 | .a--skip-link {
79 | position: absolute;
80 | z-index: 2;
81 | top: 1px;
82 | left: 1px;
83 | padding: 0.25em 0.5em;
84 | transform: translateY(-5em);
85 | transition: transform 0.25s ease-in-out;
86 | background-color: var(--clr-nav-active);
87 | color: var(--clr-text);
88 |
89 | &:focus,
90 | &:active {
91 | transform: translateY(0);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/public/humans.txt:
--------------------------------------------------------------------------------
1 | # https://humanstxt.org
2 | # The humans responsible and
3 | # technology colophon
4 |
5 | # TEAM
6 |
7 | Developer: Team Textpattern
8 | Site: https://textpattern.com
9 | GitHub: https://github.com/textpattern
10 | Mastodon: https://indieweb.social/@textpattern
11 | Twitter: https://twitter.com/textpattern
12 | Location: Everywhere
13 |
14 | # TECHNOLOGY COLOPHON
15 |
16 | Standards: HTML5, CSS3
17 | Server: Nginx, Percona Server for MySQL, PHP
18 | Components:
19 | FluxBB: https://fluxbb.org/
20 | FluxBB_by_Visman: https://github.com/MioVisman/FluxBB_by_Visman
21 | PHP-Textile: https://github.com/textile/php-textile
22 | jQuery: https://jquery.com/
23 | Prism: https://prismjs.com/
24 | Software:
25 | Node.js: https://nodejs.org/
26 | Grunt.js: https://gruntjs.com/
27 | Composer: https://getcomposer.org/
28 | git: https://git-scm.com/
29 | Source: https://github.com/textpattern/textpattern-forum
30 |
31 |
32 | .ttTTttx
33 | xPXTTTTTtt- xppx
34 | pPPTTTTTTTTXxx px xp
35 | .tPTTTTTTTTTTTTt- .t- .t-
36 | xPXTTTTTTTTTTTTTp px xx
37 | -tPTTTTTTTTTTTTTt -x -t
38 | .tPTTTTTTTTTTTTTT. -x .t-
39 | xtXTTTTTTTTTTTTTTTt- xx xx
40 | PxTTTTTTTTTTTTTTTt..-t. -t. .pttx.
41 | xxXTTTTTTTTTTTTTPpp.- px xp xXTt-
42 | -tPTTTTTTTTxTTTXppp... xx px pTTx
43 | xtPTTTTf tTTTxp-... .t-.t. .XTt.
44 | .xxXX- -XTTPxp.- ..Pp tTX-
45 | tTTTtp--xt pTTx
46 | -XTTXtt- .PTP.
47 | xTTp xTTTx
48 | pt pTTTP-.t.
49 | .t- .PTTTP- xx
50 | xx xTTTTTXp-. .t.
51 | -t. -XTx xTTTTt--. px
52 | .t- .PTP. .tTTTTx--.. xp
53 | xx xTTp .PTTTP--. -t.
54 | -t. -XTt pTTTTt.-. px
55 | .t- ..PTX. xTTTTp--.. xp
56 | px .xTTp .PTTTP----..t-
57 | px. .-XTt pTTTTx.p.. -t.
58 | -p. tTX- tTTTXp-p.. px
59 | -xxppTT. -xTTP--.-p
60 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_navigation.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 | @use "sass:math";
3 |
4 | /* Forum navigation menu
5 | ========================================================================== */
6 |
7 | #brdmenu {
8 | ul {
9 | margin: 1em 0 0;
10 | padding: 0;
11 | border-bottom: 1px solid var(--clr-brdr);
12 | list-style: none;
13 | }
14 |
15 | li {
16 | display: inline-block;
17 | }
18 |
19 | a {
20 | display: block;
21 | position: relative;
22 | bottom: -1px;
23 | padding: 0.5em 1em;
24 | border: 1px solid var(--clr-brdr);
25 | border-radius: (math.div(setup.$border-radius, 2)) (math.div(setup.$border-radius, 2)) 0 0;
26 | background-color: var(--clr-bkgd-box);
27 | box-shadow: inset 0 -0.125em 0.25em hsl(0 0% 40% / 0.2);
28 | color: var(--clr-text);
29 | text-decoration: none;
30 |
31 | &:hover {
32 | border-color: var(--clr-brdr-x-dark);
33 | background-color: var(--clr-nav-interact);
34 | }
35 |
36 | &:active {
37 | filter: brightness(0.95);
38 | }
39 |
40 | &:focus {
41 | border-color: var(--clr-focus);
42 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
43 | background-color: var(--clr-nav-interact);
44 | }
45 | }
46 | }
47 |
48 | #brdmenu .isactive a,
49 | #navextra1 a {
50 | border-bottom-color: var(--clr-bkgd);
51 | background-color: var(--clr-bkgd);
52 | box-shadow: none;
53 | }
54 |
55 | @include setup.dark-mode {
56 | #brdmenu {
57 | ul {
58 | border-bottom-color: var(--clr-brdr-lite);
59 | }
60 |
61 | a {
62 | border-color: var(--clr-brdr-lite);
63 | box-shadow: inset 0 -0.125em 0.25em hsl(0 0% 0% / 0.2);
64 |
65 | &:hover {
66 | border-color: var(--clr-brdr);
67 | }
68 |
69 | &:focus {
70 | border-color: var(--clr-focus);
71 | }
72 | }
73 | }
74 |
75 | #brdmenu .isactive a,
76 | #navextra1 a {
77 | border-bottom-color: var(--clr-bkgd);
78 | background-color: var(--clr-bkgd);
79 | box-shadow: none;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_tables.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Tables
4 | ========================================================================== */
5 |
6 | /**
7 | * Consistent tables.
8 | */
9 |
10 | table {
11 | width: 100%;
12 | margin: 1em 0;
13 | border-spacing: 0;
14 | border-collapse: collapse;
15 | }
16 |
17 | /**
18 | * Styling of table captions.
19 | */
20 |
21 | caption {
22 | margin-bottom: 0.5em;
23 | font-style: italic;
24 | text-align: left;
25 | }
26 |
27 | /**
28 | * Make table cells align top and left by default.
29 | */
30 |
31 | th,
32 | td {
33 | padding: 0.5em 1em 0.5em 0;
34 | border-bottom: 1px solid var(--clr-brdr);
35 | vertical-align: top;
36 | text-align: left;
37 |
38 | &:empty {
39 | border: 0;
40 | }
41 |
42 | &:last-child {
43 | padding-right: 0;
44 | }
45 | }
46 |
47 | @include setup.dark-mode {
48 | th,
49 | td {
50 | border-bottom-color: var(--clr-brdr-lite);
51 | }
52 | }
53 |
54 | /**
55 | * Table `thead` non-global borders and padding.
56 | */
57 |
58 | thead {
59 | tr:first-child {
60 | th,
61 | td {
62 | padding-top: 0;
63 | }
64 | }
65 |
66 | tr:last-child {
67 | th,
68 | td {
69 | border-bottom: 2px solid var(--clr-brdr);
70 | }
71 | }
72 | }
73 |
74 | @include setup.dark-mode {
75 | thead tr:last-child {
76 | th,
77 | td {
78 | border-bottom-color: var(--clr-brdr-lite);
79 | }
80 | }
81 | }
82 |
83 | /**
84 | * Table `tfoot` non-global borders and padding.
85 | */
86 |
87 | tfoot {
88 | th,
89 | td {
90 | padding: 0.6666667em; // 8px / 12px
91 | }
92 |
93 | tr:last-child {
94 | th,
95 | td {
96 | padding-bottom: 0;
97 | border-bottom: 0;
98 | }
99 | }
100 | }
101 |
102 | /**
103 | * Table `tbody` non-global borders.
104 | */
105 |
106 | tbody tr:first-child {
107 | td,
108 | th {
109 | border-top: 1px solid var(--clr-brdr);
110 | }
111 | }
112 |
113 | @include setup.dark-mode {
114 | tbody tr:first-child {
115 | td,
116 | th {
117 | border-top-color: var(--clr-brdr-lite);
118 | }
119 | }
120 | }
121 |
122 | /**
123 | * Multi-row span vertical cell alignments.
124 | */
125 |
126 | [rowspan] {
127 | vertical-align: middle;
128 | }
129 |
--------------------------------------------------------------------------------
/src/style/Textpattern/fonts/License.txt:
--------------------------------------------------------------------------------
1 | Copyright © 2009 ParaType Ltd.
2 | with Reserved Names ‘PT Sans’ and ‘ParaType’.
3 |
4 | FONT LICENSE
5 |
6 | PERMISSION & CONDITIONS
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of the font software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the font software, subject to the following conditions:
8 |
9 | 1) Neither the font software nor any of its individual components, in original or modified versions, may be sold by itself.
10 |
11 | 2) Original or modified versions of the font software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
12 |
13 | 3) No modified version of the font software may use the Reserved Name(s) or combinations of Reserved Names with other words unless explicit written permission is granted by the ParaType. This restriction only applies to the primary font name as presented to the users.
14 |
15 | 4) The name of ParaType or the author(s) of the font software shall not be used to promote, endorse or advertise any modified version, except to acknowledge the contribution(s) of ParaType and the author(s) or with explicit written permission of ParaType.
16 |
17 | 5) The font software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
18 |
19 | TERMINATION & TERRITORY
20 | This license has no limits on time and territory, but it becomes null and void if any of the above conditions are not met.
21 |
22 | DISCLAIMER
23 | THE FONT SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL PARATYPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
24 |
25 | ParaType Ltd
26 | https://www.paratype.ru/
27 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_code-highlighting.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Code highlighting (via Prism.js)
4 | ========================================================================== */
5 |
6 | code[class*="language-"],
7 | pre[class*="language-"] {
8 | direction: ltr;
9 | hyphens: none;
10 | text-align: left;
11 | word-wrap: normal;
12 | word-break: normal;
13 | word-spacing: normal;
14 | white-space: pre;
15 | }
16 |
17 | /**
18 | * Inline code.
19 | */
20 |
21 | :not(pre) > code[class*="language-"] {
22 | white-space: normal;
23 | }
24 |
25 | /**
26 | * Syntax colours/styles.
27 | */
28 |
29 | .token.comment,
30 | .token.prolog,
31 | .token.doctype,
32 | .token.cdata {
33 | color: hsl(210 13% 50%);
34 | }
35 |
36 | .token.punctuation {
37 | color: hsl(0 0% 60%);
38 | }
39 |
40 | .namespace {
41 | opacity: 0.7;
42 | }
43 |
44 | .token.property,
45 | .token.tag,
46 | .token.boolean,
47 | .token.number,
48 | .token.constant,
49 | .token.symbol,
50 | .token.deleted {
51 | color: hsl(327 100% 30%);
52 | }
53 |
54 | .token.selector,
55 | .token.attr-name,
56 | .token.string,
57 | .token.char,
58 | .token.builtin,
59 | .token.inserted {
60 | color: hsl(80 100% 30%);
61 | }
62 |
63 | .token.operator,
64 | .token.entity,
65 | .token.url,
66 | .language-css .token.string,
67 | .style .token.string {
68 | color: hsl(30 30% 50%);
69 | }
70 |
71 | .token.atrule,
72 | .token.attr-value,
73 | .token.keyword {
74 | color: hsl(198 100% 33%);
75 | }
76 |
77 | .token.function {
78 | color: hsl(348 68% 58%);
79 | }
80 |
81 | .token.regex,
82 | .token.important,
83 | .token.variable {
84 | color: hsl(39 100% 47%);
85 | }
86 |
87 | .token.important,
88 | .token.bold {
89 | font-weight: 700;
90 | }
91 |
92 | .token.italic {
93 | font-style: italic;
94 | }
95 |
96 | .token.entity {
97 | cursor: help;
98 | }
99 |
100 | @include setup.dark-mode {
101 | .token.punctuation {
102 | color: var(--clr-text-white-enforced);
103 | }
104 |
105 | .token.property,
106 | .token.tag,
107 | .token.boolean,
108 | .token.number,
109 | .token.constant,
110 | .token.symbol,
111 | .token.deleted {
112 | color: var(--clr-error-text);
113 | }
114 |
115 | .token.selector,
116 | .token.attr-name,
117 | .token.string,
118 | .token.char,
119 | .token.builtin,
120 | .token.inserted {
121 | color: var(--clr-success-text);
122 | }
123 |
124 | .token.operator,
125 | .token.entity,
126 | .token.url,
127 | .language-css .token.string,
128 | .style .token.string {
129 | color: var(--clr-warning-text);
130 | }
131 |
132 | .token.atrule,
133 | .token.attr-value,
134 | .token.keyword {
135 | color: var(--clr-info-text);
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_icons.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 |
3 | /* Forum icons
4 | ========================================================================== */
5 |
6 | /**
7 | * Don't show icons on topic lists.
8 | */
9 |
10 | .icon {
11 | display: none;
12 | }
13 |
14 | /**
15 | * Illustrated icons on main index page.
16 | */
17 |
18 | #page-index .icon {
19 | display: block;
20 | width: 60px;
21 | height: 60px;
22 | margin-right: 1em;
23 | float: left;
24 | background-image: url("../img/forum-icons.png");
25 | background-size: 1140px 120px;
26 | background-position-y: 0;
27 |
28 | @media (min-resolution: 1.25dppx), (min-resolution: 120dpi) {
29 | background-image: url("../img/forum-icons@2x.png");
30 | }
31 |
32 | &.icon-new {
33 | background-position-y: -60px;
34 | }
35 |
36 | .nosize {
37 | display: none;
38 | }
39 | }
40 |
41 | @include setup.dark-mode {
42 | #page-index .icon {
43 | background-image: url("../img/dark-forum-icons.png");
44 |
45 | @media (min-resolution: 1.25dppx), (min-resolution: 120dpi) {
46 | background-image: url("../img/dark-forum-icons@2x.png");
47 | }
48 | }
49 | }
50 |
51 | #idx1 tbody {
52 | tr:nth-child(1) .icon {
53 | background-position-x: 0;
54 | }
55 |
56 | tr:nth-child(2) .icon {
57 | background-position-x: -60px;
58 | }
59 |
60 | tr:nth-child(3) .icon {
61 | background-position-x: -120px;
62 | }
63 |
64 | tr:nth-child(4) .icon {
65 | background-position-x: -180px;
66 | }
67 | }
68 |
69 | #idx2 tbody {
70 | tr:nth-child(1) .icon {
71 | background-position-x: -240px;
72 | }
73 |
74 | tr:nth-child(2) .icon {
75 | background-position-x: -300px;
76 | }
77 |
78 | tr:nth-child(3) .icon {
79 | background-position-x: -360px;
80 | }
81 |
82 | tr:nth-child(4) .icon {
83 | background-position-x: -420px;
84 | }
85 |
86 | tr:nth-child(5) .icon {
87 | background-position-x: -480px;
88 | }
89 |
90 | tr:nth-child(6) .icon {
91 | background-position-x: -540px;
92 | }
93 |
94 | tr:nth-child(7) .icon {
95 | background-position-x: -600px;
96 | }
97 |
98 | tr:nth-child(8) .icon {
99 | background-position-x: -660px;
100 | }
101 | }
102 |
103 | #idx3 tbody {
104 | tr:nth-child(1) .icon {
105 | background-position-x: -720px;
106 | }
107 |
108 | tr:nth-child(2) .icon {
109 | background-position-x: -780px;
110 | }
111 |
112 | tr:nth-child(3) .icon {
113 | background-position-x: -840px;
114 | }
115 |
116 | tr:nth-child(4) .icon {
117 | background-position-x: -900px;
118 | }
119 |
120 | tr:nth-child(5) .icon {
121 | background-position-x: -960px;
122 | }
123 |
124 | tr:nth-child(6) .icon {
125 | background-position-x: -1020px;
126 | }
127 |
128 | tr:nth-child(7) .icon {
129 | background-position-x: -1080px;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_social.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Social media
4 | ========================================================================== */
5 |
6 | /**
7 | * Link list of social media channel icons.
8 | *
9 | * Example HTML:
10 | *
11 | *
16 | */
17 |
18 | .social-channels {
19 | padding: 0;
20 | list-style: none;
21 |
22 | li {
23 | display: inline-block;
24 | margin-right: 0.5em;
25 | }
26 |
27 | a {
28 | @include setup.hide-text;
29 |
30 | display: block;
31 | width: 32px;
32 | height: 32px;
33 | background-size: 32px 32px;
34 |
35 | &:hover {
36 | filter: brightness(1.1);
37 | }
38 |
39 | &.github {
40 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23fff' stroke='%23fff' d='M0 0h32v32H0z'/%3E%3Cpath fill='%23171515' d='M16,4C9.4,4,4,9.4,4,16c0,5.3,3.4,9.8,8.2,11.4c0.6,0.1,0.8-0.3,0.8-0.6c0-0.3,0-1,0-2c-3.3,0.7-4-1.6-4-1.6c-0.5-1.4-1.3-1.8-1.3-1.8c-1.1-0.7,0.1-0.7,0.1-0.7c1.2,0.1,1.8,1.2,1.8,1.2c1.1,1.8,2.8,1.3,3.5,1c0.1-0.8,0.4-1.3,0.8-1.6C11.1,21,8.3,20,8.3,15.4c0-1.3,0.5-2.4,1.2-3.2C9.5,11.8,9,10.6,9.7,9c0,0,1-0.3,3.3,1.2c1-0.3,2-0.4,3-0.4c1,0,2,0.1,3,0.4C21.3,8.7,22.3,9,22.3,9c0.7,1.7,0.2,2.9,0.1,3.2c0.8,0.8,1.2,1.9,1.2,3.2c0,4.6-2.8,5.6-5.5,5.9c0.4,0.4,0.8,1.1,0.8,2.2c0,1.6,0,2.9,0,3.3c0,0.3,0.2,0.7,0.8,0.6C24.6,25.8,28,21.3,28,16C28,9.4,22.6,4,16,4z'/%3E%3C/svg%3E");
41 | }
42 |
43 | &.mastodon {
44 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%231f232b' stroke='%23fff' d='M0 0h32v32H0z'/%3E%3Cpath fill='%233088d4' d='m27 18.5c-.3 1.8-3 3.7-6.1 4.1-1.6.2-3.2.4-4.9.3-2.8-.1-4.9-.7-4.9-.7v.8c.4 2.8 2.7 2.9 4.9 3s4.2-.6 4.2-.6l.1 2.1s-1.6.9-4.4 1c-1.5.1-3.5 0-5.7-.6-4.7-1.4-5.6-6.6-5.7-11.9 0-1.6 0-3.1 0-4.3 0-5.4 3.5-7 3.5-7 1.8-.8 4.8-1.2 8-1.2 3.2 0 6.2.4 8 1.2 0 0 3.5 1.6 3.5 7 0 0 0 4-.5 6.8zm-4.6-9.6c-.7-.8-1.6-1.2-2.7-1.2-1.3 0-2.3.5-3 1.5l-.7 1.2-.6-1.1c-.7-1-1.7-1.5-3-1.5-1.1 0-2 .4-2.7 1.2s-1 1.9-1 3.2v6.6h2.6v-6.4c0-1.3.6-2 1.7-2 1.2 0 1.9.8 1.9 2.4v3.5h2.6v-3.5c0-1.6.6-2.4 1.9-2.4 1.1 0 1.7.7 1.7 2v6.4h2.6v-6.6c-.3-1.4-.7-2.5-1.3-3.3z'/%3E%3C/svg%3E");
45 | }
46 |
47 | &.twitter {
48 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%2300aced' stroke='%23fff' d='M0 0h32v32H0z'/%3E%3Cpath fill='%23fff' d='M26.7,9.4c-0.8,0.3-1.6,0.6-2.5,0.7c0.9-0.5,1.6-1.4,1.9-2.4c-0.8,0.5-1.8,0.9-2.8,1c-0.8-0.9-1.9-1.4-3.2-1.4c-2.4,0-4.4,2-4.4,4.4c0,0.3,0,0.7,0.1,1c-3.6-0.2-6.9-1.9-9-4.6c-0.4,0.6-0.6,1.4-0.6,2.2c0,1.5,0.8,2.9,1.9,3.6c-0.7,0-1.4-0.2-2-0.5l0,0c0,2.1,1.5,3.9,3.5,4.3c-0.4,0.1-0.8,0.2-1.2,0.2c-0.3,0-0.6,0-0.8,0c0.6,1.7,2.2,3,4,3c-1.5,1.2-3.4,1.9-5.4,1.9c-0.4,0-0.7,0-1-0.1c1.9,1.2,4.2,2,6.7,2c8.1,0,12.5-6.7,12.5-12.5c0-0.2,0-0.4,0-0.6C25.3,11,26.1,10.3,26.7,9.4z'/%3E%3C/svg%3E");
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our standards
8 |
9 | Examples of behaviour that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behaviour by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviours that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team at enquiries@designhive.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), [version 1.4](http://contributor-covenant.org/version/1/4/).
44 |
--------------------------------------------------------------------------------
/public/api/index.php:
--------------------------------------------------------------------------------
1 | xmlToArray($xml))
39 | {
40 | foreach ($array as &$value)
41 | {
42 | if (!is_array($value) || !isset($value[0]))
43 | {
44 | $value = array($value);
45 | }
46 | }
47 |
48 | return json_encode($array);
49 | }
50 | else
51 | {
52 | if ($buffer)
53 | {
54 | header('Content-Type: application/json');
55 | header('HTTP/1.0 404 Not Found');
56 | return json_encode(array('errors' => (array) $buffer));
57 | }
58 | }
59 |
60 | return json_encode((array) $buffer);
61 | }
62 |
63 | /**
64 | * Converts XML to Array.
65 | *
66 | * @param mixed $xml The document
67 | */
68 |
69 | public function xmlToArray($xml)
70 | {
71 | if (count($xml->children()) === 0)
72 | {
73 | return (string) $xml;
74 | }
75 |
76 | $array = array();
77 |
78 | foreach ($xml->children() as $element => $node)
79 | {
80 | $data = array();
81 |
82 | if (!$node->attributes())
83 | {
84 | $data = $this->xmlToArray($node);
85 | }
86 | else
87 | {
88 | if (count($node->children()))
89 | {
90 | $data = $data + $this->xmlToArray($node);
91 | }
92 | else
93 | {
94 | $data[] = (string) $node;
95 | }
96 |
97 | foreach ($node->attributes() as $name => $value)
98 | {
99 | $data[$name] = (string) $value;
100 | }
101 | }
102 |
103 | if (count($xml->{$element}) > 1)
104 | {
105 | if (!isset($array[$element]))
106 | {
107 | $array[$element] = array();
108 | }
109 |
110 | $array[$element][] = $data;
111 | }
112 | else
113 | {
114 | $array[$element] = $data;
115 | }
116 | }
117 |
118 | return $array;
119 | }
120 | }
121 |
122 | new Textpattern_Fluxbb_Api();
123 | include dirname(dirname(__FILE__)) . '/extern.php';
124 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_buttons.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Buttons
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct `button` style inheritance in Firefox and Opera.
8 | */
9 |
10 | button {
11 | text-transform: none; /* 1 */
12 | }
13 |
14 | /**
15 | * Remove the inner border and padding in Firefox.
16 | */
17 |
18 | button::-moz-focus-inner,
19 | [type="button"]::-moz-focus-inner,
20 | [type="reset"]::-moz-focus-inner,
21 | [type="submit"]::-moz-focus-inner {
22 | padding: 0;
23 | border-style: none;
24 | }
25 |
26 | /**
27 | * 1. Remove browser-specific default styling.
28 | * 2. Improve usability and consistency of cursor style between image-type
29 | * `input` and others.
30 | */
31 |
32 | button,
33 | [type="button"],
34 | [type="reset"],
35 | [type="submit"],
36 | .button,
37 | .postlink a,
38 | .subscribelink a {
39 | @include setup.gradient-linear(var(--clr-btn-grad-from), var(--clr-btn-grad-to));
40 |
41 | display: inline-block;
42 | position: relative;
43 | width: auto;
44 | height: auto;
45 | padding: 0.25em 1em; // 4px / 16px
46 | border: 1px solid var(--clr-btn-brdr);
47 | border-radius: 1em;
48 | background-clip: padding-box;
49 | box-shadow: 0 2px 0 var(--clr-btn-shadow);
50 | color: var(--clr-text-btn);
51 | font-weight: 400;
52 | text-align: center;
53 | appearance: none; /* 2 */
54 | cursor: pointer; /* 1 */
55 | user-select: none;
56 |
57 | &:hover,
58 | &:active {
59 | border-color: var(--clr-btn-brdr-interact);
60 | color: var(--clr-text-btn-interact);
61 | text-decoration: none;
62 | }
63 |
64 | &:hover {
65 | filter: brightness(1.05);
66 | }
67 |
68 | &:active {
69 | top: 2px;
70 | box-shadow: none;
71 | filter: brightness(0.95);
72 | }
73 |
74 | &:focus {
75 | border-color: var(--clr-focus);
76 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
77 | }
78 | }
79 |
80 | /**
81 | * Primary buttons.
82 | *
83 | * Example HTML:
84 | *
85 | *
86 | */
87 |
88 | .button-primary,
89 | .postlink a,
90 | .blockform [name="submit"] {
91 | @include setup.gradient-linear(var(--clr-btn-primary-grad-from), var(--clr-btn-primary-grad-to));
92 |
93 | border-color: var(--clr-btn-primary-brdr);
94 | box-shadow: 0 2px 0 var(--clr-btn-primary-shadow);
95 | font-weight: 700;
96 |
97 | &:hover,
98 | &:active {
99 | border-color: var(--clr-btn-primary-brdr-interact);
100 | }
101 |
102 | &:active {
103 | box-shadow: none;
104 | }
105 |
106 | &:focus {
107 | border-color: var(--clr-focus);
108 | }
109 | }
110 |
111 | /**
112 | * Disbaled button additional styling.
113 | *
114 | * Example HTML:
115 | *
116 | *
117 | */
118 |
119 | button[disabled],
120 | [type="button"][disabled],
121 | [type="reset"][disabled],
122 | [type="submit"][disabled],
123 | .button.disabled {
124 | top: 0 !important;
125 | background: var(--clr-btn-bkgd-disabled) !important;
126 | }
127 |
--------------------------------------------------------------------------------
/public/addons/copyable_captcha.php:
--------------------------------------------------------------------------------
1 | bind('register_after_validation', array($this, 'hook_register_after_validation'));
23 | $manager->bind('register_before_header', array($this, 'hook_register_before_header'));
24 | $manager->bind('register_before_submit', array($this, 'hook_register_before_submit'));
25 | }
26 |
27 | function load_lang()
28 | {
29 | global $pun_user;
30 |
31 | if (isset($this->lang)) return;
32 |
33 | $user_lang = file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/copyable_captcha.php')
34 | ? $pun_user['language']
35 | : 'English';
36 | require PUN_ROOT.'lang/'.$user_lang.'/copyable_captcha.php';
37 |
38 | $this->lang = $lang_copyable_captcha;
39 | }
40 |
41 | function hook_register_after_validation()
42 | {
43 | global $errors, $cookie_name, $cookie_seed;
44 |
45 | if (isset($_POST['req_word']) && isset($_COOKIE[$cookie_name.'_captcha']) && substr_count($_COOKIE[$cookie_name.'_captcha'], '-') === 1) {
46 | list($hash, $time) = explode('-', $_COOKIE[$cookie_name.'_captcha']);
47 | $word = $_POST['req_word'];
48 | if ((int)$time <= time() - 120 || $hash !== sha1(strtolower($word).$cookie_seed.'secret'.$time)) {
49 | $this->load_lang();
50 | $errors[] = $this->lang['Captcha error'];
51 | }
52 | } else {
53 | $this->load_lang();
54 | $errors[] = $this->lang['Captcha error'];
55 | }
56 | }
57 |
58 |
59 | function hook_register_before_header()
60 | {
61 | global $required_fields, $errors, $cookie_name, $cookie_seed;
62 |
63 | $this->load_lang();
64 | $required_fields['req_word'] = $this->lang['Captcha'];
65 |
66 | $time = time();
67 | $word = random_pass(mt_rand(4, 6));
68 | $hash = sha1(strtolower($word).$cookie_seed.'secret'.$time);
69 | forum_setcookie($cookie_name.'_captcha', $hash.'-'.$time, $time + 120);
70 |
71 | $array = str_split($word);
72 | $mixin = random_pass(mt_rand(1, 3));
73 | $i = -1;
74 | $this->styles = '';
75 | foreach (str_split($mixin) as $ch) {
76 | $i = mt_rand($i+1, count($array));
77 | array_splice($array, $i, 0, $ch);
78 | $this->styles .= '.masq i:nth-child('.($i + 1).'){display:none;} ';
79 | }
80 | $this->spans = ''.implode('', $array).'';
81 | }
82 |
83 |
84 | function hook_register_before_submit()
85 | {
86 | global $lang_common;
87 |
88 | $this->load_lang();
89 |
90 | ?>
91 |
101 |
109 | */
110 |
111 | #site-navigation-toggle {
112 | @include setup.hide-text;
113 |
114 | display: none;
115 | position: absolute;
116 | z-index: 2;
117 | top: 0.75rem;
118 | right: 5%;
119 | width: 32px;
120 | height: 32px;
121 | margin-top: 1px;
122 | border: 1px solid var(--clr-bkgd);
123 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23333' d='M4 6h24v4H4zm0 8h24v4H4zm0 8h24v4H4z'/%3E%3C/svg%3E");
124 | background-size: 32px 32px;
125 | user-select: none;
126 | -webkit-touch-callout: none; /* 1 */
127 |
128 | .js & {
129 | display: block;
130 | }
131 |
132 | &.site-navigation-toggle-active {
133 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cg fill='%23333'%3E%3Cpath d='m6.1 23.1 17-17 2.8 2.8-17 17z'/%3E%3Cpath d='m8.9 6.1 17 17-2.8 2.8-17-17z'/%3E%3C/g%3E%3C/svg%3E");
134 | }
135 |
136 | &:hover {
137 | border-color: var(--clr-brdr-x-dark);
138 | }
139 |
140 | &:focus {
141 | border-color: var(--clr-focus);
142 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
143 | }
144 | }
145 |
146 | @include setup.dark-mode {
147 | #site-navigation-toggle {
148 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23ced4da' d='M4 6h24v4H4zm0 8h24v4H4zm0 8h24v4H4z'/%3E%3C/svg%3E");
149 |
150 | &:hover {
151 | border-color: var(--clr-brdr-x-lite);
152 | }
153 |
154 | &.site-navigation-toggle-active {
155 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cg fill='%23ced4da'%3E%3Cpath d='m6.1 23.1 17-17 2.8 2.8-17 17z'/%3E%3Cpath d='m8.9 6.1 17 17-2.8 2.8-17-17z'/%3E%3C/g%3E%3C/svg%3E");
156 | }
157 |
158 | &:focus {
159 | border-color: var(--clr-focus);
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_icons.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Icons
4 | ========================================================================== */
5 |
6 | /**
7 | * Only using heart icon on this site.
8 | *
9 | * Example HTML:
10 | *
11 | *
12 | *
13 | */
14 |
15 | .ui-icon {
16 | display: inline-block;
17 | width: 16px;
18 | height: 16px;
19 | margin-bottom: -2px;
20 | overflow: hidden;
21 | vertical-align: baseline;
22 | text-indent: -9999px;
23 | }
24 |
25 | @include setup.dark-mode {
26 | .ui-icon {
27 | filter: brightness(3) sepia(1) hue-rotate(168deg) saturate(33%);
28 | }
29 |
30 | .button .ui-icon {
31 | filter: none;
32 | }
33 | }
34 |
35 | .ui-icon-mail-closed { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='M1 3h14v10H1V3zm7 6c-.875 0-1.25-.5-1.25-.5L3.25 12h9.5l-3.5-3.5S8.875 9 8 9zm-6 3l4-4-4-4v8zm12 0V4l-4 4 4 4zM9.25 7.5l3.5-3.5h-9.5l3.5 3.5S7.562 8 8 8s1.25-.5 1.25-.5z'/%3E%3C/svg%3E"); }
36 | .ui-icon-home { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg fill='%23333'%3E%3Cpath d='M13 14H3V8l5-5 5 5v6zM9 9H7v4h2V9z'/%3E%3Cpath d='M8 2L2 8H1l7-7 7 7h-1z'/%3E%3C/g%3E%3C/svg%3E"); }
37 | .ui-icon-heart { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='M10.5 2c2.5-.5 4.979 2.174 3.5 5.5C12 12 8 14 8 14s-4-2-6-6.5C.522 4.174 3 1.5 5.5 2 7.522 2.404 8 4 8 4s.479-1.596 2.5-2z'/%3E%3C/svg%3E"); }
38 | .ui-extra-icon-twitter { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='M15 3.465a5.515 5.515 0 0 1-1.648.478 3.016 3.016 0 0 0 1.262-1.678c-.555.346-1.168.6-1.822.693A2.795 2.795 0 0 0 10.698 2c-1.586 0-2.87 1.357-2.87 3.031 0 .237 0 .469.074.693-2.385-.127-4.499-1.333-5.9-3.168a3.15 3.15 0 0 0-.388 1.524c0 1.052.506 1.98 1.276 2.524-.47 0-.912-.153-1.299-.379 0 1.468.983 2.694 2.302 2.973a2.747 2.747 0 0 1-.757.106h-.539c.365 1.205 1.424 2.078 2.622 2.078a5.56 5.56 0 0 1-3.563 1.299c-.232 0-.46 0-.656-.043A7.818 7.818 0 0 0 5.398 14c5.279 0 8.165-4.62 8.165-8.626v-.392c.566-.375 1.053-.908 1.437-1.517z'/%3E%3C/svg%3E"); }
39 | .ui-extra-icon-mastodon { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='m14.223 9.393c-.191.988-1.712 2.068-3.458 2.278-.911.109-1.807.209-2.763.165-1.563-.072-2.797-.375-2.797-.375 0 .153.009.298.028.435.203 1.55 1.53 1.643 2.787 1.686 1.268.044 2.398-.314 2.398-.314l.052 1.152s-.887.479-2.468.567c-.872.048-1.954-.022-3.214-.357-2.734-.727-3.204-3.654-3.276-6.624-.021-.883-.008-1.714-.008-2.41 0-3.037 1.981-3.927 1.981-3.927.999-.461 2.713-.654 4.494-.669h.044c1.782.015 3.497.208 4.495.669 0 0 1.981.89 1.981 3.927.001 0 .025 2.241-.276 3.797zm-2.633-5.352c-.395-.442-.911-.668-1.553-.668-.742 0-1.304.287-1.676.86l-.361.608-.361-.608c-.372-.573-.934-.86-1.676-.86-.641 0-1.158.226-1.553.668-.383.442-.573 1.039-.573 1.791v3.677h1.45v-3.569c0-.752.315-1.134.945-1.134.697 0 1.046.453 1.046 1.349v1.954h1.442v-1.954c0-.896.349-1.349 1.046-1.349.63 0 .946.382.946 1.134v3.569h1.45v-3.677c.001-.752-.19-1.349-.572-1.791z'/%3E%3C/svg%3E"); }
40 | .ui-extra-icon-github { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='M7.999 1a7 7 0 0 0-2.212 13.642c.35.064.478-.152.478-.337 0-.166-.006-.606-.009-1.191-1.947.423-2.358-.938-2.358-.938-.318-.809-.777-1.024-.777-1.024-.636-.434.048-.426.048-.426.702.05 1.072.721 1.072.721.624 1.07 1.638.761 2.037.582.064-.452.245-.761.444-.936-1.554-.177-3.188-.777-3.188-3.46 0-.764.273-1.389.72-1.878-.072-.176-.312-.888.069-1.852 0 0 .588-.188 1.925.718A6.683 6.683 0 0 1 8 4.385c.594.003 1.193.08 1.752.236 1.336-.906 1.923-.718 1.923-.718.382.964.142 1.675.07 1.853.449.489.72 1.114.72 1.878 0 2.689-1.637 3.281-3.196 3.454.251.216.475.643.475 1.296 0 .936-.009 1.691-.009 1.92 0 .187.126.405.481.337A7.001 7.001 0 0 0 7.999 1z'/%3E%3C/svg%3E"); }
41 | .ui-extra-icon-gitlab { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='m3.363 1.685c.078-.247.427-.247.506.002l1.631 4.814h5l1.631-4.814c.08-.249.427-.249.506 0l2.337 7.246c.072.222-.007.464-.192.602l-6.782 4.965-6.781-4.965c-.185-.138-.264-.381-.193-.602z'/%3E%3C/svg%3E"); }
42 | .ui-extra-icon-bitbucket { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23333' d='m1.376 2.001c-.244.038-.41.268-.37.5l1.994 10.999c.036.208.277.503.5.501h9c.223.002.464-.293.5-.501l1.994-10.999c.04-.233-.126-.462-.37-.5zm8.124 8h-3l-.75-4h4.5z'/%3E%3C/svg%3E"); }
43 |
44 | /**
45 | * Red heart.
46 | */
47 |
48 | .button:hover,
49 | .button:active,
50 | .button:focus {
51 | .ui-icon-heart {
52 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23e00' d='M10.5 2c2.5-.5 4.979 2.174 3.5 5.5C12 12 8 14 8 14s-4-2-6-6.5C.522 4.174 3 1.5 5.5 2 7.522 2.404 8 4 8 4s.479-1.596 2.5-2z'/%3E%3C/svg%3E");
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_typography.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 | @use "sass:math";
3 |
4 | /* Typography
5 | ========================================================================== */
6 |
7 | /**
8 | * Establish baseline.
9 | *
10 | * 1. Prevent adjustments of font size after orientation changes in iOS.
11 | */
12 |
13 | html {
14 | font-size: setup.$base-font-size;
15 | line-height: setup.$base-line-height;
16 | text-size-adjust: 100%; /* 1 */
17 | }
18 |
19 | /**
20 | * Global font.
21 | *
22 | * 1. Enable font ligatures globally, where supported by OpenType fonts.
23 | */
24 |
25 | body {
26 | font-family: var(--font-sans-serif);
27 | font-feature-settings: "liga"; /* 1 */
28 | }
29 |
30 | /**
31 | * Harmonize size, style and vertical margin of headings.
32 | */
33 |
34 | h1,
35 | h2,
36 | h3,
37 | h4,
38 | h5,
39 | h6 {
40 | clear: both;
41 | font-family: var(--font-serif);
42 | }
43 |
44 | main {
45 | h1,
46 | h2,
47 | h3,
48 | h4,
49 | h5,
50 | h6, {
51 | color: var(--clr-text-promoted);
52 | }
53 | }
54 |
55 | h1,
56 | h2,
57 | h3 {
58 | letter-spacing: -0.25px;
59 | }
60 |
61 | h1 {
62 | margin: 0.6315789em 0; // 24px / 38px
63 | font-size: 2.375rem; // 38px / 16px
64 | line-height: 1.1842105; // 45px / 38px
65 | }
66 |
67 | h2 {
68 | margin: 0.8571429em 0; // 24px / 28px
69 | font-size: 1.75rem; // 28px / 16px
70 | line-height: 1.25; // 35px / 28px
71 | }
72 |
73 | h3 {
74 | margin: 1em 0; // 22px
75 | font-size: 1.375rem; // 22px / 16px
76 | line-height: 1.3181818; // 29px / 22px
77 | }
78 |
79 | h4 {
80 | margin: 0.8888889em 0; // 16px / 18px
81 | font-size: 1.125rem; // 18px / 16px
82 | line-height: 1.4444444; // 26px / 18px
83 | }
84 |
85 | h5,
86 | h6 {
87 | margin: 1em 0; // 16px
88 | font-size: 1rem;
89 | line-height: setup.$small-line-height;
90 | }
91 |
92 | /**
93 | * Add the correct font weight in Chrome, Edge, and Safari.
94 | */
95 |
96 | b,
97 | strong {
98 | font-weight: 700;
99 | }
100 |
101 | /**
102 | * Add vertical margin to addresses.
103 | */
104 |
105 | address {
106 | margin: 1em 0;
107 | }
108 |
109 | /**
110 | * Oxford English quote behaviour (quotes: ‘ ’, quotes within quotes: “ ”).
111 | */
112 |
113 | q,
114 | blockquote {
115 | quotes: "\2018" "\2019" "\201C" "\201D";
116 | }
117 |
118 | /**
119 | * Additional styling for blockquotes.
120 | */
121 |
122 | blockquote {
123 | margin: 1em 0;
124 | padding: 1px 1em 1px 1.5em;
125 | border-left: 0.25em solid var(--clr-hilite);
126 | border-radius: 0 setup.$border-radius setup.$border-radius 0;
127 | background-color: var(--clr-hilite-box);
128 | }
129 |
130 | /**
131 | * 1. Remove the bottom border in Chrome 57+.
132 | * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
133 | */
134 |
135 | abbr[title] {
136 | border-bottom: 0; /* 1 */
137 | text-decoration: underline dotted; /* 2 */
138 | }
139 |
140 | /**
141 | * Consistent styling for `mark` and `var` tags.
142 | */
143 |
144 | mark,
145 | var {
146 | padding: 0 0.25em; // 0 4px
147 | border-radius: math.div(setup.$border-radius, 2);
148 | background: var(--clr-hilite-box);
149 | color: var(--clr-text);
150 | }
151 |
152 | /**
153 | * Harmonize size and style of computer text.
154 | *
155 | * 1. Don't use ligatures on monospace font.
156 | */
157 |
158 | pre { white-space: pre-wrap; }
159 |
160 | pre,
161 | code,
162 | kbd,
163 | samp {
164 | border: 1px solid var(--clr-brdr-x-lite);
165 | border-radius: 0.2857143em; // 4px / 14px
166 | background-color: var(--clr-bkgd-box);
167 | color: var(--clr-text);
168 | font-family: var(--font-monospaced);
169 | font-feature-settings: normal; /* 1 */
170 | font-size: setup.$code-font-size;
171 | }
172 |
173 | code,
174 | kbd,
175 | samp {
176 | padding: 1px 0.2142857em; // 3px / 14px
177 | }
178 |
179 | /**
180 | * Additional stylng for preformatted text/code.
181 | *
182 | * 1. Truncate deep code boxes.
183 | * 2. Contain overflow in all browsers.
184 | * 3. Don't wrap long words.
185 | * 4. Overflow by default is bad.
186 | * 5. Set tab size to 4 spaces.
187 | */
188 |
189 | pre {
190 | box-sizing: border-box;
191 | max-height: 50vh; /* 1 */
192 | padding: 0.5714286em 1.1428571em; // 8px / 14px + 16px / 14px
193 | overflow-x: auto; /* 2 */
194 | word-wrap: normal; /* 3 */
195 | white-space: pre-wrap; /* 4 */
196 | tab-size: 4; /* 5 */
197 |
198 | code {
199 | padding: 0;
200 | border: 0;
201 | background-color: transparent;
202 | font-size: 1em; // 14px
203 | hyphens: none;
204 | word-wrap: normal;
205 | word-break: normal;
206 | word-spacing: normal;
207 | white-space: pre;
208 | }
209 | }
210 |
211 | /**
212 | * Prevent `sub` and `sup` elements from affecting the line height in all browsers.
213 | */
214 |
215 | sub,
216 | sup.footnote, // override Textile class
217 | sup {
218 | position: relative;
219 | font-size: 0.75em; // 12px / 16px
220 | line-height: 0;
221 | vertical-align: baseline;
222 | }
223 |
224 | sup {
225 | top: -0.5em;
226 | }
227 |
228 | sub {
229 | bottom: -0.25em;
230 | }
231 |
232 | /**
233 | * Harmonize size and style of small text.
234 | */
235 |
236 | small,
237 | tfoot,
238 | .footnote {
239 | font-size: setup.$small-font-size;
240 | }
241 |
242 | /**
243 | * 1. Show the overflow in Edge and IE.
244 | * 2. Add the correct box sizing in Firefox.
245 | */
246 |
247 | hr {
248 | box-sizing: content-box; /* 2 */
249 | height: 0;
250 | overflow: visible; /* 1 */
251 | border: 0; // remove the default `hr` border
252 | border-bottom: 1px solid var(--clr-brdr);
253 | }
254 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/screen.scss:
--------------------------------------------------------------------------------
1 | @use "setup";
2 | @forward "modules";
3 |
4 | /* ==========================================================================
5 | CSS custom variables
6 | ========================================================================== */
7 |
8 | /* stylelint-disable declaration-colon-space-after */
9 |
10 | :root {
11 | // font families
12 | --font-serif: "PT Serif", Georgia, serif;
13 | --font-sans-serif: system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
14 | --font-monospaced: Menlo, Consolas, Monaco, monospace;
15 | // text colours
16 | --clr-text: hsl(0 0% 20%);
17 | --clr-text-promoted: hsl(0 0% 17%);
18 | --clr-text-promoted-a50: hsl(0 0% 17% / 0.5);
19 | --clr-text-demoted: hsl(0 0% 40%);
20 | --clr-text-form: hsl(0 0% 0%);
21 | --clr-text-placeholder: hsl(0 0% 60%);
22 | --clr-text-black-enforced: hsl(0 0% 20%);
23 | --clr-text-white-enforced: hsl(0 0% 100%);
24 | // interaction colours
25 | --clr-a: hsl(216 100% 35%);
26 | --clr-a-interact: hsl(216 100% 50%);
27 | --clr-a-alt: hsl(216 100% 80%);
28 | --clr-a-alt-interact: hsl(216 100% 95%);
29 | --clr-focus: hsl(216 100% 50% / 1);
30 | --clr-nav-interact: hsl(216 95% 85%);
31 | --clr-nav-active: hsl(216 100% 95%);
32 | // neutral colours
33 | --clr-bkgd: hsl(0 0% 100%);
34 | --clr-bkgd-box: hsl(0 0% 97%);
35 | --clr-bkgd-form: hsl(0 0% 100%);
36 | --clr-bkgd-form-disabled: hsl(0 0% 89%);
37 | --clr-grad-from: hsl(0 0% 93%);
38 | --clr-grad-to: hsl(0 0% 87%);
39 | // accent colours
40 | --clr-hilite: hsl(48 100% 63%);
41 | --clr-hilite-enforced: hsl(48 100% 63%);
42 | --clr-strong-hilite-box: hsl(48 100% 76%);
43 | --clr-hilite-box: hsl(48 100% 94%);
44 | // border colours
45 | --clr-brdr-x-lite: hsl(0 0% 85%);
46 | --clr-brdr-lite: hsl(0 0% 82.5%);
47 | --clr-brdr: hsl(0 0% 80%);
48 | --clr-brdr-dark: hsl(0 0% 75%);
49 | --clr-brdr-x-dark: hsl(0 0% 70%);
50 | // button colours
51 | --clr-text-btn: hsl(0 0% 20%);
52 | --clr-text-btn-interact: hsl(0 0% 17%);
53 | --clr-btn-grad-from: hsl(0 0% 93%);
54 | --clr-btn-grad-to: hsl(0 0% 87%);
55 | --clr-btn-brdr: hsl(0 0% 87%);
56 | --clr-btn-brdr-interact: hsl(0 0% 77%);
57 | --clr-btn-shadow: hsl(0 0% 67%);
58 | --clr-btn-primary-grad-from: hsl(48 100% 63%);
59 | --clr-btn-primary-grad-to: hsl(48 100% 57%);
60 | --clr-btn-primary-brdr: hsl(48 100% 57%);
61 | --clr-btn-primary-brdr-interact: hsl(48 100% 47%);
62 | --clr-btn-primary-shadow: hsl(48 100% 37%);
63 | --clr-btn-bkgd-disabled: hsl(0 0% 89%);
64 | // alert colours
65 | --clr-success-text: hsl(120 60% 34%);
66 | --clr-success-bkgd: hsl(120 40% 90%);
67 | --clr-success-brdr: hsl(102 40% 68%);
68 | --clr-warning-text: hsl(41 100% 40%);
69 | --clr-warning-bkgd: hsl(41 64% 91%);
70 | --clr-warning-brdr: hsl(41 64% 71%);
71 | --clr-error-text: hsl(4 69% 36%);
72 | --clr-error-bkgd: hsl(4 43% 91%);
73 | --clr-error-brdr: hsl(4 43% 78%);
74 | --clr-info-text: hsl(200 50% 45%);
75 | --clr-info-bkgd: hsl(200 78% 95%);
76 | --clr-info-brdr: hsl(200 78% 82%);
77 | }
78 |
79 | @include setup.dark-mode {
80 | :root {
81 | // dark mode text colours
82 | --clr-text: hsl(210 14% 83%);
83 | --clr-text-promoted: hsl(0 0% 100%);
84 | --clr-text-promoted-a50: hsl(0 0% 100% / 0.5);
85 | --clr-text-demoted: hsl(210 14% 77%);
86 | --clr-text-form: hsl(0 0% 100%);
87 | --clr-text-placeholder: hsl(210 6% 48%);
88 | // interaction colours
89 | --clr-a: hsl(204 100% 81%);
90 | --clr-a-interact: hsl(204 100% 87%);
91 | --clr-focus: hsl(312 100% 50%);
92 | --clr-nav-interact: hsl(214 45% 19%);
93 | --clr-nav-active: hsl(214 51% 22%);
94 | // neutral colours
95 | --clr-bkgd: hsl(210 11% 24%);
96 | --clr-bkgd-box: hsl(210 11% 21%);
97 | --clr-bkgd-form: hsl(210 11% 18%);
98 | --clr-bkgd-form-disabled: hsl(210 11% 18%);
99 | --clr-grad-from: hsl(210 7% 30%);
100 | --clr-grad-to: hsl(210 7% 36%);
101 | // accent colours
102 | --clr-hilite: hsl(48 100% 63%);
103 | --clr-strong-hilite-box: hsl(48 42% 47%);
104 | --clr-hilite-box: hsl(48 20% 30%);
105 | // border colours
106 | --clr-brdr-x-lite: hsl(210 7% 33%);
107 | --clr-brdr-lite: hsl(210 7% 43%);
108 | --clr-brdr: hsl(210 7% 53%);
109 | --clr-brdr-dark: hsl(210 7% 21%);
110 | --clr-brdr-x-dark: hsl(210 7% 6%);
111 | // alert colours
112 | --clr-success-text: hsl(100 60% 50%);
113 | --clr-success-bkgd: hsl(109 27% 20%);
114 | --clr-success-brdr: hsl(100 60% 50% / 0.33);
115 | --clr-warning-text: hsl(40 100% 62%);
116 | --clr-warning-bkgd: hsl(49 35% 21%);
117 | --clr-warning-brdr: hsl(40 100% 62% / 0.33);
118 | --clr-error-text: hsl(337 100% 60%);
119 | --clr-error-bkgd: hsl(348 34% 21%);
120 | --clr-error-brdr: hsl(337 100% 60% / 0.43);
121 | --clr-info-text: hsl(207 100% 63%);
122 | --clr-info-bkgd: hsl(207 68% 17%);
123 | --clr-info-brdr: hsl(207 100% 63% / 0.38);
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Textpattern support forum
2 |
3 | This repository contains the source code for the [Textpattern support forum](https://forum.textpattern.com/).
4 |
5 | Requires an installation of our [customized clone of FluxBB](https://github.com/textpattern/fluxbb/tree/feature-textpattern-forum).
6 |
7 | ## Supported web browsers
8 |
9 | * Chrome, Edge, Firefox, Safari and Opera the last two recent stable releases.
10 | * Firefox ESR latest major point release.
11 |
12 | Older versions of the above and other browsers may work, but these are the ones we verify.
13 |
14 | Building this repository requires:
15 |
16 | * [Node.js](https://nodejs.org/)
17 | * [Grunt](https://gruntjs.com/)
18 | * [Composer](https://getcomposer.org/)
19 |
20 | Environment must consist of:
21 |
22 | * Apache >=2.2
23 | * PHP >=7.4
24 | * MySQL >=5.0.6
25 | * Unix-like OS, e.g. Linux or macOS
26 |
27 | ## Setup
28 |
29 | ### Installing required tools
30 |
31 | The project uses [Grunt](https://gruntjs.com/) to run tasks and [Sass](http://sass-lang.com/) for CSS pre-processing. This creates a few dependencies in addition to your normal PHP required by FluxBB. First make sure you have base dependencies installed: [Node.js](https://nodejs.org/) and [Grunt](https://gruntjs.com/). You can install Node using the [installer](https://nodejs.org/), Composer using the [installer](https://getcomposer.org/), and Grunt with npm:
32 |
33 | ```ShellSession
34 | $ npm install -g grunt-cli
35 | ```
36 |
37 | Consult the Grunt documentation for more instructions if necessary.
38 |
39 | ### Setting up Apache virtual host
40 |
41 | The `public/` directory is intended to be set as the server's document root. You can do this by adding a new virtual host to your `httpd.conf`. Along the lines of:
42 |
43 | ```apache
44 |
45 | VirtualHost "/absolute/path/to/textpattern-forum/public"
46 | ServerName forum.textpattern.test
47 |
48 | ```
49 |
50 | On a local development server, after this you can use your hosts file to point the development domain to correct location (e.g. back to home), run a local DNS server that resolves .test TLDs, or use a [xip.io](http://xip.io/) domain.
51 |
52 | ### Installing dependencies
53 |
54 | After you have the base dependencies taken care of, you can install the project's dependencies. Navigate to the project's directory, and run the dependency managers:
55 |
56 | ```ShellSession
57 | $ cd textpattern-forum
58 | $ npm install
59 | $ composer install
60 | ```
61 |
62 | **npm** installs Node modules for Grunt and **composer** installs PHP libraries.
63 |
64 | ### Installing FluxBB
65 |
66 | Once you have Grunt installed, you can then install our [customized clone of FluxBB](https://github.com/textpattern/fluxbb/tree/feature-textpattern-forum) - place it in the `public/` directory. Complete FluxBB's installation by following the normal [Installation steps](https://fluxbb.org/docs/v1.5/installing), and use [this as your config.php template](https://github.com/textpattern/textpattern-forum/blob/main/src/setup/config.php.dist).
67 |
68 | ### Updating and patching FluxBB
69 |
70 | Periodically we update our [customized clone of FluxBB](https://github.com/textpattern/fluxbb/tree/feature-textpattern-forum). To update your FluxBB installation, simply install files from that repository again.
71 |
72 | You may need to [adjust the write permissions](https://fluxbb.org/docs/v1.5/installing#write-permissions) on the `public/cache/` directory after updating.
73 |
74 | ## Building
75 |
76 | This repository hosts sources and needs to be built before it can be used. After you have installed all dependencies, you will be able to run tasks using Grunt, including building:
77 |
78 | ```ShellSession
79 | $ grunt @task@
80 | ```
81 |
82 | Where the `@task@` is either `build` or `watch`.
83 |
84 | * The `build` task builds the project.
85 | * The `watch` task will launch a task that watches for file changes; the project is then automatically built if a source file is modified.
86 |
87 | ## REST API
88 |
89 | We offer a public API that can be used to retrieve data from the forums and topics. The public end point can be found from `https://forum.textpattern.com/api`. Data can be retrieved as JSON, and options can be passed optional HTTP query parameters. This API is read-only, and all requests must be done using HTTP GET method. You can also ping resource existence with HEAD, but any other methods are rejected.
90 |
91 | ### Response codes
92 |
93 | HTTP status codes can be used to detect the type of response. The server responds with:
94 |
95 | * 200: Successful response.
96 | * 401: You will need to log in to access this resource. The resource may be removed, or private.
97 | * 404: The resource has been removed, or has never existed.
98 | * 500: Internal server error.
99 | * 503: Server is under maintenance.
100 |
101 | ### Authentication
102 |
103 | Authentication happens using basic HTTP method and regular forum user account.
104 |
105 | ```ShellSession
106 | $ curl -u "username" https://forum.textpattern.com/api/
107 | ```
108 |
109 | If you request a private or removed resource without being logged in, you will be treated with 401 response:
110 |
111 | ```ShellSession
112 | $ curl -I https://forum.textpattern.com/api/posts/401
113 | ```
114 |
115 | Responds with:
116 |
117 | ```
118 | HTTP/1.0 401 Unauthorized
119 | Date: Tue, 15 Oct 2013 09:16:42 GMT
120 | Server: Apache
121 | WWW-Authenticate: Basic realm="Textpattern CMS Support Forum External Syndication"
122 | Connection: close
123 | Content-Type: application/json; charset=UTF-8
124 | ```
125 |
126 | ### Topics
127 |
128 | ```
129 | GET https://forum.textpattern.com/api/topics/:forum
130 | ```
131 |
132 | Returns topics from the specified forum.
133 |
134 | #### Optional parameters
135 |
136 | * **limit**: number items to show. A value between 1 and 50. Defaults to 15.
137 | * **sort**: either `last_post` or `posted`.
138 |
139 | #### Example request
140 |
141 | ```ShellSession
142 | $ curl https://forum.textpattern.com/api/topics/2
143 | ```
144 |
145 | Response headers:
146 |
147 | ```
148 | HTTP/1.1 200 OK
149 | Date: Sun, 13 Oct 2013 11:24:49 GMT
150 | Server: Apache
151 | Content-Type: application/json; charset=UTF-8
152 | ```
153 |
154 | Response body:
155 |
156 | ```
157 | {
158 | "url": ["https:\/\/forum.textpattern.com\/index.php"],
159 | "topic": [
160 | {
161 | "title": "Better way to upload media",
162 | "link": "https:\/\/forum.textpattern.com\/viewtopic.php?id=40096&action=new",
163 | "content": "+ lots<\/p>",
164 | "author": {
165 | "name": "tye",
166 | "uri": "https:\/\/forum.textpattern.com\/profile.php?id=5751"
167 | },
168 | "posted": "26 September 2013 21:51",
169 | "postedutc": "2013-09-24T16:18:48Z",
170 | "id": "40096"
171 | }
172 | ]
173 | }
174 | ```
175 |
176 | ### Posts
177 |
178 | ```
179 | GET https://forum.textpattern.com/api/posts/:topic
180 | ```
181 |
182 | Returns replies from a specific public topic.
183 |
184 | #### Optional parameters
185 |
186 | * **limit**: number items to show. A value between 1 and 50. Defaults to 15.
187 |
188 | #### Example request
189 |
190 | ```ShellSession
191 | $ curl https://forum.textpattern.com/api/posts/40092
192 | ```
193 |
194 | Response headers:
195 |
196 | ```
197 | HTTP/1.1 200 OK
198 | Date: Sun, 13 Oct 2013 12:24:49 GMT
199 | Server: Apache
200 | Content-Type: application/json; charset=UTF-8
201 | ```
202 |
203 | Response body:
204 |
205 | ```
206 | {
207 | "url": ["https:\/\/forum.textpattern.com\/viewtopic.php?id=40092"],
208 | "post": [
209 | {
210 | "title": "Re: Tag tree best practise: to nest or not to nest",
211 | "link": "https:\/\/forum.textpattern.com\/viewtopic.php?pid=275473#p275473",
212 | "content": "
Stef, this is really useful – I’m on the right track. Thank you very much.<\/p>",
213 | "author": {
214 | "name": "gaekwad",
215 | "uri": "https:\/\/forum.textpattern.com\/profile.php?id=7456"
216 | },
217 | "posted": "26 September 2013 21:51",
218 | "postedutc": "2013-09-24T16:18:48Z",
219 | "id": "275473"
220 | }
221 | ]
222 | }
223 | ```
224 |
225 | ## Contributing
226 |
227 | Want to help out with the development of Textpattern CMS? Please refer to the [Contributing documentation](https://docs.textpattern.com/development/contributing) for full details.
228 |
229 | ## License
230 |
231 | Licensed under MIT license.
232 |
--------------------------------------------------------------------------------
/src/style/Textpattern/maintenance.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Go to main content
30 |
31 |
35 |
49 |
50 |
51 |
Textpattern CMS support forum
52 |
53 |
54 |
55 |
56 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/style/Textpattern/js/app.js:
--------------------------------------------------------------------------------
1 | (function ()
2 | {
3 | 'use strict';
4 |
5 | // Load objects as variables.
6 |
7 | var code = document.querySelectorAll('pre code'),
8 | navmenu = document.getElementById('site-navigation');
9 |
10 | // Syntax highlighting, via 'Prism'.
11 | // Applies syntax highlighting to `code` HTML elements.
12 | // More info - https://prismjs.com.
13 |
14 | if (code.length) {
15 | var elems = document.querySelectorAll('.language-txp');
16 |
17 | [].forEach.call(elems, function(el) {
18 | el.classList.add('language-html');
19 | el.classList.remove('language-txp');
20 | });
21 |
22 | Prism.highlightAll();
23 | }
24 |
25 | // Responsive navigation menu.
26 |
27 | if (navmenu) {
28 | var navtoggle = document.getElementById('site-navigation-toggle'),
29 | navlist = document.getElementById('site-navigation-list');
30 |
31 | navtoggle.addEventListener('click', function(e)
32 | {
33 | e.preventDefault();
34 | navtoggle.classList.toggle('site-navigation-toggle-active');
35 | navmenu.classList.toggle('site-navigation-open');
36 | });
37 |
38 | navlist.addEventListener('focusin', function()
39 | {
40 | navtoggle.classList.add('site-navigation-toggle-active');
41 | navmenu.classList.add('site-navigation-open');
42 | });
43 |
44 | navlist.addEventListener('focusout', function()
45 | {
46 | navtoggle.classList.remove('site-navigation-toggle-active');
47 | navmenu.classList.remove('site-navigation-open');
48 | });
49 | }
50 |
51 | // Quoting.
52 |
53 | $(function ()
54 | {
55 | var field = $('#quickpostform textarea[name=req_message]'), button;
56 |
57 | if (!field.length) {
58 | return;
59 | }
60 |
61 | $('.postlink a').eq(0).attr('href', '#quickpostform');
62 |
63 | button = $('Quote').on('click', function ()
64 | {
65 | var $this = $(this),
66 | tagStart,
67 | tagEnd,
68 | paragraph,
69 | post = $this.parents('.blockpost').eq(0),
70 | name = post.find('.postleft dl dt').eq(0).text(),
71 | message = post.find('.postmsg').eq(0).clone().find('.postedit, table').remove().end(),
72 | link = post.find('h2 a').eq(0).attr('href'),
73 | postId = post.attr('id').substr(1),
74 | value = $.trim(field.val());
75 |
76 | // Remove quotes.
77 |
78 | message.find('blockquote').each(function ()
79 | {
80 | var bq = $(this), prev = bq.prev('h6, p');
81 |
82 | if (prev.length && $.trim(prev.text()).substr(-1) === ':') {
83 | prev.remove();
84 | }
85 |
86 | bq.remove();
87 | });
88 |
89 | // Compress code blocks to a single line.
90 |
91 | message.find('pre').each(function ()
92 | {
93 | $(this).after('@' + $.trim($('
').text($(this).text()).html().split('\n').slice(0, 1).join('')) + '...@
').remove();
94 | });
95 |
96 | // Links.
97 |
98 | message.find('a').each(function ()
99 | {
100 | $(this).prepend('"').append('":' + $('').text($(this).attr('href')).html());
101 | });
102 |
103 | // Images.
104 |
105 | message.find('img').each(function ()
106 | {
107 | $(this).after('!' + $('').text($(this).attr('src')).html() + '!').remove();
108 | });
109 |
110 | // Spans.
111 |
112 | message.find('strong').prepend('*').append('*');
113 | message.find('b').prepend('**').append('**');
114 | message.find('cite').prepend('??').append('??');
115 | message.find('em').prepend('_').append('_');
116 | message.find('i').prepend('__').append('__');
117 | message.find('del').prepend('-').append('-');
118 | message.find('ins').prepend('+').append('+');
119 | message.find('sub').prepend('~').append('~');
120 | message.find('sup').prepend('^').append('^');
121 | message.find('code').prepend('@').append('@');
122 |
123 | // Headings.
124 |
125 | message.find('h1, h2, h3, h4, h5, h6').prepend('*').append('*');
126 |
127 | // Lists. Textile will wrap the lists in paragraphs as of 3.5.x.
128 |
129 | $.each({'ol' : '#', 'ul' : '*'}, function (type, marker)
130 | {
131 | message.children(type).each(function ()
132 | {
133 | var items = [], list = $(this);
134 |
135 | list.find('li').each(function ()
136 | {
137 | var bullet = '';
138 |
139 | for (var i = 0; i < $(this).parents(list).length / 2; i++) {
140 | bullet += marker;
141 | }
142 |
143 | items.push(bullet + ' ' + $.trim($(this).clone().children(type).remove().end().html()));
144 | });
145 |
146 | list.after('' + items.join('\n') + '
').remove();
147 | });
148 | });
149 |
150 | paragraph = message.find('h1, h2, h3, h4, h5, h6, p');
151 |
152 | if (paragraph.length > 1) {
153 | tagStart = '\n\nbq.. ';
154 | tagEnd = '\n\np. ';
155 | } else {
156 | tagStart = '\n\nbq. ';
157 | tagEnd = '\n\n';
158 | }
159 |
160 | message = $.trim(paragraph.append('\n\n').text());
161 |
162 | if (value) {
163 | value = $.trim(value).replace(/\r?\n\r?\np\.$/, '') + '\n\n';
164 | }
165 |
166 | name = $.trim(name).replace(/==/, '');
167 |
168 | if (message) {
169 | value = value + 'h6. ==' + name + '== wrote "#' + postId + '":./' + link + ':' + tagStart + message + tagEnd;
170 | } else {
171 | value = value + 'h6. In reply to ==' + name + '== "#' + postId + '":./' + link + ':\n\n';
172 | }
173 |
174 | field.val(value).focus();
175 |
176 | if ($.type(field[0].setSelectionRange) !== 'undefined') {
177 | field[0].setSelectionRange(value.length, value.length);
178 | }
179 | });
180 |
181 | $('.postfootright ul').append($('').html($('').html(button)));
182 | });
183 |
184 | // Embed widgets.
185 |
186 | $(function ()
187 | {
188 | var loadTwitter = false,
189 | tweetRegex = /^https?:\/\/twitter\.com\/(#!\/)?[a-z0-9]+\/status(es)?\/[0-9]+$/i,
190 | youtubeRegex = /^https?:\/\/(?:www\.)?(?:youtube\.com\/watch(?:\/|\?v=)|youtu\.be\/)([a-z0-9\-\_]+)$/i;
191 |
192 | $('.postmsg > p > a').each(function ()
193 | {
194 | var $this = $(this), href = $this.attr('href'), matches;
195 |
196 | if ($this.parent().text() !== $this.text()) {
197 | return;
198 | }
199 |
200 | if (tweetRegex.test(href)) {
201 | loadTwitter = true;
202 |
203 | $this.parent().after(
204 | $('').html($this.parent().html())
205 | ).hide();
206 |
207 | return;
208 | }
209 |
210 | matches = href.match(youtubeRegex);
211 |
212 | if (matches) {
213 | $this.parent().after(
214 | $('').html(
215 | $('').attr('src', 'https://www.youtube-nocookie.com/embed/' + matches[1])
216 | )
217 | ).hide();
218 |
219 | return;
220 | }
221 | });
222 |
223 | if (loadTwitter) {
224 | $('head').append('');
225 |
226 | window.twttr = (function(d, s, id) {
227 | var js, fjs = d.getElementsByTagName(s)[0],
228 | t = window.twttr || {};
229 |
230 | if (d.getElementById(id)){
231 | return t;
232 | }
233 |
234 | js = d.createElement(s);
235 | js.id = id;
236 | js.src = "https://platform.twitter.com/widgets.js";
237 | fjs.parentNode.insertBefore(js, fjs);
238 | t._e = [];
239 | t.ready = function(f) {
240 | t._e.push(f);
241 | };
242 |
243 | return t;
244 | }(document, "script", "twitter-wjs"));
245 |
246 | }
247 | });
248 |
249 | })();
250 |
--------------------------------------------------------------------------------
/src/503.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 503 service unavailable / Textpattern CMS support forum
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Go to main content
32 |
33 |
37 |
51 |
52 |
53 |
54 |
55 |
56 | 503
57 | Service Unavailable
58 |
59 |
The web server is temporarily unable to fulfil your request, please try again later.
60 |
61 |
62 |

63 |
64 |
65 |
66 |
67 |
68 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/src/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 500 internal server error / Textpattern CMS support forum
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Go to main content
32 |
33 |
37 |
51 |
52 |
53 |
54 |
55 |
56 | 500
57 | Internal Server Error
58 |
59 |
The web server encountered an unexpected error that prevented it from fulfilling your request.
60 |
61 |
62 |

63 |
64 |
65 |
66 |
67 |
68 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt)
2 | {
3 | 'use strict';
4 |
5 | // Load all Grunt tasks.
6 | require('load-grunt-tasks')(grunt);
7 |
8 | grunt.initConfig({
9 | pkg: grunt.file.readJSON('package.json'),
10 |
11 | // Set up paths.
12 | paths: {
13 | src: {
14 | fonts: 'src/style/Textpattern/fonts/',
15 | sass: 'src/style/Textpattern/sass/',
16 | js: 'src/style/Textpattern/js/',
17 | templates: 'src/style/Textpattern/'
18 | },
19 | dest: {
20 | css: 'public/style/Textpattern/css/',
21 | fonts: 'public/style/Textpattern/fonts/',
22 | js: 'public/style/Textpattern/js/',
23 | templates: 'public/style/Textpattern/'
24 | }
25 | },
26 |
27 | // Set up timestamp.
28 | opt : {
29 | timestamp: '<%= new Date().getTime() %>'
30 | },
31 |
32 | // Clean distribution directory to start afresh.
33 | clean: [
34 | 'public/style/'
35 | ],
36 |
37 | // Run some tasks in parallel to speed up the build process.
38 | concurrent: {
39 | dist: [
40 | 'copy:branding',
41 | 'css',
42 | 'jshint',
43 | 'theme'
44 | ]
45 | },
46 |
47 | // Copy files from `src/` and `node_modules/` to `public/`.
48 | copy: {
49 | branding: {
50 | files: [
51 | {
52 | expand: true,
53 | cwd: '<%= paths.src.fonts %>',
54 | src: '**',
55 | dest: '<%= paths.dest.fonts %>'
56 | },
57 | {
58 | expand: true,
59 | cwd: 'node_modules/textpattern-branding/img/',
60 | src: '**',
61 | dest: 'public/style/Textpattern/img/branding/'
62 | },
63 | {
64 | expand: true,
65 | cwd: 'node_modules/textpattern-branding/img/favicons/',
66 | src: '**',
67 | dest: 'public/'
68 | }
69 | ]
70 | },
71 | theme: {
72 | files: [
73 | {
74 | expand: true,
75 | cwd: 'src/style/',
76 | src: ['Textpattern.css', '.htaccess'],
77 | dest: 'public/style/'
78 | },
79 | {
80 | expand: true,
81 | cwd: '<%= paths.src.templates %>',
82 | src: ['**', '!*.tpl', '!sass/**', '!js/**'],
83 | dest: '<%= paths.dest.templates %>'
84 | }
85 | ]
86 | }
87 | },
88 |
89 | // Check code quality of Gruntfile.js and site-specific JavaScript using JSHint.
90 | jshint: {
91 | options: {
92 | bitwise: true,
93 | browser: true,
94 | curly: true,
95 | eqeqeq: true,
96 | esversion: 6,
97 | forin: true,
98 | globals: {
99 | $: true,
100 | jquery: true,
101 | module: true,
102 | require: true,
103 | Prism: true
104 | },
105 | latedef: true,
106 | noarg: true,
107 | nonew: true,
108 | strict: true,
109 | undef: true,
110 | unused: false
111 | },
112 | files: [
113 | 'Gruntfile.js',
114 | 'src/style/Textpattern/js/app.js'
115 | ]
116 | },
117 |
118 | // Add vendor prefixed styles and other post-processing transformations.
119 | postcss: {
120 | options: {
121 | processors: [
122 | require('autoprefixer'),
123 | require('cssnano')
124 | ]
125 | },
126 | dist: {
127 | src: '<%= paths.dest.css %>*.css'
128 | }
129 | },
130 |
131 | // Generate latest timestamp within theme template files.
132 | replace: {
133 | theme: {
134 | options: {
135 | patterns: [
136 | {
137 | match: 'timestamp',
138 | replacement: '<%= opt.timestamp %>'
139 | },
140 | {
141 | match: 'year',
142 | replacement: '<%= new Date().getFullYear() %>'
143 | }
144 | ]
145 | },
146 | files: [
147 | {
148 | expand: true,
149 | cwd: '<%= paths.src.templates %>',
150 | src: ['*.tpl'],
151 | dest: '<%= paths.dest.templates %>'
152 | },
153 | {
154 | expand: true,
155 | cwd: 'src/',
156 | src: ['*.html'],
157 | dest: 'public/'
158 | }
159 | ]
160 | }
161 | },
162 |
163 | // Sass configuration.
164 | sass: {
165 | options: {
166 | implementation: require('sass'),
167 | outputStyle: 'expanded', // outputStyle = expanded, nested, compact or compressed.
168 | sourceMap: false
169 | },
170 | dist: {
171 | files: [
172 | {'<%= paths.dest.css %>screen.css': '<%= paths.src.sass %>screen.scss'}
173 | ]
174 | }
175 | },
176 |
177 | // Validate CSS files via stylelint.
178 | stylelint: {
179 | options: {
180 | configFile: '.stylelintrc.yml'
181 | },
182 | src: ['<%= paths.src.sass %>**/*.{css,scss}']
183 | },
184 |
185 | // Minify `app.js`.
186 | terser: {
187 | options: {
188 | ecma: 2015,
189 | compress: {
190 | booleans_as_integers: true,
191 | drop_console: true
192 | },
193 | format: {
194 | comments: false
195 | }
196 | },
197 | dist: {
198 | files: [
199 | {
200 | '<%= paths.dest.js %>app.js': [
201 | 'node_modules/jquery/dist/jquery.slim.js',
202 | 'node_modules/prismjs/prism.js',
203 | 'node_modules/prismjs/components/prism-markup-templating.js',
204 | 'node_modules/prismjs/components/prism-apacheconf.js',
205 | 'node_modules/prismjs/components/prism-bash.js',
206 | 'node_modules/prismjs/components/prism-git.js',
207 | 'node_modules/prismjs/components/prism-json.js',
208 | 'node_modules/prismjs/components/prism-less.js',
209 | 'node_modules/prismjs/components/prism-markdown.js',
210 | 'node_modules/prismjs/components/prism-nginx.js',
211 | 'node_modules/prismjs/components/prism-perl.js',
212 | 'node_modules/prismjs/components/prism-php.js',
213 | 'node_modules/prismjs/components/prism-sass.js',
214 | 'node_modules/prismjs/components/prism-scss.js',
215 | 'node_modules/prismjs/components/prism-sql.js',
216 | 'node_modules/prismjs/components/prism-stylus.js',
217 | 'node_modules/prismjs/components/prism-textile.js',
218 | '<%= paths.src.js %>app.js'
219 | ]
220 | }
221 | ]
222 | }
223 | },
224 |
225 | // Directories watched and tasks performed by invoking `grunt watch`.
226 | watch: {
227 | sass: {
228 | files: '<%= paths.src.sass %>**/*.scss',
229 | tasks: 'css'
230 | },
231 | js: {
232 | files: '<%= paths.src.js %>**',
233 | tasks: [
234 | 'jshint',
235 | 'terser'
236 | ]
237 | },
238 | theme: {
239 | files: [
240 | '!src/style/*/sass/**',
241 | '!src/style/*/js/**',
242 | 'src/style/*/**',
243 | 'src/*.html'
244 | ],
245 | tasks: 'theme'
246 | }
247 | }
248 | });
249 |
250 | // Register tasks.
251 | grunt.registerTask('build', ['clean', 'concurrent', 'terser']);
252 | grunt.registerTask('css', ['stylelint', 'sass', 'postcss']);
253 | grunt.registerTask('default', ['watch']);
254 | grunt.registerTask('theme', ['copy:theme', 'replace']);
255 | grunt.registerTask('travis', ['build']);
256 | };
257 |
--------------------------------------------------------------------------------
/src/style/Textpattern/redirect.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Go to main content
31 |
32 |
48 |
62 |
63 |
64 |
Textpattern CMS support forum
65 |
66 |
67 |
68 |
69 |
70 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/src/style/Textpattern/admin.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Go to main content
31 |
32 |
48 |
62 |
63 |
64 |
Textpattern CMS support forum
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/src/style/Textpattern/main.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Go to main content
31 |
32 |
48 |
62 |
63 |
64 |
Textpattern CMS support forum
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_responsive.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 | @use "sass:math";
3 |
4 | /* ==========================================================================
5 | Styling and layout for screen media at 2nd breakpoint
6 | ========================================================================== */
7 |
8 | @media (min-width: setup.$breakpoint-2) {
9 | /**
10 | * Grid container.
11 | */
12 |
13 | .layout-container {
14 | display: grid;
15 | gap: 0 2em;
16 | grid-template-columns: repeat(12, 1fr);
17 | }
18 |
19 | /**
20 | * Generate sizes all for grid column cells.
21 | *
22 | * Example HTML:
23 | *
24 | *
25 | *
26 | *
27 | *
28 | *
29 | *
30 | *
31 | */
32 |
33 | .layout-1col {
34 | grid-column: span 12;
35 | overflow: hidden; // Fix for Firefox content overflowing.
36 | }
37 |
38 | .layout-2col {
39 | grid-column: span 6;
40 | overflow: hidden; // Fix for Firefox content overflowing.
41 | }
42 |
43 | .layout-3col {
44 | grid-column: span 4;
45 | overflow: hidden; // Fix for Firefox content overflowing.
46 | }
47 |
48 | .layout-3col-2span {
49 | grid-column: span 8;
50 | overflow: hidden; // Fix for Firefox content overflowing.
51 | }
52 |
53 | /**
54 | * Changes in styling for site header.
55 | */
56 |
57 | .masthead a {
58 | width: 320px;
59 | height: 52px;
60 | background-size: 320px 52px;
61 | }
62 |
63 | /**
64 | * Changes in styling for search form.
65 | */
66 |
67 | .search-form {
68 | top: 0.75em;
69 | right: 0;
70 |
71 | [type="search"] {
72 | width: 254px;
73 | }
74 | }
75 |
76 | @include setup.dark-mode {
77 | .search-form [type="search"] {
78 | background-color: var(--clr-bkgd-form);
79 | }
80 | }
81 |
82 | /**
83 | * Changes in styling for navigation.
84 | */
85 |
86 | #site-navigation {
87 | transition: none;
88 |
89 | .js & {
90 | max-height: none;
91 | overflow: visible;
92 | }
93 |
94 | ul {
95 | display: flex;
96 | width: 90%;
97 | }
98 |
99 | li {
100 | border: 0;
101 |
102 | &:first-child,
103 | &:last-child {
104 | border: 0;
105 | }
106 | }
107 |
108 | a {
109 | margin: 0 0.2727273em 0.2727273em -0.2727273em; // 6px / 22px
110 | padding: 0 0.2727273em; // 6px / 22px
111 | border: 1px solid var(--clr-bkgd);
112 | border-radius: math.div(setup.$border-radius, 2);
113 | font-size: 1.375em; // 22px / 16px
114 | font-weight: 400;
115 |
116 | &:focus {
117 | border-color: var(--clr-focus);
118 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
119 | }
120 | }
121 | }
122 |
123 | @include setup.dark-mode {
124 | #site-navigation ul {
125 | background-color: var(--clr-bkgd);
126 | }
127 | }
128 |
129 | #site-navigation-toggle,
130 | .js #site-navigation-toggle {
131 | display: none;
132 | }
133 |
134 | /**
135 | * Changes in styling for site footer.
136 | */
137 |
138 | .wrapper-footer {
139 | contains-intrinsic-size: 0 374px;
140 | }
141 |
142 | .community-details,
143 | .host-details {
144 | display: block;
145 | }
146 |
147 | /**
148 | * Forum header area.
149 | */
150 |
151 | #brdwelcome {
152 | li {
153 | display: inline;
154 |
155 | span::before {
156 | content: " \2605 \0020";
157 | opacity: 0.5;
158 | }
159 | }
160 |
161 | li:first-child span::before {
162 | content: none;
163 | }
164 | }
165 |
166 | /**
167 | * Limit width of login panels on larger screens.
168 | */
169 |
170 | #rules,
171 | #regform,
172 | #page-login .blockform {
173 | width: 66.666%;
174 | }
175 |
176 | /**
177 | * Forum layouts with side menus.
178 | */
179 |
180 | .block2col .blockmenu {
181 | width: 22.8571429%;
182 | float: right;
183 | }
184 |
185 | /**
186 | * Forum layouts with side menus.
187 | */
188 |
189 | .block2col .block,
190 | .block2col .blockform {
191 | width: 74.2857143%;
192 | float: left;
193 | }
194 |
195 | /**
196 | * Post reply section.
197 | */
198 |
199 | #quickpost {
200 | fieldset,
201 | .buttons {
202 | padding-left: 31.4285713%;
203 | }
204 | }
205 | }
206 |
207 | @media (max-width: setup.$breakpoint-2) {
208 | /**
209 | * Changes in styling for search form.
210 | */
211 |
212 | .search-form {
213 | [type="search"] {
214 | padding-right: 0;
215 | cursor: pointer;
216 |
217 | &:focus {
218 | width: 254px;
219 | cursor: auto;
220 | }
221 | }
222 | }
223 |
224 | /**
225 | * Hide illustrated icons on main index page for small screen widths.
226 | */
227 |
228 | #page-index .icon {
229 | display: none;
230 | }
231 |
232 | /**
233 | * User bans table.
234 | */
235 |
236 | #bans1 {
237 | .tcl {
238 | width: auto;
239 | }
240 |
241 | .tc2,
242 | .tc3 {
243 | display: none;
244 | }
245 | }
246 |
247 | /**
248 | * User search table (admin).
249 | */
250 |
251 | #users2 {
252 | .tcl {
253 | width: auto;
254 | }
255 |
256 | .tc2,
257 | .tc4 {
258 | display: none;
259 | }
260 | }
261 |
262 | /**
263 | * Forum header area.
264 | */
265 |
266 | #brdwelcome {
267 | .conl {
268 | margin-bottom: 0;
269 | float: none;
270 | }
271 |
272 | .conr {
273 | margin-top: 0;
274 | float: none;
275 | }
276 | }
277 |
278 | /**
279 | * Forum announcement box.
280 | */
281 |
282 | #announce {
283 | .hd h2 {
284 | float: none;
285 | }
286 |
287 | .box {
288 | float: none;
289 | }
290 | }
291 |
292 | /**
293 | * Forum breadcrumbs, postlink and pagination layout.
294 | */
295 |
296 | .pagepost {
297 | .pagelink,
298 | .postlink {
299 | margin: 0.5em 0;
300 | float: none;
301 | }
302 | }
303 |
304 | /**
305 | * Forum layouts with side menus.
306 | */
307 |
308 | .blockform [type="email"],
309 | .blockform [type="number"],
310 | .blockform [type="password"],
311 | .blockform [type="text"],
312 | .blockform [type="url"],
313 | .blockform select {
314 | width: 100%;
315 | }
316 |
317 | /**
318 | * Forum topic list, post list and search list page layout.
319 | */
320 |
321 | #page-index,
322 | #page-viewforum,
323 | #page-moderate,
324 | #page-search {
325 | .tc2,
326 | .tc3 {
327 | // Hide columns at small screen widths
328 | display: none;
329 | }
330 |
331 | .tcr {
332 | // Widen column at small screen widths
333 | width: 36%;
334 | }
335 | }
336 |
337 | /**
338 | * Post author info section.
339 | */
340 |
341 | .postleft {
342 | position: relative;
343 | width: auto;
344 | min-height: 60px;
345 | padding-right: 86px;
346 | float: none;
347 |
348 | dl {
349 | margin-bottom: 1em;
350 | }
351 | }
352 |
353 | .postavatar {
354 | position: absolute;
355 | top: 0;
356 | right: 1em;
357 |
358 | img {
359 | margin: 0;
360 | }
361 | }
362 |
363 | /**
364 | * Post author message section.
365 | */
366 |
367 | .postright {
368 | width: auto;
369 | padding: 1px 1em;
370 | float: none;
371 | border-radius: 0;
372 | }
373 |
374 | /**
375 | * User search table.
376 | */
377 |
378 | #users1 {
379 | .tcl {
380 | width: 50%;
381 | }
382 |
383 | .tc2 {
384 | display: none;
385 | }
386 | }
387 |
388 | /**
389 | * Don't let long words break mobile layouts.
390 | */
391 |
392 | #page-viewforum .tclcon,
393 | #page-moderate .tclcon,
394 | #page-search .tclcon {
395 | hyphens: auto;
396 | }
397 |
398 | /**
399 | * Forum navigation menu.
400 | */
401 |
402 | #brdmenu {
403 | ul {
404 | border: 0;
405 | }
406 |
407 | a {
408 | margin-top: 0.25em;
409 | border-radius: math.div(setup.$border-radius, 2);
410 | box-shadow: none;
411 | }
412 | }
413 |
414 | #brdmenu .isactive a,
415 | #navextra1 a {
416 | border-bottom-color: var(--clr-brdr);
417 |
418 | &:hover {
419 | border-bottom-color: var(--clr-brdr-x-dark);
420 | }
421 | }
422 |
423 | @include setup.dark-mode {
424 | #brdmenu .isactive a,
425 | #navextra1 a {
426 | border-bottom-color: var(--clr-brdr-lite);
427 |
428 | &:hover {
429 | border-bottom-color: var(--clr-brdr);
430 | }
431 | }
432 | }
433 | }
434 |
435 | @media (max-width: setup.$breakpoint-3) {
436 | /**
437 | * User search table (admin).
438 | */
439 |
440 | #users2 .tc3 {
441 | display: none;
442 | }
443 | }
444 |
--------------------------------------------------------------------------------
/src/403.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
403 forbidden / Textpattern CMS support forum
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Go to main content
34 |
35 |
51 |
65 |
66 |
67 |
68 |
76 |
77 |

78 |
79 |
80 |
81 |
82 |
83 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/src/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
404 not found / Textpattern CMS support forum
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Go to main content
34 |
35 |
51 |
65 |
66 |
67 |
68 |
69 |
70 | 404
71 | Not Found
72 |
73 |
This page may have moved or is no longer available.
74 |
Please return to the forum index.
75 |
76 |
77 |

78 |
79 |
80 |
81 |
82 |
83 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/_forms.scss:
--------------------------------------------------------------------------------
1 | @use "../setup";
2 |
3 | /* Forms
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Address width being affected by wide descendants in Chrome, Firefox.
8 | * 2. Define consistent fieldset border, margin, and padding.
9 | */
10 |
11 | fieldset {
12 | min-width: 0; /* 1 */
13 | margin: 1em 0; /* 2 */
14 | padding: 1px 1em; /* 2 */
15 | border: 1px solid var(--clr-brdr); /* 2 */
16 | }
17 |
18 | /**
19 | * Stylize fieldset legends.
20 | *
21 | * 1. Correct wrapping not present in Edge 12/13.
22 | */
23 |
24 | legend {
25 | display: table; /* 1 */
26 | box-sizing: border-box; /* 1 */
27 | max-width: 100%; /* 1 */
28 | margin: 0 -1em;
29 | padding: 0.25em 1em; // 4px / 16px
30 | border: 1px solid var(--clr-brdr);
31 | background-color: var(--clr-bkgd-box);
32 | font-family: var(--font-serif);
33 | font-weight: 700;
34 | white-space: normal; /* 1 */
35 | }
36 |
37 | /**
38 | * Remove tap delay in modern browsers.
39 | */
40 |
41 | input,
42 | button {
43 | touch-action: manipulation;
44 | }
45 |
46 | /**
47 | * 1. Prevent elements from spilling out of their parent.
48 | * 2. Address margins set differently in Firefox 4+, Safari, and Chrome.
49 | * 3. Correct font properties not being inherited.
50 | */
51 |
52 | button,
53 | input,
54 | select,
55 | optgroup,
56 | textarea,
57 | .button,
58 | .postlink a,
59 | .subscribelink a {
60 | box-sizing: border-box;
61 | max-width: 100%; /* 1 */
62 | margin: 0; /* 2 */
63 | color: var(--clr-text-form);
64 | font-family: var(--font-sans-serif);
65 | font-size: 1rem; /* 3 */
66 | line-height: 1.375; // 22px / 16px
67 | vertical-align: baseline;
68 | }
69 |
70 | /**
71 | * Styling of form input fields.
72 | *
73 | * 1. Remove browser-specific default styling.
74 | */
75 |
76 | [type="email"],
77 | [type="number"],
78 | [type="password"],
79 | [type="search"],
80 | [type="tel"],
81 | [type="text"],
82 | [type="url"],
83 | select,
84 | textarea {
85 | height: 2em; // 32px / 16px
86 | padding: 0.25em 0.1875em; // 8px / 16px + 3px / 16px
87 | border: 1px solid var(--clr-brdr);
88 | border-radius: 0;
89 | background: var(--clr-bkgd-form);
90 | appearance: none; /* 1 */
91 |
92 | &:hover {
93 | border-color: var(--clr-brdr-x-dark);
94 | }
95 |
96 | &:focus {
97 | border-color: var(--clr-focus);
98 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
99 | }
100 | }
101 |
102 | @include setup.dark-mode {
103 | [type="email"],
104 | [type="number"],
105 | [type="password"],
106 | [type="search"],
107 | [type="tel"],
108 | [type="text"],
109 | [type="url"],
110 | select,
111 | textarea {
112 | border-color: var(--clr-brdr-x-dark);
113 |
114 | &:hover {
115 | border-color: var(--clr-brdr-x-lite);
116 | }
117 |
118 | &:focus {
119 | border-color: var(--clr-focus);
120 | }
121 | }
122 | }
123 |
124 | /**
125 | * 1. Remove any excess padding.
126 | * 2. Correct margins for inline checkbox/radio labels.
127 | */
128 |
129 | [type="checkbox"],
130 | [type="radio"] {
131 | position: relative;
132 | bottom: -2px;
133 | box-sizing: border-box;
134 | width: 16px;
135 | height: 16px;
136 | padding: 0; /* 1 */
137 | border: 1px solid var(--clr-brdr-x-dark);
138 | background: var(--clr-bkgd-form);
139 | appearance: none;
140 |
141 | + label {
142 | margin: 0 0.5em 0 0; /* 2 */
143 |
144 | &:last-of-type {
145 | margin: 0; /* 2 */
146 | }
147 | }
148 |
149 | &:hover {
150 | filter: brightness(1.05);
151 | cursor: pointer;
152 | }
153 |
154 | &:active {
155 | filter: brightness(0.95);
156 | }
157 |
158 | &:focus {
159 | border-color: var(--clr-focus);
160 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
161 | }
162 |
163 | &:not([disabled]) + label:hover {
164 | cursor: pointer;
165 | }
166 | }
167 |
168 | @include setup.dark-mode {
169 | [type="checkbox"],
170 | [type="radio"] {
171 | &:hover {
172 | border-color: var(--clr-brdr-x-lite);
173 | }
174 | }
175 | }
176 |
177 | [type="checkbox"] {
178 | &:checked {
179 | border: 0;
180 | background: var(--clr-text-demoted) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23fff' d='M13 2.5l-7 7-2-2-2 2 4 4L15 4.5z'/%3E%3C/svg%3E");
181 |
182 | &:hover,
183 | &:active {
184 | background-color: var(--clr-text);
185 | }
186 |
187 | &:focus {
188 | background-color: var(--clr-focus);
189 | }
190 | }
191 |
192 | &[disabled]:checked {
193 | background: var(color-text-visual-de-emphasis) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23fff' d='M13 2.5l-7 7-2-2-2 2 4 4L15 4.5z'/%3E%3C/svg%3E");
194 | }
195 | }
196 |
197 | @include setup.dark-mode {
198 | [type="checkbox"] {
199 | &:checked {
200 | background: var(--clr-text) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23282d32' d='M13 2.5l-7 7-2-2-2 2 4 4L15 4.5z'/%3E%3C/svg%3E");
201 |
202 | &:hover,
203 | &:active {
204 | background-color: var(--clr-text-promoted);
205 | }
206 |
207 | &:focus {
208 | background-color: var(--clr-focus);
209 | }
210 | }
211 |
212 | &[disabled]:checked {
213 | background: var(--clr-text) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23282d32' d='M13 2.5l-7 7-2-2-2 2 4 4L15 4.5z'/%3E%3C/svg%3E");
214 | }
215 | }
216 | }
217 |
218 | [type="radio"] {
219 | border-radius: 100%;
220 |
221 | &:checked {
222 | border: 5px solid var(--clr-text-demoted);
223 |
224 | &:hover,
225 | &:active {
226 | border-color: var(--clr-text);
227 | }
228 |
229 | &:focus {
230 | border-color: var(--clr-focus);
231 | }
232 | }
233 | }
234 |
235 | @include setup.dark-mode {
236 | [type="radio"]:checked {
237 | &:hover,
238 | &:active {
239 | border-color: var(--clr-text-promoted);
240 | }
241 |
242 | &:focus {
243 | border-color: var(--clr-focus);
244 | }
245 | }
246 | }
247 |
248 | /**
249 | * Styling for file inputs.
250 | */
251 |
252 | [type="file"] {
253 | box-sizing: border-box;
254 | height: auto;
255 | min-height: 2em; // 32px / 16px
256 | padding: 0.25em 0.1875em; // 8px / 16px + 3px / 16px
257 | border: 1px solid var(--clr-brdr);
258 | border-radius: 0;
259 | background: var(--clr-bkgd-form);
260 | appearance: none;
261 | cursor: pointer;
262 |
263 | &:hover {
264 | border-color: var(--clr-brdr-x-dark);
265 | }
266 |
267 | &:focus {
268 | border-color: var(--clr-focus);
269 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
270 | }
271 | }
272 |
273 | @include setup.dark-mode {
274 | [type="file"] {
275 | border-color: var(--clr-brdr-x-dark);
276 |
277 | &:hover {
278 | border-color: var(--clr-brdr-x-lite);
279 | }
280 |
281 | &:focus {
282 | border-color: var(--clr-focus);
283 | }
284 | }
285 | }
286 |
287 | [type="file"]::-webkit-file-upload-button {
288 | @include setup.gradient-linear(var(--clr-btn-grad-from), var(--clr-btn-grad-to));
289 |
290 | padding: 0 0.25em;
291 | border: 0;
292 | border-radius: 0.25em;
293 | color: var(--clr-text-btn);
294 | font: inherit;
295 | appearance: none;
296 | cursor: pointer;
297 | }
298 |
299 | [type="file"]:hover::-webkit-file-upload-button {
300 | filter: brightness(1.05);
301 | }
302 |
303 | [type="file"]:active::-webkit-file-upload-button {
304 | filter: brightness(0.95);
305 | }
306 |
307 | /**
308 | * Remove the inner padding in Chrome and Safari on macOS.
309 | */
310 |
311 | [type="search"]::-webkit-search-decoration {
312 | /* autoprefixer: off */
313 | appearance: none;
314 | }
315 |
316 | /**
317 | * Use indicator icon to signify the drop-down ability of `select`.
318 | */
319 |
320 | select {
321 | padding-right: 1.5em; // 24px / 16px
322 | background: var(--clr-bkgd-form) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='5' viewBox='0 0 17 5'%3E%3Cpolygon fill='%23333' points='0,0 5,5 10,0'/%3E%3C/svg%3E") right center no-repeat;
323 | background-size: 1.0625em 0.3125em; // 17px / 16px, 5px / 16px
324 | text-transform: none;
325 | }
326 |
327 | @include setup.dark-mode {
328 | select {
329 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='5' viewBox='0 0 17 5'%3E%3Cpolygon fill='%23788591' points='0,0 5,5 10,0'/%3E%3C/svg%3E");
330 | }
331 | }
332 |
333 | /**
334 | * Override height and background set in a previous rule and allow auto height.
335 | */
336 |
337 | select[size],
338 | select[multiple] {
339 | height: auto;
340 | padding-right: 0.5em;
341 | background-image: none;
342 | }
343 |
344 | @include setup.dark-mode {
345 | select[size],
346 | select[multiple] {
347 | background-image: none;
348 | }
349 | }
350 |
351 | /**
352 | * Override height set in rule above and restrict to one line field.
353 | */
354 |
355 | select[size="0"],
356 | select[size="1"] {
357 | height: 2em; // 32px / 16px
358 | }
359 |
360 | /**
361 | * Normalize styling of `optgroup`.
362 | */
363 |
364 | optgroup {
365 | font-style: normal;
366 | font-weight: 700;
367 | }
368 |
369 | /**
370 | * 1. Remove unwanted space below `textarea` in Safari, Chrome, Opera.
371 | * 2. Restrict to vertical resizing to prevent layout breakage.
372 | */
373 |
374 | textarea {
375 | width: 100%;
376 | height: 25vh;
377 | min-height: 3em;
378 | vertical-align: top; /* 1 */
379 | resize: vertical; /* 2 */
380 | }
381 |
382 | /**
383 | * Make sure disabled elements really are disabled and styled appropriately.
384 | *
385 | * 1. Re-set default cursor for disabled elements.
386 | */
387 |
388 | [disabled],
389 | [disabled] option,
390 | [disabled] optgroup,
391 | span.disabled {
392 | border: 1px solid var(--clr-brdr) !important;
393 | opacity: 0.33 !important;
394 | background-color: var(--clr-bkgd-form-disabled) !important;
395 | box-shadow: none !important;
396 | cursor: default !important; /* 1 */
397 | }
398 |
399 | @include setup.dark-mode {
400 | [disabled],
401 | [disabled] option,
402 | [disabled] optgroup,
403 | span.disabled {
404 | opacity: 0.25 !important;
405 | }
406 | }
407 |
408 | /**
409 | * Styling for form field validation.
410 | */
411 |
412 | input,
413 | select,
414 | textarea {
415 | &:focus:invalid {
416 | border-color: var(--clr-error-text);
417 | box-shadow: none; // Normalize Firefox styling
418 | }
419 | }
420 |
421 | /**
422 | * Styling for Firefox-specfic form field validation.
423 | */
424 |
425 | input,
426 | select,
427 | textarea {
428 | &:-moz-ui-invalid {
429 | border-color: var(--clr-error-text);
430 | box-shadow: none;
431 | }
432 | }
433 |
434 | /**
435 | * Normalize form placeholder style across browsers.
436 | *
437 | * 1. Fix placeholder font properties inheritance.
438 | */
439 |
440 | ::placeholder {
441 | opacity: 1;
442 | color: var(--clr-text-placeholder);
443 | font: inherit; /* 1 */
444 | }
445 |
--------------------------------------------------------------------------------
/src/style/Textpattern/sass/modules/fluxbb/_fluxbb_layout.scss:
--------------------------------------------------------------------------------
1 | @use "../../setup";
2 | @use "sass:math";
3 |
4 | .clearer::after {
5 | content: "";
6 | display: table;
7 | clear: both;
8 | }
9 |
10 | .clearl {
11 | clear: left;
12 | }
13 |
14 | .clearr {
15 | clear: right;
16 | }
17 |
18 |
19 | /* Forum hidden elements
20 | ========================================================================== */
21 |
22 | #brdstats,
23 | #vf h2,
24 | #brdfooter h2,
25 | #quickpost > h2,
26 | .blockform > h2,
27 | .modlist,
28 | #navrules,
29 | .textpattern-fluxbb-t,
30 | .postlinksb .postlink,
31 | #brdfooternav,
32 | .usernamefield {
33 | display: none !important;
34 | }
35 |
36 |
37 | /* Forum global layout
38 | ========================================================================== */
39 |
40 | thead td,
41 | thead th {
42 | text-transform: uppercase;
43 | }
44 |
45 | .buttons a,
46 | .modbuttons input {
47 | margin-left: 0.3333333em;
48 | }
49 |
50 | .tcmod {
51 | width: 4.5em;
52 | text-align: center;
53 | }
54 |
55 | .infldset {
56 | margin: 1em 0;
57 |
58 | label {
59 | display: block;
60 | margin: 1em 0;
61 |
62 | &.conl {
63 | display: inline-block;
64 | margin: 0 0.5em 0 0;
65 | }
66 | }
67 | }
68 |
69 | .rbox {
70 | [type="checkbox"],
71 | [type="radio"] {
72 | margin-right: 0.3333333em;
73 | }
74 | }
75 |
76 |
77 | /* Forum header area
78 | ========================================================================== */
79 |
80 | #brdwelcome {
81 | border-bottom: 1px solid var(--clr-brdr);
82 |
83 | &::after {
84 | content: "";
85 | display: table;
86 | clear: both;
87 | }
88 |
89 | ul {
90 | padding: 0;
91 | list-style: none;
92 | }
93 |
94 | .conl {
95 | float: left;
96 | }
97 |
98 | .conr {
99 | float: right;
100 | }
101 | }
102 |
103 | @include setup.dark-mode {
104 | #brdwelcome {
105 | border-bottom-color: var(--clr-brdr-lite);
106 | }
107 | }
108 |
109 |
110 | /* Forum announcement box
111 | ========================================================================== */
112 |
113 | #announce {
114 | padding: 1px 0;
115 | border-bottom: 1px solid var(--clr-brdr);
116 | background-color: var(--clr-hilite-box);
117 |
118 | &::after {
119 | content: "";
120 | display: table;
121 | clear: both;
122 | }
123 |
124 | .hd h2 {
125 | margin: 0.5em 1em 0 0;
126 | float: left;
127 | font-size: setup.$base-font-size;
128 | line-height: setup.$base-line-height;
129 | text-transform: uppercase;
130 | }
131 |
132 | .box {
133 | margin: 0.5em 0;
134 | float: left;
135 | }
136 | }
137 |
138 | @include setup.dark-mode {
139 | #announce {
140 | border-bottom-color: var(--clr-brdr-lite);
141 | }
142 | }
143 |
144 |
145 | /* Forum breadcrumbs, postlink and pagination layout
146 | ========================================================================== */
147 |
148 | .crumbs {
149 | padding: 0;
150 | list-style: none;
151 |
152 | li {
153 | display: inline-block;
154 | }
155 | }
156 |
157 | .linkst .crumbs {
158 | li {
159 | display: block;
160 | margin-bottom: 0.5em;
161 |
162 | strong {
163 | font-family: var(--font-serif);
164 | font-size: 1.75em; // 28px / 16px
165 | line-height: 1.25; // 35px / 30px
166 |
167 | a {
168 | color: var(--clr-text-promoted);
169 | text-decoration-color: var(--clr-text-promoted-a50); /* 4 */
170 | }
171 | }
172 | }
173 |
174 | li:first-child,
175 | span {
176 | display: none;
177 | }
178 | }
179 |
180 | .pagepost {
181 | &::after {
182 | content: "";
183 | display: table;
184 | clear: both;
185 | }
186 |
187 | .pagelink {
188 | margin: 0;
189 | padding: 0.5em 0;
190 | float: left;
191 | }
192 |
193 | .postlink {
194 | margin: 0;
195 | float: right;
196 | }
197 | }
198 |
199 |
200 | /* Forum layouts with side menus
201 | ========================================================================== */
202 |
203 | .block2col .blockmenu {
204 | box-sizing: border-box;
205 | margin: 1.75em 0 1em;
206 | padding: 0 1em;
207 | border: 1px solid var(--clr-brdr);
208 | background-color: var(--clr-bkgd-box);
209 |
210 | h2 {
211 | font-size: 1.125em; // 18px / 16px
212 | line-height: 1.4444444; // 26px / 18px
213 | }
214 |
215 | ul {
216 | padding: 0;
217 | list-style: none;
218 | }
219 | }
220 |
221 | /**
222 | * Blockmenu active section.
223 | */
224 |
225 | .blockmenu .isactive {
226 | font-weight: 700;
227 | }
228 |
229 |
230 | /* Forum topic list, post list and search list page layout
231 | ========================================================================== */
232 |
233 | #page-index,
234 | #page-viewforum,
235 | #page-moderate,
236 | #page-search {
237 | .tc2,
238 | .tc3 {
239 | width: 10%;
240 | }
241 |
242 | .tcr {
243 | width: 24%;
244 | }
245 |
246 | td {
247 | padding-top: 1em;
248 | padding-bottom: 1em;
249 | }
250 | }
251 |
252 | #page-search .tc2 {
253 | width: 22%;
254 | }
255 |
256 | .tclcon {
257 | position: relative;
258 | min-height: 1px;
259 | overflow: hidden;
260 |
261 | .tclcon div {
262 | width: 100%;
263 | overflow: hidden;
264 | }
265 |
266 | h3 {
267 | margin: 0 0 0.25em;
268 |
269 | .newtext {
270 | display: inline-block;
271 | font-family: var(--font-sans-serif);
272 | font-size: 0.65em;
273 | font-weight: 400;
274 | }
275 | }
276 | }
277 |
278 | #page-viewforum .tclcon,
279 | #page-moderate .tclcon,
280 | #page-search .tclcon {
281 | a {
282 | font-weight: 700;
283 | }
284 |
285 | .pagestext,
286 | .newtext {
287 | display: inline-block;
288 |
289 | a {
290 | font-weight: 400;
291 | }
292 | }
293 | }
294 |
295 |
296 | /* Forum posts page layout
297 | ========================================================================== */
298 |
299 | .blockpost {
300 | margin: 0.5em 0;
301 | border: 1px solid var(--clr-brdr);
302 | border-radius: math.div(setup.$border-radius, 2);
303 | background-color: var(--clr-bkgd-box);
304 |
305 | &::after {
306 | content: "";
307 | display: table;
308 | clear: both;
309 | }
310 |
311 | .postleft h2 {
312 | margin: 1em;
313 | font-family: var(--font-sans-serif);
314 | font-size: 1em;
315 |
316 | .conr {
317 | margin-right: 0.33em;
318 | color: var(--clr-info-text);
319 | font-weight: 400;
320 | }
321 | }
322 | }
323 |
324 | @include setup.dark-mode {
325 | .blockpost {
326 | border-color: var(--clr-brdr-lite);
327 | }
328 | }
329 |
330 | /**
331 | * Post author info section.
332 | */
333 |
334 | .postleft {
335 | width: 30%;
336 | float: left;
337 |
338 | dl {
339 | margin: 0;
340 | padding: 0 1em;
341 | }
342 |
343 | dt {
344 | font-family: var(--font-serif);
345 | font-size: 1.125em; // 18px / 16px
346 | font-style: normal;
347 | line-height: 1.4444444; // 26px / 18px
348 |
349 | a {
350 | color: var(--clr-text-promoted);
351 | }
352 | }
353 |
354 | dd {
355 | margin: 0;
356 | }
357 | }
358 |
359 | .postavatar img {
360 | margin: 0.5em 0;
361 | }
362 |
363 | .usercontacts {
364 | a {
365 | display: inline-block;
366 | margin: 0.5rem 0.25rem 0 0;
367 | padding: 1px 5px;
368 | border: 1px solid var(--clr-brdr);
369 | border-radius: math.div(setup.$border-radius, 2);
370 | background-color: var(--clr-bkgd-box);
371 |
372 | &:hover {
373 | background-color: var(--clr-nav-interact);
374 | filter: brightness(1.05);
375 | }
376 |
377 | &:active {
378 | filter: brightness(0.95);
379 | }
380 |
381 | &:focus {
382 | border-color: var(--clr-focus);
383 | outline: 2px solid transparent; // Allows for repainting in high contrast modes.
384 | }
385 | }
386 | }
387 |
388 | /**
389 | * Post author message section.
390 | */
391 |
392 | .postright {
393 | width: 63%;
394 | padding: 0 2.8%;
395 | float: right;
396 | overflow: hidden;
397 | border-radius: 0 (math.div(setup.$border-radius, 2));
398 | background-color: var(--clr-bkgd);
399 | word-wrap: break-word;
400 |
401 | > h3 {
402 | display: none;
403 | }
404 | }
405 |
406 | .postsignature hr {
407 | border-style: dashed;
408 | }
409 |
410 | .postfoot {
411 | clear: both;
412 | }
413 |
414 | /**
415 | * Post author online/offline section.
416 | */
417 |
418 | .postfootleft {
419 | width: 25%;
420 | float: left;
421 |
422 | p {
423 | padding: 0 1em;
424 | }
425 |
426 | span,
427 | strong {
428 | display: inline-block;
429 | padding: 0.125em 0.33em;
430 | border: 1px solid;
431 | border-radius: math.div(setup.$border-radius, 2);
432 | font-size: setup.$small-font-size;
433 | line-height: setup.$small-line-height;
434 | }
435 |
436 | span { // offline
437 | border-color: var(--clr-brdr-x-lite);
438 | background: var(--clr-bkgd-box);
439 | color: var(--clr-text-demoted);
440 | }
441 |
442 | strong { // online
443 | border-color: var(--clr-success-brdr);
444 | background: var(--clr-success-bkgd);
445 | color: var(--clr-success-text);
446 | font-weight: 400;
447 | }
448 | }
449 |
450 | /**
451 | * Post author quote/report/etc. section.
452 | */
453 |
454 | .postfootright {
455 | width: 74%;
456 | float: right;
457 |
458 | ul {
459 | padding: 0;
460 | padding-right: 1em;
461 | list-style: none;
462 | text-align: right;
463 | }
464 |
465 | li {
466 | display: inline;
467 |
468 | span::before {
469 | content: "| \0020";
470 | }
471 | }
472 |
473 | li:first-child span::before {
474 | content: none;
475 | }
476 | }
477 |
478 | .subscribelink {
479 | margin: 1.5em 0;
480 |
481 | a {
482 | margin: 0.5em 0;
483 | }
484 | }
485 |
486 | /**
487 | * Post reply section.
488 | */
489 |
490 | #quickpost {
491 | margin: 0 0 2em;
492 | border: 1px solid var(--clr-brdr);
493 | border-radius: math.div(setup.$border-radius, 2);
494 | background-color: hsl(48 100% 96%);
495 |
496 | fieldset {
497 | margin-bottom: 0;
498 | border: 0;
499 | }
500 |
501 | legend {
502 | margin: 0;
503 | padding: 0;
504 | border: 0;
505 | background-color: transparent;
506 | color: var(--clr-text-promoted);
507 | font-size: 1.125rem; // 18px / 16px
508 | line-height: 1.4444444; // 26px / 18px
509 | }
510 |
511 | .infldset label {
512 | margin: 0;
513 | }
514 |
515 | .buttons {
516 | margin: 0 0 1.5em;
517 | padding: 0 1em;
518 | }
519 | }
520 |
521 | @include setup.dark-mode {
522 | #quickpost {
523 | border-color: var(--clr-brdr-lite);
524 | background-color: hsl(48 20% 26%);
525 | }
526 | }
527 |
528 | .textile-help-links {
529 | margin: 0.5em 0;
530 | }
531 |
532 | #postreview .postleft {
533 | padding-top: 1em;
534 | }
535 |
536 | /**
537 | * Post edit page.
538 | */
539 |
540 | #edit textarea {
541 | height: 50vh;
542 | }
543 |
544 |
545 | /* Forum misc layout
546 | ========================================================================== */
547 |
548 | /**
549 | * User search table.
550 | */
551 |
552 | #users1 {
553 | .tcl,
554 | .tc2,
555 | .tc3,
556 | .tcr {
557 | width: 25%;
558 | }
559 | }
560 |
561 |
562 | /* Forum footer area
563 | ========================================================================== */
564 |
565 | #brdfooter {
566 | clear: both;
567 | }
568 |
569 | /**
570 | * Moderator controls.
571 | */
572 |
573 | #modcontrols {
574 | dl {
575 | margin-top: 0;
576 | }
577 |
578 | dt {
579 | font-style: normal;
580 | }
581 |
582 | dd {
583 | margin: 0;
584 | }
585 | }
586 |
--------------------------------------------------------------------------------