diff --git a/BockenTheme.php b/BockenTheme.php index a1b8745..f988613 100644 --- a/BockenTheme.php +++ b/BockenTheme.php @@ -70,12 +70,17 @@ class BockenTheme extends AbstractModule implements ModuleCustomInterface, Modul return << + HTML; @@ -358,11 +363,8 @@ class BockenTheme extends AbstractModule implements ModuleCustomInterface, Modul var iconSpan = editBtn.querySelector('.wt-icon-menu'); if (iconSpan) { editBtn.innerHTML = ''; - iconSpan.innerHTML = ''; + iconSpan.innerHTML = ''; editBtn.appendChild(iconSpan); - if (typeof lucide !== 'undefined') { - lucide.createIcons({ nodes: [editBtn] }); - } } } } @@ -400,6 +402,10 @@ class BockenTheme extends AbstractModule implements ModuleCustomInterface, Modul if (typeof lucide !== 'undefined') { lucide.createIcons(); } + + // Reveal page after DOM manipulations are done + document.documentElement.classList.remove('bocken-cloak'); + document.documentElement.classList.add('bocken-ready'); } if (document.readyState === 'loading') { @@ -426,6 +432,7 @@ class BockenTheme extends AbstractModule implements ModuleCustomInterface, Modul 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-images', $this->name() . '::individual-page-images'); View::registerCustomView('::individual-page-menu', $this->name() . '::individual-page-menu'); View::registerCustomView('::modules/family_nav/sidebar-family', $this->name() . '::modules/family_nav/sidebar-family'); } diff --git a/resources/css/individual.css b/resources/css/individual.css index e4715ea..e31b8b4 100644 --- a/resources/css/individual.css +++ b/resources/css/individual.css @@ -10,23 +10,30 @@ /* ---------- Profile photo: large circle, no border ---------- */ -.wt-route-IndividualPage .col-sm-3 .img-thumbnail { - border-radius: 50%; - aspect-ratio: 1 / 1; - object-fit: cover; - border: none; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - padding: 0; - transition: box-shadow 0.3s ease, transform 0.3s ease; - width: 100%; - max-width: 260px; +#individual-images .carousel-inner { + overflow: visible; } -.wt-route-IndividualPage .col-sm-3 .img-thumbnail:hover { - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); - transform: translateY(-2px); +.wt-route-IndividualPage .col-sm-3 a.gallery { + display: block; + width: 200px; + height: 200px; + border-radius: 50%; + overflow: hidden; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } +.wt-route-IndividualPage .col-sm-3 a.gallery .img-thumbnail { + border-radius: 0; + width: 100%; + height: 100%; + object-fit: cover; + border: none; + box-shadow: none; + padding: 0; +} + + /* Center the photo column */ .wt-route-IndividualPage .col-sm-3 { display: flex; @@ -34,26 +41,41 @@ align-items: center; } -/* Silhouette placeholder: constrain to match photo size, circular background */ -.wt-route-IndividualPage .col-sm-3 .wt-individual-silhouette { - display: block; - width: auto !important; - max-height: 260px; - aspect-ratio: 1 / 1; - object-fit: contain; +/* Silhouette placeholder: circular with gender-based background */ +.wt-route-IndividualPage .col-sm-3 > .img-thumbnail { border-radius: 50%; + width: 200px; + height: 200px; + padding: 2rem; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + border: none; } -/* "Add a media object" link — subtle */ -.wt-route-IndividualPage .col-sm-3 .text-center a { - font-size: 0.8rem; - opacity: 0.45; - transition: opacity 0.2s; +.wt-route-IndividualPage .col-sm-3 .wt-individual-silhouette { + display: block; + width: 100% !important; + height: 100%; + opacity: 0.15; + filter: brightness(0); } -.wt-route-IndividualPage .col-sm-3 .text-center a:hover { - opacity: 1; + +/* Gender-based silhouette container — light mode */ +.wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-m) { + background-color: #d1dce7; } +.wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-f) { + background-color: #ded7e2; +} + +.wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-u) { + background-color: #ddd; +} + + /* ---------- Individual header: photo + title + edit ---------- */ .wt-route-IndividualPage .bocken-individual-header { @@ -68,7 +90,7 @@ width: auto; max-width: 260px; padding: 0; - overflow: hidden; + overflow: visible; } .wt-route-IndividualPage .wt-page-title { @@ -100,20 +122,56 @@ opacity: 0.45; } -/* Edit button: icon-only pencil */ +.wt-route-IndividualPage .bocken-title-user a { + color: #2E3440; +} + +/* Edit button: fixed FAB in bottom-right corner */ .wt-route-IndividualPage .wt-page-menu-button { - width: 2.25rem; - height: 2.25rem; - padding: 0; - display: inline-flex; - align-items: center; + position: fixed; + bottom: 0; + right: 0; + width: 1rem; + height: 1rem; + padding: 2rem; + margin: 2rem; + display: grid; + align-content: center; justify-content: center; border-radius: 50%; + background-color: #BF616A; + border: none; + z-index: 100; + transition: background-color 0.3s ease, box-shadow 0.3s ease; + --shake-angle: 15deg; +} + +.wt-route-IndividualPage .wt-page-menu-button:hover, +.wt-route-IndividualPage .wt-page-menu-button:focus { + background-color: #2E3440; + box-shadow: 0 0 0.4em 0.15em rgba(0, 0, 0, 0.15); + animation: bocken-shake 0.5s forwards; } .wt-route-IndividualPage .wt-page-menu-button .wt-icon-menu svg { - width: 16px; - height: 16px; + width: 2rem; + height: 2rem; + fill: white; + stroke: none; +} + +@keyframes bocken-shake { + 0% { transform: rotate(0) scale(1); } + 25% { box-shadow: 0 0 0.5em 0.15em rgba(0, 0, 0, 0.25); transform: rotate(var(--shake-angle)) scale(1.2); } + 50% { box-shadow: 0 0 0.5em 0.15em rgba(0, 0, 0, 0.25); transform: rotate(calc(-1 * var(--shake-angle))) scale(1.2); } + 74% { box-shadow: 0 0 0.5em 0.15em rgba(0, 0, 0, 0.25); transform: rotate(var(--shake-angle)) scale(1.2); } + 100% { transform: rotate(0) scale(1.2); } +} + +@media screen and (max-width: 500px) { + .wt-route-IndividualPage .wt-page-menu-button { + margin: 1rem; + } } /* Hide dropdown caret on the round button */ @@ -516,9 +574,9 @@ font-size: 0.9rem; } - .wt-route-IndividualPage .col-sm-3 .img-thumbnail { - max-width: 80px; + .wt-route-IndividualPage .col-sm-3 a.gallery { width: 80px; + height: 80px; } /* Names accordion: full width */ @@ -571,6 +629,38 @@ background: var(--color-primary, #5E81AC); } +/* Active tab: black background, light blue accent */ +:root[data-theme=dark] .wt-tabs-individual .nav-tabs .nav-link.active { + background: #000; + border-bottom-color: #88C0D0; +} + +/* Silhouette icon tint */ +:root[data-theme=dark] .wt-route-IndividualPage .col-sm-3 .wt-individual-silhouette { + filter: brightness(0) invert(1); +} + +/* Silhouette gender colors */ +:root[data-theme=dark] .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-m) { + background-color: #505f73; +} +:root[data-theme=dark] .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-f) { + background-color: #5f596d; +} +:root[data-theme=dark] .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-u) { + background-color: #4C566A; +} + +/* Profile picture shadow */ +:root[data-theme=dark] .wt-route-IndividualPage .col-sm-3 a.gallery { + box-shadow: 0 4px 8px rgba(255, 255, 255, 0.3); +} + +/* Username link */ +:root[data-theme=dark] .wt-route-IndividualPage .bocken-title-user a { + color: #ECEFF4; +} + /* Links */ :root[data-theme=dark] .wt-route-IndividualPage .wt-facts-table a, :root[data-theme=dark] .wt-route-IndividualPage .wt-family-navigator-family a, @@ -617,6 +707,38 @@ background: var(--color-primary, #5E81AC); } + /* Active tab: black background, light blue accent */ + :root:not([data-theme=light]) .wt-tabs-individual .nav-tabs .nav-link.active { + background: #000; + border-bottom-color: #88C0D0; + } + + /* Silhouette icon tint */ + :root:not([data-theme=light]) .wt-route-IndividualPage .col-sm-3 .wt-individual-silhouette { + filter: brightness(0) invert(1); + } + + /* Silhouette gender colors */ + :root:not([data-theme=light]) .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-m) { + background-color: #505f73; + } + :root:not([data-theme=light]) .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-f) { + background-color: #5f596d; + } + :root:not([data-theme=light]) .wt-route-IndividualPage .col-sm-3 > .img-thumbnail:has(.wt-individual-silhouette-u) { + background-color: #4C566A; + } + + /* Profile picture shadow */ + :root:not([data-theme=light]) .wt-route-IndividualPage .col-sm-3 a.gallery { + box-shadow: 0 4px 8px rgba(255, 255, 255, 0.3); + } + + /* Username link */ + :root:not([data-theme=light]) .wt-route-IndividualPage .bocken-title-user a { + color: #ECEFF4; + } + /* Links */ :root:not([data-theme=light]) .wt-route-IndividualPage .wt-facts-table a, :root:not([data-theme=light]) .wt-route-IndividualPage .wt-family-navigator-family a, diff --git a/resources/views/individual-page-images.phtml b/resources/views/individual-page-images.phtml new file mode 100644 index 0000000..896abe4 --- /dev/null +++ b/resources/views/individual-page-images.phtml @@ -0,0 +1,50 @@ + $individual_media + * @var Collection $name_records + * @var Individual $record + * @var Collection $sex_records + * @var Collection $shares + * @var Collection $sidebars + * @var Collection $tabs + * @var Tree $tree + * @var string $user_link + */ +?> + +isNotEmpty() || $tree->getPreference('USE_SILHOUETTE') === '1') : ?> +
+ isEmpty()) : ?> +
+ +
+ count() === 1) : ?> + first()->displayImage(400, 400, 'contain', ['class' => 'img-thumbnail img-fluid w-100']) ?> + + + +
+