/* * Sombre par défaut, et volontairement : on juge l'éclairage et les couleurs d'une * scène 3D contre un fond neutre foncé. Une interface claire autour d'un décor * fausse la perception de l'exposition — et l'exposition est justement l'un des * réglages du manifeste. */ :root { --bg: #15171a; --panel: #1d2024; --panel-border: #2c3035; --text: #e6e8ea; --muted: #9aa2ab; --accent: #4da3ff; --warn: #ffb84d; --danger: #ff6b6b; color-scheme: dark; } * { box-sizing: border-box; } html, body { height: 100%; margin: 0; background: var(--bg); color: var(--text); font: 13px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif; } #layout { display: grid; grid-template-columns: 1fr 320px; height: 100%; } #stage { position: relative; min-width: 0; overflow: hidden; } #stage canvas { display: block; } #overlay { position: absolute; inset: 0; display: grid; place-items: center; padding: 2rem; text-align: center; background: rgba(21, 23, 26, 0.82); color: var(--muted); font-size: 14px; } /* * ⚠️ Sans cette règle, l'attribut `hidden` est inopérant : `display: grid` * ci-dessus est une déclaration d'auteur, et elle bat le `display: none` que la * feuille de style du navigateur applique à `[hidden]`. L'overlay reste alors * affiché par-dessus une scène pourtant chargée — et ça ressemble à un blocage. */ #overlay[hidden] { display: none; } #overlay.error { color: var(--danger); } #overlay.drop { outline: 2px dashed var(--accent); outline-offset: -12px; } /* ------------------------------------------------------------------ */ /* Panneau */ /* ------------------------------------------------------------------ */ #panel { display: flex; flex-direction: column; gap: 10px; padding: 12px; overflow-y: auto; background: var(--panel); border-left: 1px solid var(--panel-border); } /* Le mode lecture désactive la saisie sans masquer les valeurs : un conservateur doit pouvoir relire une scène publiée sans risquer de la modifier. */ #panel.read-only input, #panel.read-only select, #panel.read-only textarea, #panel.read-only button:not([data-export]) { pointer-events: none; opacity: 0.55; } .panel-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .panel-title { font-weight: 600; } .preview-badge { padding: 2px 8px; border: 1px solid var(--warn); border-radius: 999px; color: var(--warn); font-size: 11px; cursor: help; } .panel-row { display: flex; align-items: center; gap: 8px; } .dirty-badge { margin-left: auto; color: var(--warn); font-size: 11px; } .panel-actions { display: flex; flex-wrap: wrap; gap: 6px; } .panel-footer { margin-top: auto; padding-top: 8px; border-top: 1px solid var(--panel-border); } button { padding: 5px 10px; border: 1px solid var(--panel-border); border-radius: 6px; background: #262a2f; color: var(--text); font: inherit; cursor: pointer; } button:hover { border-color: var(--accent); } button.primary { width: 100%; border-color: var(--accent); background: var(--accent); color: #0e1013; font-weight: 600; } /* ------------------------------------------------------------------ */ /* Budget */ /* ------------------------------------------------------------------ */ .budget-label { display: flex; justify-content: space-between; color: var(--muted); font-size: 11px; } .budget-track { height: 6px; margin-top: 4px; border-radius: 3px; background: #2a2e33; overflow: hidden; } .budget-fill { height: 100%; background: var(--accent); } .budget-fill.over { background: var(--danger); } /* ------------------------------------------------------------------ */ /* Listes */ /* ------------------------------------------------------------------ */ .list-section { margin-bottom: 10px; } .list-title { display: flex; justify-content: space-between; margin-bottom: 4px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; } .list-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 5px 8px; border: 1px solid transparent; border-radius: 6px; cursor: pointer; } .list-row:hover { background: #24282d; } .list-row.selected { border-color: var(--accent); background: #1f2a35; } .list-row .remove { padding: 0 6px; border: none; background: none; color: var(--muted); line-height: 1; } .list-row .remove:hover { color: var(--danger); } .list-empty { padding: 4px 8px; color: #626a73; font-style: italic; } /* ------------------------------------------------------------------ */ /* Inspecteur */ /* ------------------------------------------------------------------ */ .inspector-title { padding-bottom: 6px; border-bottom: 1px solid var(--panel-border); color: var(--accent); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; } .field-row { display: flex; gap: 6px; margin-top: 8px; } label { display: flex; flex: 1; flex-direction: column; gap: 3px; color: var(--muted); font-size: 11px; } label.wide { margin-top: 8px; } label.checkbox { flex-direction: row; align-items: center; gap: 6px; margin-top: 8px; } input, select, textarea { padding: 4px 6px; border: 1px solid var(--panel-border); border-radius: 5px; background: #14161a; color: var(--text); font: inherit; } input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; } textarea { resize: vertical; } .unit, .asset-size { color: #626a73; font-size: 10px; } .hint { padding: 10px 2px; color: var(--muted); } .hint.small { font-size: 11px; } code { padding: 0 3px; border-radius: 3px; background: #14161a; font-size: 11px; }