Initial commit: Bocken theme for webtrees
Nord-themed dark/light mode family tree theme with: - Floating glass-morphism header bar - Auto/light/dark theme toggle with Lucide icons - Smart SVG logo with theme-aware fill colors - Active page highlighting with per-menu Nord icon colors - Language button showing 2-letter abbreviation - Start page search form - Mobile responsive icon-only nav - Custom views inherited from ArgonLight
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
351
BockenTheme.php
Normal file
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Bocken\Themes;
|
||||
|
||||
use Fisharebest\Webtrees\Module\AbstractModule;
|
||||
use Fisharebest\Webtrees\Module\ModuleCustomInterface;
|
||||
use Fisharebest\Webtrees\Module\ModuleCustomTrait;
|
||||
use Fisharebest\Webtrees\Module\ModuleGlobalInterface;
|
||||
use Fisharebest\Webtrees\Module\ModuleGlobalTrait;
|
||||
use Fisharebest\Webtrees\Module\ModuleThemeInterface;
|
||||
use Fisharebest\Webtrees\Module\ModuleThemeTrait;
|
||||
use Fisharebest\Webtrees\View;
|
||||
|
||||
class BockenTheme extends AbstractModule implements ModuleCustomInterface, ModuleGlobalInterface, ModuleThemeInterface
|
||||
{
|
||||
use ModuleCustomTrait, ModuleGlobalTrait, ModuleThemeTrait;
|
||||
|
||||
public const string MODULE_TITLE = "Bocken";
|
||||
public const string MODULE_DESCRIPTION = "Nord-themed dark/light mode family tree theme";
|
||||
public const string MODULE_AUTHOR = 'Alexander Bocken';
|
||||
public const string MODULE_VERSION = '1.0.0';
|
||||
public const string MODULE_RESOURCE_PATH = __DIR__ . '/resources/';
|
||||
|
||||
public function title(): string
|
||||
{
|
||||
return self::MODULE_TITLE;
|
||||
}
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return self::MODULE_DESCRIPTION;
|
||||
}
|
||||
|
||||
public function customModuleAuthorName(): string
|
||||
{
|
||||
return self::MODULE_AUTHOR;
|
||||
}
|
||||
|
||||
public function customModuleVersion(): string
|
||||
{
|
||||
return self::MODULE_VERSION;
|
||||
}
|
||||
|
||||
public function resourcesFolder(): string
|
||||
{
|
||||
return self::MODULE_RESOURCE_PATH;
|
||||
}
|
||||
|
||||
public function stylesheets(): array
|
||||
{
|
||||
// imports.css must be built from within the webtrees installation
|
||||
// (it references vendor/fisharebest/webtrees/resources/css/_base.css)
|
||||
$sheets = [];
|
||||
$importsPath = self::MODULE_RESOURCE_PATH . 'css/imports.css';
|
||||
if (file_exists($importsPath)) {
|
||||
$sheets[] = $this->assetUrl('css/imports.css');
|
||||
}
|
||||
$sheets[] = $this->assetUrl('css/fonts.css');
|
||||
$sheets[] = $this->assetUrl('css/theme.css');
|
||||
return $sheets;
|
||||
}
|
||||
|
||||
public function headContent(): string
|
||||
{
|
||||
$faviconUrl = $this->assetUrl('img/favicon.svg');
|
||||
|
||||
return <<<HTML
|
||||
<link rel="icon" href="{$faviconUrl}" type="image/svg+xml">
|
||||
<script>
|
||||
(function() {
|
||||
var saved = localStorage.getItem('bocken-theme');
|
||||
if (saved === 'dark' || saved === 'light') {
|
||||
document.documentElement.setAttribute('data-theme', saved);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
HTML;
|
||||
}
|
||||
|
||||
public function bodyContent(): string
|
||||
{
|
||||
$logoUrl = $this->assetUrl('img/logo.svg');
|
||||
|
||||
return <<<HTML
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// --- Theme toggle ---
|
||||
var THEMES = ['auto', 'light', 'dark'];
|
||||
var ICONS = {
|
||||
auto: 'sun-moon',
|
||||
light: 'sun',
|
||||
dark: 'moon'
|
||||
};
|
||||
|
||||
function getTheme() {
|
||||
return localStorage.getItem('bocken-theme') || 'auto';
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
localStorage.setItem('bocken-theme', theme);
|
||||
if (theme === 'auto') {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
}
|
||||
updateToggleButton();
|
||||
updateLogoFill();
|
||||
}
|
||||
|
||||
function cycleTheme() {
|
||||
var current = getTheme();
|
||||
var idx = THEMES.indexOf(current);
|
||||
var next = THEMES[(idx + 1) % THEMES.length];
|
||||
applyTheme(next);
|
||||
}
|
||||
|
||||
function updateToggleButton() {
|
||||
var btn = document.getElementById('bocken-theme-toggle');
|
||||
if (!btn) return;
|
||||
var theme = getTheme();
|
||||
btn.setAttribute('title', 'Theme: ' + theme);
|
||||
btn.setAttribute('aria-label', 'Toggle theme (' + theme + ')');
|
||||
btn.innerHTML = '<i data-lucide="' + ICONS[theme] + '"></i>';
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons({ nodes: [btn] });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Logo injection ---
|
||||
function updateLogoFill() {
|
||||
var svg = document.querySelector('.bocken-logo svg');
|
||||
if (!svg) return;
|
||||
var theme = getTheme();
|
||||
var isDark;
|
||||
if (theme === 'dark') {
|
||||
isDark = true;
|
||||
} else if (theme === 'light') {
|
||||
isDark = false;
|
||||
} else {
|
||||
// auto — let the SVG's own prefers-color-scheme handle it
|
||||
svg.style.removeProperty('--fill');
|
||||
return;
|
||||
}
|
||||
svg.style.setProperty('--fill', isDark ? '#D8DEE9' : '#2E3440');
|
||||
}
|
||||
|
||||
function injectLogo() {
|
||||
var titleEl = document.querySelector('.wt-site-title');
|
||||
if (!titleEl) return;
|
||||
|
||||
var logoContainer = document.createElement('div');
|
||||
logoContainer.className = 'bocken-logo-container';
|
||||
logoContainer.innerHTML = '<a href="https://bocken.org" class="bocken-logo-link" aria-label="Bocken.org"></a>';
|
||||
|
||||
// Fetch and inline the SVG so parent CSS variables work
|
||||
fetch('{$logoUrl}')
|
||||
.then(function(r) { return r.text(); })
|
||||
.then(function(svgText) {
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.className = 'bocken-logo';
|
||||
wrapper.innerHTML = svgText;
|
||||
logoContainer.querySelector('a').appendChild(wrapper);
|
||||
updateLogoFill();
|
||||
});
|
||||
|
||||
titleEl.parentNode.insertBefore(logoContainer, titleEl);
|
||||
}
|
||||
|
||||
// --- Theme toggle button injection ---
|
||||
function injectToggle() {
|
||||
var nav = document.querySelector('.wt-secondary-navigation .nav');
|
||||
if (!nav) return;
|
||||
|
||||
var li = document.createElement('li');
|
||||
li.className = 'nav-item bocken-theme-toggle-item';
|
||||
|
||||
var btn = document.createElement('button');
|
||||
btn.id = 'bocken-theme-toggle';
|
||||
btn.className = 'bocken-theme-btn';
|
||||
btn.type = 'button';
|
||||
btn.addEventListener('click', cycleTheme);
|
||||
|
||||
li.appendChild(btn);
|
||||
nav.insertBefore(li, nav.firstChild);
|
||||
updateToggleButton();
|
||||
}
|
||||
|
||||
// --- Language abbreviation ---
|
||||
function shortenLanguage() {
|
||||
var langItem = document.querySelector('.menu-language > .nav-link');
|
||||
if (!langItem) return;
|
||||
|
||||
// Find the active language from dropdown items
|
||||
var activeLang = document.querySelector('.menu-language .dropdown-item.active');
|
||||
var code = 'EN';
|
||||
if (activeLang) {
|
||||
// Extract from class like "menu-language-de" or "menu-language-en-US"
|
||||
var cls = Array.from(activeLang.classList).find(function(c) {
|
||||
return c.startsWith('menu-language-');
|
||||
});
|
||||
if (cls) {
|
||||
code = cls.replace('menu-language-', '').split('-')[0].toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
// Replace link content with just the abbreviation
|
||||
var caret = langItem.querySelector('.caret');
|
||||
langItem.textContent = '';
|
||||
langItem.appendChild(document.createTextNode(code));
|
||||
if (caret) langItem.appendChild(caret);
|
||||
}
|
||||
|
||||
// --- Search on start page ---
|
||||
function injectPageSearch() {
|
||||
// Only on the tree page (start page)
|
||||
if (!document.body.classList.contains('wt-route-TreePage')) return;
|
||||
|
||||
var mainContent = document.querySelector('.wt-main-container .flash-messages');
|
||||
if (!mainContent) return;
|
||||
|
||||
var csrf = document.querySelector('meta[name="csrf"]');
|
||||
var csrfValue = csrf ? csrf.getAttribute('content') : '';
|
||||
|
||||
// Derive the search action URL from the current tree path
|
||||
var path = window.location.pathname;
|
||||
var searchAction = path.replace(/\/?$/, '/search-quick');
|
||||
|
||||
var searchDiv = document.createElement('div');
|
||||
searchDiv.className = 'bocken-page-search';
|
||||
searchDiv.innerHTML =
|
||||
'<form method="post" action="' + searchAction + '" class="bocken-search-form" role="search">' +
|
||||
'<input type="search" class="bocken-search-input" name="query" placeholder="Search names, places, sources..." autocomplete="off">' +
|
||||
'<button type="submit" class="bocken-search-btn" aria-label="Search">' +
|
||||
'<i data-lucide="search"></i>' +
|
||||
'</button>' +
|
||||
'<input type="hidden" name="_csrf" value="' + csrfValue + '">' +
|
||||
'</form>';
|
||||
|
||||
mainContent.parentNode.insertBefore(searchDiv, mainContent.nextSibling);
|
||||
}
|
||||
|
||||
// --- Separator between primary nav and secondary nav ---
|
||||
function injectSeparator() {
|
||||
var headerContent = document.querySelector('.wt-header-content');
|
||||
var secondaryNav = document.querySelector('.wt-secondary-navigation');
|
||||
if (!headerContent || !secondaryNav) return;
|
||||
|
||||
// Walk up to find the direct child of headerContent that contains secondaryNav
|
||||
var target = secondaryNav;
|
||||
while (target.parentNode && target.parentNode !== headerContent) {
|
||||
target = target.parentNode;
|
||||
}
|
||||
// If we couldn't walk up to a direct child, bail
|
||||
if (target.parentNode !== headerContent) return;
|
||||
|
||||
var spacer = document.createElement('div');
|
||||
spacer.className = 'bocken-nav-spacer';
|
||||
headerContent.insertBefore(spacer, target);
|
||||
}
|
||||
|
||||
// --- Highlight active nav item ---
|
||||
function highlightActiveNav() {
|
||||
// Map body route classes to nav menu classes
|
||||
var routeMap = {
|
||||
'TreePage': 'menu-tree',
|
||||
'Chart': 'menu-chart',
|
||||
'Individual': 'menu-tree',
|
||||
'Family': 'menu-tree',
|
||||
'Branches': 'menu-list',
|
||||
'FamilyList': 'menu-list',
|
||||
'IndividualList': 'menu-list',
|
||||
'MediaList': 'menu-list',
|
||||
'NoteList': 'menu-list',
|
||||
'RepositoryList': 'menu-list',
|
||||
'SourceList': 'menu-list',
|
||||
'PlaceList': 'menu-list',
|
||||
'Calendar': 'menu-calendar',
|
||||
'Report': 'menu-report',
|
||||
'Search': 'menu-search',
|
||||
'Story': 'menu-story',
|
||||
'Faq': 'menu-faq',
|
||||
'Clippings': 'menu-clippings'
|
||||
};
|
||||
|
||||
var bodyClasses = document.body.className;
|
||||
var activeMenu = null;
|
||||
|
||||
// Find matching route
|
||||
var keys = Object.keys(routeMap);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (bodyClasses.indexOf('wt-route-' + keys[i]) !== -1) {
|
||||
activeMenu = routeMap[keys[i]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!activeMenu) return;
|
||||
|
||||
var navItem = document.querySelector('.wt-primary-navigation .' + activeMenu);
|
||||
if (navItem) {
|
||||
navItem.classList.add('bocken-nav-active');
|
||||
}
|
||||
}
|
||||
|
||||
// --- Init ---
|
||||
function init() {
|
||||
injectLogo();
|
||||
injectSeparator();
|
||||
injectToggle();
|
||||
shortenLanguage();
|
||||
injectPageSearch();
|
||||
highlightActiveNav();
|
||||
|
||||
// Init all Lucide icons
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
HTML;
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');
|
||||
|
||||
// Views inherited from ArgonLight
|
||||
View::registerCustomView('::modules/block-template', $this->name() . '::modules/block-template');
|
||||
View::registerCustomView('::modules/recent_changes/changes-list', $this->name() . '::modules/recent_changes/changes-list');
|
||||
View::registerCustomView('::modules/lightbox/tab', $this->name() . '::modules/lightbox/tab');
|
||||
View::registerCustomView('::modules/descendancy/sidebar', $this->name() . '::modules/descendancy/sidebar');
|
||||
View::registerCustomView('::modules/lifespans-chart/chart', $this->name() . '::modules/lifespans-chart/chart');
|
||||
View::registerCustomView('::modules/faq/show', $this->name() . '::modules/faq/show');
|
||||
View::registerCustomView('::modules/place-hierarchy/list', $this->name() . '::modules/place-hierarchy/list');
|
||||
View::registerCustomView('::lists/individuals-table', $this->name() . '::lists/individuals-table');
|
||||
View::registerCustomView('::lists/families-table', $this->name() . '::lists/families-table');
|
||||
View::registerCustomView('::individual-page-menu', $this->name() . '::individual-page-menu');
|
||||
}
|
||||
}
|
||||
6
module.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Bocken\Themes;
|
||||
|
||||
include "BockenTheme.php";
|
||||
return new BockenTheme();
|
||||
1905
package-lock.json
generated
Normal file
19
package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "bocken-theme",
|
||||
"description": "Nord-themed dark/light mode theme for webtrees",
|
||||
"author": "Alexander Bocken",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.24",
|
||||
"bootstrap": "^5.3.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-url": "^10.1.3",
|
||||
"sass": "^1.97.3",
|
||||
"vite": "^7.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite build --watch --mode development",
|
||||
"build": "vite build --mode production"
|
||||
}
|
||||
}
|
||||
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'autoprefixer': {},
|
||||
'postcss-url': { url: 'inline' }
|
||||
}
|
||||
}
|
||||
1
resources/css/fonts.css
Normal file
1
resources/css/theme.css
Normal file
221
resources/img/favicon.svg
Normal file
@@ -0,0 +1,221 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="44.976448mm"
|
||||
height="47.592033mm"
|
||||
viewBox="0 0 44.976448 47.592033"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1167">
|
||||
<g
|
||||
id="g1171"
|
||||
transform="translate(-839.26546,-1493.2693)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1169" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1161">
|
||||
<g
|
||||
id="g1165"
|
||||
transform="translate(-870.22246,-1471.759)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1163" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1155">
|
||||
<g
|
||||
id="g1159"
|
||||
transform="translate(-879.11756,-1418.6585)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1157" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1125">
|
||||
<g
|
||||
id="g1129"
|
||||
transform="translate(-985.61606,-1491.5374)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1127" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1119">
|
||||
<g
|
||||
id="g1123"
|
||||
transform="translate(-984.96026,-1455.9641)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1121" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1113">
|
||||
<g
|
||||
id="g1117"
|
||||
transform="translate(-945.76396,-1416.9275)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1115" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1107">
|
||||
<g
|
||||
id="g1111"
|
||||
transform="translate(-898.03256,-1543.4085)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1109" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1101">
|
||||
<g
|
||||
id="g1105"
|
||||
transform="translate(-916.79086,-1510.9075)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1103" />
|
||||
</g>
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1083">
|
||||
<g
|
||||
id="g1087"
|
||||
transform="translate(-941.26306,-1493.7234)">
|
||||
<path
|
||||
d="M -77.063638,2283.1277 H 1922.9364 V 283.12772 H -77.063638 Z"
|
||||
id="path1085" />
|
||||
</g>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-96.294406,-113.9353)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,100.41097,127.47916)"
|
||||
clip-path="url(#clipPath1167)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 6.633,-3.91 14.348,-4.302 20.992,-1.732 20.009,5.333 15.93,11.893 9.31,15.795 2.69,19.697 -5.025,20.088 -11.669,17.519 -10.7,10.462 -6.62,3.901 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path72" />
|
||||
</g>
|
||||
<g
|
||||
id="g74"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,106.63384,133.21363)"
|
||||
clip-path="url(#clipPath1161)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="m 0,0 c -6.62,3.901 -14.335,4.293 -20.979,1.724 0.97,-7.058 5.049,-13.618 11.669,-17.519 6.633,-3.91 14.348,-4.301 20.992,-1.732 C 10.699,-10.462 6.62,-3.902 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path76" />
|
||||
</g>
|
||||
<g
|
||||
id="g78"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,107.19786,150.50755)"
|
||||
clip-path="url(#clipPath1155)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 6.633,-3.909 14.348,-4.301 20.992,-1.731 20.009,5.333 15.93,11.894 9.31,15.795 2.69,19.697 -5.026,20.088 -11.669,17.52 -10.7,10.461 -6.62,3.902 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path80" />
|
||||
</g>
|
||||
<g
|
||||
id="g98"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,129.16573,138.05504)"
|
||||
clip-path="url(#clipPath1125)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 6.644,-2.57 14.358,-2.178 20.992,1.732 27.612,5.633 31.691,12.194 32.661,19.25 26.017,21.82 18.302,21.429 11.682,17.527 5.062,13.625 0.982,7.065 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path100" />
|
||||
</g>
|
||||
<g
|
||||
id="g102"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,132.036,149.80546)"
|
||||
clip-path="url(#clipPath1119)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 6.62,3.901 10.699,10.461 11.669,17.519 5.025,20.088 -2.689,19.696 -9.31,15.795 -15.93,11.893 -20.009,5.333 -20.992,-1.732 -14.348,-4.301 -6.633,-3.91 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path104" />
|
||||
</g>
|
||||
<g
|
||||
id="g106"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,139.41553,131.41004)"
|
||||
clip-path="url(#clipPath1113)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="m -27.40181,13.441787 c 6.644,-2.57 14.359,-2.178 20.9920004,1.731 6.62000002,3.902 10.699,10.461 11.669,17.519 -6.644,2.569 -14.359,2.178 -20.9790004,-1.724 -6.62,-3.901 -10.7,-10.462 -11.682,-17.526"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path108" />
|
||||
</g>
|
||||
<g
|
||||
id="g110"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,116.37715,121.06317)"
|
||||
clip-path="url(#clipPath1107)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="m 0,0 c 1.271,7.579 -1.125,14.922 -5.904,20.205 -6.242,-3.433 -10.906,-9.591 -12.178,-17.169 -1.275,-7.594 1.123,-14.937 5.902,-20.22 C -5.936,-13.736 -1.273,-7.578 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path112" />
|
||||
</g>
|
||||
<g
|
||||
id="g114"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,123.25775,134.69217)"
|
||||
clip-path="url(#clipPath1101)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="m 0,0 c 1.271,7.579 -1.125,14.922 -5.904,20.206 -6.242,-3.434 -10.906,-9.592 -12.178,-17.17 -1.275,-7.593 1.123,-14.937 5.902,-20.22 C -5.937,-13.736 -1.273,-7.578 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path116" />
|
||||
</g>
|
||||
<g
|
||||
id="g126"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,125.36425,127.9867)"
|
||||
clip-path="url(#clipPath1083)"
|
||||
style="fill:#2e3440;fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 4.779,5.283 7.176,12.627 5.901,20.22 4.629,27.798 -0.035,33.956 -6.277,37.39 -11.055,32.106 -13.453,24.763 -12.18,17.184 -10.908,9.606 -6.244,3.448 0,0"
|
||||
style="fill:#2e3440;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path128" />
|
||||
</g>
|
||||
<g
|
||||
id="g10"
|
||||
transform="translate(54.26113,76.790102)"
|
||||
style="fill:#2e3440;fill-opacity:1;stroke:#2e3440;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#2e3440;fill-opacity:1;stroke:#2e3440;stroke-width:3;stroke-linecap:butt;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 65.113709,84.638921 c -0.346049,-9.794303 8.85917,-32.693347 8.85917,-32.693347"
|
||||
id="path9" />
|
||||
<path
|
||||
style="fill:#2e3440;fill-opacity:1;stroke:#2e3440;stroke-width:3;stroke-linecap:butt;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 65.108044,84.684262 c 0.346049,-9.794303 -8.85917,-32.693347 -8.85917,-32.693347"
|
||||
id="path9-7" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
89
resources/img/logo.svg
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 45.742326 80.310542"
|
||||
version="1.1"
|
||||
id="svg12"
|
||||
width="45.742325"
|
||||
height="80.310539"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs id="defs12" />
|
||||
<style id="style1">
|
||||
svg {
|
||||
--fill: #2E3440;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
svg {
|
||||
--fill: #D8DEE9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<g
|
||||
class="stroke"
|
||||
id="branches"
|
||||
transform="translate(-42.033271,-37.145192)">
|
||||
<path
|
||||
d="m 65.113709,84.638921 c -0.346049,-9.794303 8.85917,-32.693347 8.85917,-32.693347"
|
||||
id="path1"
|
||||
style="fill:none;stroke:var(--fill);stroke-width:3;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 65.108044,84.684262 c 0.346049,-9.794303 -8.85917,-32.693347 -8.85917,-32.693347"
|
||||
id="path2"
|
||||
style="fill:none;stroke:var(--fill);stroke-width:3;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
class="leaf"
|
||||
id="g1"
|
||||
style="fill:var(--fill);fill-opacity:1">
|
||||
<path
|
||||
d="M 0,0 C 6.633,-3.91 14.348,-4.302 20.992,-1.732 20.009,5.333 15.93,11.893 9.31,15.795 2.69,19.697 -5.025,20.088 -11.669,17.519 -10.7,10.462 -6.62,3.901 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,4.116564,13.543871)"
|
||||
id="path3"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="m 0,0 c -6.62,3.901 -14.335,4.293 -20.979,1.724 0.97,-7.058 5.049,-13.618 11.669,-17.519 6.633,-3.91 14.348,-4.301 20.992,-1.732 C 10.699,-10.462 6.62,-3.902 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,10.339434,19.278333)"
|
||||
id="path4"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="M 0,0 C 6.633,-3.909 14.348,-4.301 20.992,-1.731 20.009,5.333 15.93,11.894 9.31,15.795 2.69,19.697 -5.026,20.088 -11.669,17.52 -10.7,10.461 -6.62,3.902 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,10.903454,36.572256)"
|
||||
id="path5"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="M 0,0 C 6.644,-2.57 14.358,-2.178 20.992,1.732 27.612,5.633 31.691,12.194 32.661,19.25 26.017,21.82 18.302,21.429 11.682,17.527 5.062,13.625 0.982,7.065 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,32.871328,24.119748)"
|
||||
id="path6"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="M 0,0 C 6.62,3.901 10.699,10.461 11.669,17.519 5.025,20.088 -2.689,19.696 -9.31,15.795 -15.93,11.893 -20.009,5.333 -20.992,-1.732 -14.348,-4.301 -6.633,-3.91 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,35.741597,35.870171)"
|
||||
id="path7"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="m -27.40181,13.441787 c 6.644,-2.57 14.359,-2.178 20.9920004,1.731 6.62000002,3.902 10.699,10.461 11.669,17.519 -6.644,2.569 -14.359,2.178 -20.9790004,-1.724 -6.62,-3.901 -10.7,-10.462 -11.682,-17.526"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,43.12113,17.474745)"
|
||||
id="path8"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="m 0,0 c 1.271,7.579 -1.125,14.922 -5.904,20.205 -6.242,-3.433 -10.906,-9.591 -12.178,-17.169 -1.275,-7.594 1.123,-14.937 5.902,-20.22 C -5.936,-13.736 -1.273,-7.578 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,20.082753,7.127875)"
|
||||
id="path9"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="m 0,0 c 1.271,7.579 -1.125,14.922 -5.904,20.206 -6.242,-3.434 -10.906,-9.592 -12.178,-17.17 -1.275,-7.593 1.123,-14.937 5.902,-20.22 C -5.937,-13.736 -1.273,-7.578 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,26.963346,20.756878)"
|
||||
id="path10"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
<path
|
||||
d="M 0,0 C 4.779,5.283 7.176,12.627 5.901,20.22 4.629,27.798 -0.035,33.956 -6.277,37.39 -11.055,32.106 -13.453,24.763 -12.18,17.184 -10.908,9.606 -6.244,3.448 0,0"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,29.06985,14.051408)"
|
||||
id="path11"
|
||||
style="fill:var(--fill);fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
class="fill"
|
||||
d="m 23.308833,63.179301 -3.288947,-3.831872 2.16535,-2.433461 1.123597,-1.262592 1.119364,1.257653 2.169936,2.4384 z M 37.853155,39.714993 c -0.02117,0.08396 -0.9652,3.0988 -3.220508,5.991225 -1.128536,1.453444 -2.574573,2.872317 -4.37515,3.93065 -1.617486,0.947914 -3.517195,1.617839 -5.820481,1.786467 l -1.128183,-1.267531 -1.127125,1.266825 C 19.838911,51.249415 17.912391,50.557971 16.276561,49.58254 13.551705,47.957293 11.640003,45.483263 10.434208,43.388115 9.8309581,42.34354 9.4048026,41.401624 9.134222,40.732051 8.9991081,40.397265 8.902447,40.131271 8.8414165,39.954529 8.8107248,39.865982 8.7892053,39.800013 8.7761526,39.75909 l -0.013053,-0.04233 -0.00212,-0.006 L 8.374688,38.405835 H 0.87287218 v 3.653366 H 5.7302693 c 0.5323417,1.327503 1.5515166,3.495323 3.2441444,5.720645 1.3409083,1.757539 3.1143223,3.553177 5.4257223,4.937477 1.423105,0.854428 3.055761,1.541992 4.884914,1.960034 l -1.365956,1.534936 -2.751314,3.091744 4.069998,4.741686 c -1.8415,0.426861 -3.481212,1.128536 -4.909256,1.995664 -3.439936,2.087739 -5.6744305,5.06095 -7.0735472,7.485944 -0.7094361,1.234017 -1.2043833,2.33292 -1.5250583,3.129845 H 0.87287218 v 3.653366 H 8.3746915 l 0.3869972,-1.306689 c 0.017992,-0.07479 0.9574388,-3.071988 3.1996943,-5.959122 1.120775,-1.448505 2.556934,-2.865966 4.343753,-3.928886 1.594908,-0.94615 3.464983,-1.623483 5.726994,-1.814336 l 1.276703,1.486959 1.276703,-1.486959 c 2.304697,0.193675 4.202641,0.89147 5.8166,1.865136 2.703336,1.631245 4.598811,4.097514 5.794022,6.182431 0.597605,1.039283 1.01988,1.975908 1.288344,2.640894 0.134056,0.33267 0.229658,0.597253 0.289983,0.772583 0.02999,0.08784 0.05151,0.153459 0.06456,0.194028 l 0.01305,0.04198 0.0014,0.0056 0.385939,1.306336 h 7.502877 V 76.657176 H 40.885985 C 40.357172,75.336729 39.347522,73.18549 37.673944,70.973573 36.344677,69.222384 34.586433,67.430273 32.294788,66.041387 30.865333,65.173554 29.224563,64.47082 27.3813,64.044312 L 31.450238,59.304037 28.698572,56.21194 27.33438,54.679121 c 1.829153,-0.417336 3.461456,-1.104195 4.884208,-1.957917 3.46957,-2.081036 5.72135,-5.0673 7.129639,-7.505347 0.716845,-1.244953 1.216025,-2.353733 1.538111,-3.156656 h 4.855986 v -3.653366 h -7.502877 z"
|
||||
id="path12"
|
||||
style="fill:var(--fill);fill-opacity:1;stroke-width:0.352778" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
155
resources/views/individual-page-menu.phtml
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\Auth;
|
||||
use Fisharebest\Webtrees\Fact;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteRecord;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\EditFactPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\EditRawRecordPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\ReorderFamiliesPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\ReorderMediaPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\ReorderNamesPage;
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
use Fisharebest\Webtrees\Individual;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
// Added by me
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\AddSpouseToIndividualPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\LinkSpouseToIndividualPage;
|
||||
use Fisharebest\Webtrees\Http\RequestHandlers\AddChildToIndividualPage;
|
||||
// End added
|
||||
|
||||
/**
|
||||
* @var bool $can_upload_media
|
||||
* @var Collection<int,Fact> $clipboard_facts
|
||||
* @var Individual $record
|
||||
* @var Collection<int,string> $shares
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="dropdown wt-page-menu">
|
||||
<button class="btn btn-primary dropdown-toggle wt-page-menu-button" type="button" id="page-menu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<?= view('icons/menu') ?>
|
||||
<?= I18N::translate('edit') ?>
|
||||
</button>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-end wt-page-menu-items" aria-labelledby="page-menu">
|
||||
<?php if ($shares->isNotEmpty()) : ?>
|
||||
<button class="dropdown-item" data-bs-toggle="modal" data-bs-target="#wt-shares-modal">
|
||||
<?= view('icons/share') ?>
|
||||
<?= I18N::translate('Share') ?>
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
<?php endif ?>
|
||||
|
||||
<a class="dropdown-item" href="<?= e(route(AddNewFact::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref(), 'fact' => 'NAME'])) ?>">
|
||||
<?= view('icons/add') ?>
|
||||
<?= I18N::translate('Add a name') ?>
|
||||
</a>
|
||||
|
||||
<?php if ($record->facts(['NAME'], false, null, true)->count() > 1) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(ReorderNamesPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/reorder') ?>
|
||||
<?= I18N::translate('Re-order names') ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<div class="dropdown-item disabled">
|
||||
<?= view('icons/spacer') ?>
|
||||
<?= I18N::translate('Re-order names') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<?php if ($record->facts(['SEX'], false, null, true)->isEmpty()) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(AddNewFact::class, ['fact' => 'SEX', 'tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/edit') ?>
|
||||
<?= I18N::translate('Edit the sex') ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
|
||||
<?php foreach ($record->facts(['SEX'], false, null, true) as $fact) : ?>
|
||||
<?php if ($fact->canEdit()) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(EditFactPage::class, ['xref' => $record->xref(), 'fact_id' => $fact->id(), 'tree' => $record->tree()->name()])) ?>">
|
||||
<?= view('icons/edit') ?>
|
||||
<?= I18N::translate('Edit the sex') ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<?php if ($record->spouseFamilies()->count() > 1 || $record->childFamilies()->count() > 1) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(ReorderFamiliesPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/reorder') ?>
|
||||
<?= I18N::translate('Re-order families') ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<div class="dropdown-item disabled">
|
||||
<?= view('icons/spacer') ?>
|
||||
<?= I18N::translate('Re-order families') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<!-- ADDED BY ME -->
|
||||
<a class="dropdown-item" href="<?= e(route(AddSpouseToIndividualPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/add') ?>
|
||||
<?= I18N::translate($record->sex() === 'F' ? 'Add a husband' : 'Add a wife') ?>
|
||||
</a>
|
||||
<a class="dropdown-item" href="<?= e(route(LinkSpouseToIndividualPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/link') ?>
|
||||
<?= I18N::translate($record->sex() === 'F' ? 'Add a husband using an existing individual' : 'Add a wife using an existing individual') ?>
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" href="<?= e(route(AddChildToIndividualPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/individual') ?>
|
||||
<?= I18N::translate('Add a child') ?>
|
||||
</a>
|
||||
<!-- END ADDED -->
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<?php if ($can_upload_media) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(AddNewFact::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref(), 'fact' => 'OBJE'])) ?>">
|
||||
<?= view('icons/add') ?>
|
||||
<?= I18N::translate('Add a media object') ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($record->facts(['OBJE'], false, null, true)->count() > 1) : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(ReorderMediaPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/reorder') ?>
|
||||
<?= I18N::translate('Re-order media') ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<div class="dropdown-item disabled">
|
||||
<?= view('icons/spacer') ?>
|
||||
<?= I18N::translate('Re-order media') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($clipboard_facts->isNotEmpty()) : ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<?= view('record-page-menu-clipboard', ['clipboard_facts' => $clipboard_facts, 'record' => $record]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<a class="dropdown-item" href="#" data-wt-confirm="<?= I18N::translate('Are you sure you want to delete “%s”?', strip_tags($record->fullName())) ?>" data-wt-post-url="<?= e(route(DeleteRecord::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/delete') ?>
|
||||
<?= I18N::translate('Delete') ?>
|
||||
</a>
|
||||
|
||||
<?php if (Auth::isAdmin() || $record->tree()->getPreference('SHOW_GEDCOM_RECORD') === '1') : ?>
|
||||
<a class="dropdown-item" href="<?= e(route(EditRawRecordPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>">
|
||||
<?= view('icons/edit') ?>
|
||||
<?= I18N::translate('Edit the raw GEDCOM') ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
25
resources/views/lists/families-table.phtml
Normal file
@@ -0,0 +1,25 @@
|
||||
<input type="number" id="family-page" />
|
||||
|
||||
<?= view('::lists/families-table', get_defined_vars()); ?>
|
||||
|
||||
<script>
|
||||
window.onload = function() {
|
||||
var table = $(".wt-table-family").DataTable();
|
||||
var pageInput = $("#family-page");
|
||||
var queries = new URLSearchParams(window.location.search);
|
||||
|
||||
pageInput.on('keyup', function () {
|
||||
setPage(this.value);
|
||||
});
|
||||
table.on('page.dt', function () {
|
||||
pageInput.val(table.page() + 1);
|
||||
queries.set("page", table.page() + 1);
|
||||
window.history.pushState( {} , '', '?' + queries.toString() );
|
||||
});
|
||||
|
||||
setPage(queries.get("page"));
|
||||
function setPage(page){
|
||||
table.page(page - 1).draw('page');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
25
resources/views/lists/individuals-table.phtml
Normal file
@@ -0,0 +1,25 @@
|
||||
<input type="number" id="individual-page" />
|
||||
|
||||
<?= view('::lists/individuals-table', get_defined_vars()); ?>
|
||||
|
||||
<script>
|
||||
window.onload = function() {
|
||||
var table = $(".wt-table-individual").DataTable();
|
||||
var pageInput = $("#individual-page");
|
||||
var queries = new URLSearchParams(window.location.search);
|
||||
|
||||
pageInput.on('keyup', function () {
|
||||
setPage(this.value);
|
||||
});
|
||||
table.on('page.dt', function () {
|
||||
pageInput.val(table.page() + 1);
|
||||
queries.set("page", table.page() + 1);
|
||||
window.history.pushState( {} , '', '?' + queries.toString() );
|
||||
});
|
||||
|
||||
setPage(queries.get("page"));
|
||||
function setPage(page){
|
||||
table.page(page - 1).draw('page');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
30
resources/views/modules/block-template.phtml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
|
||||
/**
|
||||
* @var string $block
|
||||
* @var string $content
|
||||
* @var string $config_url
|
||||
* @var int $id
|
||||
* @var string $title
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="mb-4 wt-block wt-block-<?= e($block) ?>" id="block-<?= e($id) ?>">
|
||||
<h3 class="wt-block-header wt-block-header-<?= e($block) ?>">
|
||||
<?php if ($config_url !== '') : ?>
|
||||
<a class="btn btn-link" href="<?= e($config_url) ?>" title="<?= I18N::translate('Preferences') ?>">
|
||||
<?= view('icons/preferences') ?>
|
||||
<span class="visually-hidden"><?= I18N::translate('Preferences') ?></span>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<?= $title ?>
|
||||
</h3>
|
||||
<div class="wt-block-content wt-block-content-<?= e($block) ?>">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
</div>
|
||||
69
resources/views/modules/descendancy/sidebar.phtml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
use Fisharebest\Webtrees\Tree;
|
||||
use Fisharebest\Webtrees\View;
|
||||
|
||||
/**
|
||||
* @var string $individual_list
|
||||
* @var Tree $tree
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<form method="post" action="<?= e(route('module', ['module' => 'descendancy', 'action' => 'Descendants', 'tree' => $tree->name()])) ?>" onsubmit="return false;">
|
||||
<div class="form-group">
|
||||
<input type="search" name="sb_desc_name" id="sb_desc_name" class="form-control" placeholder="<?= I18N::translate('Search') ?>">
|
||||
<?= csrf_field() ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="sb_desc_content">
|
||||
<ul>
|
||||
<?= $individual_list ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<?php View::push('javascript') ?>
|
||||
<script>
|
||||
function dsearchQ() {
|
||||
var query = $("#sb_desc_name").val();
|
||||
if (query.length>1) {
|
||||
$("#sb_desc_content").load(<?= json_encode(route('module', ['module' => 'descendancy', 'action' => 'Search', 'tree' => $tree->name(), 'search' => '']), JSON_THROW_ON_ERROR) ?> + encodeURIComponent(query));
|
||||
}
|
||||
}
|
||||
|
||||
$("#sb_desc_name").focus(function(){this.select();});
|
||||
$("#sb_desc_name").blur(function(){if (this.value === "") this.value="<?= I18N::translate('Search') ?>";});
|
||||
var dtimerid = null;
|
||||
$("#sb_desc_name").keyup(function(e) {
|
||||
if (dtimerid) window.clearTimeout(dtimerid);
|
||||
dtimerid = window.setTimeout("dsearchQ()", 500);
|
||||
});
|
||||
|
||||
$("#sb_desc_content").on("click", ".sb_desc_indi", function() {
|
||||
var self = $(this),
|
||||
state = self.children(".plusminus"),
|
||||
target = self.siblings("div");
|
||||
if(state.hasClass("icon-plus")) {
|
||||
if (jQuery.trim(target.html())) {
|
||||
target.show("fast"); // already got content so just show it
|
||||
} else if (this.dataset.wtHref !== "#") {
|
||||
target
|
||||
.hide()
|
||||
.load(this.dataset.wtHref, function(response, status, xhr) {
|
||||
if(status === "success" && response !== "") {
|
||||
target.show("fast");
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
target.hide("fast");
|
||||
}
|
||||
state.toggleClass("icon-minus icon-plus");
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
<?php View::endpush() ?>
|
||||
43
resources/views/modules/faq/show.phtml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
|
||||
/**
|
||||
* @var array<int,object{
|
||||
* block_id: int,
|
||||
* block_order: int,
|
||||
* gedcom_id: int,
|
||||
* header: string,
|
||||
* faqbody: string,
|
||||
* languages: string
|
||||
* }> $faqs
|
||||
* @var string $title
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<h2 class="wt-page-title"><?= $title ?></h2>
|
||||
|
||||
<ul class="faq">
|
||||
<?php foreach ($faqs as $id => $faq) : ?>
|
||||
<li>
|
||||
<a href="#faq<?= e($id) ?>"><?= e($faq->header) ?></a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
|
||||
<?php foreach ($faqs as $id => $faq) : ?>
|
||||
<article class="faq_article">
|
||||
<header class="faq_title" id="faq<?= $id ?>">
|
||||
<h3><?= e($faq->header) ?></h3>
|
||||
<span class="faq_top faq_italic">
|
||||
<a href="#content"><?= I18N::translate('back to top') ?></a>
|
||||
</span>
|
||||
</header>
|
||||
<main class="faq_body">
|
||||
<?= str_starts_with($faq->faqbody, '<') ? $faq->faqbody : nl2br(e($faq->faqbody), false) ?>
|
||||
</main>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
55
resources/views/modules/lifespans-chart/chart.phtml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\Gedcom;
|
||||
use Fisharebest\Webtrees\Individual;
|
||||
|
||||
/**
|
||||
* @var string $dir
|
||||
* @var int $end_year
|
||||
* @var array<object{
|
||||
* background: string,
|
||||
* birth_year: int,
|
||||
* death_year: int,
|
||||
* id: string,
|
||||
* individual: Individual,
|
||||
* row: int
|
||||
* }> $lifespans
|
||||
* @var int $max_rows
|
||||
* @var int $start_year
|
||||
* @var string $subtitle
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<p class="wt-lifespans-subtitle">
|
||||
<?= $subtitle ?>
|
||||
</p>
|
||||
|
||||
<div class="wt-lifespans-scale">
|
||||
<?php for ($year = $start_year; $year < $end_year; $year += 10) :
|
||||
?><div class="wt-lifespans-decade"><?= $year ?></div><?php
|
||||
endfor ?>
|
||||
</div>
|
||||
|
||||
<div class="wt-lifespans-individuals position-relative" style="height: <?= (5 + $max_rows) * 1.5 ?>rem; width: <?= ($end_year - $start_year) * 7 ?>px;">
|
||||
<?php foreach ($lifespans as $lifespan) : ?>
|
||||
<a href="#" data-bs-toggle="collapse" data-bs-target="#<?= e($lifespan->id) ?>" aria-expanded="false" aria-controls="<?= e($lifespan->id) ?>">
|
||||
<div class="wt-lifespans-individual position-absolute text-nowrap text-truncate <?= 'wt-sex-'.strtolower($lifespan->individual->sex() ?? 'u') ?>" dir="auto" style="<?= $dir === 'ltr' ? 'left' : 'right' ?>:<?= ($lifespan->birth_year - $start_year) * 7 ?>px; top:<?= $lifespan->row * 2.5 ?>rem; width:<?= ($lifespan->death_year - $lifespan->birth_year) * 7 + 5 ?>px;">
|
||||
<?= $lifespan->individual->fullName() ?>
|
||||
<?= strip_tags($lifespan->individual->lifespan()) ?>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="wt-lifespans-summary collapse position-absolute" id="<?= e($lifespan->id) ?>" style="<?= $dir === 'ltr' ? 'left' : 'right' ?>:<?= (min($lifespan->birth_year, $end_year - 50) - $start_year) * 7 ?>px; top:<?= ($lifespan->row + 1.2) * 2.5 ?>rem; width:350px;">
|
||||
<a class="wt-lifespans-summary-link" href="<?= e($lifespan->individual->url()) ?>">
|
||||
<?= $lifespan->individual->fullName() ?>
|
||||
</a>
|
||||
|
||||
<?php foreach ($lifespan->individual->facts(array_merge(Gedcom::BIRTH_EVENTS, Gedcom::DEATH_EVENTS), true) as $fact) : ?>
|
||||
<?= $fact->summary() ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
28
resources/views/modules/lightbox/tab.phtml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\Media;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @var Collection<int,Media> $media_list
|
||||
*/
|
||||
|
||||
?>
|
||||
<div class="wt-tab-album container px-0 py-4">
|
||||
<div class="row">
|
||||
<?php foreach ($media_list as $media) : ?>
|
||||
<figure class="figure text-center col-sm-6 col-md-4 col-lg-3 col-xl-3 wt-album-tab-figure">
|
||||
<?php foreach ($media->mediaFiles() as $media_file) : ?>
|
||||
<?= $media_file->displayImage(100, 100, 'contain', ['class' => 'img-thumbnail wt-album-tab-image']) ?>
|
||||
<?php endforeach ?>
|
||||
<figcaption class="figure-caption wt-album-tab-caption">
|
||||
<a href="<?= e($media->url()) ?>">
|
||||
<?= $media->fullName() ?>
|
||||
</a>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</div>
|
||||
27
resources/views/modules/place-hierarchy/list.phtml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
use Fisharebest\Webtrees\Place;
|
||||
|
||||
/**
|
||||
* @var array<array<Place>> $columns
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<h5 class="col list_label text-center">
|
||||
<?= I18N::translate('Place list') ?>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php foreach ($columns as $column) : ?>
|
||||
<ul class="col wt-page-options-value me-1 list-unstyled">
|
||||
<?php foreach ($column as $place) : ?>
|
||||
<li><?= $place->fullName(true) ?></li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
59
resources/views/modules/recent_changes/changes-list.phtml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Fisharebest\Webtrees\Contracts\TimestampInterface;
|
||||
use Fisharebest\Webtrees\Contracts\UserInterface;
|
||||
use Fisharebest\Webtrees\GedcomRecord;
|
||||
use Fisharebest\Webtrees\I18N;
|
||||
use Fisharebest\Webtrees\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @var int $id
|
||||
* @var int $limit_low
|
||||
* @var int $limit_high
|
||||
* @var Collection<int,object{record:GedcomRecord,time:TimestampInterface,user:UserInterface}> $rows
|
||||
* @var bool $show_date
|
||||
* @var bool $show_user
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="list-group">
|
||||
<?php foreach ($rows as $n => $row): ?>
|
||||
<?php if ($n === $limit_low && $rows->count() > $limit_high): ?>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-secondary my-3" id="show-more-<?= e($id) ?>">
|
||||
<?= view('icons/add') ?>
|
||||
<?= /* I18N: button label */ I18N::translate('show more') ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<a href="<?= e($row->record->url()) ?>" class="<?= $n >= $limit_low && $rows->count() > $limit_high ? 'd-none' : '' ?> list-group-item list-group-item-action">
|
||||
<span class="d-block"><?= $row->record->fullName() ?></span>
|
||||
|
||||
<small class="d-block">
|
||||
<?php if ($show_user && $show_date): ?>
|
||||
<?= /* I18N: [a record was] Changed on <date/time> by <user> */ I18N::translate('Changed on %1$s by %2$s', view('components/datetime', ['timestamp' => $row->time]), e($row->record->lastChangeUser())) ?>
|
||||
<?php elseif ($show_date): ?>
|
||||
<?= /* I18N: [a record was] Changed on <date/time> */ I18N::translate('Changed on %1$s', view('components/datetime', ['timestamp' => $row->time])) ?>
|
||||
<?php elseif ($show_user): ?>
|
||||
<?= /* I18N: [a record was] Changed by <user> */ I18N::translate('Changed by %1$s', e($row->user->userName())) ?>
|
||||
<?php endif ?>
|
||||
</small>
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<?php View::push('javascript') ?>
|
||||
<script>
|
||||
document.getElementById("show-more-<?= e($id) ?>").addEventListener("click", function (ev) {
|
||||
document.querySelectorAll("#block-<?= e($id) ?> .d-none").forEach(function (el) {
|
||||
el.classList.remove("d-none");
|
||||
});
|
||||
ev.target.parentNode.removeChild(ev.target);
|
||||
});
|
||||
</script>
|
||||
<?php View::endpush() ?>
|
||||
7
src/css/imports.css
Normal file
@@ -0,0 +1,7 @@
|
||||
/*! ********************************************
|
||||
Bocken Theme for webtrees
|
||||
************************************************
|
||||
CSS imports
|
||||
***********************************************/
|
||||
|
||||
@import "../../vendor/fisharebest/webtrees/resources/css/_base.css";
|
||||
BIN
src/fonts/OpenSans-Italic[wdth,wght].woff2
Normal file
BIN
src/fonts/OpenSans[wdth,wght].woff2
Normal file
1
src/img/bars-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 434 B |
1
src/img/book-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 668 B |
1
src/img/calendar-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
src/img/comments-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160zm122 220c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 729 B |
1
src/img/home-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 715 B |
56
src/img/icon-pedigree.svg
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
data-fa-i2svg=""
|
||||
viewBox="0 0 33.75 512"
|
||||
height="27"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="icon-pedigree.svg"
|
||||
width="33.75"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.925"
|
||||
inkscape:cx="10.661658"
|
||||
inkscape:cy="-7.5902336"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<path
|
||||
d="m -175.125,352 h -96 c -17.67,0 -32,14.33 -32,32 v 96 c 0,17.67 14.33,32 32,32 h 96 c 17.67,0 32,-14.33 32,-32 v -96 c 0,-17.67 -14.33,-32 -32,-32 z m -24,-80 h 192 v 48 h 48 v -48 h 192 v 48 h 48 v -57.59 c 0,-21.17 -17.23,-38.41 -38.41,-38.41 H 40.875 v -64 h 40 c 17.67,0 32,-14.33 32,-32 V 32 c 0,-17.67 -14.33,-32 -32,-32 h -128 c -17.67,0 -32,14.33 -32,32 v 96 c 0,17.67 14.33,32 32,32 h 40 v 64 h -201.59 c -21.18,0 -38.41,17.23 -38.41,38.41 V 320 h 48 z m 264,80 h -96 c -17.67,0 -32,14.33 -32,32 v 96 c 0,17.67 14.33,32 32,32 h 96 c 17.67,0 32,-14.33 32,-32 v -96 c 0,-17.67 -14.33,-32 -32,-32 z m 240,0 h -96 c -17.67,0 -32,14.33 -32,32 v 96 c 0,17.67 14.33,32 32,32 h 96 c 17.67,0 32,-14.33 32,-32 v -96 c 0,-17.67 -14.33,-32 -32,-32 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#5e72e4;fill-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
1
src/img/language-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
src/img/list-alt-regular.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 1008 B |
1
src/img/palette-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M204.3 5C104.9 24.4 24.8 104.3 5.2 203.4c-37 187 131.7 326.4 258.8 306.7 41.2-6.4 61.4-54.6 42.5-91.7-23.1-45.4 9.9-98.4 60.9-98.4h79.7c35.8 0 64.8-29.6 64.9-65.3C511.5 97.1 368.1-26.9 204.3 5zM96 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm32-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128-64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 711 B |
1
src/img/project-diagram-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M384 320H256c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h128c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32zM192 32c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v128c0 17.67 14.33 32 32 32h95.72l73.16 128.04C211.98 300.98 232.4 288 256 288h.28L192 175.51V128h224V64H192V32zM608 0H480c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h128c17.67 0 32-14.33 32-32V32c0-17.67-14.33-32-32-32z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 629 B |
1
src/img/question-circle-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 852 B |
1
src/img/scroll-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M48 0C21.53 0 0 21.53 0 48v64c0 8.84 7.16 16 16 16h80V48C96 21.53 74.47 0 48 0zm208 412.57V352h288V96c0-52.94-43.06-96-96-96H111.59C121.74 13.41 128 29.92 128 48v368c0 38.87 34.65 69.65 74.75 63.12C234.22 474 256 444.46 256 412.57zM288 384v32c0 52.93-43.06 96-96 96h336c61.86 0 112-50.14 112-112 0-8.84-7.16-16-16-16H288z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 551 B |
1
src/img/search-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 575 B |
1
src/img/shield-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M466.5 83.7l-192-80a48.15 48.15 0 0 0-36.9 0l-192 80C27.7 91.1 16 108.6 16 128c0 198.5 114.5 335.7 221.5 380.3 11.8 4.9 25.1 4.9 36.9 0C360.1 472.6 496 349.3 496 128c0-19.4-11.7-36.9-29.5-44.3zM256.1 446.3l-.1-381 175.9 73.3c-3.3 151.4-82.1 261.1-175.8 307.7z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 505 B |
1
src/img/shopping-cart-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 782 B |
1
src/img/sign-in-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 566 B |
1
src/img/sign-out-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 570 B |
1
src/img/silhouette-man.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 800 1000"><path fill="#fff" fill-rule="evenodd" stroke-width="2.3" d="M358 29c16 4 32-15 50-16 25 0 56 14 102-7 10-5 29-11 41 1 8 9 17 13 26 10 22-10 44 20 57 24 7 2 14 9 21 14 10 7 21 23 30 32l26 21c13 14-1 18-11 35-10 10-20 23-32 46l15 100 23 76-16 26 80 113c2 16-1 28-13 35l-51 14c-5 39 4 50 13 64l-20 14 20 26-23 15 16 55c3 20-8 32-15 42-17 21-24 20-49 21-52 3-84-6-139-26-18 27-41 42-41 105-44 46-35 70-41 128-24 4-22 24-182-138-79-80-171-130-214-88 28-80 74-111 77-198l-21-33s-19-31-20-37l-16-51-22-169c5-106 75-164 125-202 38-32 86-45 137-54 22-4 44 2 67 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 640 B |
1
src/img/silhouette-unknown.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 1000"><path fill="#fff" d="M119 956c57-142 35-248-89-448C-35 404-1 159 198 81c148-58 328-54 454 43 48 37 64 95 63 156 0 9 2 19 5 29 7 22 13 45 4 65-10 24-15 43 0 65l73 111c7 10 1 23-11 25-33 4-52 20-33 65 4 9 4 18-5 22-9 5-10 10-6 20 4 8 0 16-6 23-14 20-17 42-11 71 7 34-4 61-31 60-49-3-90-16-129 2-42 18-60 59-56 119l-390-1z"/></svg>
|
||||
|
After Width: | Height: | Size: 391 B |
1
src/img/silhouette-woman.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 1000"><path fill="#fff" d="M444 31c-93-3-152 26-211 93-69-24-158 8-197 71-59 96-49 261 55 324-5 30-1 69 34 78 1 8 3 15 6 22 24 52 105 42 119 1 14 11 29 14 46 12l-1 1c-8 24-30 19-45 5 15 28 35 30 64 21-3 41-26 120-52 154-6 7-13 11-20 17-13 13-20 30-29 46 126-51 179 50 284 81 23 6 45 8 68 12-4-9-12-18-17-27-27-41-47-81-30-130 5-16 15-30 21-46 7-19 11-39 19-57 19-39 52-23 86-17 21 4 69 14 86 0 21-17 4-47 9-65 6-20 33-21 12-45 37-16 1-23 7-45 5-19 37-16 42-38 3-14-12-22-20-31-21-20-51-64-36-93 16-32 15-27 8-66-8-38-14-70-36-103 24-16 3-56-11-71-27-28-50-25-77-44-59-41-112-58-184-60zM199 146l17 3c-83 3-147 61-159 145l-2 16c-3-86 51-171 144-164zm-82 109c-13 38-6 80 25 108 3 2 9 5 10 7h-1a79 79 0 0 1-39-108l5-7zM88 418c18 13 41 20 63 17l-5 2c-17 6-51-1-58-19z"/></svg>
|
||||
|
After Width: | Height: | Size: 828 B |
1
src/img/user-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path 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" fill="white"/></svg>
|
||||
|
After Width: | Height: | Size: 486 B |
1
src/img/webtrees.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>Webtrees SVG Icon</title><path fill="currentColor" d="M2.957 4.34q.647 0 1.269.243q.634.243 1.093.7q.459.448.662 1l1.592 4.59l1.31-3.82Q9.84 4.26 11.92 4.26q.459 0 1.106.203q.729.23 1.228.809q.5.58.905 1.782l1.296 3.82l1.606-4.59q.189-.54.649-.998q.472-.459 1.079-.703q.608-.243 1.283-.243q.62.04 1.241.338q.783.378 1.228 1.106q.459.73.459 1.66q0 .81-.364 1.54l-4.225 8.652q-1.025 2.106-3.037 2.106q-.905-.04-1.634-.567q-.728-.54-1.133-1.498L12 13.72l-1.606 3.955q-.243.634-.647 1.093q-.406.447-.945.702q-.54.257-1.134.27q-1.013 0-1.755-.486q-.742-.5-1.297-1.62L.392 8.983Q0 8.16 0 7.443q0-.89.46-1.632q.459-.756 1.254-1.134q.622-.297 1.243-.337"/></svg>
|
||||
|
After Width: | Height: | Size: 744 B |
262
src/scss/config/_bootstrap-overrides.scss
Normal file
@@ -0,0 +1,262 @@
|
||||
/*! ********************************************
|
||||
Bocken Theme for webtrees
|
||||
************************************************/
|
||||
|
||||
$prefix: "bs-";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Color System
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$primary: $nord10;
|
||||
$secondary: $gray-200;
|
||||
$tertiary: $gray-300;
|
||||
$success: $nord14;
|
||||
$info: $nord8;
|
||||
$warning: $nord13;
|
||||
$danger: $nord11;
|
||||
$light: $gray-100;
|
||||
$dark: $nord0;
|
||||
|
||||
$theme-colors: (
|
||||
"primary": $primary,
|
||||
"secondary": $secondary,
|
||||
"success": $success,
|
||||
"info": $info,
|
||||
"warning": $warning,
|
||||
"danger": $danger,
|
||||
"light": $light,
|
||||
"dark": $dark,
|
||||
"white": $white
|
||||
);
|
||||
|
||||
$min-contrast-ratio: 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Options
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$enable-negative-margins: true;
|
||||
$enable-shadows: true;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Spacing
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$spacer: 1rem !default;
|
||||
$spacers: (
|
||||
0: 0,
|
||||
1: $spacer * 0.25,
|
||||
2: $spacer * 0.5,
|
||||
3: $spacer,
|
||||
4: $spacer * 1.5,
|
||||
5: $spacer * 3,
|
||||
6: $spacer * 4,
|
||||
7: $spacer * 6,
|
||||
8: $spacer * 8,
|
||||
9: $spacer * 10,
|
||||
10: $spacer * 12,
|
||||
11: $spacer * 14,
|
||||
12: $spacer * 16,
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Body
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$body-bg: $gray-100;
|
||||
$body-color: $font-color;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Links
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$link-color: $nord10;
|
||||
$link-hover-color: $nord9;
|
||||
$link-decoration: none;
|
||||
$link-hover-decoration: none;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Border & Shadows
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$box-shadow-sm: 0 .3125rem .625rem 0 rgba(0, 0, 0, 0.08);
|
||||
$box-shadow: 0 .25rem .375rem -.0625rem rgba(0, 0, 0, .08), 0 .125rem .25rem -.0625rem rgba(0, 0, 0, .04);
|
||||
$box-shadow-lg: 0 8px 26px -4px rgba(0, 0, 0, 0.1), 0 8px 9px -5px rgba(0, 0, 0, 0.04);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Typography
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$font-family-sans-serif: "Open Sans", Helvetica, Arial, "Noto Sans", sans-serif;
|
||||
|
||||
$font-weight-bold: 600;
|
||||
$font-weight-bolder: 700;
|
||||
|
||||
$small-font-size: .8em;
|
||||
$h1-font-size: 3rem;
|
||||
$h2-font-size: 2.25rem;
|
||||
$h3-font-size: 1.875rem;
|
||||
|
||||
$headings-font-weight: 400;
|
||||
$headings-color: $h-color;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tables
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$table-cell-padding-y: 1rem;
|
||||
$table-cell-padding-x: 1rem;
|
||||
$table-cell-padding-y-sm: .75rem;
|
||||
$table-cell-padding-x-sm: .75rem;
|
||||
$table-border-color: $gray-200;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Buttons
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$btn-padding-y: .625rem;
|
||||
$btn-padding-x: 1.25rem;
|
||||
$btn-font-size: .875rem;
|
||||
$btn-font-weight: 700;
|
||||
|
||||
$btn-padding-y-sm: .5rem;
|
||||
$btn-padding-x-sm: 2rem;
|
||||
$btn-font-size-sm: .75rem;
|
||||
|
||||
$btn-padding-y-lg: .875rem;
|
||||
$btn-padding-x-lg: 4rem;
|
||||
$btn-font-size-lg: .875rem;
|
||||
|
||||
$btn-box-shadow: 0 4px 6px rgba(50, 50, 93, .06), 0 1px 3px rgba(0, 0, 0, .05);
|
||||
$btn-focus-box-shadow: 0 7px 14px rgba(50, 50, 93, .06), 0 3px 6px rgba(0, 0, 0, .05);
|
||||
$btn-active-box-shadow: none;
|
||||
|
||||
$btn-border-radius: $border-radius-md;
|
||||
$btn-border-radius-sm: .25rem;
|
||||
$btn-border-radius-lg: .75rem;
|
||||
|
||||
$btn-transition: all .15s ease-in;
|
||||
|
||||
$btn-close-color: $gray-700;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Forms
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$form-label-font-size: .75rem;
|
||||
$form-label-font-weight: 700;
|
||||
$form-label-color: $dark;
|
||||
|
||||
$input-padding-y: .5rem;
|
||||
$input-padding-x: .75rem;
|
||||
$input-font-size: .875rem;
|
||||
$input-line-height: 1.4rem;
|
||||
|
||||
$input-color: $gray-700;
|
||||
$input-border-color: $gray-300;
|
||||
$input-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
||||
|
||||
$input-border-radius: $border-radius-md;
|
||||
$input-border-radius-sm: $border-radius-md;
|
||||
$input-border-radius-lg: $border-radius-md;
|
||||
|
||||
$input-focus-border-color: $primary;
|
||||
$input-focus-width: 2px;
|
||||
$input-focus-box-shadow: 0 3px 9px rgba(50, 50, 9, 0), 3px 4px 8px rgba(94, 129, 172, .10);
|
||||
|
||||
$input-placeholder-color: $gray-500;
|
||||
|
||||
$form-switch-color: rgba(0, 0, 0, 1);
|
||||
$form-switch-bg-image: none;
|
||||
$form-switch-focus-bg-image: none;
|
||||
$form-switch-checked-bg-image: none;
|
||||
|
||||
$form-feedback-valid-color: $nord14;
|
||||
$form-feedback-invalid-color: $nord11;
|
||||
|
||||
$input-group-addon-color: $dark;
|
||||
$input-group-addon-bg: #fff;
|
||||
|
||||
$form-select-border-radius: $border-radius-md;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Navs & Navbar
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$nav-tabs-border-radius: $border-radius-md;
|
||||
|
||||
$nav-pills-border-radius: 0.75rem;
|
||||
$nav-pills-link-active-color: $white;
|
||||
$nav-pills-link-active-bg: $dark;
|
||||
|
||||
$navbar-dark-color: rgba(#fff, .85);
|
||||
$navbar-dark-hover-color: rgba(#fff, .75);
|
||||
|
||||
$navbar-light-color: $white;
|
||||
$navbar-light-hover-color: rgba($white, .7);
|
||||
$navbar-light-active-color: rgba($white, .9);
|
||||
$navbar-light-disabled-color: rgba($white, .3);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tooltips, Popovers, Toasts
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$tooltip-border-radius: $border-radius-md;
|
||||
|
||||
$popover-font-size: $font-size-xs;
|
||||
$popover-border-width: 0;
|
||||
$popover-border-radius: .75rem;
|
||||
|
||||
$toast-border-width: 0;
|
||||
$toast-border-color: transparent;
|
||||
$toast-border-radius: $border-radius-md;
|
||||
$toast-header-color: $h-color;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Modals
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$modal-content-border-radius: .75rem;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Alerts
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$alert-border-radius: $border-radius-md;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Progress
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$progress-height: 8px;
|
||||
$progress-border-radius: $border-radius-md;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// List Group
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$list-group-border-radius: $border-radius-md;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Breadcrumbs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$breadcrumb-border-radius: $border-radius-md;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Pagination
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$pagination-border-radius: 50%;
|
||||
$pagination-padding-x: 3px;
|
||||
$pagination-padding-y: 3px;
|
||||
$pagination-font-size: $btn-font-size;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Card
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$card-box-shadow: var(--#{$prefix}box-shadow-lg);
|
||||
$card-inner-border-radius: var(--#{$prefix}card-border-radius);
|
||||
$card-border-color: var(--#{$prefix}gray-200);
|
||||
100
src/scss/config/_theme-variables.scss
Normal file
@@ -0,0 +1,100 @@
|
||||
/*! ********************************************
|
||||
Bocken Theme for webtrees
|
||||
Nord color palette with dark/light mode
|
||||
************************************************/
|
||||
|
||||
@use "sass:color";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Nord Color Palette
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$nord0: #2E3440;
|
||||
$nord1: #3B4252;
|
||||
$nord2: #434C5E;
|
||||
$nord3: #4C566A;
|
||||
$nord4: #D8DEE9;
|
||||
$nord5: #E5E9F0;
|
||||
$nord6: #ECEFF4;
|
||||
$nord7: #8FBCBB;
|
||||
$nord8: #88C0D0;
|
||||
$nord9: #81A1C1;
|
||||
$nord10: #5E81AC;
|
||||
$nord11: #BF616A;
|
||||
$nord12: #D08770;
|
||||
$nord13: #EBCB8B;
|
||||
$nord14: #A3BE8C;
|
||||
$nord15: #B48EAD;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Light Mode Base Colors (cream background)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$font-color: #555 !default;
|
||||
$h-color: #2a2a2a !default;
|
||||
|
||||
$white: #fff;
|
||||
$gray-100: #f8f6f1; // cream base
|
||||
$gray-200: #efecea;
|
||||
$gray-300: #e8e5e1;
|
||||
$gray-400: #dfdcd8;
|
||||
$gray-500: #aaa;
|
||||
$gray-600: #888;
|
||||
$gray-700: #555;
|
||||
$gray-800: #333;
|
||||
$gray-900: #2a2a2a;
|
||||
$black: #000;
|
||||
|
||||
$blue: $nord10;
|
||||
$indigo: $nord10;
|
||||
$purple: $nord15;
|
||||
$pink: #f3a4b5;
|
||||
$red: $nord11;
|
||||
$orange: $nord12;
|
||||
$yellow: $nord13;
|
||||
$green: $nord14;
|
||||
$teal: $nord8;
|
||||
$cyan: $nord7;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Genealogy Sex Colors (Nord-adapted)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$f-color: $nord11 !default;
|
||||
$m-color: $nord8 !default;
|
||||
$u-color: $nord3 !default;
|
||||
$x-color: $nord13 !default;
|
||||
|
||||
$f-background: color.scale($f-color, $lightness: 90%) !default;
|
||||
$m-background: color.scale($m-color, $lightness: 90%) !default;
|
||||
$u-background: $gray-100 !default;
|
||||
$x-background: color.scale($x-color, $lightness: 90%) !default;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Layout Options
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$compact-header: false !default;
|
||||
$header-breakpoint: xxl;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Extended Font Sizes
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$font-size-xxs: .65rem !default;
|
||||
$font-size-xs: .75rem !default;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Extended Box Shadows
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$box-shadow-xs: 0 1px 3px rgba(0,0,0,0.08), 0 1px rgba(0,0,0,0.02) !default;
|
||||
$box-shadow-xl: 0 23px 45px -11px rgba(0, 0, 0, .15) !default;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Extended Border Radii
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
$border-radius-xs: .125rem !default;
|
||||
$border-radius-md: .5rem !default;
|
||||
$border-radius-section: 10rem !default;
|
||||
21
src/scss/fonts.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
/*! ********************************************
|
||||
Bocken Theme for webtrees
|
||||
************************************************/
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300 800;
|
||||
font-stretch: 75% 100%;
|
||||
font-display: swap;
|
||||
src: url('../fonts/OpenSans[wdth\,wght].woff2') format('woff2-variations');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300 800;
|
||||
font-stretch: 75% 100%;
|
||||
font-display: swap;
|
||||
src: url('../fonts/OpenSans-Italic[wdth\,wght].woff2') format('woff2-variations');
|
||||
}
|
||||
28
src/scss/gustine-sosa.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
/*! ********************************************
|
||||
Argon Light Theme
|
||||
Originally made by jchue
|
||||
Under the Internet Systems Consortium License
|
||||
https://github.com/jchue/argon-webtrees-theme
|
||||
|
||||
Forked and maintained by Evan Galli
|
||||
Under the same licence
|
||||
https://github.com/06Games/Webtrees-ArgonLight
|
||||
************************************************/
|
||||
|
||||
$collapse_mode: true !default;
|
||||
|
||||
@if $collapse_mode {
|
||||
#sidebar-header-_sosa20_{
|
||||
display: unset !important;
|
||||
}
|
||||
|
||||
#sidebar-content-_sosa20_.collapse:not(.show) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#sidebar-content-_sosa20_{
|
||||
#wt-sidebar-sosa1{
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
35
src/scss/magicsunday.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
/*! ********************************************
|
||||
Argon Light Theme
|
||||
Originally made by jchue
|
||||
Under the Internet Systems Consortium License
|
||||
https://github.com/jchue/argon-webtrees-theme
|
||||
|
||||
Forked and maintained by Evan Galli
|
||||
Under the same licence
|
||||
https://github.com/06Games/Webtrees-ArgonLight
|
||||
************************************************/
|
||||
|
||||
.wt-route-webtrees {
|
||||
&-pedigree-chart,
|
||||
&-descendants-chart,
|
||||
&-fan-chart {
|
||||
.icon {
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
svg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-fan-chart {
|
||||
& > div.tooltip table {
|
||||
border-collapse: initial;
|
||||
|
||||
th {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/scss/main.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
/*! ********************************************
|
||||
Bocken Theme for webtrees
|
||||
************************************************/
|
||||
|
||||
@use "theme.scss";
|
||||
@use "gustine-sosa.scss";
|
||||
@use "magicsunday.scss";
|
||||
1731
src/scss/theme.scss
Normal file
1
version.txt
Normal file
@@ -0,0 +1 @@
|
||||
1.0.0
|
||||
41
vite.config.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import path from 'path';
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
const isProd = mode === 'production';
|
||||
|
||||
return {
|
||||
base: './',
|
||||
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
quietDeps: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
build: {
|
||||
outDir: 'resources',
|
||||
emptyOutDir: false,
|
||||
sourcemap: 'inline',
|
||||
minify: isProd,
|
||||
esbuild: {
|
||||
legalComments: 'inline',
|
||||
},
|
||||
rollupOptions: {
|
||||
input: {
|
||||
'theme': path.resolve(__dirname, 'src/scss/main.scss'),
|
||||
'fonts': path.resolve(__dirname, 'src/scss/fonts.scss'),
|
||||
// imports.css references webtrees vendor path — build separately when deployed
|
||||
// 'imports': path.resolve(__dirname, 'src/css/imports.css'),
|
||||
},
|
||||
output: {
|
||||
entryFileNames: `js/[name].js`,
|
||||
chunkFileNames: `js/[name].js`,
|
||||
assetFileNames: '[ext]/[name].[ext]'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||