* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background: #0a0f1e; min-height: 100vh; color: #e2e8f0; line-height: 1.6; padding: 12px 24px; } .container { max-width: 1600px; margin: 0 auto; height: 100%; display: flex; flex-direction: column; transition: max-width 0.3s ease, padding 0.3s ease; } /* Header */ .header-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; } h1 { font-size: 1.6em; font-weight: 700; color: #fff; margin-bottom: 0; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: fadeInUp 0.6s ease-out; } h1:hover { color: #6495ed; text-shadow: 0 0 20px rgba(100, 149, 237, 0.5); transform: translateX(5px); } .subtitle { color: #94a3b8; font-size: 0.88em; margin-bottom: 6px; transition: color 0.3s ease; animation: fadeInUp 0.6s ease-out 0.1s both; } .repo-credit { margin: 0; padding: 5px 10px; color: #a7f3d0; font-size: 0.85em; font-weight: 600; line-height: 1.5; text-align: center; background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(110, 231, 183, 0.35); border-radius: 8px; animation: fadeInUp 0.6s ease-out 0.15s both; } .header-right { display: flex; flex-direction: row; align-items: center; gap: 8px; } .header-title { display: flex; flex-direction: column; gap: 4px; } .waak-credit { margin: 0; color: #6ee7b7; font-size: 0.8em; opacity: 0.8; } .waak-credit a { color: #a7f3d0; font-weight: 600; text-decoration: none; } .waak-credit a:hover { text-decoration: underline; } .warning-banner { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 auto 8px; padding: 6px 14px; max-width: 700px; background: rgba(234, 179, 8, 0.1); border: 1px solid rgba(234, 179, 8, 0.45); border-radius: 8px; color: #fde68a; font-size: 0.88em; font-weight: 500; text-align: center; line-height: 1.4; } .warning-icon { width: 18px; height: 18px; flex-shrink: 0; color: #fbbf24; } .gitea-link { display: inline-flex; align-items: center; gap: 6px; align-self: flex-end; color: #a7f3d0; font-size: 0.85em; font-weight: 600; text-decoration: none; padding: 5px 10px; border: 1px solid rgba(110, 231, 183, 0.35); border-radius: 8px; background: rgba(16, 185, 129, 0.1); transition: background 0.2s, color 0.2s; } .gitea-link:hover { background: rgba(16, 185, 129, 0.22); color: #ecfdf5; } .gitea-icon { width: 16px; height: 16px; flex-shrink: 0; } .repo-credit a { color: #a7f3d0; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; } .repo-credit a:hover { color: #ecfdf5; } /* Main Layout */ .main-layout { display: grid; grid-template-columns: 460px 1fr; gap: 28px; flex: 1; min-height: 0; align-items: stretch; transition: grid-template-columns 0.4s cubic-bezier(0.4, 0, 0.2, 1), gap 0.3s ease; } /* Sections */ .section { background: rgba(15, 23, 42, 0.6); border: 1px solid rgba(100, 149, 237, 0.1); border-radius: 12px; padding: 36px; margin-bottom: 28px; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); animation: fadeInUp 0.6s ease-out backwards; } .section:nth-child(1) { animation-delay: 0.2s; } .section:nth-child(2) { animation-delay: 0.26s; } .section:nth-child(3) { animation-delay: 0.32s; } .section:nth-child(4) { animation-delay: 0.38s; } .section:nth-child(5) { animation-delay: 0.44s; } .section:nth-child(6) { animation-delay: 0.5s; } /* Sidebar tab navigation — each tab shows a stacked icon + label. An animated gradient pill (.tab-indicator) slides to the active tab; panels cross-fade. */ .config-sidebar { background: rgba(15, 23, 42, 0.6); border: 1px solid rgba(100, 149, 237, 0.1); border-radius: 14px; padding: 20px 20px 24px; overflow-y: auto; min-height: 0; transition: border-color 0.3s ease, box-shadow 0.3s ease; } .config-sidebar:hover { border-color: rgba(100, 149, 237, 0.28); box-shadow: 0 16px 44px rgba(100, 149, 237, 0.14); } .sidebar-tabs { position: relative; display: flex; gap: 4px; background: rgba(0, 0, 0, 0.28); border: 1px solid rgba(100, 149, 237, 0.08); border-radius: 14px; padding: 6px; margin-bottom: 22px; } .sidebar-tabs .tab { flex: 1 1 0; min-width: 0; position: relative; z-index: 1; background: transparent; border: none; color: #94a3b8; padding: 12px 4px 10px; font-size: 0.78em; font-weight: 600; letter-spacing: 0.35px; cursor: pointer; border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; transition: color 0.25s ease, transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); } .sidebar-tabs .tab-icon { width: 22px; height: 22px; color: inherit; transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.25s ease; } .sidebar-tabs .tab-label { line-height: 1; white-space: nowrap; } .sidebar-tabs .tab:hover { color: #cbd5e1; } .sidebar-tabs .tab:hover .tab-icon { transform: translateY(-1px) scale(1.05); } .sidebar-tabs .tab:focus-visible { outline: 2px solid rgba(100, 149, 237, 0.55); outline-offset: 2px; } .sidebar-tabs .tab.active { color: #fff; } .sidebar-tabs .tab.active .tab-icon { color: #fff; transform: translateY(-1px) scale(1.08); } .sidebar-tabs .tab-indicator { position: absolute; top: 6px; bottom: 6px; left: 0; width: 0; background: linear-gradient(135deg, rgba(102, 126, 234, 0.95), rgba(118, 75, 162, 0.9)); border-radius: 10px; box-shadow: 0 6px 18px rgba(102, 126, 234, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.08); transition: left 0.38s cubic-bezier(0.4, 0, 0.2, 1), width 0.38s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; pointer-events: none; } .tab-panels { position: relative; padding: 4px 4px 4px; min-height: 220px; } .tab-panel { display: none; } .tab-panel.active { display: block; animation: tabFadeIn 0.32s cubic-bezier(0.4, 0, 0.2, 1); } @keyframes tabFadeIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } } .tab-panel .form-group:last-child { margin-bottom: 0; } .field-hint { display: block; margin-top: 6px; color: #64748b; font-size: 0.8em; letter-spacing: 0.1px; } .pack-summary { margin-top: 18px; padding: 12px 16px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.08)); border: 1px solid rgba(100, 149, 237, 0.25); border-radius: 10px; color: #cbd5e1; font-size: 0.9em; line-height: 1.5; } .pack-summary strong { color: #fff; font-weight: 700; font-size: 1.05em; letter-spacing: 0.3px; } .pack-summary .muted { color: #94a3b8; font-size: 0.92em; } .config-sidebar > .btn { margin-top: 20px; padding: 16px 24px; font-size: 1.05em; letter-spacing: 0.3px; } /* Segmented toggle (SP vs mm). Animated gradient pill slides to the active segment. */ .seg-toggle { position: relative; display: inline-flex; background: rgba(0, 0, 0, 0.28); border: 1px solid rgba(100, 149, 237, 0.1); border-radius: 10px; padding: 4px; margin-bottom: 18px; width: 100%; } .seg-toggle .seg { position: relative; z-index: 1; flex: 1 1 0; background: transparent; border: none; color: #94a3b8; padding: 9px 14px; font-size: 0.85em; font-weight: 600; letter-spacing: 0.25px; cursor: pointer; border-radius: 7px; transition: color 0.25s ease; white-space: nowrap; } .seg-toggle .seg:hover { color: #cbd5e1; } .seg-toggle .seg.active { color: #fff; } .seg-toggle .seg-indicator { position: absolute; top: 4px; bottom: 4px; left: 0; width: 0; background: linear-gradient(135deg, rgba(102, 126, 234, 0.92), rgba(118, 75, 162, 0.88)); border-radius: 7px; box-shadow: 0 4px 14px rgba(102, 126, 234, 0.32); transition: left 0.32s cubic-bezier(0.4, 0, 0.2, 1), width 0.32s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; pointer-events: none; } /* Subtle divider between the cells group and the housing group inside the Cells tab. */ .panel-divider { height: 1px; background: linear-gradient(90deg, transparent, rgba(100, 149, 237, 0.22), transparent); margin: 18px 0 20px; } .preview-container { padding: 28px; display: flex; flex-direction: column; min-height: 0; } .section:hover { border-color: rgba(100, 149, 237, 0.4); box-shadow: 0 12px 40px rgba(100, 149, 237, 0.2); filter: brightness(1.02); transform: translateY(-3px); } .section h2 { color: #fff; font-size: 1.3em; margin-bottom: 20px; font-weight: 600; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .section:hover h2 { color: #6495ed; transform: translateX(4px) scale(1.02); text-shadow: 0 0 15px rgba(100, 149, 237, 0.3); } .section h3 { color: #94a3b8; font-size: 0.9em; margin-bottom: 12px; margin-top: 20px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; transition: color 0.2s ease; } .section:hover h3 { color: #cbd5e1; } /* Form Elements */ .form-group { margin-bottom: 20px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; } .form-group:hover { transform: translateX(2px) scale(1.005); background: rgba(100, 149, 237, 0.02); border-radius: 8px; } .form-group:has(select) { z-index: 100; } .form-group:hover { opacity: 1; } label { display: block; color: #cbd5e1; font-size: 0.9em; margin-bottom: 6px; font-weight: 500; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .form-group:hover label { color: #e2e8f0; filter: brightness(1.1); transform: scale(1.02) translateX(2px); } select, input[type="number"] { width: 100%; padding: 10px 12px; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(100, 149, 237, 0.2); border-radius: 6px; color: #e2e8f0; font-size: 0.95em; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type="number"] { -moz-appearance: textfield; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); isolation: isolate; } input[type="number"]:hover { border-color: rgba(100, 149, 237, 0.5); box-shadow: 0 4px 12px rgba(100, 149, 237, 0.2); filter: brightness(1.05); transform: translateY(-1px); } input[type="number"]:focus { outline: none; border-color: rgba(100, 149, 237, 0.6); background: rgba(0, 0, 0, 0.4); box-shadow: 0 0 0 3px rgba(100, 149, 237, 0.1); } select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M6 9L1 4h10z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 36px; cursor: pointer; } select:hover { border-color: rgba(100, 149, 237, 0.4); } select:focus { outline: none; border-color: rgba(100, 149, 237, 0.6); background: rgba(0, 0, 0, 0.4); } select option { background: #1e293b; color: #e2e8f0; padding: 10px; } .custom-select{position:relative;width:100%;isolation:isolate} .custom-select select{display:none} .select-selected{background:rgba(0,0,0,.3);border:1px solid rgba(100,149,237,.2);border-radius:6px;padding:10px 36px 10px 12px;color:#e2e8f0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;user-select:none;font-size:.95em;z-index:1;isolation:isolate} .select-selected:after{content:'';position:absolute;top:50%;right:12px;width:0;height:0;border:5px solid transparent;border-top-color:#94a3b8;transform:translateY(-30%);transition:transform .3s ease} .select-selected.select-arrow-active:after{transform:translateY(-50%) rotate(180deg);border-top-color:#6495ed} .select-selected:hover{border-color:rgba(100,149,237,.6);background:rgba(0,0,0,.4);box-shadow:0 4px 12px rgba(100,149,237,.2);filter:brightness(1.05);transform:translateY(-1px)} .select-items{position:absolute;background:#1e293b;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(100,149,237,.3);border-radius:8px;top:calc(100% + 4px);left:0;right:0;z-index:10000;max-height:0;overflow:hidden;opacity:0;visibility:hidden;transform:translateY(-15px) scale(0.95);transform-origin:top center;transition:max-height 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),opacity 0.3s ease,transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),visibility 0s 0.4s;box-shadow:0 10px 40px rgba(0,0,0,.5);pointer-events:none} .select-items.show{max-height:300px;opacity:1;visibility:visible;transform:translateY(0) scale(1);overflow-y:auto;transition-delay:0s;pointer-events:auto} .select-items div{padding:12px 16px;color:#cbd5e1;cursor:pointer;transition:all .2s ease;border-left:3px solid transparent;font-size:.95em;opacity:0;transform:translateX(-10px)} .select-items.show div{opacity:1;transform:translateX(0)} .select-items.show div:nth-child(1){transition-delay:.05s} .select-items.show div:nth-child(2){transition-delay:.08s} .select-items.show div:nth-child(3){transition-delay:.11s} .select-items.show div:nth-child(4){transition-delay:.14s} .select-items.show div:nth-child(5){transition-delay:.17s} .select-items div:hover{background:rgba(100,149,237,.15);color:#fff;border-left-color:#6495ed;padding-left:20px} .select-items div.same-as-selected{background:rgba(100,149,237,.2);color:#6495ed;font-weight:600;border-left-color:#6495ed} .select-items::-webkit-scrollbar{width:6px} .select-items::-webkit-scrollbar-track{background:rgba(0,0,0,.2);border-radius:3px} .select-items::-webkit-scrollbar-thumb{background:rgba(100,149,237,.4);border-radius:3px} .select-items::-webkit-scrollbar-thumb:hover{background:rgba(100,149,237,.6)} .select-hide{display:none} /* Checkbox */ .checkbox-group { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; transition: all 0.2s ease; } .checkbox-group:hover { filter: brightness(1.1); transform: translateX(3px); } input[type="checkbox"] { width: 22px; height: 22px; cursor: pointer; position: relative; appearance: none; background: rgba(0, 0, 0, 0.3); border: 2px solid rgba(100, 149, 237, 0.3); border-radius: 6px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); outline: none; overflow: hidden; } input[type="checkbox"]::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); transform: translate(-50%, -50%); transition: width 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), height 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); } input[type="checkbox"]:checked::before { width: 150%; height: 150%; } input[type="checkbox"]:hover { border-color: rgba(100, 149, 237, 0.6); background: rgba(100, 149, 237, 0.1); transform: scale(1.05); } input[type="checkbox"]:active { transform: scale(0.95); } input[type="checkbox"]:checked { border-color: #667eea; background: transparent; } input[type="checkbox"]:checked::after { content: '✓'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0); color: white; font-size: 14px; font-weight: bold; z-index: 1; animation: checkmarkPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s forwards; } @keyframes checkmarkPop { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0) rotate(-45deg); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.3) rotate(10deg); } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); } } input[type="checkbox"]:focus { box-shadow: 0 0 0 3px rgba(100, 149, 237, 0.2); } .checkbox-group label { margin-bottom: 0; cursor: pointer; transition: color 0.2s ease; } .checkbox-group:hover label { color: #fff; } /* Button */ .btn { width: 100%; padding: 14px 24px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #fff; border: none; border-radius: 8px; font-size: 1em; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); margin-top: 8px; position: relative; overflow: hidden; isolation: isolate; } .btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); transition: left 0.5s ease; } .btn:hover::before { left: 100%; } .btn:hover { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(102, 126, 234, 0.4); filter: brightness(1.1); animation: pulse 2s ease-in-out infinite; } .btn:active { transform: translateY(0) scale(0.98); box-shadow: 0 5px 10px rgba(102, 126, 234, 0.2); filter: brightness(0.95); animation: none; } /* Grid Layout */ .row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; transition: grid-template-columns 0.3s ease, gap 0.3s ease; } .row .form-group { margin-bottom: 0; } /* Preview */ .preview-container { background: rgba(15, 23, 42, 0.6); border: 1px solid rgba(100, 149, 237, 0.1); border-radius: 12px; padding: 36px; height: fit-content; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: fadeInUp 0.6s ease-out 0.3s backwards; } .preview-container:hover { border-color: rgba(100, 149, 237, 0.4); box-shadow: 0 12px 40px rgba(100, 149, 237, 0.2); filter: brightness(1.02); transform: translateY(-3px); } .preview-container h2 { margin-bottom: 20px; color: #fff; font-size: 1.3em; font-weight: 600; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .preview-container:hover h2 { color: #6495ed; transform: translateX(4px) scale(1.02); text-shadow: 0 0 15px rgba(100, 149, 237, 0.3); } .preview-container.updating { border-color: rgba(100, 149, 237, 0.4); } /* Dual-canvas layout */ .previews-row { display: flex; gap: 12px; flex: 1; min-height: 0; align-items: stretch; } .preview-face-wrap { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 6px; } .preview-face-wrap[hidden] { display: none !important; } .face-label { text-align: center; font-size: 0.85em; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: #94a3b8; padding: 2px 0; } #preview, #preview-bottom { width: 100%; height: min(calc(100vh - 280px), 580px); min-height: 380px; border: 1px solid rgba(100, 149, 237, 0.2); border-radius: 10px; background: #1e293b; display: block; cursor: grab; transition: border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1); } #preview:hover, #preview-bottom:hover { border-color: rgba(100, 149, 237, 0.5); } #preview:active { cursor: grabbing; } /* Busbar add-row: two buttons side by side */ .busbar-add-row { display: flex; gap: 8px; margin-top: 8px; } .busbar-add-row .btn-secondary { flex: 1; font-size: 0.85em; padding: 8px 6px; } /* Busbar controls row: face filter + right-side action buttons */ .busbar-controls-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; } .busbar-controls-right { display: flex; align-items: center; gap: 6px; } .busbar-face-filter { display: flex; border: 1px solid rgba(100, 149, 237, 0.25); border-radius: 6px; overflow: hidden; } .face-filter-btn { flex: 1; padding: 5px 10px; font-size: 0.78em; font-weight: 600; background: none; border: none; color: #64748b; cursor: pointer; transition: background 0.15s, color 0.15s; white-space: nowrap; } .face-filter-btn + .face-filter-btn { border-left: 1px solid rgba(100, 149, 237, 0.25); } .face-filter-btn.active { background: rgba(100, 149, 237, 0.2); color: #93c5fd; } .face-filter-btn:not(.active):hover { background: rgba(100, 149, 237, 0.08); color: #94a3b8; } .btn-clear-markings { padding: 5px 10px; font-size: 0.78em; font-weight: 600; background: none; border: 1px solid rgba(239, 68, 68, 0.25); border-radius: 6px; color: #94a3b8; cursor: pointer; white-space: nowrap; transition: background 0.15s, color 0.15s, border-color 0.15s; } .btn-clear-markings:hover { background: rgba(239, 68, 68, 0.1); border-color: rgba(239, 68, 68, 0.5); color: #ef4444; } .btn-dl-all { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; font-size: 0.78em; font-weight: 600; background: none; border: 1px solid rgba(100, 149, 237, 0.25); border-radius: 6px; color: #94a3b8; cursor: pointer; white-space: nowrap; transition: background 0.15s, color 0.15s, border-color 0.15s; } .btn-dl-all:hover { background: rgba(100, 149, 237, 0.1); border-color: rgba(100, 149, 237, 0.5); color: #93c5fd; } /* Per-busbar download button inside each row */ .busbar-dl { background: none; border: none; color: #64748b; cursor: pointer; padding: 0 5px; line-height: 1; border-radius: 4px; display: flex; align-items: center; transition: color 0.15s, background 0.15s; } .busbar-dl:hover { color: #93c5fd; background: rgba(100, 149, 237, 0.15); } /* Hide thickness label when DXF format is selected */ .busbar-list-dxf .busbar-thickness-label { display: none; } /* Face sections in busbar list */ .busbar-face-section { margin-bottom: 12px; } .busbar-face-label { font-size: 0.75em; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #64748b; padding: 4px 0 6px; border-bottom: 1px solid rgba(100, 149, 237, 0.12); margin-bottom: 6px; } .busbar-face-empty { font-size: 0.82em; color: #475569; padding: 4px 0; } #preview:active, #preview-bottom:active { cursor: grabbing; } #previewStats { margin-top: 12px; padding: 12px; background: rgba(0, 0, 0, 0.2); border-radius: 6px; text-align: center; font-size: 0.95em; color: #94a3b8; transition: all 0.3s ease; } #previewStats:hover { background: rgba(0, 0, 0, 0.3); color: #e2e8f0; } /* Loading Overlay */ .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(10, 15, 30, 0.95); backdrop-filter: blur(8px); display: none; justify-content: center; align-items: center; z-index: 9999; animation: fadeIn 0.3s ease; } .loading-overlay.active { display: flex; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .loading-content { text-align: center; animation: slideUp 0.4s ease; } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .spinner { width: 60px; height: 60px; border: 4px solid rgba(100, 149, 237, 0.2); border-top-color: #6495ed; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 24px; } @keyframes spin { to { transform: rotate(360deg); } } .loading-text { font-size: 1.2em; color: #fff; font-weight: 600; margin-bottom: 8px; } .loading-subtext { font-size: 0.95em; color: #94a3b8; } @keyframes fadeInUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0%, 100% { box-shadow: 0 4px 24px rgba(100, 149, 237, 0.3); } 50% { box-shadow: 0 4px 32px rgba(100, 149, 237, 0.5); } } @keyframes ripple { 0% { transform: scale(0); opacity: 0.5; } 100% { transform: scale(2); opacity: 0; } } /* Responsive Design */ @media (max-width: 1500px) { .main-layout { grid-template-columns: 420px 1fr; } #preview { height: 640px; } } @media (max-width: 1200px) { .main-layout { grid-template-columns: 1fr; } .config-sidebar { order: 2; } .preview-container { order: 1; } #preview { height: 520px; } } @media (max-width: 768px) { body { padding: 20px 16px; } .header-row { flex-direction: column; align-items: stretch; gap: 12px; margin-bottom: 12px; } h1 { font-size: 2em; margin-bottom: 0; } .subtitle { font-size: 0.95em; margin-bottom: 28px; } .repo-credit { font-size: 0.9em; margin: 0; padding: 10px 12px; text-align: left; max-width: none; } .section { padding: 24px; margin-bottom: 20px; } .preview-container { padding: 24px; } .row { grid-template-columns: 1fr; gap: 16px; } #preview { height: 400px; cursor: default; } .form-group { margin-bottom: 16px; } label { font-size: 0.9em; margin-bottom: 8px; } select, input[type="number"] { font-size: 16px; padding: 12px 14px; } .btn { padding: 14px 24px; font-size: 1em; } #copyShareUrlBtn { font-size: 1em; min-height: 48px; padding: 12px 16px; } .loading-text { font-size: 1.1em; } .loading-subtext { font-size: 0.9em; } } @media (max-width: 480px) { body { padding: 16px 12px; } h1 { font-size: 1.75em; } .section { padding: 20px; border-radius: 10px; } .preview-container { padding: 20px; } .section h2 { font-size: 1.2em; margin-bottom: 20px; } .section h3 { font-size: 0.85em; } #preview { height: 350px; } .spinner { width: 50px; height: 50px; } } /* Landscape orientation for mobile */ @media (max-width: 768px) and (orientation: landscape) { .main-layout { grid-template-columns: 300px 1fr; } .config-sidebar { order: 1; } .preview-container { order: 2; } #preview { height: 350px; } } /* Touch device optimizations */ @media (hover: none) and (pointer: coarse) { select, input[type="number"], .btn { min-height: 48px; font-size: 16px; } .checkbox-group input[type="checkbox"] { width: 28px; height: 28px; } .checkbox-group label { padding-left: 12px; } .form-group:hover { transform: none; background: transparent; } input[type="number"]:hover, select:hover, .btn:hover { transform: none; filter: none; } .btn:active { transform: scale(0.97); } #preview { cursor: default; touch-action: pan-x pan-y pinch-zoom; } } /* ── Copper Sheet Order Calculator ─────────────────────────────────────── */ .order-header { font-size: 0.72em; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #64748b; padding: 4px 0 10px; margin-top: 4px; } .order-placeholder { font-size: 0.85em; color: #475569; padding: 4px 0 8px; } .order-summary { background: rgba(0, 0, 0, 0.2); border: 1px solid rgba(100, 149, 237, 0.1); border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; display: flex; flex-direction: column; gap: 5px; } .order-summary-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 0.85em; } .order-label { color: #64748b; white-space: nowrap; } .order-value { color: #e2e8f0; font-weight: 600; text-align: right; } .order-muted { color: #64748b; font-weight: 400; font-size: 0.9em; } .order-table { width: 100%; border-collapse: collapse; font-size: 0.83em; margin-bottom: 4px; } .order-table th { text-align: left; padding: 5px 8px; color: #64748b; font-weight: 600; font-size: 0.9em; border-bottom: 1px solid rgba(100, 149, 237, 0.15); white-space: nowrap; } .order-table td { padding: 5px 8px; color: #cbd5e1; border-bottom: 1px solid rgba(100, 149, 237, 0.06); white-space: nowrap; } .order-table tr:last-child td { border-bottom: none; } .order-row-nofit td { color: #334155; } .order-row-best td { color: #fff; font-weight: 600; } .order-row-best td:last-child { color: #6ee7b7; } .order-table tr:not(.order-row-nofit):not(.order-row-best):hover td { background: rgba(100, 149, 237, 0.07); color: #e2e8f0; } .order-warning { display: flex; align-items: flex-start; gap: 7px; font-size: 0.82em; color: #fbbf24; background: rgba(251, 191, 36, 0.08); border: 1px solid rgba(251, 191, 36, 0.25); border-radius: 6px; padding: 7px 10px; margin-bottom: 8px; line-height: 1.4; } .order-warning strong { color: #fde68a; } .order-busbar-sizes { background: rgba(0, 0, 0, 0.15); border: 1px solid rgba(100, 149, 237, 0.08); border-radius: 6px; padding: 7px 12px; margin-bottom: 10px; display: flex; flex-direction: column; gap: 4px; } .order-busbar-size-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 0.82em; } /* Axis diagram — resolves width/depth confusion by showing which input maps to which on-screen dimension. Mirrors the canvas orientation: X horizontal, Y vertical, Z depth. */ .axis-diagram { display: flex; justify-content: center; align-items: center; padding: 8px 12px 4px; margin: -4px -4px 16px; background: rgba(0, 0, 0, 0.18); border: 1px solid rgba(100, 149, 237, 0.12); border-radius: 10px; } .axis-diagram svg { width: 100%; max-width: 260px; height: auto; display: block; } /* Busbars */ #busbarList { margin-bottom: 8px; } .busbar-empty { color: #94a3b8; font-size: 0.85em; font-style: italic; text-align: center; padding: 12px 8px; border: 1px dashed rgba(100, 149, 237, 0.2); border-radius: 6px; } .busbar-row { padding: 8px 10px; border: 1px solid rgba(100, 149, 237, 0.15); border-radius: 8px; margin-bottom: 6px; cursor: pointer; transition: all 0.2s ease; background: rgba(0, 0, 0, 0.2); } .busbar-row:hover { border-color: rgba(100, 149, 237, 0.35); background: rgba(0, 0, 0, 0.3); } .busbar-row.active { border-color: #6495ed; box-shadow: 0 0 0 1px rgba(100, 149, 237, 0.4), 0 4px 12px rgba(100, 149, 237, 0.15); background: rgba(100, 149, 237, 0.08); } .busbar-header { display: flex; align-items: center; gap: 8px; } .busbar-color-wrap { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; border-radius: 6px; overflow: hidden; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.15); background: rgba(255, 255, 255, 0.04); } .busbar-color { width: 100%; height: 100%; border: none; padding: 0; background: transparent; cursor: pointer; } .busbar-color::-webkit-color-swatch-wrapper { padding: 0; } .busbar-color::-webkit-color-swatch { border: none; border-radius: 0; } .busbar-color::-moz-color-swatch { border: none; border-radius: 0; } .busbar-name { flex: 1; min-width: 0; padding: 4px 6px; background: transparent; border: 1px solid transparent; color: #e2e8f0; font-size: 0.9em; border-radius: 4px; } .busbar-name:hover { border-color: rgba(100, 149, 237, 0.25); } .busbar-name:focus { outline: none; border-color: rgba(100, 149, 237, 0.6); background: rgba(0, 0, 0, 0.3); } .busbar-del { background: none; border: none; color: #94a3b8; cursor: pointer; font-size: 1.25em; padding: 0 6px; line-height: 1; border-radius: 4px; transition: all 0.15s ease; } .busbar-del:hover { color: #ef4444; background: rgba(239, 68, 68, 0.15); } .busbar-meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-top: 6px; padding-left: 24px; font-size: 0.8em; color: #94a3b8; } .busbar-overlap-label { display: inline-flex; align-items: center; gap: 6px; color: #cbd5e1; cursor: pointer; user-select: none; } .busbar-overlap { accent-color: #6495ed; } .busbar-overlap-size-label { display: inline-flex; align-items: center; gap: 6px; color: #94a3b8; font-size: 0.95em; } .busbar-overlap-size { width: 64px; padding: 3px 6px; font-size: 0.9em; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(100, 149, 237, 0.2); border-radius: 4px; color: #e2e8f0; } .busbar-overlap-size:focus { outline: none; border-color: rgba(100, 149, 237, 0.6); } .busbar-overlap-size:disabled { opacity: 0.45; cursor: not-allowed; } .busbar-thickness-label { display: flex; align-items: center; gap: 6px; color: #94a3b8; font-size: 0.95em; cursor: text; } .busbar-thickness { width: 64px; padding: 3px 6px; font-size: 0.9em; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(100, 149, 237, 0.2); border-radius: 4px; color: #e2e8f0; } .busbar-thickness:focus { outline: none; border-color: rgba(100, 149, 237, 0.6); } .busbar-blocked { margin-top: 6px; padding: 6px 8px; font-size: 0.8em; color: #ef4444; background: rgba(239, 68, 68, 0.08); border-radius: 4px; } .btn-secondary { width: 100%; padding: 10px 16px; background: rgba(100, 149, 237, 0.12); border: 1px solid rgba(100, 149, 237, 0.3); color: #e2e8f0; border-radius: 8px; cursor: pointer; font-size: 0.9em; font-weight: 500; transition: all 0.2s ease; margin-bottom: 12px; } .btn-secondary:hover { background: rgba(100, 149, 237, 0.22); border-color: rgba(100, 149, 237, 0.5); transform: translateY(-1px); } .btn-secondary:active { transform: translateY(0); } #copyShareUrlBtn { margin-top: 10px; margin-bottom: 0; min-height: 44px; } #copyShareUrlBtn.is-success { background: rgba(16, 185, 129, 0.26); border-color: rgba(16, 185, 129, 0.75); color: #ecfdf5; } #copyShareUrlBtn.is-error { background: rgba(239, 68, 68, 0.2); border-color: rgba(248, 113, 113, 0.75); color: #fee2e2; }