Files
busbar-designer/static/holder.css
T
wenil 5bba0e3c4a holder: expose all 59 scad parameters auto-extracted from the .scad source
The bundled hex_cell.scad has many more knobs than the dozen we used to
expose (box clearances, cap/box wall, vertical stacking, busbar template,
etc). Maintaining a hand-curated PARAMS list in Python next to a SCAD file
that already documents every variable inline was always going to drift.

Sync + auto-extract approach:
- scad/hex_cell.scad: replace with the upstream master file from
  Albert Phan's Hex-Cell-Holder fork (adds the BUSBAR TEMPLATE section
  and the "busbar template" part option).
- holder.py: PARAMS now built at import time by _scan_scad(), which
  regexes top-level `name = literal;  // help` lines into Param entries
  up until the // END OF CONFIGURATION marker. Scan handles bool /
  number / string literals; derived expressions and helper variables
  are skipped automatically.
- Manual maps stay small and explicit: _SELECT_OPTIONS for the few
  string-enum params (part, pack_style, box_style, template_outline,
  template_hole_style, etc.), _GROUP_RULES for UI sectioning, and
  _NUMBER_HINTS for sensible min/max/step on the most-tweaked numbers.

UI:
- holder-app.js: extra GROUP_ORDER / GROUP_LABELS for the new
  sections (cap, box, insulator, bolts, wires, stacking, template,
  advanced). Group titles are now click-to-collapse; the advanced
  groups start collapsed so the form isn't a wall of inputs on load.
- holder.css: caret marker on the group title, smooth rotate on
  collapse, hides the body via .collapsed class.

Net effect: every variable in the .scad — including the new busbar
template knobs — is editable from the page, with helpful comments
copied straight from the .scad source.
2026-05-25 12:44:45 +03:00

168 lines
3.2 KiB
CSS

/* Holder-designer specific styles; complements styles.css. */
.holder-left { width: 340px; }
.viewer3d {
width: 100%;
height: 100%;
background: #0a0d12;
}
.right { position: relative; }
/* Parameter form */
.param-form {
display: flex;
flex-direction: column;
gap: 14px;
}
.param-group {
border: 1px solid var(--border);
border-radius: 4px;
background: var(--bg);
padding: 8px 10px;
}
.param-group-title {
font-size: 11px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.05em;
margin: 0 0 6px;
font-weight: 600;
cursor: pointer;
user-select: none;
display: flex;
align-items: center;
gap: 6px;
}
.param-group-title::before {
content: "\25BC"; /* ▼ */
display: inline-block;
font-size: 8px;
transition: transform 0.12s ease;
}
.param-group.collapsed .param-group-title::before {
transform: rotate(-90deg); /* ▶ */
}
.param-group.collapsed .param-group-body {
display: none;
}
.param-group-body {
display: flex;
flex-direction: column;
gap: 4px;
}
.param-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 6px;
}
.param-row label {
flex: 1;
font-size: 12px;
color: var(--text);
text-transform: none;
letter-spacing: 0;
flex-direction: row;
align-items: center;
}
.param-row input[type=number],
.param-row select {
width: 110px;
flex-shrink: 0;
font-size: 12px;
padding: 3px 6px;
}
.param-row .param-help {
font-size: 10px;
color: var(--muted);
flex-basis: 100%;
margin-top: -2px;
}
/* Render progress (indeterminate bar + elapsed-time counter) */
.render-progress {
display: flex;
align-items: center;
gap: 8px;
margin: 6px 0;
}
.render-progress-bar {
flex: 1;
height: 6px;
border-radius: 3px;
background: var(--border, #2a2f3a);
overflow: hidden;
position: relative;
}
.render-progress-fill {
position: absolute;
inset: 0;
width: 35%;
border-radius: 3px;
background: linear-gradient(90deg, transparent, var(--accent, #4a9eff), transparent);
animation: render-progress-slide 1.2s linear infinite;
}
@keyframes render-progress-slide {
0% { left: -35%; }
100% { left: 100%; }
}
.render-elapsed {
font-size: 11px;
color: var(--muted);
font-variant-numeric: tabular-nums;
min-width: 42px;
text-align: right;
}
/* Dirty indicator on Render button when params changed since last render */
#btn-render.dirty {
box-shadow: 0 0 0 2px var(--accent, #4a9eff) inset;
}
/* Cell-count over the server limit — render is disabled, status flagged */
.topbar-status.over-limit {
color: var(--danger, #d94a4a);
font-weight: 600;
}
/* Fit-check panel */
.fit-toggle {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
cursor: pointer;
user-select: none;
}
.fit-toggle input { margin: 0; }
.fit-sep {
border: none;
border-top: 1px solid var(--border, #2a2f3a);
margin: 10px 0 8px;
}
.enc-inputs {
display: flex;
align-items: center;
gap: 4px;
margin: 6px 0;
font-size: 12px;
}
.enc-inputs input {
width: 56px;
padding: 3px 6px;
font-size: 12px;
}
.enc-inputs .unit { color: var(--muted); margin-left: 2px; }
#fit-verdict.fit-ok { color: #4ad97a; font-weight: 600; }
#fit-verdict.fit-bad { color: var(--danger, #d94a4a); font-weight: 600; }