diff --git a/public/index.html b/public/index.html
index c69c370..d0efa8d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -242,18 +242,32 @@
.list-block h4.no { color: #a0523d; }
.dark .list-block h4.yes { color: #8aaa6a; }
.dark .list-block h4.no { color: #c07050; }
- .list-item { padding: 8px 0; font-size: 15px; color: var(--text); display: flex; align-items: flex-start; gap: 8px; }
+ .list-item { padding: 10px 0; font-size: 15px; color: var(--text); display: flex; align-items: flex-start; gap: 8px; }
.list-item .bullet { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; margin-top: 8px; }
.list-item.yes .bullet { background: #5a7a3a; }
.list-item.no .bullet { background: #a0523d; }
.dark .list-item.yes .bullet { background: #8aaa6a; }
.dark .list-item.no .bullet { background: #c07050; }
+ .list-item-title { font-weight: 600; }
+ .list-item-desc { font-size: 14px; color: var(--text-muted); line-height: 1.6; margin-top: 4px; }
+ .list-item.expanded { background: var(--bg-alt); border-radius: 8px; padding: 12px; border-left: 3px solid; margin: 4px 0; }
+ .list-item.expanded.yes { border-left-color: #5a7a3a; }
+ .list-item.expanded.no { border-left-color: #a0523d; }
+ .dark .list-item.expanded.yes { border-left-color: #8aaa6a; }
+ .dark .list-item.expanded.no { border-left-color: #c07050; }
+ .list-item-expand { font-size: 12px; color: var(--text-hint); cursor: pointer; margin-left: 8px; white-space: nowrap; }
+ .list-item-expand:hover { color: var(--accent); }
- .inspi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
- .inspi-card { background: var(--bg); border-radius: 10px; padding: 16px; text-align: center; border: 1px solid var(--border); }
- .inspi-icon { font-size: 28px; margin-bottom: 8px; }
- .inspi-title { font-size: 14px; font-weight: 500; color: var(--brown); }
- .inspi-type { font-size: 13px; color: var(--text-hint); margin-top: 4px; }
+ .mood-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; }
+ .mood-card { position: relative; border-radius: 10px; overflow: hidden; aspect-ratio: 1; background: var(--bg-alt); border: 1px solid var(--border); cursor: pointer; display: flex; align-items: flex-end; background-size: cover; background-position: center; }
+ .mood-card.has-image { border-color: transparent; }
+ .mood-label { width: 100%; padding: 6px 10px; font-size: 12px; font-weight: 600; color: #fff; background: rgba(44,24,16,0.55); backdrop-filter: blur(4px); text-align: center; }
+ .mood-card:not(.has-image) .mood-label { color: var(--text-muted); background: transparent; }
+ .mood-card-remove { position: absolute; top: 4px; right: 4px; display: none; background: rgba(139,48,48,0.8); color: #fff; border: none; border-radius: 50%; width: 20px; height: 20px; font-size: 12px; cursor: pointer; align-items: center; justify-content: center; z-index: 2; }
+ .mood-card:hover .mood-card-remove { display: flex; }
+ .mood-add { border: 1px dashed var(--border); background: transparent; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; aspect-ratio: 1; border-radius: 10px; }
+ .mood-add:hover { background: var(--bg-alt); }
+ .mood-add-icon { font-size: 24px; color: var(--text-hint); }
.vision-quote { font-family: 'Playfair Display', serif; font-size: 17px; font-style: italic; color: var(--text-muted); line-height: 1.7; border-left: 3px solid var(--accent); padding-left: 16px; margin: 12px 0; }
@@ -280,9 +294,6 @@
.list-add { padding: 6px 0; font-size: 14px; color: var(--text-hint); cursor: pointer; display: flex; align-items: center; gap: 6px; }
.list-add:hover { color: var(--accent); }
- .inspi-card-remove { position: absolute; top: 4px; right: 4px; display: none; background: rgba(139,48,48,0.8); color: #fff; border: none; border-radius: 50%; width: 20px; height: 20px; font-size: 12px; cursor: pointer; align-items: center; justify-content: center; }
- .inspi-card:hover .inspi-card-remove { display: flex; }
- .inspi-card { position: relative; }
/* Responsive */
@media (max-width: 768px) {
@@ -382,6 +393,12 @@
+
+
Ce qu'on veut / ne veut pas
-
-
Inspirations et références
-
-
-
@@ -971,39 +983,87 @@ function removeTag(index) {
renderTags();
}
-// ── Lists (on-veut / on-ne-veut-pas) ──
+// ── Lists (on-veut / on-ne-veut-pas) — items with title + optional description ──
function renderList(section, containerId, cssClass) {
const container = document.getElementById(containerId);
const row = visionData[section];
let items = [];
try { items = JSON.parse(row?.Contenu || '[]'); } catch { items = []; }
+ // Normalize: old format was plain strings, new format is {title, desc}
+ items = items.map(it => typeof it === 'string' ? { title: it, desc: '' } : it);
container.innerHTML = '';
- items.forEach((text, i) => {
+ items.forEach((item, i) => {
+ const hasDesc = !!item.desc;
const div = document.createElement('div');
- div.className = `list-item ${cssClass}`;
- div.innerHTML = `${esc(text)}×`;
- const textEl = div.querySelector('.list-item-text');
- textEl.addEventListener('blur', () => {
- const newText = textEl.textContent.trim();
- if (newText && newText !== items[i]) {
- items[i] = newText;
- saveVisionSection(section, JSON.stringify(items));
- }
+ div.className = `list-item ${cssClass}${hasDesc ? ' expanded' : ''}`;
+
+ const content = document.createElement('div');
+ content.className = 'list-item-text';
+ content.style.flex = '1';
+
+ const titleEl = document.createElement('div');
+ titleEl.className = 'list-item-title';
+ titleEl.contentEditable = 'true';
+ titleEl.textContent = item.title;
+ titleEl.addEventListener('blur', () => {
+ const v = titleEl.textContent.trim();
+ if (v && v !== items[i].title) { items[i].title = v; saveVisionSection(section, JSON.stringify(items)); }
});
- textEl.addEventListener('keydown', e => {
- if (e.key === 'Enter') { e.preventDefault(); textEl.blur(); }
+ titleEl.addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); titleEl.blur(); } });
+ content.appendChild(titleEl);
+
+ const descEl = document.createElement('div');
+ descEl.className = 'list-item-desc';
+ descEl.contentEditable = 'true';
+ descEl.textContent = item.desc || '';
+ descEl.style.display = hasDesc ? 'block' : 'none';
+ descEl.setAttribute('data-placeholder', 'Développer...');
+ descEl.addEventListener('blur', () => {
+ const v = descEl.textContent.trim();
+ if (v !== (items[i].desc || '')) { items[i].desc = v; saveVisionSection(section, JSON.stringify(items)); }
+ if (!v) { descEl.style.display = 'none'; div.classList.remove('expanded'); }
});
+ content.appendChild(descEl);
+
+ const bullet = document.createElement('span');
+ bullet.className = 'bullet';
+
+ const actions = document.createElement('span');
+ actions.style.cssText = 'display:flex; gap:6px; align-items:center;';
+
+ const expandBtn = document.createElement('span');
+ expandBtn.className = 'list-item-expand';
+ expandBtn.textContent = hasDesc ? '' : 'développer →';
+ expandBtn.style.display = hasDesc ? 'none' : '';
+ expandBtn.onclick = () => {
+ descEl.style.display = 'block';
+ div.classList.add('expanded');
+ expandBtn.style.display = 'none';
+ descEl.focus();
+ };
+
+ const removeBtn = document.createElement('span');
+ removeBtn.className = 'list-item-remove';
+ removeBtn.innerHTML = '×';
+ removeBtn.onclick = () => { items.splice(i, 1); saveVisionSection(section, JSON.stringify(items)); renderList(section, containerId, cssClass); };
+
+ actions.appendChild(expandBtn);
+ actions.appendChild(removeBtn);
+
+ div.appendChild(bullet);
+ div.appendChild(content);
+ div.appendChild(actions);
container.appendChild(div);
});
const addEl = document.createElement('div');
addEl.className = 'list-add';
- addEl.innerHTML = '+ Ajouter';
+ addEl.innerHTML = '+ Ajouter un élément';
addEl.onclick = () => {
const text = prompt('Nouvel élément :');
if (!text) return;
- items.push(text);
+ items.push({ title: text, desc: '' });
saveVisionSection(section, JSON.stringify(items));
renderList(section, containerId, cssClass);
};
@@ -1019,61 +1079,84 @@ function removeListItem(section, containerId, cssClass, index) {
renderList(section, containerId, cssClass);
}
-// ── Inspirations ──
-const INSPI_ICONS = { 'Livre': '\u{1F4D6}', 'Film': '\u{1F3AC}', 'Peinture': '\u{1F3A8}', 'Musique': '\u{1F3B5}', 'Série': '\u{1F4FA}', 'Jeu': '\u{1F3AE}', 'Autre': '\u{2728}' };
-
-function renderInspirations() {
- const container = document.getElementById('v-inspirations');
- const row = visionData['inspirations'];
+// ── Moodboard ──
+function renderMoodboard() {
+ const container = document.getElementById('v-moodboard');
+ const row = visionData['moodboard'];
let items = [];
try { items = JSON.parse(row?.Contenu || '[]'); } catch { items = []; }
container.innerHTML = '';
items.forEach((item, i) => {
const card = document.createElement('div');
- card.className = 'inspi-card';
+ card.className = 'mood-card' + (item.image ? ' has-image' : '');
+ if (item.image) card.style.backgroundImage = `url(${item.image})`;
+
card.innerHTML = `
-
- ${item.icon || INSPI_ICONS[item.type] || '\u{2728}'}
- ${esc(item.title)}
- ${esc(item.type)}
+
+ ${esc(item.label)}
`;
- const titleEl = card.querySelector('.inspi-title');
- titleEl.addEventListener('blur', () => {
- const newTitle = titleEl.textContent.trim();
- if (newTitle && newTitle !== items[i].title) {
- items[i].title = newTitle;
- saveVisionSection('inspirations', JSON.stringify(items));
- }
- });
- titleEl.addEventListener('keydown', e => {
- if (e.key === 'Enter') { e.preventDefault(); titleEl.blur(); }
- });
+ card.onclick = (e) => {
+ if (e.target.closest('.mood-card-remove')) return;
+ moodUploadTarget = i;
+ document.getElementById('mood-file-input').click();
+ };
container.appendChild(card);
});
const addCard = document.createElement('div');
- addCard.className = 'inspi-card';
- addCard.style.cssText = 'border:1px dashed var(--border); background:transparent; display:flex; flex-direction:column; align-items:center; justify-content:center; cursor:pointer;';
- addCard.innerHTML = '+
Ajouter
';
+ addCard.className = 'mood-add';
+ addCard.innerHTML = '+
';
addCard.onclick = () => {
- const title = prompt('Titre de la référence :');
- if (!title) return;
- const type = prompt('Type (Livre, Film, Peinture, Musique, Série, Jeu, Autre) :', 'Livre') || 'Livre';
- items.push({ title, type, icon: INSPI_ICONS[type] || '\u{2728}' });
- saveVisionSection('inspirations', JSON.stringify(items));
- renderInspirations();
+ const label = prompt('Catégorie (ex : Ambiance, Architecture, Costumes...) :');
+ if (!label) return;
+ items.push({ label, image: '' });
+ saveVisionSection('moodboard', JSON.stringify(items));
+ renderMoodboard();
};
container.appendChild(addCard);
}
-function removeInspiration(index) {
- const row = visionData['inspirations'];
+let moodUploadTarget = -1;
+document.addEventListener('DOMContentLoaded', () => {
+ const moodInput = document.getElementById('mood-file-input');
+ if (moodInput) moodInput.addEventListener('change', function() {
+ const file = this.files[0];
+ if (!file || moodUploadTarget < 0) return;
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ const img = new Image();
+ img.onload = () => {
+ const maxW = 400;
+ let w = img.width, h = img.height;
+ if (w > maxW) { h = Math.round(h * maxW / w); w = maxW; }
+ const canvas = document.createElement('canvas');
+ canvas.width = w; canvas.height = h;
+ canvas.getContext('2d').drawImage(img, 0, 0, w, h);
+ const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
+ const row = visionData['moodboard'];
+ let items = [];
+ try { items = JSON.parse(row?.Contenu || '[]'); } catch { items = []; }
+ if (items[moodUploadTarget]) {
+ items[moodUploadTarget].image = dataUrl;
+ saveVisionSection('moodboard', JSON.stringify(items));
+ renderMoodboard();
+ }
+ };
+ img.src = e.target.result;
+ };
+ reader.readAsDataURL(file);
+ this.value = '';
+ });
+});
+
+function removeMoodItem(index) {
+ const row = visionData['moodboard'];
let items = [];
try { items = JSON.parse(row?.Contenu || '[]'); } catch { return; }
items.splice(index, 1);
- saveVisionSection('inspirations', JSON.stringify(items));
- renderInspirations();
+ saveVisionSection('moodboard', JSON.stringify(items));
+ renderMoodboard();
}
// ── Hero image with drag-to-reposition ──
@@ -1197,7 +1280,7 @@ async function loadVision() {
renderTags();
renderList('on-veut', 'v-on-veut', 'yes');
renderList('on-ne-veut-pas', 'v-on-ne-veut-pas', 'no');
- renderInspirations();
+ renderMoodboard();
} catch (e) {
console.error('Vision load error:', e);
}