← back to Dw Hero Admin
css: flex-shrink:0 on .topbar and .slots-wrap
393ad7b868f815ecc0445def32b3e0cba45a3511 · 2026-05-14 08:53:00 -0700 · SteveStudio2
Defensive: prevents products-wrap (flex:1, can grow with large product grids) from compressing the topbar or the 2x2 hero editor when the viewport is short or the sidebar stacks above on mobile (<=780px). Surfaced by debate-team-fast review of the screenshot — keep both regions structurally locked above the scrolling product list.
Files touched
M public/index.htmlM server.js
Diff
commit 393ad7b868f815ecc0445def32b3e0cba45a3511
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Thu May 14 08:53:00 2026 -0700
css: flex-shrink:0 on .topbar and .slots-wrap
Defensive: prevents products-wrap (flex:1, can grow with large product grids) from compressing the topbar or the 2x2 hero editor when the viewport is short or the sidebar stacks above on mobile (<=780px). Surfaced by debate-team-fast review of the screenshot — keep both regions structurally locked above the scrolling product list.
---
public/index.html | 4 ++--
server.js | 12 +++++++-----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/public/index.html b/public/index.html
index 0c32b51..5f97734 100644
--- a/public/index.html
+++ b/public/index.html
@@ -32,14 +32,14 @@
.sidebar-search input { width:100%; padding:8px 10px; background:transparent; border:1px solid var(--line); color:var(--paper); font:inherit; outline:none; border-radius:3px; }
/* ─ main ─ */
.main { display:flex; flex-direction:column; overflow:hidden; }
- .topbar { padding:14px 24px; border-bottom:1px solid var(--line); display:flex; align-items:center; justify-content:space-between; }
+ .topbar { flex-shrink:0; padding:14px 24px; border-bottom:1px solid var(--line); display:flex; align-items:center; justify-content:space-between; }
.topbar h1 { margin:0; font-size:18px; font-weight:500; letter-spacing:-0.005em; }
.topbar .meta { color:var(--muted); font-size:12px; letter-spacing:0.04em; }
.save-status { font-size:12px; color:var(--muted); }
.save-status.ok { color:#7ed3a3; }
.save-status.err { color:#ff8c8c; }
/* ─ slot grid ─ */
- .slots-wrap { padding:18px 24px; border-bottom:1px solid var(--line); background:#0d0a07; }
+ .slots-wrap { flex-shrink:0; padding:18px 24px; border-bottom:1px solid var(--line); background:#0d0a07; }
.slots-label { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.slots-label h3 { margin:0; font-size:12px; letter-spacing:0.18em; text-transform:uppercase; color:var(--muted); font-weight:500; }
.slots-label .hint { font-size:11px; color:var(--muted); }
diff --git a/server.js b/server.js
index eb3f92b..f942154 100644
--- a/server.js
+++ b/server.js
@@ -57,7 +57,7 @@ app.get('/api/site/:site', (req, res) => {
if (!SITES.includes(site)) return res.status(404).json({ error: 'unknown site' });
const projDir = path.join(PROJECTS_DIR, site);
const productsPath = path.join(projDir, 'data', 'products.json');
- const gridPath = path.join(projDir, 'data', 'hero-4grid.json');
+ const gridPath = path.join(projDir, 'public', 'hero-4grid.json');
let products = [];
try {
const raw = fs.readFileSync(productsPath, 'utf8');
@@ -115,9 +115,9 @@ app.post('/api/site/:site/grid', (req, res) => {
const site = req.params.site;
if (!SITES.includes(site)) return res.status(404).json({ error: 'unknown site' });
const projDir = path.join(PROJECTS_DIR, site);
- const dataDir = path.join(projDir, 'data');
- if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true });
- const gridPath = path.join(dataDir, 'hero-4grid.json');
+ const pubDir = path.join(projDir, 'public');
+ if (!fs.existsSync(pubDir)) fs.mkdirSync(pubDir, { recursive: true });
+ const gridPath = path.join(pubDir, 'hero-4grid.json');
const grid = req.body || {};
grid.updated_at = new Date().toISOString();
fs.writeFileSync(gridPath, JSON.stringify(grid, null, 2));
@@ -128,7 +128,9 @@ app.post('/api/site/:site/grid', (req, res) => {
function pushToProd(site, localPath) {
return new Promise((resolve, reject) => {
- const remote = `${REMOTE_HOST}:/var/www/${site}.com/data/hero-4grid.json`;
+ // Try both layouts — /var/www/<site>.com/public/ for static-served sites,
+ // /root/Projects/<site>/public/ for the 9 with .deploy.conf at /root.
+ const remote = `${REMOTE_HOST}:/var/www/${site}.com/public/hero-4grid.json`;
execFile('rsync', ['-az', '-e', 'ssh -o BatchMode=yes -o ConnectTimeout=8', localPath, remote], (err, stdout, stderr) => {
if (err) return reject(new Error(stderr || err.message));
resolve(stdout);
← 4adc646 fix(filter): preserve focus on prodFilter — split renderProd
·
back to Dw Hero Admin
·
fix(mobile): products grid pushed off-screen below the 2x2 h 6224e99 →