* {margin: 0;padding: 0;box-sizing: border-box} body {font-family: "Pretendard", sans-serif;min-height: 100vh;display: flex;background: #fff;color: #111} /* ───── Sidebar ───── */ .sidebar {width: 260px;border-right: 1px solid #ddd;padding: 32px 24px;display: flex;flex-direction: column} .sidebar h2 {font-size: 24px;margin-bottom: 32px} details.nav { margin-bottom: 24px } .nav > summary { list-style: none; cursor: pointer; display: flex; align-items: center; font-size: 20px } .nav > summary::before { content: ""; width: 8px; height: 8px; margin-right: 8px; border-left: 2px solid #111; border-bottom: 2px solid #111; transform: rotate(-135deg); transition: .2s } .nav[open] > summary::before { transform: rotate(-45deg) } .nav-items { display: flex; flex-direction: column; margin-top: 10px; padding-left: 16px; gap: 6px } .nav-items button { background: none; border: none; cursor: pointer; font-size: 16px; text-align: left; padding: 4px 0 } /* ───── Top-bar ───── */ .topbar { height: 68px; background: #d9d9d9; display: flex; align-items: center; justify-content: space-between; padding: 0 32px; font-size: 28px; font-weight: 500; box-shadow: 0 2px 4px rgba(0, 0, 0, .15) inset } .topbar-actions { display: flex; align-items: center; gap: 12px; } .topbar-file-actions { display: flex; align-items: center; gap: 12px; } .topbar-actions .file-upload-wrapper-device { display: flex; align-items: center; } .topbar-actions .file-upload-wrapper-protocol { display: flex; align-items: center; } .topbar-actions button { min-width: 140px; height: 40px; padding: 10px 18px; line-height: 1; font-size: 16px; border: 1px solid #bbb; border-radius: 4px; cursor: pointer; } .topbar-actions .select-file-btn-device, .topbar-actions .download-device-file { background: #2f6fdf; border-color: #245cc0; color: #fff; } .topbar-actions .select-file-btn-device:hover, .topbar-actions .download-device-file:hover { background-color: #245cc0; } .topbar-actions .select-file-btn-device:active, .topbar-actions .download-device-file:active { background-color: #1d4da3; transform: scale(0.97); } .topbar-actions .select-file-btn-protocol, .topbar-actions .download-protocol-file { background: #d97706; border-color: #b85f00; color: #fff; } .topbar-actions .select-file-btn-protocol:hover, .topbar-actions .download-protocol-file:hover { background-color: #b85f00; } .topbar-actions .select-file-btn-protocol:active, .topbar-actions .download-protocol-file:active { background-color: #924b00; transform: scale(0.97); } .topbar-actions .save-file { background-color: #4caf50; border-color: #3f9a43; color: #fff; } .topbar-actions .save-file:hover { background-color: #45a049; } .topbar-actions .save-file:active { background-color: #3e8e41; transform: scale(0.97); } /* ───── Main Board ───── */ .content { flex: 1; display: flex; flex-direction: column } .board { flex: 1; overflow: auto; padding: 40px; display: flex; flex-direction: column; gap: 32px } .card { background: #fff; border: 1px solid #e5e5e5; box-shadow: 0 2px 4px rgba(0, 0, 0, .15) inset; padding: 32px; border-radius: 8px } .card h3 { font-size: 24px; margin-bottom: 24px } /* SSID rows */ .ssid-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } .ssid-row input.ssid-name, .ssid-row input.ssid-pw { width: 200px; padding: 6px 8px; font-size: 16px; border: 1px solid #aaa; border-radius: 4px; } .ssid-row .toggle-pw { padding: 6px 10px; font-size: 14px; border: 1px solid #aaa; background-color: #eee; border-radius: 4px; cursor: pointer; min-width: 60px; text-align: center; } .ssid-row .toggle-pw:hover { background-color: #cecece; } .ssid-row .toggle-pw:active { background-color: #bdbdbd; transform: scale(0.97); } .ssid-row select { width: 100px; padding: 6px 8px; font-size: 16px; border: 1px solid #aaa; border-radius: 4px; } .ssid-row .delete-ssid { padding: 6px 10px; font-size: 14px; background-color: #ffdddd; border: 1px solid #aaa; border-radius: 4px; cursor: pointer; } .ssid-row .delete-ssid:hover { background-color: #ffaaaa; } .ssid-row .delete-ssid:active{ background-color: #fd9e9e; transform: scale(0.97); } .icon-button { font-size: 10px; background-color: #f0f0f0; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer; transition: background-color 0.2s ease; } .icon-button:hover { background-color: #dcdcdc; } .icon-button:active { background-color: #c0c0c0; } .ssid-country-code { display: flex; align-items: center; gap: 12px; margin-top: 16px; } .ssid-country-code label { min-width: 100px; font-weight: 600; } .ssid-country-code input { width: 80px; padding: 6px 8px; font-size: 16px; border: 1px solid #aaa; border-radius: 4px; text-transform: uppercase; } .separate-setting-card { margin-top: 16px; } .field-hint { color: #666; font-size: 13px; } /* 3-column grids (Network / Server) */ .grid-3-col { display: grid; grid-template-columns: 180px 220px 100px; /* SSID와 유사하게 축소 */ align-items: center; gap: 12px; margin: 8px 0; } .grid-3-col input { padding: 6px 8px; font-size: 16px; border: 1px solid #aaa; border-radius: 4px; /* 기존 1px → 4px 통일 */ width: 100%; /* grid item 내에서만 퍼지므로 유지 가능 */ } .grid-3-col input::placeholder { color: #999; } /* radio */ .radio-group {display: flex;align-items: center;gap: 24px} .radio-label {display: inline-flex;align-items: center;gap: 4px;cursor: pointer} .radio-label input {margin: 0} /* I/O */ .io-top {display: grid;grid-template-columns:repeat(auto-fit, minmax(360px, 1fr));gap: 40px;margin-bottom: 32px} .io-bot {display: grid; /* Ethernet·LTE와 같은 2열(가변) 그리드 */grid-template-columns:repeat(auto-fit, minmax(360px, 1fr));gap: 40px;} .io-group {display: flex;flex-direction: column;gap: 8px} .io-group h4 {font-size: 20px;font-weight: 600;margin-bottom: 16px;display: flex;align-items: center;gap: 8px} .io-group h4::before {content: "";width: 8px;height: 8px;background: #aaa;display: inline-block} .io-fieldset {border: 1px solid #bbb;padding: 24px 32px;border-radius: 4px;display: flex;flex-direction: column;gap: 16px;width: 100%} .io-row {display: grid;grid-template-columns:120px 12px 1fr;align-items: center;gap: 8px} .io-row input, .io-row select {padding: 4px 6px;border: 1px solid #aaa;border-radius: 4px;font-size: 14px;width: 50%} .io-row span.label {font-size: 14px;color: #333;display: block;width: 100%;} .io-row span.label-inline {font-size: 14px;color: #333;display: inline;width: auto} .io-row span.colon {font-size: 14px;color: #333;text-align: center;} .reg-io-grid {display: grid;grid-template-columns: 1fr 1fr;gap: 4px} .reg-io-grid .io-fieldset .io-row {display: grid;grid-template-columns: 140px 220px;align-items: center;gap: 4px;margin-bottom: 8px;} /* config 내부 라벨 */ .reg-io-grid .io-fieldset .io-row span.label {font-size: 14px;color: #333;} .reg-io-grid .io-fieldset .io-row input, .reg-io-grid .io-fieldset .io-row select {padding: 4px 6px;border: 1px solid #aaa;border-radius: 4px;font-size: 14px;width: 100%;box-sizing: border-box;} .reg-io-grid .io-fieldset .io-row.checkbox-group {display: flex;align-items: center;gap: 16px;grid-column: 2 / 3;} .reg-io-grid .io-fieldset .io-row .checkbox-with-text {display: flex;align-items: center;gap: 10px;width: 100%;} .reg-io-grid .io-fieldset .io-row .checkbox-with-text input[type="checkbox"] {width: auto;margin: 0;} /* 비활성 input 시각화 */ .disabled {background: #f5f5f5;cursor: not-allowed} /* Footer Buttons */ .actions {display: flex;gap: 24px;justify-content: center;padding: 20px} .actions button {min-width: 140px;padding: 10px 18px;font-size: 16px;border: 1px solid #bbb;background: #d9d9d9;border-radius: 4px;cursor: pointer} .actions button:hover {background-color: #bdbdbd;} .actions button:active {background-color: #bdbdbd; transform: scale(0.97);} .config-actions{display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} .config-actions button{min-width:140px;padding:10px 18px;font-size:16px;border:1px solid #bbb;background:#d9d9d9;border-radius:4px;cursor:pointer} .topbar { display: flex; justify-content: space-between; align-items: center; padding: 0 32px; height: 68px; background: #d9d9d9; font-size: 28px; font-weight: 500; box-shadow: 0 2px 4px rgba(0, 0, 0, .15) inset; } .save-file { font-size: 16px; padding: 8px 16px; background-color: #4caf50; color: white; border: none; border-radius: 4px; cursor: pointer; } .save-file:hover { background-color: #45a049;; } .save-file:active { background-color: #3e8e41; transform: scale(0.97); } /* MODBUS 화면 심플 스타일 */ #page-modbus .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} #page-modbus table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #page-modbus th, #page-modbus td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} #page-modbus th {background: #e5e5e5;font-weight: 500;} #page-modbus tbody td {height: 34px;vertical-align: middle;} #page-modbus td input, #page-modbus td select {width: 100%;border: 1px solid #c7c7c7;border-radius: 2px;padding: 6px 8px;background: #fdfdfd;font: inherit;box-sizing: border-box;} /* 하단 버튼 영역 */ #modbus-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} #modbus-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} /* OPC_UA 화면 */ #page-opcua .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} #page-opcua table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #page-opcua th, #page-opcua td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} #page-opcua th {background: #e5e5e5;font-weight: 500;} #page-opcua tbody td {height: 34px;vertical-align: middle;} #page-opcua td input, #page-opcua td select {width: 100%;border: 1px solid #c7c7c7;border-radius: 2px;padding: 6px 8px;background: #fdfdfd;font: inherit;box-sizing: border-box;} #opcUa-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} #opcUa-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} /* CAN 화면 스타일 */ #page-can .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} #page-can table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #page-can th, #page-can td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} #page-can th {background: #e5e5e5;font-weight: 500;} #page-can tbody td {height: 34px;vertical-align: middle;} #page-can tbody td > span:empty::before {content: "\00a0";} #page-can td input, #page-can td select {width: 100%;border: 1px solid #c7c7c7;border-radius: 2px;padding: 6px 8px;background: #fdfdfd;font: inherit;box-sizing: border-box;} #can-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} #can-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} .inline-table-actions {display: flex;justify-content: flex-end;margin-top: 16px;} .inline-table-actions button, .inline-delete-btn {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 8px 16px;font-size: 14px;cursor: pointer;} /* Odometer page styles */ #page-odometer .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} #page-odometer table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #page-odometer th, #page-odometer td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} #page-odometer th {background: #e5e5e5;font-weight: 500;} #page-odometer tbody td {height: 34px;vertical-align: middle;} #page-odometer td input, #page-odometer td select {width: 100%;padding: 4px 6px;border: 1px solid #aaa;border-radius: 4px;font-size: 14px;background: #fff;box-sizing: border-box;} #odometer-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} #odometer-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} .selected-row {background: #d0e6ff !important;} .selected-row > td {background: #d0e6ff !important;} .file-upload-section{padding: 10px;margin: 10px;text-align: center;}