diff --git a/shaarli-pro/css/custom_views.css b/shaarli-pro/css/custom_views.css
index 959c586..6fac56a 100644
--- a/shaarli-pro/css/custom_views.css
+++ b/shaarli-pro/css/custom_views.css
@@ -542,6 +542,100 @@ body.view-notes .content-container {
color: #e8eaed;
}
+.bookmark-palette {
+ display: inline-flex;
+ align-items: center;
+ position: relative;
+}
+
+.bookmark-palette > button {
+ background: none;
+ border: none;
+ width: 34px;
+ height: 34px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--text-light, #5f6368);
+ cursor: pointer;
+ font-size: 1.1rem;
+ transition: background-color 0.2s, color 0.2s;
+}
+
+[data-theme="dark"] .bookmark-palette > button {
+ color: #9aa0a6;
+}
+
+.palette-popup {
+ display: none;
+ position: absolute;
+ left: 0;
+ bottom: calc(100% + 8px);
+ background: var(--background-secondary, #ffffff);
+ border: 1px solid rgba(0, 0, 0, 0.12);
+ border-radius: 12px;
+ padding: 10px;
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
+ z-index: 50;
+ width: max-content;
+ max-width: min(340px, calc(100vw - 32px));
+}
+
+[data-theme="dark"] .palette-popup {
+ background: #202124;
+ border-color: rgba(255, 255, 255, 0.16);
+}
+
+.palette-popup.open {
+ display: block;
+}
+
+.palette-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.palette-row + .palette-row {
+ margin-top: 10px;
+}
+
+.palette-btn {
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ border: 1px solid rgba(0, 0, 0, 0.18);
+ cursor: pointer;
+ padding: 0;
+ background-position: center bottom;
+ background-size: cover;
+}
+
+[data-theme="dark"] .palette-btn {
+ border-color: rgba(255, 255, 255, 0.22);
+}
+
+.palette-btn.is-active {
+ outline: 2px solid var(--primary-color, #2563eb);
+ outline-offset: 2px;
+}
+
+.palette-btn-bg-none {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.note-modal-color-picker {
+ position: relative;
+}
+
+.palette-popup.note-modal-palette {
+ bottom: auto;
+ top: calc(100% + 8px);
+}
+
.spacer {
flex: 1;
}
@@ -708,18 +802,12 @@ body.view-notes .content-container {
--note-card-fg: #2a2d31;
}
-[data-theme="dark"] .note-card.note-color-grey {
- background-color: #e8eaed;
- border-color: transparent;
- --note-card-fg: #2a2d31;
-}
-
.note-card.note-has-bg,
.note-modal.note-has-bg,
.link-outer.note-has-bg {
background-image: linear-gradient(rgba(0, 0, 0, 0.16), rgba(0, 0, 0, 0.16)), var(--note-bg-image);
background-size: cover;
- background-position: center;
+ background-position: center bottom;
}
.note-card .note-title,
@@ -734,642 +822,83 @@ body.view-notes .content-container {
color: var(--note-card-fg, #202124);
}
-.link-outer[class*="note-color-"] {
- color: var(--note-card-fg, #202124);
-}
-
-.link-outer.note-color-default {
- background-color: #20293a;
- border-color: transparent;
- --note-card-fg: #dbe7ff;
-}
-
-[data-theme="dark"] .link-outer.note-color-default {
- background-color: #20293a;
- border-color: transparent;
- --note-card-fg: #dbe7ff;
-}
-
-.link-outer.note-color-red {
- background-color: #f28b82;
- border-color: transparent;
- --note-card-fg: #2f1714;
-}
-
-[data-theme="dark"] .link-outer.note-color-red {
- background-color: #f28b82;
- border-color: transparent;
- --note-card-fg: #2f1714;
-}
-
-.link-outer.note-color-orange {
- background-color: #fbbc04;
- border-color: transparent;
- --note-card-fg: #3d2a00;
-}
-
-[data-theme="dark"] .link-outer.note-color-orange {
- background-color: #fbbc04;
- border-color: transparent;
- --note-card-fg: #3d2a00;
-}
-
-.link-outer.note-color-yellow {
- background-color: #fff475;
- border-color: transparent;
- --note-card-fg: #383100;
-}
-
-[data-theme="dark"] .link-outer.note-color-yellow {
- background-color: #fff475;
- border-color: transparent;
- --note-card-fg: #383100;
-}
-
-.link-outer.note-color-green {
- background-color: #ccff90;
- border-color: transparent;
- --note-card-fg: #203400;
-}
-
-[data-theme="dark"] .link-outer.note-color-green {
- background-color: #ccff90;
- border-color: transparent;
- --note-card-fg: #203400;
-}
-
-.link-outer.note-color-teal {
- background-color: #a7ffeb;
- border-color: transparent;
- --note-card-fg: #08342d;
-}
-
-[data-theme="dark"] .link-outer.note-color-teal {
- background-color: #a7ffeb;
- border-color: transparent;
- --note-card-fg: #08342d;
-}
-
-.link-outer.note-color-blue {
- background-color: #cbf0f8;
- border-color: transparent;
- --note-card-fg: #113541;
-}
-
-[data-theme="dark"] .link-outer.note-color-blue {
- background-color: #cbf0f8;
- border-color: transparent;
- --note-card-fg: #113541;
-}
-
-.link-outer.note-color-darkblue {
- background-color: #aecbfa;
- border-color: transparent;
- --note-card-fg: #102645;
-}
-
-[data-theme="dark"] .link-outer.note-color-darkblue {
- background-color: #aecbfa;
- border-color: transparent;
- --note-card-fg: #102645;
-}
-
-.link-outer.note-color-purple {
- background-color: #d7aefb;
- border-color: transparent;
- --note-card-fg: #2f1845;
-}
-
-[data-theme="dark"] .link-outer.note-color-purple {
- background-color: #d7aefb;
- border-color: transparent;
- --note-card-fg: #2f1845;
-}
-
-.link-outer.note-color-pink {
- background-color: #fdcfe8;
- border-color: transparent;
- --note-card-fg: #4a1d34;
-}
-
-[data-theme="dark"] .link-outer.note-color-pink {
- background-color: #fdcfe8;
- border-color: transparent;
- --note-card-fg: #4a1d34;
-}
-
-.link-outer.note-color-brown {
- background-color: #e6c9a8;
- border-color: transparent;
- --note-card-fg: #3c2714;
-}
-
-[data-theme="dark"] .link-outer.note-color-brown {
- background-color: #e6c9a8;
- border-color: transparent;
- --note-card-fg: #3c2714;
-}
-
-.link-outer.note-color-grey {
- background-color: #e8eaed;
- border-color: transparent;
- --note-card-fg: #2a2d31;
-}
-
-[data-theme="dark"] .link-outer.note-color-grey {
- background-color: #e8eaed;
- border-color: transparent;
- --note-card-fg: #2a2d31;
-}
-
-.link-outer[class*="note-color-"] .link-title,
-.link-outer[class*="note-color-"] .link-url,
-.link-outer[class*="note-color-"] .link-meta,
-.link-outer[class*="note-color-"] .link-description,
-.link-outer[class*="note-color-"] .link-tag a,
-.link-outer[class*="note-color-"] .link-actions a,
-.link-outer[class*="note-color-"] .link-actions button,
-.link-outer[class*="note-color-"] .bookmark-palette > button {
- color: inherit;
-}
-
-.link-actions .bookmark-palette {
- display: flex;
- align-items: center;
-}
-
-.link-actions .bookmark-palette > button {
- background: none;
- border: none;
- width: 36px;
- height: 36px;
- border-radius: 0.5rem;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 0;
- cursor: pointer;
-}
-
-.link-actions .bookmark-palette > button i {
- font-size: 1.15rem;
-}
-
-.link-actions .bookmark-palette > button:hover {
- background: rgba(255, 255, 255, 0.08);
-}
-
-.link-actions .bookmark-palette .palette-popup {
- left: 0;
- right: auto;
-}
-
-/* --- PALETTE POPUP --- */
-.palette-popup {
- position: absolute;
- bottom: 100%;
- left: 0;
- width: min(500px, 92vw);
- background: #1f232b;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
- border-radius: 12px;
- padding: 0;
- z-index: 5000;
- display: none;
- /* JS toggles this */
-}
-
-[data-theme="dark"] .palette-popup {
- background: #1f232b;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
- border: 1px solid #5f6368;
-}
-
-.palette-popup.open {
- display: block;
-}
-
-.palette-popup.open-down {
- top: calc(100% + 8px);
- bottom: auto;
-}
-
-.palette-btn {
- width: 32px;
- height: 32px;
- min-width: 32px;
- min-height: 32px;
- padding: 0;
- border-radius: 50%;
- border: 1px solid rgba(255, 255, 255, 0.18);
- cursor: pointer;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- position: relative;
- flex: 0 0 auto;
- background-position: center;
+/* --- NOTES: Vue Masonry/Grid (multi-colonnes, largeur variable) --- */
+.notes-masonry .note-card.note-has-bg {
+ /* Les cartes masonry ont des largeurs variables selon les breakpoints:
+ - >1200px: ~25% (4 colonnes)
+ - 800-1200px: ~33% (3 colonnes)
+ - 500-800px: ~50% (2 colonnes)
+ - <500px: 100% (1 colonne)
+ On utilise 'cover' avec un focus sur le centre pour garder l'essentiel visible */
background-size: cover;
+ background-position: center bottom;
+ /* Pour les petites cartes en masonry, on s'assure que l'image couvre bien */
+ min-height: 120px;
}
-.palette-btn:hover {
- border-color: rgba(255, 255, 255, 0.8);
-}
-
-[data-theme="dark"] .palette-btn {
- border-color: rgba(255, 255, 255, 0.2);
-}
-
-.palette-btn.is-active {
- outline: 2px solid #a855f7;
- outline-offset: 1px;
-}
-
-.palette-row {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 10px 12px;
- overflow-x: auto;
- flex-wrap: nowrap;
- scrollbar-width: thin;
-}
-
-.palette-row::-webkit-scrollbar {
- height: 6px;
-}
-
-.palette-row::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.24);
- border-radius: 999px;
-}
-
-.palette-row+.palette-row {
- border-top: 1px solid rgba(255, 255, 255, 0.14);
-}
-
-.palette-btn-default,
-.palette-btn-bg-none {
- background: #2b313c;
- color: #d7dce5;
- display: inline-flex;
- align-items: center;
- justify-content: center;
-}
-
-.palette-btn-default i,
-.palette-btn-bg-none i {
- font-size: 1rem;
-}
-
-/* Prevent link action generic button rules from deforming swatches in bookmark palette */
-.link-actions .palette-popup .palette-btn {
- width: 32px;
- height: 32px;
- min-width: 32px;
- min-height: 32px;
- border-radius: 50%;
- padding: 0;
- background: transparent;
- border: 1px solid rgba(255, 255, 255, 0.18);
- background-position: center;
+/* --- NOTES: Vue Liste (600px max, centré) --- */
+.notes-list-view .note-card.note-has-bg {
+ /* Vue liste: largeur fixe de 600px, cards plus larges qu'en masonry
+ On peut utiliser cover mais avec une position légèrement ajustée */
background-size: cover;
+ background-position: center bottom;
+ /* Les cards en liste sont souvent plus hautes, on adapte */
+ min-height: 100px;
}
-.link-actions .palette-popup .palette-btn:hover {
- background: transparent;
- border-color: rgba(255, 255, 255, 0.8);
+/* --- NOTES: Modal (min(720px, 92vw)) --- */
+.note-modal.note-has-bg {
+ /* Modal plus large (jusqu'à 720px), on privilégie une couverture complète
+ avec une légère obscurcissement pour la lisibilité du texte */
+ background-size: cover;
+ background-position: center bottom;
+ /* L'overlay gradient est déjà présent dans la règle de base */
}
-.link-outer.palette-open,
-.view-list .link-outer.palette-open,
-.view-compact .link-outer.palette-open {
- overflow: visible;
- z-index: 4000;
- content-visibility: visible;
- contain: none;
- contain-intrinsic-size: auto;
+/* --- BOOKMARKS: Vue Grid (minmax(320px, 1fr)) --- */
+.view-grid .link-outer.note-has-bg {
+ /* Grid bookmarks: cards de minimum 320px, layout en grille
+ Les cards sont généralement carrées ou rectangulaires selon le contenu */
+ background-size: cover;
+ background-position: center bottom;
+ /* S'assurer que le background couvre bien la card avec le padding existant */
+ background-origin: padding-box;
}
-/* --- MODAL FOR NOTE VIEW --- */
-.note-modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.6);
- z-index: 1000;
- display: flex;
- align-items: center;
- justify-content: center;
- backdrop-filter: blur(2px);
- opacity: 0;
- pointer-events: none;
- transition: opacity 0.2s;
+/* --- BOOKMARKS: Vue Liste (1 colonne, thumbnail latéral) --- */
+.view-list .link-outer.note-has-bg {
+ /* List view: cards en pleine largeur avec layout flex et thumbnail de 300px
+ On ajuste pour que le background couvre toute la hauteur malgré le thumbnail */
+ background-size: cover;
+ background-position: center bottom;
+ /* Le thumbnail a son propre mask gradient, on s'assure que le background
+ couvre bien toute la card derrière le contenu */
+ background-origin: padding-box;
}
-.note-modal-overlay.open {
- opacity: 1;
- pointer-events: auto;
+/* --- BOOKMARKS: Vue Compact (liste dense, pas de thumbnail) --- */
+.view-compact .link-outer.note-has-bg {
+ /* Compact view: cards très compactes sans thumbnail, hauteur réduite (~60px)
+ On utilise contain ou une taille spécifique pour éviter que l'image
+ soit trop étirée sur une si petite hauteur */
+ background-size: 200% auto;
+ background-position: center bottom;
+ /* Réduire l'opacité du gradient pour plus de visibilité sur petites cards */
+ background-image: linear-gradient(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.08)), var(--note-bg-image);
}
-.note-modal {
- background: var(--modal-note-bg, #7a4b00);
- color: var(--modal-note-fg, #fff2d9);
- width: min(720px, 92vw);
- max-height: 88vh;
- border-radius: 10px;
- overflow: hidden;
- box-shadow: 0 12px 32px rgba(0, 0, 0, 0.42);
- position: relative;
- display: flex;
- flex-direction: column;
- --note-scrollbar-thumb: rgba(255, 229, 170, 0.75);
- --note-separator: rgba(255, 230, 182, 0.22);
- --note-footer-bg: rgba(0, 0, 0, 0.14);
-}
-
-.note-modal.note-color-default {
- --modal-note-bg: #20293a;
- --modal-note-fg: #dbe7ff;
- --note-scrollbar-thumb: rgba(219, 231, 255, 0.45);
- --note-separator: rgba(219, 231, 255, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.08);
-}
-
-.note-modal.note-color-red {
- --modal-note-bg: #f28b82;
- --modal-note-fg: #2f1714;
- --note-scrollbar-thumb: rgba(47, 23, 20, 0.45);
- --note-separator: rgba(47, 23, 20, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.18);
-}
-
-.note-modal.note-color-orange {
- --modal-note-bg: #fbbc04;
- --modal-note-fg: #3d2a00;
- --note-scrollbar-thumb: rgba(61, 42, 0, 0.45);
- --note-separator: rgba(61, 42, 0, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-.note-modal.note-color-yellow {
- --modal-note-bg: #fff475;
- --modal-note-fg: #383100;
- --note-scrollbar-thumb: rgba(56, 49, 0, 0.45);
- --note-separator: rgba(56, 49, 0, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.24);
-}
-
-.note-modal.note-color-green {
- --modal-note-bg: #ccff90;
- --modal-note-fg: #203400;
- --note-scrollbar-thumb: rgba(32, 52, 0, 0.45);
- --note-separator: rgba(32, 52, 0, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.22);
-}
-
-.note-modal.note-color-teal {
- --modal-note-bg: #a7ffeb;
- --modal-note-fg: #08342d;
- --note-scrollbar-thumb: rgba(8, 52, 45, 0.45);
- --note-separator: rgba(8, 52, 45, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.22);
-}
-
-.note-modal.note-color-blue {
- --modal-note-bg: #cbf0f8;
- --modal-note-fg: #113541;
- --note-scrollbar-thumb: rgba(17, 53, 65, 0.45);
- --note-separator: rgba(17, 53, 65, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.22);
-}
-
-.note-modal.note-color-darkblue {
- --modal-note-bg: #aecbfa;
- --modal-note-fg: #102645;
- --note-scrollbar-thumb: rgba(16, 38, 69, 0.45);
- --note-separator: rgba(16, 38, 69, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-.note-modal.note-color-purple {
- --modal-note-bg: #d7aefb;
- --modal-note-fg: #2f1845;
- --note-scrollbar-thumb: rgba(47, 24, 69, 0.45);
- --note-separator: rgba(47, 24, 69, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-.note-modal.note-color-pink {
- --modal-note-bg: #fdcfe8;
- --modal-note-fg: #4a1d34;
- --note-scrollbar-thumb: rgba(74, 29, 52, 0.45);
- --note-separator: rgba(74, 29, 52, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-.note-modal.note-color-brown {
- --modal-note-bg: #e6c9a8;
- --modal-note-fg: #3c2714;
- --note-scrollbar-thumb: rgba(60, 39, 20, 0.45);
- --note-separator: rgba(60, 39, 20, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-.note-modal.note-color-grey {
- --modal-note-bg: #e8eaed;
- --modal-note-fg: #2a2d31;
- --note-scrollbar-thumb: rgba(42, 45, 49, 0.45);
- --note-separator: rgba(42, 45, 49, 0.2);
- --note-footer-bg: rgba(255, 255, 255, 0.2);
-}
-
-[data-theme="dark"] .note-modal {
- border: 1px solid rgba(255, 255, 255, 0.12);
-}
-
-.note-modal-header {
- display: flex;
- align-items: flex-start;
- justify-content: space-between;
- gap: 12px;
- padding: 18px 20px 10px;
- flex-shrink: 0;
-}
-
-.note-modal .note-title {
- font-size: 1.6rem;
- line-height: 1.35;
- margin: 0;
- color: inherit;
- font-weight: 500;
-}
-
-.note-modal-pin-toggle {
- background: transparent;
- border: none;
- color: inherit;
- opacity: 0.85;
- width: 34px;
- height: 34px;
- border-radius: 50%;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- flex-shrink: 0;
- transition: background-color 0.2s, opacity 0.2s;
-}
-
-.note-modal-pin-toggle i {
- font-size: 1.2rem;
-}
-
-.note-modal-pin-toggle:hover,
-.note-modal-pin-toggle.active {
- opacity: 1;
- background-color: rgba(255, 255, 255, 0.14);
-}
-
-.note-modal-content {
- flex: 1;
- overflow-y: auto;
- padding: 0 20px 18px;
- scrollbar-width: thin;
- scrollbar-color: var(--note-scrollbar-thumb) transparent;
-}
-
-.note-modal-content::-webkit-scrollbar {
- width: 10px;
-}
-
-.note-modal-content::-webkit-scrollbar-track {
- background: transparent;
-}
-
-.note-modal-content::-webkit-scrollbar-thumb {
- background: var(--note-scrollbar-thumb);
- border-radius: 10px;
- border: 2px solid transparent;
- background-clip: content-box;
-}
-
-.note-modal .note-body {
- font-size: 1rem;
- line-height: 1.75;
- display: block;
- -webkit-line-clamp: initial;
- line-clamp: initial;
- -webkit-box-orient: initial;
- max-height: none;
- overflow: visible;
- color: inherit;
-}
-
-.note-modal .note-body * {
- color: inherit;
-}
-
-.note-modal-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- padding: 10px 20px 12px;
- border-top: 1px solid var(--note-separator);
- flex-shrink: 0;
-}
-
-.note-modal-tags.is-empty {
- display: none;
-}
-
-.note-modal-tags .note-tag {
- background: rgba(255, 255, 255, 0.12);
- border: 1px solid rgba(255, 255, 255, 0.22);
- color: inherit;
- border-radius: 999px;
- padding: 4px 10px;
- font-size: 0.72rem;
- letter-spacing: 0.02em;
-}
-
-.note-modal-actions {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 10px;
- padding: 8px 12px;
- border-top: 1px solid var(--note-separator);
- background: var(--note-footer-bg);
- flex-shrink: 0;
-}
-
-.note-modal-actions-left {
- display: flex;
- align-items: center;
- gap: 2px;
- flex-wrap: wrap;
-}
-
-.note-modal-actions-left > button,
-.note-modal-actions-left > a,
-.note-modal-actions-left > .note-modal-color-picker > button {
- background: transparent;
- border: none;
- color: inherit;
- opacity: 0.9;
- width: 32px;
- height: 32px;
- border-radius: 50%;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- text-decoration: none;
- transition: background-color 0.2s, opacity 0.2s;
-}
-
-.note-modal-actions-left > button:hover,
-.note-modal-actions-left > a:hover,
-.note-modal-actions-left > .note-modal-color-picker > button:hover {
- opacity: 1;
- background: rgba(255, 255, 255, 0.14);
-}
-
-.note-modal-color-picker {
- position: relative;
- display: inline-flex;
-}
-
-.note-modal-palette {
- left: -8px;
- bottom: calc(100% + 8px);
- width: min(500px, 92vw);
-}
-
-.note-modal-close-btn {
- background: transparent;
- border: none;
- color: inherit;
- font-weight: 600;
- border-radius: 8px;
- padding: 6px 10px;
- cursor: pointer;
-}
-
-.note-modal-close-btn:hover {
- background: rgba(255, 255, 255, 0.14);
-}
-
-@media (max-width: 640px) {
- .note-modal {
- width: 96vw;
- max-height: 92vh;
+/* Responsive: sur petits écrans, ajuster les backgrounds */
+@media (max-width: 768px) {
+ /* En mobile, les cards sont plus étroites, on ajuste */
+ .notes-masonry .note-card.note-has-bg,
+ .view-grid .link-outer.note-has-bg {
+ background-size: cover;
+ background-position: center bottom;
}
-
- .note-modal .note-title {
- font-size: 1.25rem;
+
+ /* Vue liste en mobile: thumbnail passe en haut */
+ .view-list .link-outer.note-has-bg {
+ background-size: cover;
+ background-position: center bottom;
}
}
\ No newline at end of file
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-JournalDeTravail.png b/shaarli-pro/img/gg-note-bg-light/bg-JournalDeTravail.png
deleted file mode 100644
index f609893..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-JournalDeTravail.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-Radio.png b/shaarli-pro/img/gg-note-bg-light/bg-Radio.png
deleted file mode 100644
index 3967cc8..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-Radio.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-cafe.png b/shaarli-pro/img/gg-note-bg-light/bg-cafe.png
deleted file mode 100644
index f242566..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-cafe.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-cerisier.png b/shaarli-pro/img/gg-note-bg-light/bg-cerisier.png
deleted file mode 100644
index 752deea..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-cerisier.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-codes.png b/shaarli-pro/img/gg-note-bg-light/bg-codes.png
deleted file mode 100644
index aee42a8..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-codes.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-feuilleLigne.png b/shaarli-pro/img/gg-note-bg-light/bg-feuilleLigne.png
deleted file mode 100644
index 9839d52..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-feuilleLigne.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-feuilleQuadrille.png b/shaarli-pro/img/gg-note-bg-light/bg-feuilleQuadrille.png
deleted file mode 100644
index cfe48aa..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-feuilleQuadrille.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-foret.png b/shaarli-pro/img/gg-note-bg-light/bg-foret.png
deleted file mode 100644
index b1f2cb9..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-foret.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-legumes.png b/shaarli-pro/img/gg-note-bg-light/bg-legumes.png
deleted file mode 100644
index 6c13c80..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-legumes.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-livres.png b/shaarli-pro/img/gg-note-bg-light/bg-livres.png
deleted file mode 100644
index b19dedc..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-livres.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-montagnes.png b/shaarli-pro/img/gg-note-bg-light/bg-montagnes.png
deleted file mode 100644
index 391bfbe..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-montagnes.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-ocean.png b/shaarli-pro/img/gg-note-bg-light/bg-ocean.png
deleted file mode 100644
index bbd82a7..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-ocean.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-vague1.png b/shaarli-pro/img/gg-note-bg-light/bg-vague1.png
deleted file mode 100644
index 52b9c21..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-vague1.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-vague2.png b/shaarli-pro/img/gg-note-bg-light/bg-vague2.png
deleted file mode 100644
index e298490..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-vague2.png and /dev/null differ
diff --git a/shaarli-pro/img/gg-note-bg-light/bg-valise.png b/shaarli-pro/img/gg-note-bg-light/bg-valise.png
deleted file mode 100644
index d6fb139..0000000
Binary files a/shaarli-pro/img/gg-note-bg-light/bg-valise.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/README.md b/shaarli-pro/img/note-backgrounds/README.md
deleted file mode 100644
index 58c1ac1..0000000
--- a/shaarli-pro/img/note-backgrounds/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Note backgrounds (Shaarli Pro)
-
-Ce dossier contient les images de fond utilisées par la palette des notes (`notebg-*`).
-
-## Fichiers attendus
-
-Le thème référence actuellement ces fichiers :
-
-- `bg-canyon.png`
-- `bg-leaves.png`
-- `bg-shore.png`
-- `bg-sunset.png`
-- `bg-planet.png`
-- `bg-crystal.png`
-- `bg-orchid.png`
-- `bg-lake.png`
-- `bg-ladder.png`
-- `bg-burst.png`
-
-## Formats recommandés
-
-- **SVG** (idéal pour motifs/illustrations légères)
-- **JPG / JPEG** (photos)
-- **PNG** (illustrations avec transparence)
-- **WEBP** (poids réduit, recommandé)
-
-## Conseils d'image
-
-- Ratio conseillé: **16:9** ou **4:3**
-- Taille conseillée: entre **1200x800** et **1920x1080**
-- Poids conseillé: **< 500 KB** par image pour garder l'interface fluide
-- Privilégier des visuels **peu chargés** pour conserver la lisibilité du texte
-
-Si vous remplacez une image, conservez le même nom de fichier pour qu'elle apparaisse automatiquement dans la palette.
diff --git a/shaarli-pro/img/note-backgrounds/bg-burst.png b/shaarli-pro/img/note-backgrounds/bg-burst.png
deleted file mode 100644
index 71c144d..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-burst.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-canyon.png b/shaarli-pro/img/note-backgrounds/bg-canyon.png
deleted file mode 100644
index 5149df4..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-canyon.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-crystal.png b/shaarli-pro/img/note-backgrounds/bg-crystal.png
deleted file mode 100644
index ca143c3..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-crystal.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-ladder.png b/shaarli-pro/img/note-backgrounds/bg-ladder.png
deleted file mode 100644
index b65c490..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-ladder.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-lake.png b/shaarli-pro/img/note-backgrounds/bg-lake.png
deleted file mode 100644
index b822f2a..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-lake.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-leaves.png b/shaarli-pro/img/note-backgrounds/bg-leaves.png
deleted file mode 100644
index a2e2965..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-leaves.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-orchid.png b/shaarli-pro/img/note-backgrounds/bg-orchid.png
deleted file mode 100644
index 1d2fc98..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-orchid.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-planet.png b/shaarli-pro/img/note-backgrounds/bg-planet.png
deleted file mode 100644
index 6047b81..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-planet.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-shore.png b/shaarli-pro/img/note-backgrounds/bg-shore.png
deleted file mode 100644
index ca3f510..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-shore.png and /dev/null differ
diff --git a/shaarli-pro/img/note-backgrounds/bg-sunset.png b/shaarli-pro/img/note-backgrounds/bg-sunset.png
deleted file mode 100644
index f0224d9..0000000
Binary files a/shaarli-pro/img/note-backgrounds/bg-sunset.png and /dev/null differ
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_cafe.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-cafe.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_cafe.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-cafe.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_codes.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-codes.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_codes.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-codes.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_dune.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-dune.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_dune.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-dune.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_feuilleLigne.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-feuilleLigne.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_feuilleLigne.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-feuilleLigne.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_feuilleQuadrille.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-feuilleQuadrille.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_feuilleQuadrille.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-feuilleQuadrille.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_fleurs.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-fleurs.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_fleurs.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-fleurs.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_foret.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-foret.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_foret.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-foret.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_grid.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-grid.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_grid.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-grid.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_JournalDeTravail.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-journal.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_JournalDeTravail.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-journal.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_livres.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-lecture.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_livres.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-lecture.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_legumes.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-legumes.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_legumes.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-legumes.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_montagnes.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-montagnes.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_montagnes.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-montagnes.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_ocean.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-ocean.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_ocean.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-ocean.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_sports.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-sports.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_sports.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-sports.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_vague1.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-vague1.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_vague1.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-vague1.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_vague2.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-vague2.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_vague2.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-vague2.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_ville.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-ville.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_ville.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-ville.jpg
diff --git a/shaarli-pro/img/note-bg-dark/bg-Dark_voyages.jpg b/shaarli-pro/img/note-bg-dark/bg-dark-voyage.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-dark/bg-Dark_voyages.jpg
rename to shaarli-pro/img/note-bg-dark/bg-dark-voyage.jpg
diff --git a/shaarli-pro/img/note-bg-light/bg-light-dune.jpg b/shaarli-pro/img/note-bg-light/bg-light-dune.jpg
new file mode 100644
index 0000000..23d21f5
Binary files /dev/null and b/shaarli-pro/img/note-bg-light/bg-light-dune.jpg differ
diff --git a/shaarli-pro/img/note-bg-light/bg-light-feuilleLignes.jpg b/shaarli-pro/img/note-bg-light/bg-light-feuilleLigne.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-light/bg-light-feuilleLignes.jpg
rename to shaarli-pro/img/note-bg-light/bg-light-feuilleLigne.jpg
diff --git a/shaarli-pro/img/note-bg-light/bg-light-feuilleQuadrilles.jpg b/shaarli-pro/img/note-bg-light/bg-light-feuilleQuadrille.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-light/bg-light-feuilleQuadrilles.jpg
rename to shaarli-pro/img/note-bg-light/bg-light-feuilleQuadrille.jpg
diff --git a/shaarli-pro/img/note-bg-light/bg-light-fleur.jpg b/shaarli-pro/img/note-bg-light/bg-light-fleurs.jpg
similarity index 100%
rename from shaarli-pro/img/note-bg-light/bg-light-fleur.jpg
rename to shaarli-pro/img/note-bg-light/bg-light-fleurs.jpg
diff --git a/shaarli-pro/img/note-bg-light/bg-light-grid.jpg b/shaarli-pro/img/note-bg-light/bg-light-grid.jpg
new file mode 100644
index 0000000..d9a1928
Binary files /dev/null and b/shaarli-pro/img/note-bg-light/bg-light-grid.jpg differ
diff --git a/shaarli-pro/img/note-bg-light/bg-light-sports.jpg b/shaarli-pro/img/note-bg-light/bg-light-sports.jpg
new file mode 100644
index 0000000..3320c62
Binary files /dev/null and b/shaarli-pro/img/note-bg-light/bg-light-sports.jpg differ
diff --git a/shaarli-pro/img/note-bg-light/bg-light-ville.jpg b/shaarli-pro/img/note-bg-light/bg-light-ville.jpg
new file mode 100644
index 0000000..d586b31
Binary files /dev/null and b/shaarli-pro/img/note-bg-light/bg-light-ville.jpg differ
diff --git a/shaarli-pro/includes.html b/shaarli-pro/includes.html
index f990884..877c3f3 100644
--- a/shaarli-pro/includes.html
+++ b/shaarli-pro/includes.html
@@ -61,8 +61,8 @@ visibility: '{$visibility}',
untaggedonly: {if="$untaggedonly"}true{else}false{/if}
};
-
-
+
+
{if="file_exists('tpl/shaarli-pro/extra.html')"}
{include="extra"}
diff --git a/shaarli-pro/js/backgrounds-manifest.js b/shaarli-pro/js/backgrounds-manifest.js
new file mode 100644
index 0000000..55f4d0f
--- /dev/null
+++ b/shaarli-pro/js/backgrounds-manifest.js
@@ -0,0 +1,146 @@
+window.SHAARLI_NOTE_BACKGROUNDS_MANIFEST = [
+ {
+ key: "cafe",
+ label: "Café",
+ files: {
+ light: "bg-light-cafe.jpg",
+ dark: "bg-dark-cafe.jpg",
+ },
+ },
+ {
+ key: "codes",
+ label: "Codes",
+ files: {
+ light: "bg-light-codes.jpg",
+ dark: "bg-dark-codes.jpg",
+ },
+ },
+ {
+ key: "dune",
+ label: "Dune",
+ files: {
+ light: "bg-light-dune.jpg",
+ dark: "bg-dark-dune.jpg",
+ },
+ },
+ {
+ key: "feuille-ligne",
+ label: "Feuille Ligne",
+ files: {
+ light: "bg-light-feuilleLigne.jpg",
+ dark: "bg-dark-feuilleLigne.jpg",
+ },
+ },
+ {
+ key: "feuille-quadrillage",
+ label: "Feuille Quadrillage",
+ files: {
+ light: "bg-light-feuilleQuadrille.jpg",
+ dark: "bg-dark-feuilleQuadrille.jpg",
+ },
+ },
+ {
+ key: "fleurs",
+ label: "Fleurs",
+ files: {
+ light: "bg-light-fleurs.jpg",
+ dark: "bg-dark-fleurs.jpg",
+ },
+ },
+ {
+ key: "foret",
+ label: "Forêt",
+ files: {
+ light: "bg-light-foret.jpg",
+ dark: "bg-dark-foret.jpg",
+ },
+ },
+ {
+ key: "grid",
+ label: "Grid",
+ files: {
+ light: "bg-light-grid.jpg",
+ dark: "bg-dark-grid.jpg",
+ },
+ },
+ {
+ key: "journal",
+ label: "Journal",
+ files: {
+ light: "bg-light-journal.jpg",
+ dark: "bg-dark-journal.jpg",
+ },
+ },
+ {
+ key: "lecture",
+ label: "Lecture",
+ files: {
+ light: "bg-light-lecture.jpg",
+ dark: "bg-dark-lecture.jpg",
+ },
+ },
+ {
+ key: "legumes",
+ label: "Légumes",
+ files: {
+ light: "bg-light-legumes.jpg",
+ dark: "bg-dark-legumes.jpg",
+ },
+ },
+ {
+ key: "montagnes",
+ label: "Montagnes",
+ files: {
+ light: "bg-light-montagnes.jpg",
+ dark: "bg-dark-montagnes.jpg",
+ },
+ },
+ {
+ key: "ocean",
+ label: "Océan",
+ files: {
+ light: "bg-light-ocean.jpg",
+ dark: "bg-dark-ocean.jpg",
+ },
+ },
+ {
+ key: "sports",
+ label: "Sports",
+ files: {
+ light: "bg-light-sports.jpg",
+ dark: "bg-dark-sports.jpg",
+ },
+ },
+ {
+ key: "vague1",
+ label: "Vague 1",
+ files: {
+ light: "bg-light-vague1.jpg",
+ dark: "bg-dark-vague1.jpg",
+ },
+ },
+ {
+ key: "vague2",
+ label: "Vague 2",
+ files: {
+ light: "bg-light-vague2.jpg",
+ dark: "bg-dark-vague2.jpg",
+ },
+ },
+ {
+ key: "ville",
+ label: "Ville",
+ files: {
+ light: "bg-light-ville.jpg",
+ dark: "bg-dark-ville.jpg",
+ },
+ },
+ {
+ key: "voyage",
+ label: "Voyage",
+ files: {
+ light: "bg-light-voyage.jpg",
+ dark: "bg-dark-voyage.jpg",
+ },
+ },
+];
diff --git a/shaarli-pro/js/backgrounds-manifest.json b/shaarli-pro/js/backgrounds-manifest.json
new file mode 100644
index 0000000..17536df
--- /dev/null
+++ b/shaarli-pro/js/backgrounds-manifest.json
@@ -0,0 +1,146 @@
+[
+ {
+ "key": "cafe",
+ "label": "Café",
+ "files": {
+ "light": "bg-light-cafe.jpg",
+ "dark": "bg-dark-cafe.jpg"
+ }
+ },
+ {
+ "key": "codes",
+ "label": "Codes",
+ "files": {
+ "light": "bg-light-codes.jpg",
+ "dark": "bg-dark-codes.jpg"
+ }
+ },
+ {
+ "key": "dune",
+ "label": "Dune",
+ "files": {
+ "light": "bg-light-dune.jpg",
+ "dark": "bg-dark-dune.jpg"
+ }
+ },
+ {
+ "key": "feuille-ligne",
+ "label": "Feuille Ligne",
+ "files": {
+ "light": "bg-light-feuilleLigne.jpg",
+ "dark": "bg-dark-feuilleLigne.jpg"
+ }
+ },
+ {
+ "key": "feuille-quadrillage",
+ "label": "Feuille Quadrillage",
+ "files": {
+ "light": "bg-light-feuilleQuadrille.jpg",
+ "dark": "bg-dark-feuilleQuadrille.jpg"
+ }
+ },
+ {
+ "key": "fleurs",
+ "label": "Fleurs",
+ "files": {
+ "light": "bg-light-fleurs.jpg",
+ "dark": "bg-dark-fleurs.jpg"
+ }
+ },
+ {
+ "key": "foret",
+ "label": "Forêt",
+ "files": {
+ "light": "bg-light-foret.jpg",
+ "dark": "bg-dark-foret.jpg"
+ }
+ },
+ {
+ "key": "grid",
+ "label": "Grid",
+ "files": {
+ "light": "bg-light-grid.jpg",
+ "dark": "bg-dark-grid.jpg"
+ }
+ },
+ {
+ "key": "journal",
+ "label": "Journal",
+ "files": {
+ "light": "bg-light-journal.jpg",
+ "dark": "bg-dark-journal.jpg"
+ }
+ },
+ {
+ "key": "lecture",
+ "label": "Lecture",
+ "files": {
+ "light": "bg-light-lecture.jpg",
+ "dark": "bg-dark-lecture.jpg"
+ }
+ },
+ {
+ "key": "legumes",
+ "label": "Légumes",
+ "files": {
+ "light": "bg-light-legumes.jpg",
+ "dark": "bg-dark-legumes.jpg"
+ }
+ },
+ {
+ "key": "montagnes",
+ "label": "Montagnes",
+ "files": {
+ "light": "bg-light-montagnes.jpg",
+ "dark": "bg-dark-montagnes.jpg"
+ }
+ },
+ {
+ "key": "ocean",
+ "label": "Océan",
+ "files": {
+ "light": "bg-light-ocean.jpg",
+ "dark": "bg-dark-ocean.jpg"
+ }
+ },
+ {
+ "key": "sports",
+ "label": "Sports",
+ "files": {
+ "light": "bg-light-sports.jpg",
+ "dark": "bg-dark-sports.jpg"
+ }
+ },
+ {
+ "key": "vague1",
+ "label": "Vague 1",
+ "files": {
+ "light": "bg-light-vague1.jpg",
+ "dark": "bg-dark-vague1.jpg"
+ }
+ },
+ {
+ "key": "vague2",
+ "label": "Vague 2",
+ "files": {
+ "light": "bg-light-vague2.jpg",
+ "dark": "bg-dark-vague2.jpg"
+ }
+ },
+ {
+ "key": "ville",
+ "label": "Ville",
+ "files": {
+ "light": "bg-light-ville.jpg",
+ "dark": "bg-dark-ville.jpg"
+ }
+ },
+ {
+ "key": "voyage",
+ "label": "Voyage",
+ "files": {
+ "light": "bg-light-voyage.jpg",
+ "dark": "bg-dark-voyage.jpg"
+ }
+ }
+]
diff --git a/shaarli-pro/js/custom_views.js b/shaarli-pro/js/custom_views.js
index 89cd0bd..568b454 100644
--- a/shaarli-pro/js/custom_views.js
+++ b/shaarli-pro/js/custom_views.js
@@ -6,38 +6,117 @@ document.addEventListener("DOMContentLoaded", function () {
const linkList = document.getElementById("links-list");
const container = document.querySelector(".content-container");
- if (typeof initBookmarkPaletteButtons === "function") {
- initBookmarkPaletteButtons();
- }
+ const startViewInitialization = function () {
+ if (typeof initBookmarkPaletteButtons === "function") {
+ initBookmarkPaletteButtons();
+ }
- // Always init Pinned Items logic (sorting and listeners)
- // This function is defined at the end of the file
- if (typeof initPinnedItems === "function") {
- initPinnedItems();
- }
+ // Always init Pinned Items logic (sorting and listeners)
+ // This function is defined at the end of the file
+ if (typeof initPinnedItems === "function") {
+ initPinnedItems();
+ }
- if (!linkList || !container) return;
+ if (!linkList || !container) return;
- if (searchTags === "todo") {
- initTodoView(linkList, container);
- } else if (searchTags === "note") {
- initNoteView(linkList, container);
+ if (searchTags === "todo") {
+ initTodoView(linkList, container);
+ } else if (searchTags === "note") {
+ initNoteView(linkList, container);
+ }
+ };
+
+ // Charger les backgrounds dynamiquement, puis initialiser les vues
+ initThemeModeBackgroundSync();
+
+ if (typeof loadBackgroundOptions === "function") {
+ loadBackgroundOptions()
+ .then(() => {
+ startViewInitialization();
+ })
+ .catch((err) => {
+ console.error("Erreur lors du chargement des backgrounds:", err);
+ // Initialiser quand même même si le chargement échoue
+ startViewInitialization();
+ });
+ } else {
+ startViewInitialization();
}
});
const NOTE_COLOR_OPTIONS = [
- { key: "default", label: "Par défaut", hex: "#20293A" },
- { key: "red", label: "Rouge", hex: "#f28b82" },
- { key: "orange", label: "Orange", hex: "#fbbc04" },
- { key: "yellow", label: "Jaune", hex: "#fff475" },
- { key: "green", label: "Vert", hex: "#ccff90" },
- { key: "teal", label: "Menthe", hex: "#a7ffeb" },
- { key: "blue", label: "Bleu clair", hex: "#cbf0f8" },
- { key: "darkblue", label: "Bleu", hex: "#aecbfa" },
- { key: "purple", label: "Violet", hex: "#d7aefb" },
- { key: "pink", label: "Rose", hex: "#fdcfe8" },
- { key: "brown", label: "Beige", hex: "#e6c9a8" },
- { key: "grey", label: "Gris", hex: "#e8eaed" },
+ {
+ key: "default",
+ label: "Par défaut",
+ light: "#ffffff",
+ dark: "#20293A"
+ },
+ {
+ key: "red",
+ label: "Rouge",
+ light: "#f28b82",
+ dark: "#9c2116"
+ },
+ {
+ key: "orange",
+ label: "Orange",
+ light: "#fbbc04",
+ dark: "#9c7a16"
+ },
+ {
+ key: "yellow",
+ label: "Jaune",
+ light: "#fff475",
+ dark: "#9c9116"
+ },
+ {
+ key: "green",
+ label: "Vert",
+ light: "#ccff90",
+ dark: "#5e9c16"
+ },
+ {
+ key: "teal",
+ label: "Menthe",
+ light: "#a7ffeb",
+ dark: "#169c7d"
+ },
+ {
+ key: "blue",
+ label: "Bleu clair",
+ light: "#cbf0f8",
+ dark: "#16849c"
+ },
+ {
+ key: "darkblue",
+ label: "Bleu",
+ light: "#aecbfa",
+ dark: "#16499c"
+ },
+ {
+ key: "purple",
+ label: "Violet",
+ light: "#d7aefb",
+ dark: "#5d169c"
+ },
+ {
+ key: "pink",
+ label: "Rose",
+ light: "#fdcfe8",
+ dark: "#9c165f"
+ },
+ {
+ key: "brown",
+ label: "Beige",
+ light: "#e6c9a8",
+ dark: "#9c5d16"
+ },
+ {
+ key: "grey",
+ label: "Gris",
+ light: "#e8eaed",
+ dark: "#4e5764"
+ }
];
const NOTE_BACKGROUND_TAG_PREFIX = "notebg-";
@@ -68,25 +147,325 @@ function resolveThemeAssetBasePath() {
return "/tpl/shaarli-pro";
}
-const NOTE_BACKGROUND_BASE_PATH = `${resolveThemeAssetBasePath().replace(/\/$/, "")}/img/note-backgrounds`;
-const NOTE_BACKGROUND_OPTIONS = [
- { key: "bg-canyon", label: "Canyon", file: "bg-canyon.png" },
- { key: "bg-leaves", label: "Feuilles", file: "bg-leaves.png" },
- { key: "bg-shore", label: "Rivage", file: "bg-shore.png" },
- { key: "bg-sunset", label: "Coucher", file: "bg-sunset.png" },
- { key: "bg-planet", label: "Planète", file: "bg-planet.png" },
- { key: "bg-crystal", label: "Cristal", file: "bg-crystal.png" },
- { key: "bg-orchid", label: "Orchidée", file: "bg-orchid.png" },
- { key: "bg-lake", label: "Lac", file: "bg-lake.png" },
- { key: "bg-ladder", label: "Échelle", file: "bg-ladder.png" },
- { key: "bg-burst", label: "Étoile", file: "bg-burst.png" },
+const NOTE_BACKGROUND_ASSET_ROOT = `${resolveThemeAssetBasePath().replace(/\/$/, "")}/img`;
+
+// Liste des backgrounds - chargée dynamiquement depuis le serveur
+let NOTE_BACKGROUND_OPTIONS = [];
+let isBackgroundOptionsLoaded = false;
+let backgroundOptionsLoadPromise = null;
+
+window.__shaarliCustomViewsVersion = "1.0.5-inline-bg-manifest";
+if (typeof console !== "undefined" && console && typeof console.info === "function") {
+ console.info("[custom_views] loaded", window.__shaarliCustomViewsVersion);
+}
+
+const NOTE_BACKGROUND_MANIFEST_INLINE = [
+ { key: "cafe", label: "Café", files: { light: "bg-light-cafe.jpg", dark: "bg-dark-cafe.jpg" } },
+ { key: "codes", label: "Codes", files: { light: "bg-light-codes.jpg", dark: "bg-dark-codes.jpg" } },
+ { key: "dune", label: "Dune", files: { light: "bg-light-dune.jpg", dark: "bg-dark-dune.jpg" } },
+ { key: "feuille-ligne", label: "Feuille Ligne", files: { light: "bg-light-feuilleLigne.jpg", dark: "bg-dark-feuilleLigne.jpg" } },
+ { key: "feuille-quadrillage", label: "Feuille Quadrillage", files: { light: "bg-light-feuilleQuadrille.jpg", dark: "bg-dark-feuilleQuadrille.jpg" } },
+ { key: "fleurs", label: "Fleurs", files: { light: "bg-light-fleurs.jpg", dark: "bg-dark-fleurs.jpg" } },
+ { key: "foret", label: "Forêt", files: { light: "bg-light-foret.jpg", dark: "bg-dark-foret.jpg" } },
+ { key: "grid", label: "Grid", files: { light: "bg-light-grid.jpg", dark: "bg-dark-grid.jpg" } },
+ { key: "journal", label: "Journal", files: { light: "bg-light-journal.jpg", dark: "bg-dark-journal.jpg" } },
+ { key: "lecture", label: "Lecture", files: { light: "bg-light-lecture.jpg", dark: "bg-dark-lecture.jpg" } },
+ { key: "legumes", label: "Légumes", files: { light: "bg-light-legumes.jpg", dark: "bg-dark-legumes.jpg" } },
+ { key: "montagnes", label: "Montagnes", files: { light: "bg-light-montagnes.jpg", dark: "bg-dark-montagnes.jpg" } },
+ { key: "ocean", label: "Océan", files: { light: "bg-light-ocean.jpg", dark: "bg-dark-ocean.jpg" } },
+ { key: "sports", label: "Sports", files: { light: "bg-light-sports.jpg", dark: "bg-dark-sports.jpg" } },
+ { key: "vague1", label: "Vague 1", files: { light: "bg-light-vague1.jpg", dark: "bg-dark-vague1.jpg" } },
+ { key: "vague2", label: "Vague 2", files: { light: "bg-light-vague2.jpg", dark: "bg-dark-vague2.jpg" } },
+ { key: "ville", label: "Ville", files: { light: "bg-light-ville.jpg", dark: "bg-dark-ville.jpg" } },
+ { key: "voyage", label: "Voyage", files: { light: "bg-light-voyage.jpg", dark: "bg-dark-voyage.jpg" } },
];
-function getNoteBackgroundUrl(backgroundKey) {
- const found = NOTE_BACKGROUND_OPTIONS.find((bg) => bg.key === backgroundKey);
- if (!found) return "";
+/**
+ * Charge la liste des backgrounds depuis le endpoint PHP
+ * @returns {Promise} Liste des backgrounds
+ */
+function loadBackgroundOptions() {
+ if (isBackgroundOptionsLoaded) {
+ return Promise.resolve(NOTE_BACKGROUND_OPTIONS);
+ }
- return `${NOTE_BACKGROUND_BASE_PATH}/${found.file}`;
+ if (backgroundOptionsLoadPromise) {
+ return backgroundOptionsLoadPromise;
+ }
+
+ NOTE_BACKGROUND_OPTIONS = normalizeDynamicBackgroundOptions(NOTE_BACKGROUND_MANIFEST_INLINE);
+ isBackgroundOptionsLoaded = true;
+ backgroundOptionsLoadPromise = Promise.resolve(NOTE_BACKGROUND_OPTIONS);
+ return backgroundOptionsLoadPromise;
+}
+
+function normalizeBackgroundKey(key) {
+ if (typeof key !== "string") return "";
+
+ return key
+ .trim()
+ .toLowerCase()
+ .replace(/[\s_]+/g, "-")
+ .replace(/[^a-z0-9-]/g, "-")
+ .replace(/-+/g, "-")
+ .replace(/^-|-$/g, "");
+}
+
+function formatBackgroundLabel(rawLabel, fallbackKey) {
+ const base = (typeof rawLabel === "string" && rawLabel.trim() !== "" ? rawLabel : fallbackKey)
+ .replace(/[_-]+/g, " ")
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
+ .replace(/\s+/g, " ")
+ .trim();
+
+ return base
+ .split(" ")
+ .filter((part) => part !== "")
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
+ .join(" ");
+}
+
+function getCurrentThemeMode() {
+ return document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
+}
+
+function getColorOption(colorKey) {
+ const normalizedKey = typeof colorKey === "string" ? colorKey.trim().toLowerCase() : "";
+
+ return NOTE_COLOR_OPTIONS.find((opt) => opt.key === normalizedKey) || NOTE_COLOR_OPTIONS.find((opt) => opt.key === "default") || null;
+}
+
+function getThemeColorValue(option, mode = getCurrentThemeMode()) {
+ if (!option || typeof option !== "object") return "";
+
+ const safeMode = mode === "dark" ? "dark" : "light";
+ const preferred = typeof option[safeMode] === "string" ? option[safeMode].trim() : "";
+ const fallbackLight = typeof option.light === "string" ? option.light.trim() : "";
+ const fallbackDark = typeof option.dark === "string" ? option.dark.trim() : "";
+
+ return preferred || fallbackLight || fallbackDark;
+}
+
+function parseHexColor(colorValue) {
+ if (typeof colorValue !== "string") return null;
+
+ const safeValue = colorValue.trim();
+ const shortHexMatch = /^#([0-9a-f]{3})$/i.exec(safeValue);
+ if (shortHexMatch) {
+ return {
+ r: parseInt(shortHexMatch[1].charAt(0).repeat(2), 16),
+ g: parseInt(shortHexMatch[1].charAt(1).repeat(2), 16),
+ b: parseInt(shortHexMatch[1].charAt(2).repeat(2), 16),
+ };
+ }
+
+ const longHexMatch = /^#([0-9a-f]{6})$/i.exec(safeValue);
+ if (longHexMatch) {
+ return {
+ r: parseInt(longHexMatch[1].slice(0, 2), 16),
+ g: parseInt(longHexMatch[1].slice(2, 4), 16),
+ b: parseInt(longHexMatch[1].slice(4, 6), 16),
+ };
+ }
+
+ return null;
+}
+
+function getReadableForegroundForBackground(colorValue, mode = getCurrentThemeMode()) {
+ const rgb = parseHexColor(colorValue);
+ if (!rgb) {
+ return mode === "dark" ? "#e8eaed" : "#202124";
+ }
+
+ const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
+ return luminance > 0.56 ? "#202124" : "#f5f7fb";
+}
+
+function normalizeDynamicBackgroundOptions(rawOptions) {
+ const rawList = Array.isArray(rawOptions)
+ ? rawOptions
+ : rawOptions && Array.isArray(rawOptions.backgrounds)
+ ? rawOptions.backgrounds
+ : [];
+
+ const mergedByKey = {};
+
+ rawList.forEach((option) => {
+ if (!option || typeof option !== "object") return;
+
+ const key = normalizeBackgroundKey(typeof option.key === "string" ? option.key : option.label || "");
+ if (!key) return;
+
+ const files = option.files && typeof option.files === "object" ? option.files : {};
+ const lightFile = typeof files.light === "string" ? files.light.trim() : "";
+ const darkFile = typeof files.dark === "string" ? files.dark.trim() : "";
+ if (!lightFile && !darkFile) return;
+
+ if (!mergedByKey[key]) {
+ mergedByKey[key] = {
+ key,
+ label: formatBackgroundLabel(option.label || "", key),
+ paths: {
+ light: "",
+ dark: "",
+ },
+ };
+ }
+
+ if (lightFile) {
+ mergedByKey[key].paths.light = `note-bg-light/${lightFile}`;
+ }
+ if (darkFile) {
+ mergedByKey[key].paths.dark = `note-bg-dark/${darkFile}`;
+ }
+ });
+
+ return Object.values(mergedByKey).sort((a, b) => a.label.localeCompare(b.label, "fr", { sensitivity: "base" }));
+}
+
+function getAvailableBackgroundOptionsForMode(mode = getCurrentThemeMode()) {
+ const safeMode = mode === "dark" ? "dark" : "light";
+ return NOTE_BACKGROUND_OPTIONS.filter((option) => option.paths && option.paths[safeMode]);
+}
+
+function getNoteBackgroundUrl(backgroundKey, mode = getCurrentThemeMode()) {
+ const normalizedKey = normalizeBackgroundKey(backgroundKey);
+ if (!normalizedKey) return "";
+
+ const found = NOTE_BACKGROUND_OPTIONS.find((bg) => bg.key === normalizedKey);
+ if (!found || !found.paths) return "";
+
+ const safeMode = mode === "dark" ? "dark" : "light";
+ const selectedPath = found.paths[safeMode] || "";
+
+ if (!selectedPath) return "";
+ return `${NOTE_BACKGROUND_ASSET_ROOT}/${selectedPath}`;
+}
+
+function getElementVisualColor(element) {
+ if (!element) return "default";
+
+ const colorClass = Array.from(element.classList).find((cls) => cls.startsWith("note-color-"));
+ if (colorClass) {
+ return colorClass.replace("note-color-", "") || "default";
+ }
+
+ return element.dataset.color || "default";
+}
+
+function getElementVisualBackground(element) {
+ if (!element) return "none";
+
+ const normalizedBackground = normalizeBackgroundKey(element.dataset.background || "");
+ return normalizedBackground || "none";
+}
+
+function refreshNoteBackgroundVisuals() {
+ document.querySelectorAll(".note-card, .note-modal, .link-outer").forEach((element) => {
+ applyNoteVisualState(element, {
+ color: getElementVisualColor(element),
+ background: getElementVisualBackground(element),
+ });
+ });
+}
+
+function refreshBackgroundPalettes() {
+ document.querySelectorAll(".note-card").forEach((card) => {
+ const palettePopup = card.querySelector(".note-hover-actions .palette-popup");
+ if (!palettePopup) return;
+
+ const noteId = card.dataset.id || "";
+ if (!noteId) return;
+
+ const editLink = card.querySelector(
+ '.note-hover-actions a[href*="/admin/shaare/"], .note-hover-actions a[href*="do=editlink"], .note-hover-actions a[title="Edit"]',
+ );
+
+ palettePopup.innerHTML = generatePaletteButtons({
+ id: noteId,
+ editUrl: editLink && editLink.href ? editLink.href : "#",
+ color: getElementVisualColor(card),
+ background: getElementVisualBackground(card),
+ });
+ });
+
+ document.querySelectorAll(".link-outer").forEach((card) => {
+ const palettePopup = card.querySelector(".bookmark-palette .palette-popup");
+ if (!palettePopup) return;
+
+ const noteId = card.dataset.id || card.getAttribute("data-id") || card.id;
+ if (!noteId) return;
+
+ const actions = card.querySelector(".link-actions");
+ const editLink = actions
+ ? actions.querySelector('a[title="Modifier"], a[aria-label="Modifier ce bookmark"], a[href*="/admin/shaare/"]')
+ : null;
+
+ palettePopup.innerHTML = generateBookmarkPaletteButtons(
+ noteId,
+ editLink && editLink.href ? editLink.href : "#",
+ getElementVisualColor(card),
+ getElementVisualBackground(card),
+ );
+ });
+
+ const modal = document.querySelector(".note-modal-overlay");
+ if (!modal || !modal.currentNote) return;
+
+ const modalCard = modal.querySelector(".note-modal");
+ if (modalCard) {
+ modal.currentNote.color = getElementVisualColor(modalCard);
+ modal.currentNote.background = getElementVisualBackground(modalCard);
+ }
+
+ const modalColorPopup = modal.querySelector("#note-modal-color-popup");
+ if (modalColorPopup) {
+ modalColorPopup.innerHTML = generateModalPaletteButtons(modal.currentNote);
+ }
+}
+
+function parseBackgroundManifestPayload(rawPayload) {
+ const payload = typeof rawPayload === "string" ? rawPayload.trim() : "";
+ if (!payload) return [];
+
+ try {
+ return JSON.parse(payload);
+ } catch (parseError) {
+ const firstArrayBracket = payload.indexOf("[");
+ const lastArrayBracket = payload.lastIndexOf("]");
+ if (firstArrayBracket === -1 || lastArrayBracket === -1 || lastArrayBracket <= firstArrayBracket) {
+ throw parseError;
+ }
+
+ const jsonSlice = payload.slice(firstArrayBracket, lastArrayBracket + 1);
+ return JSON.parse(jsonSlice);
+ }
+}
+
+
+let isThemeModeBackgroundSyncInitialized = false;
+
+function initThemeModeBackgroundSync() {
+ if (isThemeModeBackgroundSyncInitialized) return;
+
+ const root = document.documentElement;
+ if (!root) return;
+
+ let lastTheme = getCurrentThemeMode();
+ const observer = new MutationObserver((mutations) => {
+ const themeChanged = mutations.some((mutation) => mutation.attributeName === "data-theme");
+ if (!themeChanged) return;
+
+ const nextTheme = getCurrentThemeMode();
+ if (nextTheme === lastTheme) return;
+
+ lastTheme = nextTheme;
+ refreshNoteBackgroundVisuals();
+ refreshBackgroundPalettes();
+ });
+
+ observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
+ isThemeModeBackgroundSyncInitialized = true;
}
function positionPalettePopup(popup) {
@@ -123,14 +502,29 @@ function positionPalettePopup(popup) {
function applyNoteVisualState(element, note) {
if (!element || !note) return;
- const color = note.color || "default";
- const background = note.background || "none";
+ const resolvedColorOption = getColorOption(note.color || "default");
+ const color = resolvedColorOption ? resolvedColorOption.key : "default";
+ const colorValue = getThemeColorValue(resolvedColorOption);
+ const foregroundColor = getReadableForegroundForBackground(colorValue);
+ const normalizedBackground = normalizeBackgroundKey(note.background || "");
+ const background = normalizedBackground || "none";
element.classList.forEach((cls) => {
if (cls.startsWith("note-color-")) element.classList.remove(cls);
});
element.classList.add(`note-color-${color}`);
+ if (colorValue) {
+ element.style.backgroundColor = colorValue;
+ element.style.borderColor = "transparent";
+ } else {
+ element.style.removeProperty("background-color");
+ }
+
+ if (foregroundColor) {
+ element.style.setProperty("--note-card-fg", foregroundColor);
+ }
+
if (background && background !== "none") {
const bgUrl = getNoteBackgroundUrl(background);
if (bgUrl) {
@@ -166,8 +560,8 @@ function extractNoteVisualStateFromTags(tags) {
let background = "none";
const foundBgTag = safeTags.find((t) => typeof t === "string" && t.startsWith(NOTE_BACKGROUND_TAG_PREFIX));
if (foundBgTag) {
- const candidate = foundBgTag.substring(NOTE_BACKGROUND_TAG_PREFIX.length);
- if (candidate && NOTE_BACKGROUND_OPTIONS.some((bg) => bg.key === candidate)) {
+ const candidate = normalizeBackgroundKey(foundBgTag.substring(NOTE_BACKGROUND_TAG_PREFIX.length));
+ if (candidate) {
background = candidate;
}
}
@@ -246,19 +640,21 @@ function initBookmarkPaletteButtons() {
function generateBookmarkPaletteButtons(bookmarkId, editUrl, currentColor, currentBackground) {
const color = currentColor || "default";
- const background = currentBackground || "none";
+ const background = normalizeBackgroundKey(currentBackground || "") || "none";
const colorButtons = [
``,
...NOTE_COLOR_OPTIONS.filter((opt) => opt.key !== "default").map(
- (opt) =>
- ``,
+ (opt) => {
+ const swatchColor = getThemeColorValue(opt);
+ return ``;
+ },
),
].join("");
const backgroundButtons = [
``,
- ...NOTE_BACKGROUND_OPTIONS.map((bg) => {
+ ...getAvailableBackgroundOptionsForMode().map((bg) => {
const bgUrl = getNoteBackgroundUrl(bg.key);
return ``;
}),
@@ -754,7 +1150,7 @@ function parseNoteFromLink(linkEl) {
tags.push(t);
}
} else if (t.startsWith(NOTE_BACKGROUND_TAG_PREFIX)) {
- background = t.substring(NOTE_BACKGROUND_TAG_PREFIX.length) || "none";
+ background = normalizeBackgroundKey(t.substring(NOTE_BACKGROUND_TAG_PREFIX.length)) || "none";
} else {
tags.push(t);
}
@@ -970,19 +1366,21 @@ function openNoteModal(note) {
function generateModalPaletteButtons(note) {
const currentColor = note.color || "default";
- const currentBackground = note.background || "none";
+ const currentBackground = normalizeBackgroundKey(note.background || "") || "none";
const colorButtons = [
``,
...NOTE_COLOR_OPTIONS.filter((opt) => opt.key !== "default").map(
- (opt) =>
- ``,
+ (opt) => {
+ const swatchColor = getThemeColorValue(opt);
+ return ``;
+ },
),
].join("");
const backgroundButtons = [
``,
- ...NOTE_BACKGROUND_OPTIONS.map((bg) => {
+ ...getAvailableBackgroundOptionsForMode().map((bg) => {
const bgUrl = getNoteBackgroundUrl(bg.key);
return ``;
}),
@@ -1020,9 +1418,10 @@ window.setModalNoteBackground = function (backgroundKey) {
if (!modal || !modal.currentNote) return;
const currentNote = modal.currentNote;
- setNoteBackground(currentNote.id, backgroundKey, currentNote.editUrl);
+ const normalizedBackgroundKey = backgroundKey === "none" ? "none" : normalizeBackgroundKey(backgroundKey) || "none";
+ setNoteBackground(currentNote.id, normalizedBackgroundKey, currentNote.editUrl);
- currentNote.background = backgroundKey;
+ currentNote.background = normalizedBackgroundKey;
const modalCard = modal.querySelector(".note-modal");
if (modalCard) {
applyNoteVisualState(modalCard, currentNote);
@@ -1038,19 +1437,21 @@ window.setModalNoteBackground = function (backgroundKey) {
function generatePaletteButtons(note) {
const currentColor = note.color || "default";
- const currentBackground = note.background || "none";
+ const currentBackground = normalizeBackgroundKey(note.background || "") || "none";
const colorButtons = [
``,
...NOTE_COLOR_OPTIONS.filter((opt) => opt.key !== "default").map(
- (opt) =>
- ``,
+ (opt) => {
+ const swatchColor = getThemeColorValue(opt);
+ return ``;
+ },
),
].join("");
const backgroundButtons = [
``,
- ...NOTE_BACKGROUND_OPTIONS.map((bg) => {
+ ...getAvailableBackgroundOptionsForMode().map((bg) => {
const bgUrl = getNoteBackgroundUrl(bg.key);
return ``;
}),
@@ -1157,27 +1558,29 @@ window.setNoteColor = function (noteId, color, editUrl) {
};
window.setNoteBackground = function (noteId, backgroundKey, editUrl) {
+ const normalizedBackgroundKey = backgroundKey === "none" ? "none" : normalizeBackgroundKey(backgroundKey) || "none";
+
const card = document.querySelector(`.note-card[data-id="${noteId}"]`);
if (card) {
const colorClass = Array.from(card.classList).find((cls) => cls.startsWith("note-color-"));
const color = colorClass ? colorClass.replace("note-color-", "") : card.dataset.color || "default";
- applyNoteVisualState(card, { color, background: backgroundKey });
+ applyNoteVisualState(card, { color, background: normalizedBackgroundKey });
}
const bookmarkCard = document.querySelector(`.link-outer[data-id="${noteId}"]`);
if (bookmarkCard) {
const colorClass = Array.from(bookmarkCard.classList).find((cls) => cls.startsWith("note-color-"));
const color = colorClass ? colorClass.replace("note-color-", "") : bookmarkCard.dataset.color || "default";
- applyNoteVisualState(bookmarkCard, { color, background: backgroundKey });
+ applyNoteVisualState(bookmarkCard, { color, background: normalizedBackgroundKey });
const palettePopup = bookmarkCard.querySelector(".bookmark-palette .palette-popup");
if (palettePopup) {
- palettePopup.innerHTML = generateBookmarkPaletteButtons(noteId, editUrl, color, backgroundKey);
+ palettePopup.innerHTML = generateBookmarkPaletteButtons(noteId, editUrl, color, normalizedBackgroundKey);
}
}
const modal = document.querySelector(".note-modal-overlay");
if (modal && modal.currentNote && String(modal.currentNote.id) === String(noteId)) {
- modal.currentNote.background = backgroundKey;
+ modal.currentNote.background = normalizedBackgroundKey;
const modalCard = modal.querySelector(".note-modal");
if (modalCard) {
applyNoteVisualState(modalCard, modal.currentNote);
@@ -1212,8 +1615,8 @@ window.setNoteBackground = function (noteId, backgroundKey, editUrl) {
let tagsArray = currentTags.split(/[\s,]+/).filter((t) => t.trim() !== "");
tagsArray = tagsArray.filter((t) => !t.startsWith(NOTE_BACKGROUND_TAG_PREFIX));
- if (backgroundKey && backgroundKey !== "none") {
- tagsArray.push(`${NOTE_BACKGROUND_TAG_PREFIX}${backgroundKey}`);
+ if (normalizedBackgroundKey && normalizedBackgroundKey !== "none") {
+ tagsArray.push(`${NOTE_BACKGROUND_TAG_PREFIX}${normalizedBackgroundKey}`);
}
formData.set("lf_tags", tagsArray.join(" "));