├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── .gitmodules ├── README.md ├── assets ├── capture_individual.png ├── capture_interactive-tree.png ├── capture_tree-home.png ├── individual.png ├── interactive-tree.png └── tree-home.png ├── babel.config.js ├── composer.json ├── composer.lock ├── module.php ├── package-lock.json ├── package.json ├── postcss.config.js ├── resources ├── css │ ├── theme.css │ └── vendor.css ├── js │ ├── theme.js │ └── vendor.js └── views │ ├── calendar-list.phtml │ ├── calendar-page.phtml │ ├── chart-box.phtml │ ├── individual-page-images.phtml │ ├── individual-page-tabs.phtml │ ├── layouts │ └── default.phtml │ ├── lists │ ├── notes-table.phtml │ ├── repositories-table.phtml │ ├── sources-table.phtml │ └── surnames-table.phtml │ ├── modules │ ├── contact-links │ │ └── footer.phtml │ ├── descendancy │ │ └── sidebar.phtml │ ├── faq │ │ └── show.phtml │ ├── gedcom_stats │ │ └── statistics.phtml │ ├── hit-counter │ │ └── footer.phtml │ ├── interactive-tree │ │ └── chart.phtml │ ├── lifespans-chart │ │ └── chart.phtml │ ├── lightbox │ │ └── tab.phtml │ ├── media-list │ │ └── page.phtml │ ├── pedigree-map │ │ └── chart.phtml │ ├── place-hierarchy │ │ ├── list.phtml │ │ ├── map.phtml │ │ ├── page.phtml │ │ ├── popup.phtml │ │ └── sidebar.phtml │ ├── places │ │ └── tab.phtml │ ├── powered-by-webtrees │ │ └── footer.phtml │ ├── privacy-policy │ │ └── footer.phtml │ ├── recent_changes │ │ └── changes-list.phtml │ ├── relatives │ │ └── family.phtml │ ├── statistics-chart │ │ └── page.phtml │ ├── stories │ │ └── tab.phtml │ └── todo │ │ └── research-tasks.phtml │ └── place-hierarchy.phtml ├── src ├── js │ ├── theme.js │ └── vendor.js └── scss │ ├── _forms.scss │ ├── _icons.scss │ ├── _tables.scss │ └── theme.scss └── webpack.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | # Browsers that we support 2 | 3 | defaults 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: [ 7 | 'airbnb-base', 8 | ], 9 | parserOptions: { 10 | ecmaVersion: 'latest', 11 | sourceType: 'module', 12 | }, 13 | rules: { 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directories 2 | node_modules/ 3 | vendor/ 4 | 5 | # Sass 6 | .sass-cache/ 7 | *.css.map 8 | *.sass.map 9 | *.scss.map 10 | 11 | # Dev 12 | dev/ 13 | 14 | # Build 15 | dist/ 16 | 17 | # Misc 18 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/scss/argon-dashboard"] 2 | path = src/scss/argon-dashboard 3 | url = git@github.com:creativetimofficial/argon-dashboard.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/jchue/argon-webtrees-theme)](https://github.com/jchue/argon-webtrees-theme/releases/latest) 2 | [![webtrees major version](https://img.shields.io/badge/webtrees-v2.1.x-9cf)](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 | ![Screenshot of Tree Home](assets/tree-home.png) 13 | 14 | **Individual Page** 15 | 16 | ![Screenshot of Individual Page](assets/individual.png) 17 | 18 | **Interactive Tree Chart** 19 | 20 | ![Screenshot of Interactive Tree Chart](assets/interactive-tree.png) 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. -------------------------------------------------------------------------------- /assets/capture_individual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/capture_individual.png -------------------------------------------------------------------------------- /assets/capture_interactive-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/capture_interactive-tree.png -------------------------------------------------------------------------------- /assets/capture_tree-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/capture_tree-home.png -------------------------------------------------------------------------------- /assets/individual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/individual.png -------------------------------------------------------------------------------- /assets/interactive-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/interactive-tree.png -------------------------------------------------------------------------------- /assets/tree-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchue/argon-webtrees-theme/f266909a3a668f2dff799240a87dd749a251fb94/assets/tree-home.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@babel/preset-env'], 3 | }; 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /resources/views/calendar-page.phtml: -------------------------------------------------------------------------------- 1 | /', 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 | -------------------------------------------------------------------------------- /resources/views/individual-page-images.phtml: -------------------------------------------------------------------------------- 1 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <?= strip_tags($title) ?> 44 | <?php if ($tree !== null && $tree->getPreference('META_TITLE') !== '') : ?> 45 | – <?= e($tree->getPreference('META_TITLE')) ?> 46 | <?php endif ?> 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | stylesheets() as $stylesheet) : ?> 61 | 62 | 63 | 64 | 65 | 66 | findByInterface(ModuleGlobalInterface::class)->map(static function (ModuleGlobalInterface $module): string { 67 | return $module->headContent(); 68 | })->implode('') ?> 69 | 70 | 71 | 72 |
73 |
74 |
75 |
76 | 82 | 83 | 90 | 91 | 92 | 107 | 108 |
109 |
110 |
111 |
112 |
113 |
114 | 115 | 116 | 117 |

118 | 119 | title()) ?> 120 | 121 |

122 | 123 | 124 | 125 | 132 | 133 |
134 |
135 |
136 |
137 | 138 |
139 |
140 |
141 | 142 | 147 | 148 |
149 | 150 | 151 |
152 |
153 | 154 | 161 | 162 | 163 | 164 | 165 | 199 | 200 | 201 | 202 | findByInterface(ModuleGlobalInterface::class)->map(static function (ModuleGlobalInterface $module): string { 203 | return $module->bodyContent(); 204 | })->implode('') ?> 205 | 206 | 207 | -------------------------------------------------------------------------------- /resources/views/lists/notes-table.phtml: -------------------------------------------------------------------------------- 1 | /', '', $view); 9 | 10 | echo $view; 11 | -------------------------------------------------------------------------------- /resources/views/modules/faq/show.phtml: -------------------------------------------------------------------------------- 1 | $faqs 12 | * @var string $title 13 | */ 14 | 15 | ?> 16 | 17 |

18 | 19 | 26 | 27 | $faq) : ?> 28 |
29 |
30 |

header) ?>

31 | 32 | 33 | 34 |
35 |
36 | faqbody, '<') ? $faq->faqbody : nl2br(e($faq->faqbody), false) ?> 37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /resources/views/modules/gedcom_stats/statistics.phtml: -------------------------------------------------------------------------------- 1 | $lifespans 13 | * @var int $max_rows 14 | * @var int $start_year 15 | * @var string $subtitle 16 | */ 17 | 18 | ?> 19 | 20 |

21 | 22 |

23 | 24 |
25 |
28 |
29 | 30 |
31 | 32 | 38 | 39 |
40 | 41 | individual->fullName() ?> 42 | 43 | 44 | individual->facts(array_merge(Gedcom::BIRTH_EVENTS, Gedcom::DEATH_EVENTS), true) as $fact) : ?> 45 | summary() ?> 46 | 47 |
48 | 49 |
50 | -------------------------------------------------------------------------------- /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/media-list/page.phtml: -------------------------------------------------------------------------------- 1 | 2 | /* Increase padding around entries in relatives list */ 3 | /* Need to override this Bootstrap class in this case because entries are loaded dynamically */ 4 | .gchart.px-md-2 { 5 | padding: 1.5rem !important; 6 | } 7 | 8 | 9 | /', '
', $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/place-hierarchy/map.phtml: -------------------------------------------------------------------------------- 1 | $rows 18 | * @var bool $show_date 19 | * @var bool $show_user 20 | */ 21 | 22 | ?> 23 | 24 |
25 | $row) : ?> 26 | count() > $limit_high) : ?> 27 |
28 | 32 |
33 | 34 | 35 | 43 | 44 | 45 | 46 | 47 | record->fullName() ?> 48 | 49 | 50 | 51 | by */I18N::translate('Changed on %1$s by %2$s', view('components/datetime', ['timestamp' => $row->time]), e($row->record->lastChangeUser())) ?> 52 | 53 | */ I18N::translate('Changed on %1$s', view('components/datetime', ['timestamp' => $row->time])) ?> 54 | 55 | */ I18N::translate('Changed by %1$s', e($row->user->userName())) ?> 56 | 57 | 58 | 59 | 60 |
61 | -------------------------------------------------------------------------------- /resources/views/modules/relatives/family.phtml: -------------------------------------------------------------------------------- 1 | $stories 11 | * @var Tree $tree 12 | */ 13 | 14 | ?> 15 | 16 |
17 | 18 | 23 |
24 |
25 |

title) ?>

26 |
27 |
28 |

story_body ?>

29 |
30 | 31 | 37 | 38 |
39 | 40 | 41 | 46 | 47 |

48 | 49 | 50 | 51 |

52 | 53 |
-------------------------------------------------------------------------------- /resources/views/modules/todo/research-tasks.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/js/vendor.js: -------------------------------------------------------------------------------- 1 | // Need to import stylesheet so Webpack processes it 2 | import '../../vendor/fisharebest/webtrees/resources/css/vendor.tmp.css'; 3 | -------------------------------------------------------------------------------- /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/_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/_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 | } -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------