diff --git a/frontend/biochem-library.html b/frontend/biochem-library.html
index 5afa4c8..088f20f 100644
--- a/frontend/biochem-library.html
+++ b/frontend/biochem-library.html
@@ -209,6 +209,26 @@
}
.detail-open-btn:hover { background: linear-gradient(135deg, rgba(155,93,229,.4), rgba(6,214,224,.25)); border-color: rgba(6,214,224,.5); color: #fff; }
+ /* ── Shimmer skeleton ── */
+ @keyframes bc-shimmer {
+ 0% { background-position: -200% 0; }
+ 100% { background-position: 200% 0; }
+ }
+ .bc-sk {
+ background: linear-gradient(90deg,
+ rgba(255,255,255,0.04) 0%,
+ rgba(255,255,255,0.10) 50%,
+ rgba(255,255,255,0.04) 100%);
+ background-size: 200% 100%;
+ animation: bc-shimmer 1.6s infinite;
+ border-radius: 8px;
+ }
+ .bc-sk-square { aspect-ratio: 1; }
+ .bc-sk-line { height: 12px; margin: 6px 0; }
+ .bc-sk-line.sm { width: 60%; }
+ .bc-sk-line.md { width: 80%; }
+ .bc-sk-card { padding: 12px; border: 1px solid rgba(255,255,255,.06); border-radius: 10px; }
+
/* Empty state */
.lib-empty {
grid-column: 1/-1;
@@ -294,14 +314,7 @@
@@ -470,7 +483,17 @@ let selectedId = null;
const CAT_LABELS = { inorganic:'Неорганика', organic:'Органика', biomolecule:'Биомолекулы' };
const DIFF_STARS = ['', '
', '
', '
'];
+function bcSkLibrary(n = 12) {
+ return Array.from({length: n}, () => `
+
`).join('');
+}
+
async function init() {
+ document.getElementById('lib-grid').innerHTML = bcSkLibrary(12);
try {
[allMols, allReactions] = await Promise.all([
LS.biochemGetMolecules(),
diff --git a/frontend/biochem-properties.html b/frontend/biochem-properties.html
index 6a1479a..fd832f6 100644
--- a/frontend/biochem-properties.html
+++ b/frontend/biochem-properties.html
@@ -155,6 +155,27 @@
.add-card:hover { border-color: rgba(155,93,229,.5); color: #9B5DE5; background: rgba(155,93,229,.05); }
.add-card-icon { font-size: 2rem; }
+ /* ── Shimmer skeleton ── */
+ @keyframes bc-shimmer {
+ 0% { background-position: -200% 0; }
+ 100% { background-position: 200% 0; }
+ }
+ .bc-sk {
+ background: linear-gradient(90deg,
+ rgba(255,255,255,0.04) 0%,
+ rgba(255,255,255,0.10) 50%,
+ rgba(255,255,255,0.04) 100%);
+ background-size: 200% 100%;
+ animation: bc-shimmer 1.6s infinite;
+ border-radius: 8px;
+ }
+ .bc-sk-line { height: 10px; margin: 5px 0; }
+ .bc-sk-line.sm { width: 55%; }
+ .bc-sk-line.md { width: 80%; }
+ .bc-sk-molrow { display: flex; align-items: center; gap: 8px; padding: 7px 8px; margin-bottom: 2px; }
+ .bc-sk-molrow .bc-sk-thumb { width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0; }
+ .bc-sk-molrow .bc-sk-info { flex: 1; }
+
/* ── Mobile ── */
@media (max-width: 768px) {
html, body { overflow: auto; }
@@ -193,7 +214,7 @@
-