├── .browserslistrc
├── babel.config.js
├── assets
├── tree-home.png
├── individual.png
├── capture_tree-home.png
├── interactive-tree.png
├── capture_individual.png
└── capture_interactive-tree.png
├── src
├── js
│ ├── vendor.js
│ └── theme.js
└── scss
│ ├── _forms.scss
│ ├── _tables.scss
│ ├── _icons.scss
│ └── theme.scss
├── .gitmodules
├── composer.json
├── resources
├── views
│ ├── modules
│ │ ├── hit-counter
│ │ │ └── footer.phtml
│ │ ├── contact-links
│ │ │ └── footer.phtml
│ │ ├── privacy-policy
│ │ │ └── footer.phtml
│ │ ├── powered-by-webtrees
│ │ │ └── footer.phtml
│ │ ├── statistics-chart
│ │ │ └── page.phtml
│ │ ├── todo
│ │ │ └── research-tasks.phtml
│ │ ├── gedcom_stats
│ │ │ └── statistics.phtml
│ │ ├── interactive-tree
│ │ │ └── chart.phtml
│ │ ├── place-hierarchy
│ │ │ ├── sidebar.phtml
│ │ │ ├── page.phtml
│ │ │ ├── popup.phtml
│ │ │ ├── map.phtml
│ │ │ └── list.phtml
│ │ ├── relatives
│ │ │ └── family.phtml
│ │ ├── media-list
│ │ │ └── page.phtml
│ │ ├── descendancy
│ │ │ └── sidebar.phtml
│ │ ├── lightbox
│ │ │ └── tab.phtml
│ │ ├── places
│ │ │ └── tab.phtml
│ │ ├── pedigree-map
│ │ │ └── chart.phtml
│ │ ├── faq
│ │ │ └── show.phtml
│ │ ├── stories
│ │ │ └── tab.phtml
│ │ ├── lifespans-chart
│ │ │ └── chart.phtml
│ │ └── recent_changes
│ │ │ └── changes-list.phtml
│ ├── individual-page-tabs.phtml
│ ├── lists
│ │ ├── sources-table.phtml
│ │ ├── surnames-table.phtml
│ │ ├── notes-table.phtml
│ │ └── repositories-table.phtml
│ ├── individual-page-images.phtml
│ ├── calendar-page.phtml
│ ├── place-hierarchy.phtml
│ ├── chart-box.phtml
│ ├── calendar-list.phtml
│ └── layouts
│ │ └── default.phtml
└── js
│ ├── vendor.js
│ └── theme.js
├── .gitignore
├── .eslintrc.js
├── postcss.config.js
├── package.json
├── webpack.config.js
├── README.md
└── module.php
/.browserslistrc:
--------------------------------------------------------------------------------
1 | # Browsers that we support
2 |
3 | defaults
4 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['@babel/preset-env'],
3 | };
4 |
--------------------------------------------------------------------------------
/assets/tree-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/tree-home.png
--------------------------------------------------------------------------------
/assets/individual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/individual.png
--------------------------------------------------------------------------------
/assets/capture_tree-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/capture_tree-home.png
--------------------------------------------------------------------------------
/assets/interactive-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/interactive-tree.png
--------------------------------------------------------------------------------
/assets/capture_individual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/capture_individual.png
--------------------------------------------------------------------------------
/assets/capture_interactive-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jchue/argon-webtrees-theme/HEAD/assets/capture_interactive-tree.png
--------------------------------------------------------------------------------
/src/js/vendor.js:
--------------------------------------------------------------------------------
1 | // Need to import stylesheet so Webpack processes it
2 | import '../../vendor/fisharebest/webtrees/resources/css/vendor.tmp.css';
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/scss/argon-dashboard"]
2 | path = src/scss/argon-dashboard
3 | url = git@github.com:creativetimofficial/argon-dashboard.git
4 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": {
3 | "preferred-install": {
4 | "fisharebest/webtrees": "source"
5 | }
6 | },
7 | "require-dev": {
8 | "fisharebest/webtrees": "~2.1"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/resources/views/modules/hit-counter/footer.phtml:
--------------------------------------------------------------------------------
1 | /', '', $view);
9 |
10 | echo $view;
11 |
--------------------------------------------------------------------------------
/resources/views/modules/place-hierarchy/list.phtml:
--------------------------------------------------------------------------------
1 | /', '', $view);
7 | $view = preg_replace('/<\/span>(\r\n|\r|\n)<\/div>/', '
', $view);
8 |
9 | $view = preg_replace('/list-unstyled/', '', $view); // Make list normal
10 |
11 | echo $view;
12 |
--------------------------------------------------------------------------------
/resources/views/modules/lightbox/tab.phtml:
--------------------------------------------------------------------------------
1 | /', '', $view); // Add Bootstrap grid classes for proper sizing
6 | $view = preg_replace('/col-xl-2/', 'col-xl-3', $view); // Reduce maximum number of items per row to four by increasing column width
7 | $view .= '
';
8 |
9 | echo $view;
10 |
--------------------------------------------------------------------------------
/resources/views/modules/places/tab.phtml:
--------------------------------------------------------------------------------
1 | /', '
', $view);
7 | $view = preg_replace('/<\/span>(\r\n|\r|\n)<\/div>/', '
', $view);
8 |
9 | $view = preg_replace('/list-unstyled/', '', $view); // Make list normal
10 | $view = preg_replace('/list_table/', 'list_table mx-auto', $view); // Center list
11 |
12 | echo $view;
13 |
--------------------------------------------------------------------------------
/resources/views/modules/pedigree-map/chart.phtml:
--------------------------------------------------------------------------------
1 |
8 |
9 | /', view('icons/pedigree-right'), $view); // Replace icon for individual's links
7 | $view = preg_replace('/dropdown-item p-1/', 'dropdown-item', $view); // Increase padding around individual's links by removing small padding class
8 | $view = preg_replace('/dropdown-menu-end/', '', $view); // Remove right aligning of dropdowns because Argon applies a positioning incompatible with Popper
9 |
10 | echo $view;
11 |
--------------------------------------------------------------------------------
/src/js/theme.js:
--------------------------------------------------------------------------------
1 | // Need to import stylesheet so Webpack processes it
2 | import '../scss/theme.scss';
3 |
4 | const secondaryHeader = document.getElementById('secondary-header');
5 | const secondaryHeaderHeight = secondaryHeader.offsetHeight;
6 |
7 | const primaryHeader = document.getElementById('primary-header');
8 | const primaryHeaderHeight = primaryHeader.offsetHeight;
9 |
10 | const siteContent = document.getElementById('content');
11 |
12 | function setHeader() {
13 | const scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
14 |
15 | if (scrollPosition > secondaryHeaderHeight) {
16 | primaryHeader.style.position = 'fixed';
17 | siteContent.style.marginTop = `${primaryHeaderHeight}px`;
18 | } else {
19 | primaryHeader.style.position = 'static';
20 | siteContent.style.marginTop = 0;
21 | }
22 | }
23 |
24 | window.addEventListener('load', setHeader);
25 | window.addEventListener('scroll', setHeader);
26 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | const path = require('node:path');
2 |
3 | module.exports = (ctx) => ({
4 | map: false,
5 | plugins: {
6 | autoprefixer: ctx.env === 'production' ? {} : false,
7 | cssnano: ctx.env === 'production' ? {
8 | preset: ['default', {
9 | discardComments: {
10 | removeAll: true,
11 | },
12 | }],
13 | } : false,
14 | 'postcss-import': {
15 | path: [
16 | 'vendor/fisharebest/webtrees/resources/css',
17 | 'src/scss',
18 | ],
19 | },
20 |
21 | /**
22 | * TODO: Reconsider inlining font faces and instead defining them on page;
23 | * would need to figure out how to exclude fontawesome.css from PostCSS processing
24 | */
25 | 'postcss-url': {
26 | url: 'inline',
27 | basePath: [
28 | path.resolve('node_modules/@fortawesome/fontawesome-free/webfonts'),
29 | path.resolve('vendor/fisharebest/webtrees/resources/css'),
30 | ],
31 | },
32 | },
33 | });
34 |
--------------------------------------------------------------------------------
/resources/views/calendar-list.phtml:
--------------------------------------------------------------------------------
1 | (\r\n|\r|\n|\s)+
(\r\n|\r|\n|\s)+ | (\r\n|\r|\n|\s)+<\/tr>(\r\n|\r|\n|\s)+ | (\r\n|\r|\n|\s)+| (\r\n|\r|\n|\s)+<\/table>/', ' |
', $view); // Close tbody before table end
10 |
11 | echo $view;
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "vendor": "cd vendor/fisharebest/webtrees && npm install",
5 | "lint": "eslint src/js/",
6 | "dev": "webpack --watch",
7 | "build": "rm -r dist && npm run vendor && npm run lint && webpack --node-env production"
8 | },
9 | "devDependencies": {
10 | "@babel/core": "^7.21.0",
11 | "@babel/preset-env": "^7.20.2",
12 | "@fortawesome/fontawesome-free": "^6.3.0",
13 | "autoprefixer": "^10.4.13",
14 | "babel-loader": "^9.1.2",
15 | "copy-webpack-plugin": "^11.0.0",
16 | "css-loader": "^6.7.3",
17 | "cssnano": "^5.1.15",
18 | "eslint": "^8.35.0",
19 | "eslint-config-airbnb-base": "^15.0.0",
20 | "eslint-plugin-import": "^2.27.5",
21 | "filemanager-webpack-plugin": "^8.0.0",
22 | "mini-css-extract-plugin": "^2.7.2",
23 | "postcss": "^8.4.21",
24 | "postcss-import": "^14.1.0",
25 | "postcss-loader": "^7.0.2",
26 | "postcss-url": "^10.1.3",
27 | "sass": "^1.58.3",
28 | "sass-loader": "^13.2.0",
29 | "webpack": "^5.75.0",
30 | "webpack-cli": "^5.0.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/resources/views/modules/faq/show.phtml:
--------------------------------------------------------------------------------
1 | $faqs
12 | * @var string $title
13 | */
14 |
15 | ?>
16 |
17 | = $title ?>
18 |
19 |
26 |
27 | $faq) : ?>
28 |
29 |
35 |
36 | = str_starts_with($faq->faqbody, '<') ? $faq->faqbody : nl2br(e($faq->faqbody), false) ?>
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/resources/views/modules/stories/tab.phtml:
--------------------------------------------------------------------------------
1 | $stories
11 | * @var Tree $tree
12 | */
13 |
14 | ?>
15 |
16 |
17 |
18 |
19 | /**
20 | * Add a container for each story
21 | */
22 | ?>
23 |
24 |
25 | = e($story->title) ?>
26 |
27 |
28 |
= $story->story_body ?>
29 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 | /**
43 | * Display Add link even when there are existing stories
44 | */
45 | ?>
46 |
47 |
48 |
49 | = I18N::translate('Add a story') ?>
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/resources/views/modules/lifespans-chart/chart.phtml:
--------------------------------------------------------------------------------
1 | $lifespans
13 | * @var int $max_rows
14 | * @var int $start_year
15 | * @var string $subtitle
16 | */
17 |
18 | ?>
19 |
20 |
21 | = $subtitle ?>
22 |
23 |
24 |
29 |
30 |
50 |
--------------------------------------------------------------------------------
/resources/views/modules/recent_changes/changes-list.phtml:
--------------------------------------------------------------------------------
1 | $rows
18 | * @var bool $show_date
19 | * @var bool $show_user
20 | */
21 |
22 | ?>
23 |
24 |
61 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const CopyPlugin = require('copy-webpack-plugin');
3 | const FileManagerPlugin = require('filemanager-webpack-plugin');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 |
6 | const copyPatterns = [
7 | // Workaround to exclude redundant Bootstrap
8 | {
9 | from: 'vendor/fisharebest/webtrees/resources/css/vendor.css',
10 | to: path.resolve(__dirname, 'vendor/fisharebest/webtrees/resources/css/vendor.tmp.css'),
11 | transform(content) {
12 | return content
13 | .toString()
14 | .replace('@import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";', '/* @import "../../node_modules/bootstrap/dist/css/bootstrap.min.css"; */');
15 | },
16 | },
17 | ];
18 |
19 | if (process.env.NODE_ENV === 'production') {
20 | copyPatterns.push(
21 | {
22 | from: 'module.php',
23 | to: path.resolve(__dirname, 'dist/module.php'),
24 | },
25 | {
26 | from: 'resources/views',
27 | to: path.resolve(__dirname, 'dist/resources/views'),
28 | },
29 | );
30 | }
31 |
32 | module.exports = {
33 | mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
34 | entry: {
35 | theme: './src/js/theme.js',
36 | vendor: './src/js/vendor.js',
37 | },
38 | devtool: process.env.NODE_ENV === 'production' ? false : 'inline-source-map',
39 | watchOptions: {
40 | // Prevent looping due to vendor.css workaround
41 | ignored: path.resolve(__dirname, './vendor'),
42 | },
43 | output: {
44 | filename: 'js/[name].js',
45 | path: path.resolve(__dirname, process.env.NODE_ENV === 'production' ? 'dist/resources' : 'resources'),
46 | clean: {
47 | keep: 'views',
48 | },
49 | },
50 | plugins: [
51 | new CopyPlugin({
52 | patterns: copyPatterns,
53 | }),
54 |
55 | // vendor.js is only used to trigger Webpack for the vendor CSS and is not required in prod
56 | new FileManagerPlugin({
57 | events: {
58 | onEnd: {
59 | delete: [path.resolve(__dirname, 'dist/resources/js/vendor.js')],
60 | },
61 | },
62 | }),
63 | new MiniCssExtractPlugin({
64 | filename: 'css/[name].css',
65 | }),
66 | ],
67 | module: {
68 | rules: [
69 | {
70 | test: /\.m?js$/,
71 | exclude: /node_modules/,
72 | use: {
73 | loader: 'babel-loader',
74 | options: {
75 | presets: ['@babel/preset-env'],
76 | },
77 | },
78 | },
79 | {
80 | test: /\.(sa|sc|c)ss$/,
81 | use: [
82 | MiniCssExtractPlugin.loader,
83 | 'css-loader',
84 | 'postcss-loader',
85 | 'sass-loader',
86 | ],
87 | },
88 | ],
89 | },
90 | };
91 |
--------------------------------------------------------------------------------
/src/scss/_forms.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Forms
3 | */
4 |
5 | @each $color,
6 | $value in $theme-colors {
7 | .btn-#{$color} {
8 | &:hover {
9 | background-color: lighten($value, 5%);
10 | }
11 | }
12 | }
13 |
14 | button[role=button] {
15 | @extend .btn;
16 | }
17 |
18 | .btn-link {
19 | margin: 0;
20 | padding: 0 0.5rem;
21 | }
22 |
23 | input[type=text] {
24 | @extend .form-control;
25 | }
26 |
27 | // If button is part of group, group should handle margins
28 | .input-group .btn {
29 | margin-bottom: 0;
30 | }
31 |
32 | // If preceeded by ARIA element, treat form control as first element in group
33 | .input-group .visually-hidden +.form-control:not(:first-child),
34 | .input-group .visually-hidden + input[type="text"]:not(:first-child) {
35 | padding-left: 0.75rem;
36 | }
37 |
38 | .input-group > .visually-hidden + :not(:first-child):not(.dropdown-menu):not(.fan_chart_menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {
39 | border-top-left-radius: 0.5rem;
40 | border-bottom-left-radius: 0.5rem;
41 | }
42 |
43 | select {
44 | @extend .form-select;
45 | }
46 |
47 | .form-label,
48 | .label,
49 | label {
50 | font-weight: $form-label-font-weight !important;
51 | margin: 0 0 $form-label-margin-bottom 0;
52 | }
53 |
54 | // Tom Select
55 | .ts-control {
56 | min-height: 2.25rem;
57 | }
58 |
59 | // Twitter Typahead
60 | .twitter-typeahead {
61 | width: 100%;
62 |
63 | .input-group & {
64 | display: block !important;
65 |
66 | .tt-dropdown-menu {
67 | top: 2rem !important;
68 | }
69 | }
70 |
71 | .input-group.input-group-lg & {
72 | .tt-dropdown-menu {
73 | top: 2.75rem !important;
74 | }
75 | }
76 |
77 | .input-group.input-group-sm & {
78 | .tt-dropdown-menu {
79 | top: 1.75rem !important;
80 | }
81 | }
82 |
83 | .input-group>& {
84 | flex-basis: 0;
85 | flex-grow: 1;
86 | flex-shrink: 1;
87 | }
88 |
89 | // Override no left border or padding when not-first-child form controls
90 | .tt-hint+.tt-input {
91 | border-left: $input-border-width solid $input-border-color !important;
92 | padding-left: $input-padding-x !important;
93 | }
94 |
95 | .tt-dropdown-menu,
96 | .tt-menu {
97 | @extend .dropdown-menu;
98 | display: none;
99 | float: left;
100 | left: 0;
101 | min-width: 10rem;
102 | position: absolute;
103 | top: 100%;
104 |
105 | .tt-dataset {
106 | .tt-suggestion {
107 | @extend .dropdown-item;
108 | }
109 | }
110 | }
111 |
112 | .active.tt-suggestion {
113 | @extend .dropdown-item, .active;
114 | }
115 |
116 |
117 | .disabled.tt-suggestion {
118 | @extend .dropdown-item, .disabled;
119 | }
120 | }
--------------------------------------------------------------------------------
/src/scss/_tables.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Tables
3 | */
4 |
5 | table,
6 | .table {
7 | // Override separated border applied by DataTables to Individuals table
8 | &.dataTable {
9 | border-collapse: collapse !important;
10 | }
11 |
12 | td,
13 | th,
14 | thead th,
15 | tbody th,
16 | tbody td {
17 | border: none;
18 | font-size: $font-size-sm;
19 |
20 | // Override Argon no-wrap
21 | white-space: normal;
22 | }
23 |
24 | th {
25 | background-color: $gray-100;
26 | vertical-align: middle;
27 | }
28 |
29 | thead th {
30 | @extend .text-uppercase, .text-xs, .font-weight-bolder;
31 | border-top: $table-border-width solid $table-border-color;
32 | }
33 |
34 | & > :not(:first-child) {
35 | // Override dark border above tbody
36 | border-top: none;
37 | }
38 |
39 | td,
40 | tbody th,
41 | tbody td {
42 | border-bottom: $table-border-width solid $table-border-color;
43 | }
44 |
45 | tbody tr:first-child {
46 | th,
47 | td {
48 | border-top: $table-border-width solid $table-border-color;
49 | }
50 | }
51 |
52 | tbody tr:last-child {
53 | th,
54 | td {
55 | // Override missing bottom border
56 | border-width: 1px;
57 | }
58 | }
59 |
60 | p {
61 | font-size: $font-size-sm;
62 | }
63 | }
64 |
65 | .table-sm {
66 | td,
67 | th,
68 | thead th,
69 | tbody th,
70 | tbody td {
71 | font-size: $font-size-xs;
72 | padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;
73 | }
74 |
75 | p {
76 | font-size: $font-size-xs;
77 | }
78 | }
79 |
80 | .table-bordered {
81 | td,
82 | th,
83 | thead th,
84 | tbody th,
85 | tbody td {
86 | border: $table-border-width solid $table-border-color;
87 | }
88 | }
89 |
90 | .sorting,
91 | .sorting_asc,
92 | .sorting_desc {
93 | background-clip: padding-box;
94 | cursor: pointer;
95 | position: relative;
96 |
97 | &::before,
98 | &::after {
99 | bottom: 1rem;
100 | display: block;
101 | position: absolute;
102 |
103 | .table-sm & {
104 | bottom: 0.9rem;
105 | }
106 | }
107 |
108 | &::before {
109 | content: "\2191";
110 | }
111 |
112 | &::after {
113 | content: "\2193";
114 | }
115 | }
116 |
117 | [dir="ltr"] .sorting,
118 | [dir="ltr"] .sorting_asc,
119 | [dir="ltr"] .sorting_desc {
120 | &::before {
121 | right: 0.85em;
122 | }
123 |
124 | &::after {
125 | right: 0.5em;
126 | }
127 | }
128 |
129 | [dir="rtl"] .sorting,
130 | [dir="rtl"] .sorting_asc,
131 | [dir="rtl"] .sorting_desc {
132 | &::before {
133 | left: 0.85em;
134 | }
135 |
136 | &::after {
137 | left: 0.5em;
138 | }
139 | }
140 |
141 | .sorting {
142 | &::before,
143 | &::after {
144 | opacity: 0.5;
145 | }
146 |
147 | // Icons in table header
148 | i {
149 | padding: 0 0.313rem;
150 | vertical-align: -0.094rem;
151 | }
152 | }
153 |
154 | .sorting_asc {
155 | &::before {
156 | opacity: 1;
157 | }
158 |
159 | &::after {
160 | opacity: 0.5;
161 | }
162 | }
163 |
164 | .sorting_desc {
165 | &::before {
166 | opacity: 0.5;
167 | }
168 |
169 | &::after {
170 | opacity: 1;
171 | }
172 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/jchue/argon-webtrees-theme/releases/latest)
2 | [](https://webtrees.net/download)
3 |
4 | # Argon Theme for webtrees
5 |
6 | A theme for the [webtrees](https://github.com/fisharebest/webtrees) online geneology application based on the [Argon Dashboard](https://github.com/creativetimofficial/argon-dashboard). Since webtrees is templated with Bootstrap, this theme applies Argon styles in the majority of places but adapts where necessary.
7 |
8 | ## Screenshots
9 |
10 | **Tree Home**
11 |
12 | 
13 |
14 | **Individual Page**
15 |
16 | 
17 |
18 | **Interactive Tree Chart**
19 |
20 | 
21 |
22 | ## Compatibility
23 |
24 | webtrees 2.1.x (see [prior releases](https://github.com/jchue/argon-webtrees-theme/releases) for older versions)
25 |
26 | ## Installation
27 |
28 | 1. Download the .zip file of the [latest release](https://github.com/jchue/argon-webtrees-theme/releases/latest).
29 | 2. Unzip the package.
30 | 3. Ensure the folder is named `argon`.
31 | 4. Upload the folder into the `modules_v4` directory of the webtrees installation on your web server.
32 | 5. Ensure the theme is enabled in your Control panel.
33 |
34 | ## Structure
35 |
36 | Because webtrees 2 is built with Bootstrap by default, the majority of this theme is just a matter of applying the Argon stylesheet.
37 |
38 | Additionally, there are a handful of opinionated changes, mostly regarding sizing and spacing, requiring some views to be overwritten. Most of these are achieved with a simple replacement function to add/remove/modify classes and elements. Therefore, when a change is introduced in the webtrees codebase, these views should adopt them accordingly unless there is a drastic change to the template.
39 |
40 | There are, however, a few cases that require the entire view to be rebuilt/reorganized, due to either a completely different template or a change in the PHP code. These views are:
41 |
42 | - `::layouts/default`
43 | - `::modules/faq/show`
44 | - `::modules/lifespans-chart/chart`
45 | - `::modules/recent_changes/changes-list`
46 | - `::modules/stories/tab`
47 |
48 | When change is made to these views in the webtrees codebase, it needs to be incorporated in the corresponding Argon view.
49 |
50 | ## Develop and Build
51 |
52 | **Prerequisites:**
53 |
54 | - Node.js
55 | - webtrees
56 |
57 | **Clone repository**
58 |
59 | `argon-dashboard` must be sourced as a Git submodules.
60 |
61 | Therefore, you must pass the `--recurse-submodules` flag when cloning the repository in order for its contents to be populated (under `src/resources/scss/argon-dashboard`):
62 |
63 | ```
64 | git clone --recurse-submodules git@github.com:jchue/argon-webtrees-theme.git
65 | ```
66 |
67 | **Install dependencies and run in watch mode**
68 |
69 | webtrees itself is a required dependency, since its base and vendor styles are utilized in the pipeline. First install it as well as its subdependencies:
70 |
71 | ```sh
72 | composer install
73 | npm run vendor
74 | ```
75 |
76 | Composer is configured to install webtrees from source, so it should include the required stylesheets.
77 |
78 | Then install the theme's Node dependencies and start the webpack watcher:
79 |
80 | ```sh
81 | npm install
82 | npm run dev
83 | ```
84 |
85 | To support Sass and ECMAScript, the stylesheets and scripts are developed in their respective directories under `src/`. When a change is detected, they are compiled/transpiled to `resources/`, from which webtrees serves the theme. The PHP views themselves are housed directly under the `resources/` directory already.
86 |
87 | **Build and package**
88 |
89 | ```sh
90 | npm run build
91 | ```
92 |
93 | This will compile/transpile the stylsheets/scripts and package them, along with the PHP views, in a `dist/` directory.
--------------------------------------------------------------------------------
/resources/js/vendor.js:
--------------------------------------------------------------------------------
1 | /******/ (function() { // webpackBootstrap
2 | /******/ "use strict";
3 | /******/ var __webpack_modules__ = ({
4 |
5 | /***/ "./vendor/fisharebest/webtrees/resources/css/vendor.tmp.css":
6 | /*!******************************************************************!*\
7 | !*** ./vendor/fisharebest/webtrees/resources/css/vendor.tmp.css ***!
8 | \******************************************************************/
9 | /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10 |
11 | __webpack_require__.r(__webpack_exports__);
12 | // extracted by mini-css-extract-plugin
13 |
14 |
15 | /***/ })
16 |
17 | /******/ });
18 | /************************************************************************/
19 | /******/ // The module cache
20 | /******/ var __webpack_module_cache__ = {};
21 | /******/
22 | /******/ // The require function
23 | /******/ function __webpack_require__(moduleId) {
24 | /******/ // Check if module is in cache
25 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
26 | /******/ if (cachedModule !== undefined) {
27 | /******/ return cachedModule.exports;
28 | /******/ }
29 | /******/ // Create a new module (and put it into the cache)
30 | /******/ var module = __webpack_module_cache__[moduleId] = {
31 | /******/ // no module.id needed
32 | /******/ // no module.loaded needed
33 | /******/ exports: {}
34 | /******/ };
35 | /******/
36 | /******/ // Execute the module function
37 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
38 | /******/
39 | /******/ // Return the exports of the module
40 | /******/ return module.exports;
41 | /******/ }
42 | /******/
43 | /************************************************************************/
44 | /******/ /* webpack/runtime/make namespace object */
45 | /******/ !function() {
46 | /******/ // define __esModule on exports
47 | /******/ __webpack_require__.r = function(exports) {
48 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
49 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
50 | /******/ }
51 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
52 | /******/ };
53 | /******/ }();
54 | /******/
55 | /************************************************************************/
56 | var __webpack_exports__ = {};
57 | // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
58 | !function() {
59 | /*!**************************!*\
60 | !*** ./src/js/vendor.js ***!
61 | \**************************/
62 | __webpack_require__.r(__webpack_exports__);
63 | /* harmony import */ var _vendor_fisharebest_webtrees_resources_css_vendor_tmp_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../vendor/fisharebest/webtrees/resources/css/vendor.tmp.css */ "./vendor/fisharebest/webtrees/resources/css/vendor.tmp.css");
64 | // Need to import stylesheet so Webpack processes it
65 |
66 | }();
67 | /******/ })()
68 | ;
69 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMvdmVuZG9yLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7Ozs7Ozs7VUNBQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBOzs7OztXQ3RCQTtXQUNBO1dBQ0E7V0FDQSx1REFBdUQsaUJBQWlCO1dBQ3hFO1dBQ0EsZ0RBQWdELGFBQWE7V0FDN0Q7Ozs7Ozs7Ozs7OztBQ05BIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vdmVuZG9yL2Zpc2hhcmViZXN0L3dlYnRyZWVzL3Jlc291cmNlcy9jc3MvdmVuZG9yLnRtcC5jc3M/OWNkZCIsIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vL3dlYnBhY2svcnVudGltZS9tYWtlIG5hbWVzcGFjZSBvYmplY3QiLCJ3ZWJwYWNrOi8vLy4vc3JjL2pzL3ZlbmRvci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCIvLyBOZWVkIHRvIGltcG9ydCBzdHlsZXNoZWV0IHNvIFdlYnBhY2sgcHJvY2Vzc2VzIGl0XG5pbXBvcnQgJy4uLy4uL3ZlbmRvci9maXNoYXJlYmVzdC93ZWJ0cmVlcy9yZXNvdXJjZXMvY3NzL3ZlbmRvci50bXAuY3NzJztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==
--------------------------------------------------------------------------------
/resources/js/theme.js:
--------------------------------------------------------------------------------
1 | /******/ (function() { // webpackBootstrap
2 | /******/ "use strict";
3 | /******/ var __webpack_modules__ = ({
4 |
5 | /***/ "./src/scss/theme.scss":
6 | /*!*****************************!*\
7 | !*** ./src/scss/theme.scss ***!
8 | \*****************************/
9 | /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10 |
11 | __webpack_require__.r(__webpack_exports__);
12 | // extracted by mini-css-extract-plugin
13 |
14 |
15 | /***/ })
16 |
17 | /******/ });
18 | /************************************************************************/
19 | /******/ // The module cache
20 | /******/ var __webpack_module_cache__ = {};
21 | /******/
22 | /******/ // The require function
23 | /******/ function __webpack_require__(moduleId) {
24 | /******/ // Check if module is in cache
25 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
26 | /******/ if (cachedModule !== undefined) {
27 | /******/ return cachedModule.exports;
28 | /******/ }
29 | /******/ // Create a new module (and put it into the cache)
30 | /******/ var module = __webpack_module_cache__[moduleId] = {
31 | /******/ // no module.id needed
32 | /******/ // no module.loaded needed
33 | /******/ exports: {}
34 | /******/ };
35 | /******/
36 | /******/ // Execute the module function
37 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
38 | /******/
39 | /******/ // Return the exports of the module
40 | /******/ return module.exports;
41 | /******/ }
42 | /******/
43 | /************************************************************************/
44 | /******/ /* webpack/runtime/make namespace object */
45 | /******/ !function() {
46 | /******/ // define __esModule on exports
47 | /******/ __webpack_require__.r = function(exports) {
48 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
49 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
50 | /******/ }
51 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
52 | /******/ };
53 | /******/ }();
54 | /******/
55 | /************************************************************************/
56 | var __webpack_exports__ = {};
57 | // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
58 | !function() {
59 | /*!*************************!*\
60 | !*** ./src/js/theme.js ***!
61 | \*************************/
62 | __webpack_require__.r(__webpack_exports__);
63 | /* harmony import */ var _scss_theme_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scss/theme.scss */ "./src/scss/theme.scss");
64 | // Need to import stylesheet so Webpack processes it
65 |
66 | const secondaryHeader = document.getElementById('secondary-header');
67 | const secondaryHeaderHeight = secondaryHeader.offsetHeight;
68 | const primaryHeader = document.getElementById('primary-header');
69 | const primaryHeaderHeight = primaryHeader.offsetHeight;
70 | const siteContent = document.getElementById('content');
71 | function setHeader() {
72 | const scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
73 | if (scrollPosition > secondaryHeaderHeight) {
74 | primaryHeader.style.position = 'fixed';
75 | siteContent.style.marginTop = `${primaryHeaderHeight}px`;
76 | } else {
77 | primaryHeader.style.position = 'static';
78 | siteContent.style.marginTop = 0;
79 | }
80 | }
81 | window.addEventListener('load', setHeader);
82 | window.addEventListener('scroll', setHeader);
83 | }();
84 | /******/ })()
85 | ;
86 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMvdGhlbWUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7OztVQ0FBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7Ozs7O1dDdEJBO1dBQ0E7V0FDQTtXQUNBLHVEQUF1RCxpQkFBaUI7V0FDeEU7V0FDQSxnREFBZ0QsYUFBYTtXQUM3RDs7Ozs7Ozs7Ozs7O0FDTkE7QUFDNEI7QUFFNUIsTUFBTUEsZUFBZSxHQUFHQyxRQUFRLENBQUNDLGNBQWMsQ0FBQyxrQkFBa0IsQ0FBQztBQUNuRSxNQUFNQyxxQkFBcUIsR0FBR0gsZUFBZSxDQUFDSSxZQUFZO0FBRTFELE1BQU1DLGFBQWEsR0FBR0osUUFBUSxDQUFDQyxjQUFjLENBQUMsZ0JBQWdCLENBQUM7QUFDL0QsTUFBTUksbUJBQW1CLEdBQUdELGFBQWEsQ0FBQ0QsWUFBWTtBQUV0RCxNQUFNRyxXQUFXLEdBQUdOLFFBQVEsQ0FBQ0MsY0FBYyxDQUFDLFNBQVMsQ0FBQztBQUV0RCxTQUFTTSxTQUFTQSxDQUFBLEVBQUc7RUFDbkIsTUFBTUMsY0FBYyxHQUFHUixRQUFRLENBQUNTLGVBQWUsQ0FBQ0MsU0FBUyxJQUFJVixRQUFRLENBQUNXLElBQUksQ0FBQ0QsU0FBUztFQUVwRixJQUFJRixjQUFjLEdBQUdOLHFCQUFxQixFQUFFO0lBQzFDRSxhQUFhLENBQUNRLEtBQUssQ0FBQ0MsUUFBUSxHQUFHLE9BQU87SUFDdENQLFdBQVcsQ0FBQ00sS0FBSyxDQUFDRSxTQUFTLEdBQUksR0FBRVQsbUJBQW9CLElBQUc7RUFDMUQsQ0FBQyxNQUFNO0lBQ0xELGFBQWEsQ0FBQ1EsS0FBSyxDQUFDQyxRQUFRLEdBQUcsUUFBUTtJQUN2Q1AsV0FBVyxDQUFDTSxLQUFLLENBQUNFLFNBQVMsR0FBRyxDQUFDO0VBQ2pDO0FBQ0Y7QUFFQUMsTUFBTSxDQUFDQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUVULFNBQVMsQ0FBQztBQUMxQ1EsTUFBTSxDQUFDQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUVULFNBQVMsQ0FBQyxDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vc3JjL3Njc3MvdGhlbWUuc2Nzcz9kOTViIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly8vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly8vLi9zcmMvanMvdGhlbWUuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQge307IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiLy8gTmVlZCB0byBpbXBvcnQgc3R5bGVzaGVldCBzbyBXZWJwYWNrIHByb2Nlc3NlcyBpdFxuaW1wb3J0ICcuLi9zY3NzL3RoZW1lLnNjc3MnO1xuXG5jb25zdCBzZWNvbmRhcnlIZWFkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2Vjb25kYXJ5LWhlYWRlcicpO1xuY29uc3Qgc2Vjb25kYXJ5SGVhZGVySGVpZ2h0ID0gc2Vjb25kYXJ5SGVhZGVyLm9mZnNldEhlaWdodDtcblxuY29uc3QgcHJpbWFyeUhlYWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmltYXJ5LWhlYWRlcicpO1xuY29uc3QgcHJpbWFyeUhlYWRlckhlaWdodCA9IHByaW1hcnlIZWFkZXIub2Zmc2V0SGVpZ2h0O1xuXG5jb25zdCBzaXRlQ29udGVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb250ZW50Jyk7XG5cbmZ1bmN0aW9uIHNldEhlYWRlcigpIHtcbiAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wO1xuXG4gIGlmIChzY3JvbGxQb3NpdGlvbiA+IHNlY29uZGFyeUhlYWRlckhlaWdodCkge1xuICAgIHByaW1hcnlIZWFkZXIuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xuICAgIHNpdGVDb250ZW50LnN0eWxlLm1hcmdpblRvcCA9IGAke3ByaW1hcnlIZWFkZXJIZWlnaHR9cHhgO1xuICB9IGVsc2Uge1xuICAgIHByaW1hcnlIZWFkZXIuc3R5bGUucG9zaXRpb24gPSAnc3RhdGljJztcbiAgICBzaXRlQ29udGVudC5zdHlsZS5tYXJnaW5Ub3AgPSAwO1xuICB9XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgc2V0SGVhZGVyKTtcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzZXRIZWFkZXIpO1xuIl0sIm5hbWVzIjpbInNlY29uZGFyeUhlYWRlciIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJzZWNvbmRhcnlIZWFkZXJIZWlnaHQiLCJvZmZzZXRIZWlnaHQiLCJwcmltYXJ5SGVhZGVyIiwicHJpbWFyeUhlYWRlckhlaWdodCIsInNpdGVDb250ZW50Iiwic2V0SGVhZGVyIiwic2Nyb2xsUG9zaXRpb24iLCJkb2N1bWVudEVsZW1lbnQiLCJzY3JvbGxUb3AiLCJib2R5Iiwic3R5bGUiLCJwb3NpdGlvbiIsIm1hcmdpblRvcCIsIndpbmRvdyIsImFkZEV2ZW50TGlzdGVuZXIiXSwic291cmNlUm9vdCI6IiJ9
--------------------------------------------------------------------------------
/module.php:
--------------------------------------------------------------------------------
1 | 'fff4f9',
37 | 'chart-background-m' => 'f4fdff',
38 | 'chart-background-u' => 'f4f5f7',
39 | 'chart-box-x' => 260,
40 | 'chart-box-y' => 85,
41 | 'chart-font-color' => '000000',
42 | 'chart-spacing-x' => 5,
43 | 'chart-spacing-y' => 10,
44 | 'compact-chart-box-x' => 240,
45 | 'compact-chart-box-y' => 50,
46 | 'distribution-chart-high-values' => '84beff',
47 | 'distribution-chart-low-values' => 'c3dfff',
48 | 'distribution-chart-no-values' => 'ffffff',
49 | ];
50 |
51 | return $parameters[$parameter_name];
52 | }
53 |
54 | /**
55 | * Bootstrap the module
56 | */
57 | public function boot(): void
58 | {
59 | // Register a namespace for our views.
60 | View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');
61 |
62 | // Replace an existing views with our own versions.
63 |
64 | /**
65 | * Global
66 | */
67 | View::registerCustomView('::layouts/default', $this->name() . '::layouts/default'); // Site template
68 | View::registerCustomView('::modules/contact-links/footer', $this->name() . '::modules/contact-links/footer'); // Footer > contact line
69 | View::registerCustomView('::modules/hit-counter/footer', $this->name() . '::modules/hit-counter/footer'); // Footer > view count
70 | View::registerCustomView('::modules/powered-by-webtrees/footer', $this->name() . '::modules/powered-by-webtrees/footer'); // Footer > webtrees link
71 | View::registerCustomView('::modules/privacy-policy/footer', $this->name() . '::modules/privacy-policy/footer'); // Footer > privacy policy link
72 |
73 | /**
74 | * Tree Page Blocks
75 | */
76 | View::registerCustomView('::modules/gedcom_stats/statistics', $this->name() . '::modules/gedcom_stats/statistics'); // Blocks > Statistics
77 | View::registerCustomView('::modules/todo/research-tasks', $this->name() . '::modules/todo/research-tasks'); // Blocks > Research tasks
78 | View::registerCustomView('::modules/recent_changes/changes-list', $this->name() . '::modules/recent_changes/changes-list'); // Blocks > Recent changes (list layout)
79 |
80 | /**
81 | * Individual Page
82 | */
83 | View::registerCustomView('::individual-page-images', $this->name() . '::individual-page-images'); // Individual page thumbnails
84 | View::registerCustomView('::individual-page-tabs', $this->name() . '::individual-page-tabs'); // Individual page tabs
85 | View::registerCustomView('::modules/relatives/family', $this->name() . '::modules/relatives/family'); // Individual > Families tab
86 | View::registerCustomView('::modules/stories/tab', $this->name() . '::modules/stories/tab'); // Individual > Stories tab
87 | View::registerCustomView('::modules/lightbox/tab', $this->name() . '::modules/lightbox/tab'); // Individual > Album tab
88 | View::registerCustomView('::modules/places/tab', $this->name() . '::modules/places/tab'); // Individual > Places tab
89 | View::registerCustomView('::modules/descendancy/sidebar', $this->name() . '::modules/descendancy/sidebar'); // Individual > Descendants sidebar
90 |
91 | /**
92 | * Charts
93 | */
94 | View::registerCustomView('::modules/interactive-tree/chart', $this->name() . '::modules/interactive-tree/chart'); // Charts > Interactive tree AND Individual > Interactive tree tab
95 | View::registerCustomView('::chart-box', $this->name() . '::chart-box'); // Individuals' boxes in Charts > Ancestors, Compact Tree, Descendants, Family Book, Hourglass Chart, Pedigree, Relationships
96 | View::registerCustomView('::modules/lifespans-chart/chart', $this->name() . '::modules/lifespans-chart/chart'); // Charts > Lifespans
97 | View::registerCustomView('::modules/pedigree-map/chart', $this->name() . '::modules/pedigree-map/chart'); // Charts > Pedigree map
98 | View::registerCustomView('::modules/statistics-chart/page', $this->name() . '::modules/statistics-chart/page'); // Charts > Statistics
99 |
100 | /**
101 | * FAQ Page
102 | */
103 | View::registerCustomView('::modules/faq/show', $this->name() . '::modules/faq/show'); // Page template
104 |
105 | /**
106 | * Lists
107 | */
108 | View::registerCustomView('::lists/surnames-table', $this->name() . '::lists/surnames-table'); // Lists > Families AND Lists > Individuals
109 | View::registerCustomView('::modules/media-list/page', $this->name() . '::modules/media-list/page'); // Lists > Media objects
110 | View::registerCustomView('::modules/place-hierarchy/page', $this->name() . '::modules/place-hierarchy/page'); // Lists > Place hierarchy page
111 | View::registerCustomView('::place-hierarchy', $this->name() . '::place-hierarchy'); // Lists > Place hierarchy page > Place hierarchy (without map)
112 | View::registerCustomView('::modules/place-hierarchy/map', $this->name() . '::modules/place-hierarchy/map'); // Lists > Place hierarchy page > map
113 | View::registerCustomView('::modules/place-hierarchy/sidebar', $this->name() . '::modules/place-hierarchy/sidebar'); // Lists > Place hierarchy page > location entries
114 | View::registerCustomView('::modules/place-hierarchy/popup', $this->name() . '::modules/place-hierarchy/popup'); // Lists > Place hierarchy page > map pin popup
115 | View::registerCustomView('::modules/place-hierarchy/list', $this->name() . '::modules/place-hierarchy/list'); // Lists > Place hierarchy page > Place list (under map)
116 | View::registerCustomView('::lists/repositories-table', $this->name() . '::lists/repositories-table'); // Lists > Repositories
117 | View::registerCustomView('::lists/notes-table', $this->name() . '::lists/notes-table'); // Lists > Shared notes
118 | View::registerCustomView('::lists/sources-table', $this->name() . '::lists/sources-table'); // Lists > Sources
119 |
120 | /**
121 | * Calendar
122 | */
123 | View::registerCustomView('::calendar-page', $this->name() . '::calendar-page'); // Calendar > Day/Month/Year > "View" row
124 | View::registerCustomView('::calendar-list', $this->name() . '::calendar-list'); // Calendar > Day > individuals/families table
125 | }
126 |
127 | /**
128 | * Where does this module store its resources
129 | *
130 | * @return string
131 | */
132 | public function resourcesFolder(): string
133 | {
134 | return __DIR__ . '/resources/';
135 | }
136 |
137 | /**
138 | * Replace Minimal spreadsheet with Argon spreadsheet
139 | *
140 | * @return array
141 | */
142 | public function stylesheets(): array
143 | {
144 | // NOTE - a future version of webtrees will allow the modules to be stored in a private folder.
145 | // Only files in the /public/ folder will be accessible via the webserver.
146 | // Since modules cannot copy their files to the /public/ folder, they need to provide them via a callback.
147 | $stylesheets[] = $this->assetUrl('css/vendor.css');
148 | $stylesheets[] = $this->assetUrl('css/theme.css');
149 |
150 | return $stylesheets;
151 | }
152 |
153 | /**
154 | * Raw content, to be added at the end of the element.
155 | * Typically, this will be ';
162 |
163 | return $bodyContent;
164 | }
165 | };
166 |
--------------------------------------------------------------------------------
/resources/views/layouts/default.phtml:
--------------------------------------------------------------------------------
1 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | = strip_tags($title) ?>
44 | getPreference('META_TITLE') !== '') : ?>
45 | – = e($tree->getPreference('META_TITLE')) ?>
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | stylesheets() as $stylesheet) : ?>
61 |
62 |
63 |
64 | = View::stack('styles') ?>
65 |
66 | = app(ModuleService::class)->findByInterface(ModuleGlobalInterface::class)->map(static function (ModuleGlobalInterface $module): string {
67 | return $module->headContent();
68 | })->implode('') ?>
69 |
70 |
71 |
72 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
145 | = $message->text ?>
146 |
147 |
148 |
149 |
150 | = $content ?>
151 |
152 |
153 |
154 |
161 |
162 |
163 |
164 |
165 |
199 |
200 | = View::stack('javascript') ?>
201 |
202 | = app(ModuleService::class)->findByInterface(ModuleGlobalInterface::class)->map(static function (ModuleGlobalInterface $module): string {
203 | return $module->bodyContent();
204 | })->implode('') ?>
205 |
206 |
207 |
--------------------------------------------------------------------------------
/src/scss/_icons.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Icons
3 | */
4 |
5 | .icon-loading-small {
6 | content: url("data:image/gif;base64,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");
7 | }
8 |
9 | .icon-minus {
10 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wsPEywVOTtwpwAAAG5JREFUOMtjYBjsgBFTKO0/hDaG8s8iyRlD+TB6FiMRdsz8TwxgYJj5H5tuJkyhsxR5GYuBxkRqPUusgZQBFpyxxTgLySWokfH//0ycPsFp4P//adTyMrGRYkztMBy4SDGGRshZLDnDmCppdZgBAHCgPcALClCyAAAAAElFTkSuQmCC");
11 | vertical-align: middle;
12 | }
13 |
14 | .icon-plus {
15 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wsPEyo0IwjHfwAAAH1JREFUOMvlk8ENwCAIRcF0I3ayM+FOzkQPWmPCb4L20qT/QvxGEJ4SfV3srWwtSl/XaU/6+o6FAzXUIiJSQ6eTt6pvg0u4ZZBQKFIEezAhkoRveDzSGm02CMzngGGmK0UUAMjQ24ayMoa0/4RfQGkz24YiHUgFP0MWx/ILXT2mYpxmWZVIAAAAAElFTkSuQmCC");
16 | vertical-align: middle;
17 | }
18 |
19 | .icon-mypage {
20 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512' width='32' height='24'%3E%3Cpath fill='%23212529' d='M528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-352 96c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H86.4C74 384 64 375.4 64 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2zM512 312c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-64c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-64c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16z'%3E%3C/path%3E%3C/svg%3E");
21 | }
22 |
23 | .icon-pedigree {
24 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512' width='25' height='30'%3E%3Cpath fill='%23212529' d='M576 192c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zM64 240c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64zm449.6-37.2l-19.2-25.6-48 36 19.2 25.6 48-36zM576 384c-14.4 0-27.6 5-38.3 13l-96-57.6c3.8-11.2 6.3-23 6.3-35.5 0-61.9-50.1-112-112-112-8.4 0-16.6 1.1-24.4 2.9l-40.8-87.4C281.4 96 288 80.8 288 64c0-35.3-28.7-64-64-64s-64 28.7-64 64 28.7 64 64 64c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304c0 61.9 50.1 112 112 112 32.1 0 60.8-13.7 81.2-35.3l95.8 57.5c-.5 3.2-1 6.5-1 9.8 0 35.3 28.7 64 64 64s64-28.7 64-64-28.7-64-64-64zm-240-32c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm-184-32h48v-32h-48v32z' class=''%3E%3C/path%3E%3C/svg%3E");
25 | }
26 |
27 | // Family icon on Individual page > Families tab
28 | .icon-cfamily {
29 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' width='15' height='15' fill='%23525f7f'%3E%3Cpath d='M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z' /%3E%3C/svg%3E");
30 | display: inline-block;
31 | height: 15px;
32 | width: 15px;
33 | }
34 |
35 | // Children column in individual and family lists
36 | .icon-children {
37 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='15' height='15' fill='%23525f7f'%3E%3Cpath d='M13,2V10H21A8,8 0 0,0 13,2M19.32,15.89C20.37,14.54 21,12.84 21,11H6.44L5.5,9H2V11H4.22C4.22,11 6.11,15.07 6.34,15.42C5.24,16 4.5,17.17 4.5,18.5A3.5,3.5 0 0,0 8,22C9.76,22 11.22,20.7 11.46,19H13.54C13.78,20.7 15.24,22 17,22A3.5,3.5 0 0,0 20.5,18.5C20.5,17.46 20.04,16.53 19.32,15.89M8,20A1.5,1.5 0 0,1 6.5,18.5A1.5,1.5 0 0,1 8,17A1.5,1.5 0 0,1 9.5,18.5A1.5,1.5 0 0,1 8,20M17,20A1.5,1.5 0 0,1 15.5,18.5A1.5,1.5 0 0,1 17,17A1.5,1.5 0 0,1 18.5,18.5A1.5,1.5 0 0,1 17,20Z'%3E%3C/path%3E%3C/svg%3E");
38 | }
39 |
40 | // Default individual
41 | .icon-indis {
42 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' width='24' height='27'%3E%3Cpath fill='%23212529' d='M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z'%3E%3C/path%3E%3C/svg%3E");
43 | }
44 |
45 | // Marriage icon in Branches list
46 | .icon-rings {
47 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAMAAADXT/YiAAAAilBMVEX///+qq6p5eXkvLy9dXl1lZWVgYGB3d3d6eXpqamp1dHVeW15CQ0JLS0tCQkIpKCkxMTFcXVwpJylcWVxXWFdYWFh6enrW19bd3928vby5uLm7u7vq6+rt7u3n6Ofe3t7i4uKztLOUlJSXl5eTk5OGhoaIiIivsa+wsLCvrq+YmJhnZWeZmZmSkZKS18eoAAAAAXRSTlMAQObYZgAAAEpJREFUeF4dyEMCxUAAQLE3qG37G/e/XpFloM8jyWl07p31BygeMMcLkDYI7atjS7fWlZ6+LdxUmAheHvAOBrA/AJvxlCaXNfvBDsPZBEeBRMqLAAAAAElFTkSuQmCC")
48 | }
49 |
50 | // Request new account
51 | .icon-user_add {
52 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512' width='34' height='27'%3E%3Cpath fill='%23212529' d='M624 208h-64v-64c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v64h-64c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h64v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-64h64c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z'%3E%3C/path%3E%3C/svg%3E");
53 | }
54 |
55 | .icon-edit_indi {
56 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='13.125' height='15'%3E%3Cpath fill='%23212529' d='M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z'%3E%3C/path%3E%3C/svg%3E");
57 | }
58 |
59 | // Silhouettes in chart boxes
60 | .icon-silhouette-f {
61 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAyCAQAAABxRNqrAAAD+ElEQVR4AaWUb0xbVRjGXyoOBmPBbTH+yQY4dAubigtD1skAmePPVkDppNhRwCKwUgXCWlpKe95zadmmMwvRDy5Z1MwlZjPRDwxjNJJo+GYkLtOZGWLGB0xM1MWgk4C5r+SeNPcGbtKe+nty27TNec57et73ARl8WewJfo/++dThUSfeB3KcSwOo3dzyHjsLgBsxG7MA6loHfvEtBj4Ld0WyIRnQAqv0PzC8w3bESbEzrBtncAG/i7w/OOebbQ48PfHK5bBDEbWagxm4FQuwFG24Z+Sx5pqTgd6rHuKEmhghhf+KzCpfxc7blWBHNB3MYZm4DwfxKi6iWLaCX3hvRq4rmoUQU8VvjPg/2MsssB63JVyCHH/F+CIVtUU8vnytVO3ZDms5scXvZXMGi8QSZh2YBkaaC/ovjYrdNRsJqzfRaFWd47oyQpyYjE28+mbQsWY5Qn5JI6ZycaffsCzQqSxoXo4RU5lERZwGqe+u791IMRipKThOUWEkocBvnq7juWBkj6W+sZMUSSNGeEM5z4tYGuiUZtad9hKXtuKq59PwxTMbQadkU+2Hw5JWog1G6dWPQk1j+gyW5tR8MiSsJM04tU8EG6O6Vdmmmg/kDyjGesjRKYwE5ZttU35hJW+2D4xYM6vRSWOE8lrEPDDyVHrDSf2AktoLRuofdf8QJSZ1MPG3M0Iv3gtxDmbUT3LxtUQbMGJiYt9CfQKrsuv+8MkMssqI/zvwt29F25xjpn5/6RV9TbcjJGMV+9w22bekZWstGgen8v6mm1L5dGe449jZ9uUg4be4DYxU5tvmg8RVliCfkLSEWuFjL+SfOFj1cc81pVJJByNlGc++3kqJYzi83DffPR1yR7VKrI+37IT1PFNUNzOYsLMi851N+wvAHD0b6i94SUnUS7fGd0AirDmHJ1x0mhRVISE0a9mf8BFITMWu56bt1LUqF7WRm0bMmvYW5kNiDqQdyjqy/Wix/aGXcl/OLr/Uo5p02m20giylLa6FkFkORECW/SUtPwYI12sKZHmy0HE9aDLEOIeHQI4Du103RsyqWsJxkGFnrkcJ3TEfI5xECyRPw/gQmSaYqvVWNSRLcXHPbNg4kfEsE4O1wjgki015jTixNZkZJj+dWn0Y8WuRLZAMewu7pkOGw4nq2M+BdzrfaH3b+aX7z4HvYxWQDHUez7Kix7N4n2K1oFGUV+Z6vm3iQUjMw1vbLvtFCOpGF1g+yFN11P07Fxbi9S6GMBdSYIM91i9qEhm+gE7MhFQo2d0+E7dZ1TRa0QKp0eDsJiV+Z+cwD1KlcJvjYpAUGqXQ18yKGZA65aWNS71LvVfcx+yb4f9RkVO168UN/WmQEv8BWtevBS+ro80AAAAASUVORK5CYII=");
62 | }
63 |
64 | .icon-silhouette-m {
65 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAyCAQAAABxRNqrAAACbUlEQVR4AaWUS0hUURjHP3xAoJuKKDIwN4GzEheh44z3NtmDJAvdqDmBhUZkQqRMzsg9372TLnrkylWbIAqEIBLctevhJghc1KYIF9WiRZtcJPj9Awu7eq73cfz9mcXA8OP7nznno3C4jyc5z5X8gFcYDP7KKUoOV/ASg4XhizD4FY/xrviavfyIV3mNoUX+fZ7E0VTxjDZNkPI311MYajFK45O9CxENPmYkyv3gYvuLMx44aQ5oouaa8edKWBKrhjWVPX4RCpw8vzRVx9C0iUgY3ER+Kquu/VDCMEqB/GScqzBUCT8kP5bKg6HARiE/9kAGw8IwTI78WBMtuG2qmqDNtC3eNK1YpM1YdweEzWQXtqq606Y3q5G2kvk4KiZTkU7WKZgUfEo6zks2mUp/0LdmjTYDtD2fHh4xKSe8rC+ZqYyUoJL/ey7p2O/PwGCLVgepajvhGW0FXbU7l0wlCuoQBZNOpkJvjrYj+9aLffAKyifSaP8+svHDcE0ZZ4sUhj1lIYcOHJdJCVOVkO2gKOxau87a1/ZpIrzeAsUlM18KV81TXNpfKwlV/Yw/1Uox6rmMUDzaFpzoDZGiOFz5rKKfzIc49fqdbe8Tw8U0pv5+r6MoupddCRY56MFJWLBxGoUlNUfhHDl4HSpA4671In0j25yrOVZtN1pz7V8oCrugn0tZhpC9Q0npXnW18+l7k9pDSTncMAYlG5r1dJXJhBOznvgmkklY58iM/v9HLiyjaKonM1KnShvFPLn8raGWTOl85olaL+ag6wVVkDmDUHDB6MPRLtoJrZfyyOM8Wu+1VNPOsHusspW3jTV/AC4z+BByxrV6AAAAAElFTkSuQmCC");
66 | }
67 |
68 | .icon-silhouette-u {
69 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAyCAQAAABxRNqrAAAB2ElEQVR4Ae3UMWhTQQDG8WvAIVUEXZQWlHYQqZOlrVArRRsQBRWqjUhFUlQKFcXSh5BYe19eFQRBsjmKmyA4iHHQMYJidFQRBd0EBzHiFr3P6XH6uHvcXdf3/9bwg7scT+Q5lIcN2IUGHuMT3qGJVQytFMOgQTwHU2uWx0KoDyCUZqAkwer72S2+0F0N6UlKzj880uMDDaUhvSvcP+FDrdooqWKWn/lQT0HbYjVH4XpEFNGGslF1LnB4ryvVi9dgFjV62J1qB1Dm0Mo64HmOjLtT97KufZYbe92pczZI8jpLX4R76Lc/0YiTt4VPaFluSlV4YNCPOmo+3jKnX+wpCL/w0YQtsXTZF+rBDRM193V4p/ANx01v6sTbgaI/dcpEzbwR/uGB6YCLn3f0+TEFnDT/g9f+XFqoFdyhSdwHoSyPtCvvYNSF2YZX+GWHpAJB/MQTDGQxW3ELBDVinP5FQ/aboQo62ZAB+74yL9Kh7MEkmAJlN7r5P9QHhq7G09PpN6RCIKliVn5raB2+gcFTEXdPJNR2dMIpyZgjF/VbWisVJdRm/IAKx5Y5tiSSZAsMvHhV51mOT4mk+qarL6usBazKCzz4SPzb4vqZqWNnQnaotC/9MczL+wt62AQGzYp3ZAAAAABJRU5ErkJggg==");
70 | }
71 |
72 | // Default thumbnail - gender unknown
73 | .wt-individual-silhouette {
74 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABhCAQAAACKJsxsAAAESklEQVR4Ae3aW2gcVRzH8UlTQyHWai0RpHixjVqLIFZbyW52/rlbtqnWBClJ6cVL04Q2xtRuE7bp/CY1+KgQiyh4sailBAMqoojQR/EiCGJfCkLxQVPS0Fgk8dLzk3nxYeNOm5mTnDNl5/uQ13z4z9k5c3GwEK3GNrSiD+P4MAgfoR9bsBUrnIU7oK8yrEIlXgX/SxX8DXoJN2Ol3ZAjhf92SAedJXZCOsB5pDxi2nvCPki+2BzCe+6kOFJmD6Q6GgM8wkbaM5EHMBvOCKd09tkCYfQ8QuWY3WEeUoGvwXj5ah83tJqGNIJQ8SAeh9k+VbPGLOQMGD+PhyjHTUKeLJxH9LKsW20OMq2LAfYy/bkpyCOYAXXlq5bJ1K1mIF2gvoa5g+k9ZiBjoM76mR4zA5nUCxlUDTQDIZROSJ4tlObFh2RAvR1lK+XA4kMGdUN8tlE+W3xIDtRcAPm1BClBSpASpAQJr1U3w+NjSibMbFG0luejlE+vCUgzpdsE5LReyGFmKDkTkJN6Ic+rWkPb+F167xA7mLloBnI3Lun7xRphDeUDM5CluAili3KQtZROE5CgE/ruRTrozshDpiCb9Z1aWco5qTAFcXQxBtlM+cnks99RPZT9zFDqTUI2YjY+4xg306XZp/GVOA8VFzLAFKXXJCSoJ/6lMEt3RtabhtwYf6E3KTljwzvEfDzK03Qp3TZA7sfl6PM4xizdKVves/8QdcH77GEtpdcWyHD0hb6N7pTcYgvkwegPrpsop81/MBD7FUOODZT3bYJ8AUbpAIXSbhPkvWiQHrqUKpsgjNYLrKfjWAmJsEa22wOpA6PWSNliD+T76BfELpX+0hZIA2bjbFEeP/fwCjsgZ+PtfvvZ+Ix5yDL8GPd9u696WL/BLGRdgIj/4Rl49HfcZQpyD46DuAxqawi3Lz5kHH+AWlMgZvEWKhYLUg0UfDauF/Mn8rht4SEfY1o/oIBCXMK7uG+hIDegDYxQdM441uiHHMIvkU+n6JgZvI3rdUGWow0T+hARJjOAqviQPvxcsLRNNIl34kBW4nWDhMLJXEB1NMgd+K2AYbx8t1M2X0gW50HLUkM8/Mr8IHeCIJR9FJ9Pja9fe7WQclwA7cyjx92jVwdZgm9DpmE+NcCWE2vLrwzZEyBszmfvP5vargQpB23PI9g5KTeFQxpAKOsxai/dmXDICJiE+uiquuXFIavwVzIgPltVqqY4pAlMRsPcrVIjUlYM0pUUiM/9TH8n5cUgb0IlA+LRZ+qsLC0GeQNMSp5KU5ZdCxCWIAYqQUaTAxlSYZCG5FwQd7H2b6koBqlKDmQrM98UuyAGnUrE7pc5ZihjUlYcch0mk7DQ2ylKUuF3iBs9gp7FU3mRO4OFfkoqwiBBLbkJ0LP03hDcSZfuVzL3CVfT3O7tfG0fn+Ve69rORtYq+UTWOXOPTf9fpTvivmxhI1Ip5U4CjtLxLyQgqH0cUqD2AAAAAElFTkSuQmCC");
75 | }
76 |
77 | // Default thumbnail - female
78 | .wt-individual-silhouette-f {
79 | content: url("data:image/png;base64,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");
80 | }
81 |
82 | // Default thumbnail - male
83 | .wt-individual-silhouette-m {
84 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGMAAABjCAQAAAAlMnYeAAAFh0lEQVR4AdXb3W8UVRgG8NOmpRSlFBAwxm8gaCIJYqLQ7c68y1IqLZQPhUCBsmAIFG1BWmn52J53dpdEgxcaboRAoqigJMYoF0ZSblATbxoTPxAUiUoDaCkBYwS0PY+7LCbKCm3ZOWd2nucPaH+Zec+ck5kV7oXzhOA3+BTjWru5k18RfguX8AlGRj/g0VzNO/kc42qbeXTuEmbyR9zDYHUdQjEyeoEnilwK53Exr+DfMv7hvrswdxDDeQd3MQbcNPkQN/FY76/DJL4y4GuQebvt9hIxjt/mvxhZN01p4cHeMHYyXGuK8jtHzCMeTf9x1/sNzzCHKE3NhJ7Ki7HxphgHGfpa/9m4ISYQHzI0Vjmo7tSPGJ+eCn2ViKnmhObnCW9nGGgPX+ADnK8LUcDtDCNVjHnDdTGKGKYaw7yTwbWUr4PxnjlGHKToKA12H3F7xnhrbALloF/oNvcZtQxzldgG64tgkfuMA6wYJtt6CnnaD6j666B6j9uMEXzaNCOmalHuuLpa8f0M4ww8BesElbjJ2GieEUcYBLrLTQZYmWZsSTEu0ij3EFPNAiQYDpoQAh2noe4xEgyz3YyVsEGgT6jQPcZhs7eURBWCoFR3u7nYnjR9UwVAir6jRVTgHuMO/sksglOM710DeMNw8AyCoIT7jJ9NXosYlsACvSTcDh9hmGsU02CD7nURYH6lkoikEKBB7jMazSFkGtGu4QDLlea2g4thKQLNEjrCYGWMAXpf6Am/ampXWwMbQld4tqlnxmqENDJG8QVTI77orD5GMXcwjFRFwRF9kHcZpiDJ1uliTGaYbOBODQjDB1nlINIzdqT+VzRaKxHHAmV9ToU6GAsZptoASrVUB2MI95i4Eg7Wg2Ar6qUSoSP8ponpiCKUQoBY15BPMDHmtaBUdX6JxccZursUBDqk/wsF/Yxemiz0htt1j/hckKIy3YxZfFnnhLShOsUICN2RU5w/dK5TFqiXioT+1G2XYKWLUQ66LMxEbmNNkCgCoB3CVGRCQiodjOmgNmOMiUVrvk2AXYZIMMKgTcJk5vzY5vrOdjZs0GGjjIdLph1bk+Wt5WArNmEDmtCAyD+7qQ5hNuV5Fa0vgLNoE8IIXS3BTiPOU74wH2dXNoxGWIpAJ6mbvqSv6SCtFd6El2TJAO2hQVRCxcnmC6/CS7NmLBJ6o5+xASHQ0lxgtGTDaMV0UK33iAI+yipLRsJ7Roj/zPKmUtThNWIYX2JkOeJeM7iUL7LKlmGDXvSWEWdk200Iez3ibpw5HNRjSsRLxGF3drUJzG738gda5xnuQDZgqu0VYzUrhoSTbCLZWLLylr+eqjztFaMzjXgWKxCEhfmogwN5SxQHNbBXeYGwJOL7lndZCCKoCAQr2QAIc9RaxMED5KxH+REvGHlvFYQnXjvmgJjqqFAIetneb4MQwhY1MEhClXXTfcKLUDt10b7MNZ/GUKP91WI0q/5Pi4NVKFvuDWPojb/KtAqtyhDmYlu/V6tWhPeLXExoiLW34lwDYqo/kKiqAo0RuZnAMPvgMkgl+/VCwHpd5G4en1Hbtbkf25YmVX5e5HIeKa3+eCNk3y+RrwSCIrdT8U7rFdkHpRFT1+U4Y1JBILRaOTeZEomtmKFE7mdyXeOvbbgZZD7skA8gE0Y+fSx+kyd8PawO4Yc8VFLT3ZKC3Oj3ZZfsMcIfmfnac4j/75TEEFFlK4VfEmxaCQnOoEhEEfhU+CePVS3ofB5OJgTzFN0t/JTgqXo4uB6yBHab8FemtFT1NCDxH8wWZUH4LdYIOvMkGlTsX5uSmt7AE8J/sVYEOisRwTo0I44E6hHYK/wYKrKX2WdDmIaKZMOwz1CB8GtoIe2iH+g0Idl7hJ9Dw2gkPUAPUrEYQP4GWd+IXPEzWf4AAAAASUVORK5CYII=");
85 | }
86 |
87 | /**
88 | * Map icons (Vesta Facts and events)
89 | */
90 |
91 | .wt-icon-google-maps {
92 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAMAAAAhxq8pAAABgFBMVEVlc2X++Pf/89L/77//7rn/66n/6qL/6Z7/6Zr/6JX/55P/5o7/5Yn/5IT/5H7/4XH/32r/3Vz/3FX/2kv/2UX/2D7+1kn1yaP/1z3/1zn/1jb/1TH+0UD/1C3+0jj/1Cr/0y3/0yf6yGr+0DP/0iH+y0b+zDr/0Rr+zin/0BX/zxj/zxf4taT0yzz/zgz/zQX+xiv1yyf/zAH/zAD/ywP/yQX9wDb+yAn+xwr6yA32yg3wrqXqxjn8wxP0tHH0xRbayUX9vh2Ozt+gy7zRxkvcxDTFxmTtpp+pyZ3up4+tx47xsj22wXVwyv1pyP9mx/+UvqZixv9exf93wNdxv+LupxVgwfhZw/9fwfhWwv+RtZ1RwP9PwP5Kvv9Gvf9Bu//uglbhhWjxfF47uf82uP/ud17ucVTnblvsak3pZkzpYkfgZFHfbB7oX0XlWUDbXDTjVT7hTzrXUifeSjfeSDTcRTLXSSDaPy7ZPCzWNyjUOCXVNCbNNwvSLSHOIxrKGRLASgbBAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfjCw8TLgUWugJBAAABBElEQVQY02NgAAFGndTMdGsGVKCTlplXWOyOLMTMlpSRW1Bcni8DAlAxFra0rLzC0ooiCSmgoCpYkJWVIyGvsKS8OpEJDMCCXBw8Snkl5ZVltvrGJua2jmBBbi4ePrvyyipvKVl5BWU1iHZ+Pn5BzuzaHEV1TW1DGwMzsKCQgJAIj2ddqJ6RkUtIRFQUWFBUUESaT7zeEmiil39QdCxYUF5YSoWXpwYoZuoWGB4dBxZUF5WXYpJ0tTIxtfAJioyNh1jEy8Uk6OZkYmofEBYeE5cMFmRn5Vc08vD18QkOCo+OjU+BaFfQMjV18PMPDIoEiiVDVDKIyWlo6Dr7+vr5A5XGAAUAJdc2bEv6OzEAAAAASUVORK5CYII=");
93 | }
94 |
95 | .wt-icon-bing-maps {
96 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAMAAAAhxq8pAAAAM1BMVEUDAAD/phX/rCT/sTL/t0H/vFD/x23/zXv/04r/2Jn/3qf/47b/6cX/7tP/9OL/+fD///+nYNNKAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfjCw8TJjJm3i1GAAAAb0lEQVQY04XQSw6AIAwEUKyUb4G5/2kFhUhE46yaB6QtSqntEdXyjpr1igL5QOJxf2DyGS2RJwSyYza1CBMGOl8awN9IvUlA6RiRR2cHdLQAX0a5nveNEoptxrXQA8kDRaSOlfS0+26jiDj++ZAFDw0CBO37whbRAAAAAElFTkSuQmCC");
97 | }
98 |
99 | .wt-icon-openstreetmap {
100 | content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wsPEysflq8PfgAAA2ZJREFUOMud0l9sU2UcxvFvT0/b0z9rR9eylnWrBDY2kY0hEOfEcGNUwo3xToOJRqKJcOWVN8bEGExUvFETEyFxKHHoEm6YTImYbbipU2IY4mACXTe3nbU9O2tP23N2/nihM002bnyu3rx583mfX/Jz8W8mcv3dQL/jOFecucrn4fvSN9yC0F2oFB+7q9x+wsa41tm89ctjz75y8a33Tu6PxZOP27bwvLtSibUmn3TWHBc1+Vn+QnYc4syX8aeTrFoWS2UV3SqD4lBciLAt3Y6qlZiRb9HRFiHR1NC+Pfjo1Joh1oKmZZ90OZzAtlkp5gj46hBsi5nJFQ71PIPdXAa3i6DhIRLdRa6kc2NwogP4DxRqPJex4vzqFSXsBgl7QcOgSkAQaG3cj4mGx+cl5AsRCYSRwiIOKhUj/FFtqVrQicVjxyUxRCS8mWh9kgV1ieHxaZrT7fiEGHo5zFLBh7IcYrGk4A4LtHW3Jrv2PtK6EYiFedh0DHSzyoqtoqyWqXdvo1IVKWpgmP88VysmkpnChQM+i30P9cTXgSMzZ9LlahHTNrAzeQy/RSqwHV1XqOgOlkfG9N4mr2mYJkhBBUmU2Oxt4JMP3pleBx5oOZIxrdVStaph+V1IYgCvR6AptYfRy19TqlqsWjqh+lnC0SwBn5+dDR2MDI2fFzye8kYjC/Mz8jmXW8AxbXTdwudsQZKCXDh7mt/GruPxSrhcLiSvSMKX4KervyOrN9/ecf/OwEZrYy8tKFcSqegLuiQSUiW+vXgOTzVHLOknO3uZH7+XScSbsd0wKl8iHovR1BLsKi5r1zfcw96HD+7RTT/hmMxXfcOMDU2ilIocffUYvT0h5tQC8uIf5A0Vy2+Rige4Npife/DAXm02c2s9uLKqv+SIKhf6xhkeuIpaLvH00YN0ddssaI00SiZNLZuYIoNSVpENmYHP+sbkrOKsa/j+wBtxg6I4+PEIo4MTqJrGy68/xb7EFpxIhHohSyGfJhydpTC3jNsnUi0ZGTmrFGpLudcOyznVo8/n5pQ7S4em7vzFkeOHS4ZR/O7TU0Ov9Z8+/+7Nycwvqa1SLFgXSP05fXfs0tmxD78588Obcja/yL0STrRHX3yu91T7rt0nPN5IW+2HNQX8G9zfOzs6d29qe6Czjv+ZvwEzfn+Xi9vJQwAAAABJRU5ErkJggg==");
101 | }
102 |
103 | .wt-icon-help {
104 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' height='16' width='16'%3E%3Cpath fill='%23344767' d='M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3h58.3c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24V250.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1H222.6c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM288 352c0 17.7-14.3 32-32 32s-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32z'%3E%3C/path%3E%3C/svg%3E");
105 | }
--------------------------------------------------------------------------------
/src/scss/theme.scss:
--------------------------------------------------------------------------------
1 | $custom-colors: ("default": #172b4d);
2 |
3 | $table-cell-padding-y: 1rem;
4 | $table-cell-padding-x: 1rem;
5 | $table-cell-padding-y-sm: 0.75rem;
6 | $table-cell-padding-x-sm: 0.75rem;
7 |
8 | $dropdown-border-color: #dee2e6;
9 | $box-shadow-xs: 0 1px 3px rgba(50, 50, 93, .15), 0 1px 0 rgba(0, 0, 0, .02);
10 |
11 | // Common formatting for all themes
12 | @import "_base.css";
13 |
14 | // Argon
15 | @import "@fortawesome/fontawesome-free/css/all";
16 | @import "argon-dashboard/assets/scss/argon-dashboard";
17 |
18 | // Component customization
19 | @import "forms";
20 | @import "tables";
21 | @import "icons";
22 |
23 | :root {
24 | --chart-line-radius: #{$border-radius-sm};
25 | --chart-line: solid #{$border-color} #{$border-width};
26 | --link-color-hover: #f00;
27 | --link-color: #555;
28 | --link-decoration-hover: none;
29 | --link-decoration: none;
30 | --sex-f-bg: #fff4f9;
31 | --sex-f-fg: var(--bs-body-color);
32 | --sex-m-bg: #f4fdff;
33 | --sex-m-fg: var(--bs-body-color);
34 | --sex-u-bg: #fff;
35 | --sex-u-fg: var(--bs-body-color);
36 | --sex-x-bg: #fceaa1;
37 | --sex-x-fg: var(--bs-body-color);
38 | }
39 |
40 | /**
41 | * Bootstrap
42 | */
43 |
44 | .markdown p {
45 | white-space: pre-wrap;
46 | }
47 |
48 | caption {
49 | caption-side: top;
50 | padding-top: 0;
51 | }
52 |
53 | // Make card header gray
54 | .card {
55 | .card-header {
56 | background-color: rgba($black, .05);
57 | border-bottom: none;
58 | font-weight: $font-weight-bolder;
59 |
60 | &[id^=name-header-] {
61 | font-size: $font-size-lg;
62 | }
63 |
64 | name-header-add {
65 | font-size: $font-size-base;
66 | font-weight: $font-weight-normal;
67 | }
68 | }
69 |
70 | .card-header:first-child:last-child {
71 | border-radius: $card-border-radius;
72 | }
73 | }
74 |
75 | // Make accordions like cards
76 | .accordion-item {
77 | @extend .card;
78 | border-radius: 0;
79 |
80 | .accordion-button,
81 | .accordion-button:first-child,
82 | .accordion-button:first-child:last-child {
83 | @extend .card-header;
84 | border-radius: 0;
85 | padding: $accordion-button-padding-y $accordion-button-padding-x;
86 | }
87 | }
88 |
89 | .accordion-item:first-of-type {
90 | border-radius: $card-border-radius $card-border-radius 0 0;
91 |
92 | .accordion-button,
93 | .accordion-button:first-child {
94 | border-radius: $card-border-radius $card-border-radius 0 0;
95 | }
96 | }
97 |
98 | .accordion-item:last-of-type {
99 | border-radius: 0 0 $card-border-radius $card-border-radius;
100 |
101 | .accordion-button.collapsed {
102 | border-radius: 0 0 $card-border-radius $card-border-radius;
103 | }
104 | }
105 |
106 | .nav-pills {
107 | // Because spacing not set in HTML
108 | @extend .p-1;
109 |
110 | .nav-link {
111 | // Because spacing not set in HTML
112 | @extend .mb-0, .px-3, .py-1;
113 | }
114 |
115 | .nav-link.active {
116 | background-color: $white;
117 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.12);
118 | }
119 | }
120 |
121 | .dropdown .dropdown-menu {
122 | // Remove pointer from menu (should only be for individual dropdown items
123 | cursor: auto;
124 |
125 | display: none;
126 | overflow: visible;
127 |
128 | &.show {
129 | animation: $dropdown-animation-show;
130 | display: block;
131 | }
132 |
133 | .dropdown-item.active {
134 | background-color: map-get($theme-colors, "primary");
135 | color: map-get($theme-colors, "white");
136 | }
137 | }
138 |
139 | // Transform properties in Argon's animation causes an issue with popper
140 | .dropdown.position-static .dropdown-menu.show {
141 | animation: none;
142 | margin-top: 0 !important;
143 | }
144 |
145 | .modal {
146 | z-index: 1052;
147 | }
148 |
149 | .list-group {
150 | a.list-group-item {
151 | border-right: none;
152 | border-left: none;
153 | border-radius: 0;
154 | font-size: $font-size-sm;
155 | }
156 | }
157 |
158 | .tab-content {
159 | padding-top: 0.5rem;
160 | }
161 |
162 | .d-flex.justify-content-between {
163 | align-items: center;
164 | }
165 |
166 | ul.pagination {
167 | margin-bottom: $form-label-margin-bottom !important;
168 | }
169 |
170 | // Hack for pagination arrows
171 | .paginate_button.previous,
172 | .paginate_button.next {
173 | a {
174 | visibility: hidden;
175 |
176 | &::after {
177 | @extend .page-link;
178 | border-radius: 50%;
179 | color: $gray-600;
180 | display: block;
181 | font-weight: bold;
182 | height: 36px;
183 | padding-right: 0;
184 | padding-left: 0;
185 | position: absolute;
186 | text-align: center;
187 | top: 0;
188 | visibility: visible;
189 | width: 36px;
190 | }
191 | }
192 | }
193 |
194 | .paginate_button.previous a::after {
195 | content: "\2039";
196 | }
197 |
198 | .paginate_button.next a::after {
199 | content: "\203A";
200 | }
201 |
202 | .paginate_button.disabled a.page-link {
203 | color: $gray-400;
204 |
205 | &::after {
206 | color: $gray-400;
207 | }
208 | }
209 |
210 | /**
211 | * Webtrees
212 | */
213 |
214 | .wt-sex-m,
215 | .wt-chart-box-m,
216 | .tvM {
217 | background-color: var(--sex-m-bg) !important;
218 | color: var(--sex-m-fg) !important;
219 | }
220 |
221 | .wt-sex-f,
222 | .wt-chart-box-f,
223 | .tvF {
224 | background-color: var(--sex-f-bg) !important;
225 | color: var(--sex-f-fg) !important;
226 | }
227 |
228 | .wt-sex-u,
229 | .wt-chart-box-u,
230 | .tvU {
231 | background-color: var(--sex-u-bg) !important;
232 | color: var(--sex-u-fg) !important;
233 | }
234 |
235 | .wt-new {
236 | box-shadow: 0 0 0 2px $teal;
237 | }
238 |
239 | .wt-old {
240 | box-shadow: 0 0 0 2px $orange;
241 | }
242 |
243 | .wt-site-logo {
244 | display: none;
245 | }
246 |
247 | // Keyboard
248 | .wt-osk {
249 | box-shadow: $box-shadow;
250 | display: none;
251 | position: fixed;
252 | }
253 |
254 | .indent {
255 | padding-left: 1rem;
256 | }
257 |
258 | #secondary-header {
259 | background-color: map-get($custom-colors, "default");
260 | background-image: linear-gradient(310deg,#141727,#3a416f);
261 | color: map-get($theme-colors, "white");
262 | @include font-size($font-size-sm);
263 | padding: 0.313rem 0;
264 |
265 | ul.wt-user-menu {
266 | margin: 0 2.5rem 0 0;
267 |
268 | &>li {
269 | &>a {
270 | color: map-get($theme-colors, "white");
271 | display: inline-block;
272 | padding: 0.625rem 1.25rem;
273 |
274 | &:hover {
275 | color: darken(map-get($theme-colors, "white"), 20%);
276 | }
277 | }
278 |
279 | &.menu-pending {
280 | a {
281 | color: map-get($theme-colors, "warning");
282 |
283 | &:hover {
284 | color: darken(map-get($theme-colors, "warning"), 20%);
285 | }
286 | }
287 | }
288 | }
289 | }
290 |
291 | .wt-header-search {
292 | .wt-header-search-field {
293 | height: auto;
294 | }
295 |
296 | .wt-header-search-button {
297 | padding: 0.625rem 0.75rem;
298 | }
299 | }
300 | }
301 |
302 | #primary-header {
303 | background-color: map-get($custom-colors, "default");
304 | background-image: linear-gradient(310deg,#141727,#3a416f);
305 | box-shadow: 0 10px 20px rgba(50, 50, 93, .2);
306 | left: 0;
307 | padding: 1.25rem 0;
308 | right: 0;
309 | top: 0;
310 | z-index: 1052;
311 |
312 | .wt-header-content {
313 | align-items: center;
314 |
315 | .wt-site-title {
316 | color: map-get($theme-colors, "white");
317 | flex-basis: content;
318 | font-size: 2rem;
319 | margin-bottom: 0;
320 |
321 | a {
322 | color: map-get($theme-colors, "white");
323 | transition: $nav-link-transition;
324 |
325 | &:hover {
326 | color: darken(map-get($theme-colors, "white"), 20%);
327 | }
328 | }
329 | }
330 |
331 | .wt-primary-navigation {
332 | flex-basis: content;
333 | flex-grow: 1;
334 |
335 | ul.wt-genealogy-menu {
336 | justify-content: flex-end;
337 |
338 | &>li {
339 | &>a {
340 | color: map-get($theme-colors, "white");
341 | padding: 0.75rem;
342 |
343 | &:hover {
344 | color: darken(map-get($theme-colors, "white"), 20%);
345 | }
346 | }
347 | }
348 | }
349 | }
350 | }
351 | }
352 |
353 | .wt-main-container {
354 | margin-top: 3rem;
355 | }
356 |
357 | .wt-page-content {
358 | margin-bottom: 2rem;
359 | }
360 |
361 | #site-footer {
362 | background-color: $gray-100;
363 | font-size: $font-size-sm;
364 | padding: 2.5rem 0;
365 | text-align: center;
366 | }
367 |
368 | // Calendar modals for editing dates
369 | div[id^=caldiv] {
370 | border-radius: $dropdown-border-radius;
371 | box-shadow: $dropdown-box-shadow;
372 | padding: 1.25rem 1.375rem;
373 |
374 | table {
375 | border: none !important;
376 | }
377 |
378 | td,
379 | tbody td {
380 | border-bottom: none;
381 | }
382 |
383 | input,
384 | select {
385 | @extend .form-control-sm;
386 | }
387 |
388 | tr:first-child td {
389 | border-top: none;
390 | }
391 |
392 | table table {
393 | margin-top: 0.5rem;
394 |
395 | td {
396 | font-size: .875rem;
397 | height: 36px;
398 | text-align: center;
399 | }
400 |
401 | // Calendar days
402 | tr:not(:first-child) {
403 | td {
404 | background-color: transparent !important;
405 | border: none !important;
406 | border-radius: 50%;
407 | padding: 3px;
408 | transition: all .15s ease;
409 | width: 36px;
410 |
411 | a {
412 | color: $gray-500;
413 | }
414 |
415 | &.descriptionbox {
416 | background-color: map-get($theme-colors, "primary") !important;
417 |
418 | a {
419 | color: map-get($theme-colors, "white");
420 | }
421 | }
422 | }
423 | }
424 |
425 | tr:first-child td,
426 | tr:not(:first-child) td.optionbox {
427 | color: $body-color;
428 |
429 | a {
430 | color: $body-color;
431 | }
432 | }
433 | }
434 | }
435 |
436 | /**
437 | * Maps (Pedigree Page, Place Hierarchy Page, Place Hierarhy Tab)
438 | */
439 |
440 | .wt-places-tab-wrapper,
441 | .wt-pedigree-map-wrapper,
442 | .wt-place-hierarchy-wrapper {
443 | border-radius: $border-radius;
444 | box-shadow: $box-shadow-sm;
445 | }
446 |
447 | .wt-places-tab-sidebar,
448 | .wt-pedigree-map-sidebar,
449 | .wt-place-hierarchy-sidebar {
450 | background-color: map-get($theme-colors, "white");
451 | padding: 0;
452 |
453 | li.gchart {
454 | border-bottom: $border-width solid $border-color;
455 | font-size: $font-size-sm !important;
456 | padding: 1.5rem;
457 | transition: background-color $dropdown-transition-time;
458 |
459 | .tab-pane & {
460 | font-size: $font-size-xs !important;
461 | padding: 1rem;
462 | }
463 |
464 | &:last-child {
465 | border-bottom: none;
466 | }
467 |
468 | // Currently selected
469 | &.messagebox {
470 | background-color: $gray-100;
471 | }
472 |
473 | >div {
474 | margin-bottom: 0.625rem;
475 | }
476 | }
477 | }
478 |
479 | .wt-places-tab-sidebar,
480 | .wt-place-hierarchy-sidebar {
481 | li.gchart:hover {
482 | background-color: $gray-100;
483 | cursor: pointer;
484 | }
485 | }
486 |
487 | // OSM options
488 | .leaflet-control-layers {
489 | .leaflet-layerstree-header-label {
490 | margin: 0;
491 | }
492 |
493 | }
494 |
495 | // Pin details
496 | .leaflet-popup {
497 | font-family: $font-family-base;
498 |
499 | a {
500 | color: $link-color;
501 |
502 | &:hover {
503 | color: $link-hover-color;
504 | }
505 | }
506 |
507 | .leaflet-popup-content-wrapper {
508 | border-radius: $border-radius;
509 | padding: 0.75rem 1rem;
510 |
511 | .leaflet-popup-content {
512 | margin: 0;
513 |
514 | .table {
515 | margin: 0;
516 | }
517 | }
518 | }
519 | }
520 |
521 | .marker-cluster {
522 | div {
523 | font-family: $font-family-base;
524 | }
525 | }
526 |
527 | /**
528 | * Individual Page
529 | */
530 |
531 | // Names
532 | #individual-names {
533 | .label {
534 | font-weight: $font-weight-normal;
535 | margin-bottom: 0;
536 | }
537 | }
538 |
539 | // Preferred name
540 | .starredname {
541 | text-decoration: underline;
542 | }
543 |
544 | // Families tab
545 | .wt-chart-box-dropdown {
546 | div[class^=fact_] {
547 | padding: $dropdown-item-padding-y $dropdown-item-padding-x; /* Add padding */
548 | }
549 | }
550 |
551 | // Interactive Tree tab
552 | .tv_out {
553 | background-color: map-get($theme-colors, "white");
554 | border: none;
555 | }
556 |
557 | // Only the tab, not the chart
558 | #tvTab_out {
559 | background-color: map-get($theme-colors, "white");
560 | border-radius: $border-radius;
561 | box-shadow: $box-shadow-sm;
562 | }
563 |
564 | #tvStylesSubmenu,
565 | #tv_tools {
566 | background-color: transparent;
567 | border: none;
568 | box-shadow: none;
569 | }
570 |
571 | #tvStylesSubmenu {
572 | [dir=ltr] {
573 | left: 0;
574 | }
575 |
576 | [dir=rtl] {
577 | right: 0;
578 | }
579 | }
580 |
581 | #tv_tools {
582 | ul {
583 | li.tv_button {
584 | border: none;
585 |
586 | [dir=ltr] & {
587 | float: left;
588 | }
589 |
590 | [dir=rtl] & {
591 | float: right;
592 | }
593 |
594 | [dir] & {
595 | float: none;
596 | }
597 |
598 | &:hover {
599 | border: none;
600 | }
601 | }
602 | }
603 |
604 | #tvbCompact {
605 | background-position: center;
606 | background-repeat: no-repeat;
607 | }
608 | }
609 |
610 | #tvToolsHandler {
611 | [dir=ltr] & {
612 | float: left;
613 | }
614 |
615 | [dir=rtl] {
616 | float: right;
617 | }
618 | }
619 |
620 | table#tv_tree {
621 | div.tv_hline,
622 | div.tv_vline {
623 | background-color: $table-border-color;
624 | }
625 |
626 | .tv_box {
627 | background: map-get($theme-colors, "white");
628 | border: none;
629 | border-radius: $border-radius;
630 | box-shadow: $box-shadow-xs;
631 | font-size: $font-size-xs;
632 | margin-bottom: 0.625rem;
633 | width: 11.25rem;
634 |
635 | > div {
636 | padding: 0.25rem 0.5rem !important;
637 | }
638 |
639 | .dashed {
640 | border-top-left-radius: 0 !important;
641 | border-top-right-radius: 0 !important;
642 | }
643 |
644 | img {
645 | [dir=ltr] & {
646 | float: left;
647 | margin-right: 0.625rem;
648 | }
649 |
650 | [dir=rtl] & {
651 | float: right;
652 | margin-left: 0.625rem;
653 | }
654 | }
655 |
656 | .icon-silhouette-f,
657 | .icon-silhouette-m,
658 | .icon-silhouette-u {
659 | [dir=ltr] & {
660 | float: left;
661 | margin-right: 0.5rem;
662 | }
663 |
664 | [dir=rtl] & {
665 | float: right;
666 | margin-left: 0.5rem;
667 | }
668 | }
669 | }
670 | }
671 |
672 | // Stories tab
673 | .story:not(:last-child) {
674 | border-bottom: 1px solid $border-color;
675 | }
676 |
677 | // Album tab
678 | .wt-tab-album .figure-caption {
679 | font-size: $font-size-xs;
680 | }
681 |
682 | // Descendants sidebar
683 | #sb_desc_content {
684 | font-size: $font-size-sm;
685 |
686 | ul {
687 | padding-left: 0;
688 |
689 | ul {
690 | padding-left: 1rem;
691 | }
692 |
693 | .sb_desc_indi_li {
694 | list-style-type: none;
695 | }
696 | }
697 | }
698 |
699 | // Extra Information sidebar
700 | #sidebar-content-extra_info {
701 | font-size: $font-size-sm;
702 |
703 | .wt-fact-edit-links {
704 | margin-bottom: 0.5rem;
705 | }
706 | }
707 |
708 | /**
709 | * User Page
710 | */
711 |
712 | .wt-block-content-user_messages {
713 | .table-responsive {
714 | margin-bottom: 2rem;
715 | }
716 |
717 | // Center header of checkbox column
718 | .wt-page-options-label:first-child {
719 | text-align: center;
720 | }
721 |
722 | .center {
723 | left: auto;
724 | text-align: center;
725 | -webkit-transform: translateX(0);
726 | transform: translateX(0);
727 | }
728 |
729 | // Message cells
730 | .wt-page-options-value[colspan] {
731 | padding-top: 0;
732 | padding-bottom: 0;
733 | }
734 | }
735 |
736 | /**
737 | * Charts
738 | */
739 |
740 | .wt-chart {
741 | margin-bottom: 2rem;
742 | overflow-x: auto;
743 | overflow-y: hidden;
744 | }
745 |
746 | // For charts with potential overflow
747 | .wt-chart-interactive,
748 | .wt-chart-pedigree {
749 | background-color: map-get($theme-colors, "white");
750 | border-radius: $border-radius;
751 | box-shadow: $box-shadow-sm;
752 | }
753 |
754 | // Also includes blocks and Family page (since they utilize many of the same components but lack a chart wrapper class)
755 | .wt-chart,
756 | .wt-family-members,
757 | .wt-block-charts,
758 | .wt-block-gedcom_favorites {
759 | td {
760 | border-bottom: none;
761 | }
762 |
763 | tr:first-child td {
764 | border-top: none;
765 | }
766 |
767 | .wt-chart-box {
768 | background: map-get($theme-colors, "white");
769 | border-radius: $border-radius;
770 | box-shadow: $box-shadow-xs;
771 | font-size: $font-size-xs;
772 | margin-bottom: 0.125rem;
773 | margin-top: 0.125rem;
774 | padding: 0.5rem 0.625rem;
775 | }
776 |
777 | .wt-chart-box-zoom-dropdown {
778 | line-height: $line-height-sm;
779 | }
780 | }
781 |
782 | // Compact Tree
783 | .wt-chart-compact {
784 | table {
785 | border-collapse: separate;
786 | }
787 |
788 | .wt-chart-box {
789 | height: 5rem;
790 | width: 9.375rem;
791 | }
792 | }
793 |
794 | // Ancestors and Descendants charts
795 | .wt-chart-ancestors,
796 | .wt-chart-descendants {
797 | .wt-chart-box {
798 | font-size: $font-size-sm;
799 | margin-bottom: 0.313rem;
800 | margin-top: 0.313rem;
801 | min-height: 5rem;
802 | }
803 |
804 | .wt-sosa-number,
805 | .wt-daboville-number {
806 | border: $border-width dotted $border-color;
807 | font-size: $font-size-sm;
808 | margin: 0 0.625rem;
809 | padding: 0.313rem 0.625rem;
810 | }
811 | }
812 |
813 | // Fan chart
814 | .fan_chart_menu {
815 | @extend .dropdown-menu;
816 | }
817 |
818 | // Hourglass chart
819 | .wt-chart-hourglass {
820 | overflow-y: auto;
821 |
822 | .wt-chart-box {
823 | margin-top: 0.625rem;
824 | margin-bottom: 0.625rem;
825 | }
826 | }
827 |
828 | // Lifespans chart
829 | .wt-timeline-chart {
830 | .wt-lifespans-scale {
831 | white-space: nowrap;
832 | }
833 |
834 | // Timeline markers
835 | .wt-lifespans-decade {
836 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAlBAMAAAANYIJDAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4wLjVlhTJlAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAAD1BMVEUAAAAAAABHcEw2NjYAAADzBAk1AAAABHRSTlPT1wDTEG7QNgAAAElJREFUOMtjEFIiBBQYBlQNI03VAEWVUSgFIGWIoBgQojgpBgwDUM1hJMscit2jgM9ZVHOPC2Ew6NTQM3yGaPqhZx4kXc3AllEANjazI4q82bEAAAAASUVORK5CYII=");
837 | background-position-y: bottom;
838 | background-repeat: no-repeat;
839 | background-size: 70px 37px;
840 | display: inline-block;
841 | height: 3.75rem;
842 | width: 4.375rem;
843 | }
844 |
845 | // Lifespans
846 | .wt-lifespans-individual {
847 | border-radius: $border-radius;
848 | box-shadow: $box-shadow-xs;
849 | font-size: $font-size-sm;
850 | margin-top: 1rem;
851 | padding: 0.313rem 0.625rem;
852 | }
853 |
854 | // Popup
855 | .wt-lifespans-summary {
856 | background-color: #fff;
857 | border-radius: $dropdown-border-radius;
858 | box-shadow: $dropdown-box-shadow;
859 | font-size: $font-size-sm;
860 | padding: 0.625rem 1rem;
861 | z-index: 1;
862 | }
863 | }
864 |
865 | // Pedigree chart
866 | .wt-chart-pedigree {
867 | overflow-y: auto;
868 |
869 | .wt-chart-pedigree-left,
870 | .wt-chart-pedigree-right {
871 | .wt-chart-box {
872 | margin-bottom: 1.5rem;
873 | min-height: 5rem;
874 | }
875 | }
876 |
877 | .wt-chart-pedigree-right {
878 | .wt-chart-box {
879 | margin-right: 1.5rem;
880 | }
881 | }
882 |
883 | .wt-chart-pedigree-left {
884 | .wt-chart-box {
885 | margin-left: 1.5rem;
886 | }
887 | }
888 |
889 | .wt-chart-pedigree-down,
890 | .wt-chart-pedigree-up {
891 | .wt-chart-box {
892 | margin-right: 1.5rem;
893 | min-width: 10rem;
894 | }
895 | }
896 |
897 | .wt-chart-pedigree-down {
898 | .wt-chart-box {
899 | margin-bottom: 1.5rem;
900 | }
901 | }
902 |
903 | .wt-chart-pedigree-up {
904 | .wt-chart-box {
905 | margin-top: 1.5rem;
906 | }
907 | }
908 | }
909 |
910 | // Relationships chart
911 | .wt-chart-relationships {
912 | .wt-chart-box {
913 | height: 5rem;
914 | }
915 | }
916 |
917 | // Timeline chart
918 | .wt-route-TimelineChartModule {
919 | // Person panels
920 | div[class*=person] {
921 | font-size: $font-size-sm;
922 | padding: 0.625rem 1rem;
923 | }
924 |
925 | .person0 {
926 | background-color: map-get($theme-colors, "primary");
927 | color: map-get($theme-colors, "white");
928 |
929 | a {
930 | color: map-get($theme-colors, "white");
931 |
932 | &:hover {
933 | color: darken(map-get($theme-colors, "white"), 20%);
934 | }
935 | }
936 | }
937 |
938 | .person1 {
939 | background-color: map-get($theme-colors, "secondary");
940 | color: map-get($theme-colors, "white");
941 |
942 | a {
943 | color: map-get($theme-colors, "white");
944 |
945 | &:hover {
946 | color: darken(map-get($theme-colors, "white"), 20%);
947 | }
948 | }
949 | }
950 |
951 | .person2 {
952 | background-color: map-get($theme-colors, "info");
953 | color: map-get($theme-colors, "white");
954 |
955 | a {
956 | color: map-get($theme-colors, "white");
957 |
958 | &:hover {
959 | color: darken(map-get($theme-colors, "white"), 20%);
960 | }
961 | }
962 | }
963 |
964 | .person3 {
965 | background-color: map-get($theme-colors, "success");
966 | color: map-get($theme-colors, "white");
967 |
968 | a {
969 | color: map-get($theme-colors, "white");
970 |
971 | &:hover {
972 | color: darken(map-get($theme-colors, "white"), 20%);
973 | }
974 | }
975 | }
976 |
977 | .person4 {
978 | background-color: map-get($theme-colors, "danger");
979 | color: map-get($theme-colors, "white");
980 |
981 | a {
982 | color: map-get($theme-colors, "white");
983 |
984 | &:hover {
985 | color: darken(map-get($theme-colors, "white"), 20%);
986 | }
987 | }
988 | }
989 |
990 | .person5 {
991 | background-color: map-get($theme-colors, "warning");
992 | color: map-get($theme-colors, "white");
993 |
994 | a {
995 | color: map-get($theme-colors, "white");
996 |
997 | &:hover {
998 | color: darken(map-get($theme-colors, "white"), 20%);
999 | }
1000 | }
1001 | }
1002 | }
1003 |
1004 | .wt-timeline-chart {
1005 | overflow-x: auto;
1006 | overflow-y: hidden;
1007 |
1008 | #timeline_chart {
1009 | position: relative;
1010 | top: 0;
1011 |
1012 | [dir=ltr] & {
1013 | left: 0;
1014 | }
1015 |
1016 | [dir=rtl] & {
1017 | right: 0;
1018 | }
1019 |
1020 | td[class^=person] {
1021 | font-size: $font-size-xs;
1022 | padding: 0 0.5rem;
1023 | }
1024 | }
1025 | }
1026 |
1027 | /**
1028 | * Lists
1029 | */
1030 |
1031 | // Families and Individuals lists
1032 | .wt-initials-list {
1033 | font-size: $font-size-base;
1034 |
1035 | .wt-initial.active {
1036 | color: map-get($theme-colors, "primary");
1037 | cursor: default;
1038 | }
1039 | }
1040 |
1041 | /**
1042 | * Calendar
1043 | */
1044 |
1045 | .wt-route-CalendarPage {
1046 |
1047 | // Weekday labels
1048 | .wt-page-options-label {
1049 | padding-top: 0.625rem;
1050 | padding-bottom: 0.625rem;
1051 | }
1052 |
1053 | // Event list
1054 | .wt-page-options-value>ul {
1055 | margin-bottom: 0;
1056 |
1057 | li:not(:last-child) {
1058 | margin-bottom: 1rem;
1059 | }
1060 | }
1061 | }
1062 |
1063 | /**
1064 | * FAQ
1065 | */
1066 |
1067 | .faq {
1068 | border-top: $border-width solid $border-color;
1069 | margin-bottom: $hr-margin-y;
1070 | padding-top: $hr-margin-y;
1071 |
1072 | *:last-child {
1073 | margin-bottom: 0;
1074 | }
1075 |
1076 | .faq_title {
1077 | align-items: center;
1078 | display: flex;
1079 |
1080 | // Fixed header offset
1081 | margin-top: -9.5rem;
1082 |
1083 | // Fixed header offset
1084 | padding-top: 9.5rem;
1085 |
1086 | h3 {
1087 | flex-grow: 1;
1088 | }
1089 |
1090 | .faq_top {
1091 | flex-basis: content;
1092 | font-size: $font-size-base;
1093 | font-weight: normal;
1094 | }
1095 | }
1096 |
1097 | .faq_body {
1098 | margin-bottom: $hr-margin-y;
1099 | }
1100 | }
1101 |
1102 |
1103 | /**
1104 | * ColorBox
1105 | */
1106 |
1107 | #cboxContent {
1108 | border: none;
1109 | border-radius: $popover-border-radius;
1110 | box-shadow: $popover-box-shadow;
1111 | box-sizing: border-box;
1112 | padding: 1rem;
1113 | }
1114 |
1115 | [dir] #cboxError {
1116 | border: $border-radius solid $border-color;
1117 | padding: 3.125rem;
1118 | }
1119 |
1120 | #cboxTitle {
1121 | font-size: $font-size-sm;
1122 | margin: 0;
1123 | padding: 0.25rem 0;
1124 | width: 100%;
1125 | }
1126 |
1127 | #cboxClose,
1128 | #cboxNext,
1129 | #cboxPrevious,
1130 | #cboxSlideshow {
1131 | @extend .btn;
1132 | @extend .btn-primary !optional;
1133 | @extend .btn-sm;
1134 | padding: $btn-padding-y-xs $btn-padding-x-xs;
1135 |
1136 | &:not(:last-child) {
1137 | margin-right: 0;
1138 | }
1139 | }
1140 |
1141 | #cboxPrevious {
1142 | border-top-right-radius: 0;
1143 | border-bottom-right-radius: 0;
1144 | }
1145 |
1146 | #cboxNext {
1147 | border-top-left-radius: 0;
1148 | border-bottom-left-radius: 0;
1149 | }
1150 |
1151 | #cboxSlideshow {
1152 | [dir=ltr] & {
1153 | right: 1rem;
1154 | }
1155 |
1156 | [dir=rtl] & {
1157 | left: 1rem;
1158 | }
1159 | }
1160 |
1161 | #cboxPrevious {
1162 | [dir=ltr] & {
1163 | left: 1rem;
1164 | }
1165 |
1166 | [dir=rtl] & {
1167 | right: 1rem;
1168 | }
1169 | }
1170 |
1171 | #cboxNext {
1172 | [dir=ltr] & {
1173 | left: 3.7rem;
1174 | }
1175 |
1176 | [dir=rtl] & {
1177 | right: 3.7rem;
1178 | }
1179 | }
1180 |
1181 | #cboxClose {
1182 | top: 1rem;
1183 |
1184 | [dir=ltr] & {
1185 | right: 1rem;
1186 | }
1187 |
1188 | [dir=rtl] & {
1189 | left: 1rem;
1190 | }
1191 | }
--------------------------------------------------------------------------------