:root{--bg:#f4f5f7;--panel:#fff;--line:#d9dde3;--text:#1c2430;--muted:#6b7686;--accent:#0f7a4a;--accent-soft:#e3f4ec;--laser:#e5322d;--warn:#b45309;--warn-soft:#fff4e0;color:var(--text);font-family:system-ui,Segoe UI,Roboto,sans-serif;font-size:16px}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--bg);overscroll-behavior:none;-webkit-tap-highlight-color:transparent}.app{grid-template:"top top""stage side"1fr/1fr 340px;height:100%;display:grid}button,input,.file{font:inherit;color:inherit;border:1px solid var(--line);background:var(--panel);border-radius:10px;min-height:46px;padding:0 14px}button{cursor:pointer;white-space:nowrap}button:active:not(:disabled){background:var(--bg)}button:disabled{opacity:.45;cursor:default}button.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}button.primary{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}button.link{min-height:32px;color:var(--accent);background:0 0;border:0;padding:0;font-size:.9rem;text-decoration:underline}button.link.danger{color:var(--laser)}.big{width:100%;min-height:54px}:focus-visible{outline:3px solid var(--accent);outline-offset:2px}.topbar{background:var(--panel);border-bottom:1px solid var(--line);grid-area:top;align-items:center;gap:8px;padding:8px 12px;display:flex;overflow-x:auto}.topbar .icon{padding:0 12px;font-size:1.4rem}.topbar .name{flex:0 240px;min-width:160px;font-weight:600}.spacer{flex:1}.seg{display:flex}.seg button{border-radius:0}.seg button:first-child{border-radius:10px 0 0 10px}.seg button:last-child{border-radius:0 10px 10px 0;margin-left:-1px}.stage{grid-area:stage;min-width:0;min-height:0;position:relative}.canvas{touch-action:none;-webkit-user-select:none;user-select:none;background:#fbfcfd;width:100%;height:100%;display:block}.canvas.tool-draw{cursor:crosshair}.grid-line{fill:none;stroke:#e3e7ec;stroke-width:1px}.room-fill{fill:#0f7a4a12;stroke:none}.wall line{stroke:#8a94a3;stroke-width:4px;stroke-linecap:round;stroke-dasharray:2 9}.wall.measured line{stroke:#1c2430;stroke-dasharray:none}.wall.mismatch line{stroke:var(--warn)}.wall.selected line{stroke:var(--laser);stroke-width:7px;stroke-dasharray:none}.wall text{fill:var(--muted);paint-order:stroke;stroke:#fbfcfd;stroke-width:5px;stroke-linejoin:round;pointer-events:none;font-size:15px}.wall.measured text{fill:var(--text);font-weight:700}.wall.mismatch text{fill:var(--warn)}.wall.selected text{fill:var(--laser);font-weight:700}.vertex{fill:#fff;stroke:#1c2430;stroke-width:2.5px}.vertex.selected{fill:var(--laser);stroke:#fff}.vertex.closer{fill:var(--accent-soft);stroke:var(--accent);stroke-width:3px}.hint{color:#fff;pointer-events:none;background:#1c2430e0;border-radius:10px;max-width:calc(100% - 24px);padding:8px 12px;font-size:.9rem;position:absolute;bottom:12px;left:12px}.side{border-left:1px solid var(--line);flex-direction:column;grid-area:side;gap:10px;padding:10px;display:flex;overflow-y:auto}.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;flex-direction:column;gap:10px;padding:12px;display:flex}.card h2{letter-spacing:.06em;text-transform:uppercase;color:var(--muted);justify-content:space-between;align-items:center;margin:0;font-size:.8rem;display:flex}.card h2 .link{text-transform:none;letter-spacing:0}.row{gap:8px;display:flex}.row>*{flex:1;min-width:0}.row button{white-space:normal;padding:4px 8px;font-size:.92rem;line-height:1.15}.note{color:var(--muted);margin:0;font-size:.88rem}.note.warn{color:var(--warn);background:var(--warn-soft);border-radius:8px;padding:8px 10px}.status{align-items:center;gap:8px;font-weight:600;display:flex}.status .dot{background:#b6bdc8;border-radius:50%;width:12px;height:12px}.status.on .dot{background:var(--accent)}.status.connecting .dot{background:var(--warn)}.last{gap:2px;display:grid}.last span{color:var(--muted);font-size:.8rem}.last strong{font-variant-numeric:tabular-nums;font-size:2.2rem;line-height:1.1}.last em{color:var(--warn);font-size:.85rem;font-style:normal}.log{color:#cfe8d8;white-space:pre-wrap;word-break:break-all;background:#10151c;border-radius:8px;max-height:200px;margin:0;padding:8px;font-size:.72rem;overflow:auto}dl{grid-template-columns:auto 1fr;gap:4px 12px;margin:0;display:grid}dt{color:var(--muted)}dd{text-align:right;font-variant-numeric:tabular-nums;margin:0;font-weight:700}.walls{gap:6px;margin:0;padding:0;list-style:none;display:grid}.walls button{justify-content:space-between;gap:8px;width:100%;display:flex}.walls .muted{color:var(--muted)}.walls .ok{font-variant-numeric:tabular-nums;font-weight:700}.walls .warn{color:var(--warn);font-weight:700}.file{cursor:pointer;justify-content:center;align-items:center;display:flex;position:relative}.file input{opacity:0;cursor:pointer;position:absolute;inset:0}.slider{color:var(--muted);gap:4px;font-size:.88rem;display:grid}.slider input{min-height:36px;accent-color:var(--accent);border:0;padding:0}.opening .gap{stroke:#fbfcfd;stroke-width:9px}.opening path,.opening polygon,.opening line:not(.gap){fill:none;stroke:#2563a8;stroke-width:2px}.opening polygon{fill:#fbfcfd}.opening text{fill:#2563a8;paint-order:stroke;stroke:#fbfcfd;stroke-width:4px;pointer-events:none;font-size:12px}.opening.selected path,.opening.selected polygon,.opening.selected line:not(.gap){stroke:var(--laser);stroke-width:3.5px}.opening.selected text{fill:var(--laser);font-weight:700}.room-name{fill:var(--muted);pointer-events:none;font-size:14px;font-weight:600}.opening.fixed polygon{fill:#f3e8ff;stroke:#7c3aed}.opening.fixed text{fill:#7c3aed}.room-fill.selected{fill:#0f7a4a2e;stroke:var(--accent);stroke-width:2px;stroke-dasharray:6 5}.diag line{stroke:#8a94a3;stroke-width:2px;stroke-dasharray:8 6}.diag text{fill:var(--muted);paint-order:stroke;stroke:#fbfcfd;stroke-width:4px;pointer-events:none;font-size:13px}.diag.measured line{stroke:#1c2430}.diag.measured text{fill:var(--text);font-weight:700}.diag.mismatch line,.diag.mismatch text{stroke:var(--warn);fill:var(--warn)}.diag.mismatch text{stroke:#fbfcfd}.diag.selected line{stroke:var(--laser);stroke-width:4px}.diag.selected text{fill:var(--laser);font-weight:700}.vertex-no{fill:var(--muted);pointer-events:none;font-size:12px}.link-label{fill:#7a4b00;paint-order:stroke;stroke:#fbfcfd;stroke-width:4px;pointer-events:none;font-size:12px;font-weight:700}.topbar select,.card select{font:inherit;border:1px solid var(--line);background:var(--panel);min-height:46px;color:inherit;border-radius:10px;padding:0 10px}.card select{width:100%}.card.current{border-color:var(--accent)}.row.wrap{flex-wrap:wrap}.row.wrap>*{flex:0 0 56px}.row .num{flex:1;min-width:0}.sub{border-top:1px dashed var(--line);gap:8px;padding-top:10px;display:grid}.sub strong{justify-content:space-between;align-items:center;gap:8px;font-size:.9rem;display:flex}.inline{color:var(--muted);justify-content:space-between;align-items:center;gap:8px;font-size:.85rem;display:flex}.inline input{text-align:right;width:84px;min-height:38px}.modal{z-index:10;background:#1c243080;place-items:center;padding:16px;display:grid;position:fixed;inset:0}.modal .card{width:min(100%,900px);max-height:100%;overflow:hidden}.modal h2 .row{flex:none}.modal h2 button{text-transform:none;letter-spacing:0;color:var(--text)}.table-wrap{gap:16px;display:grid;overflow:auto}table{border-collapse:collapse;font-variant-numeric:tabular-nums;width:100%;font-size:.92rem}th,td{border-bottom:1px solid var(--line);text-align:right;white-space:nowrap;padding:8px 10px}th:first-child,td:first-child,th:nth-child(2),td:nth-child(2){text-align:left}th{color:var(--muted);font-size:.78rem;font-weight:600}tfoot td{border-bottom:0;font-weight:700}.num{color:var(--muted);gap:4px;font-size:.88rem;display:grid}.num div{gap:8px;display:flex}.num input{font-variant-numeric:tabular-nums;flex:1;min-width:0}.num button{flex:0 0 50px;padding:0;font-size:1.3rem}.num.armed input{border-color:var(--laser);box-shadow:0 0 0 2px #e5322d33}.num.armed button{background:var(--laser);border-color:var(--laser);color:#fff}.card>input{width:100%}.cloud{color:var(--muted);white-space:nowrap;padding:0 4px;font-size:.82rem}.cloud.ok{color:var(--accent)}.cloud.auth,.cloud.error{color:var(--warn)}.login{place-items:center;min-height:100%;padding:16px;display:grid}.login form{text-align:center;align-items:stretch;gap:16px;width:min(100%,380px);padding:28px 24px}.login img{border-radius:16px;margin:0 auto}.login h1{margin:0;font-size:1.3rem}.login label{text-align:left;color:var(--muted);gap:6px;font-size:.9rem;display:grid}.login input{width:100%;min-height:54px;font-size:1.1rem}.user-row{justify-content:space-between;align-items:center;gap:8px;min-height:40px;display:flex}.user-form{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));align-items:center;gap:8px;display:grid}.check{align-items:center;gap:8px;display:flex}.check input{width:22px;height:22px;min-height:0;accent-color:var(--accent)}.loading{height:100%;color:var(--muted);place-items:center;display:grid}.projects{flex-direction:column;height:100%;display:flex}.projects .title{padding:0 6px;font-size:1.2rem}.projects-body{flex:1;align-content:start;gap:14px;width:100%;max-width:860px;margin:0 auto;padding:16px;display:grid;overflow-y:auto}.project-list{gap:10px;margin:0;padding:0;list-style:none;display:grid}.project-list li{gap:8px;display:flex}.project-list .open{text-align:left;flex:1;align-content:center;gap:2px;min-height:68px;padding:8px 16px;display:grid}.project-list .open span{color:var(--muted);font-size:.85rem}.project-list li.current .open{border-color:var(--accent);background:var(--accent-soft)}.project-list .danger{color:var(--laser);min-height:68px}.empty{text-align:center;color:var(--muted);padding:40px 0}@media print{.topbar,.side,.hint,.modal,.vertex-no{display:none!important}.app{height:100vh;display:block}.stage{height:100vh}.grid-line{stroke:none}.vertex{display:none}}@media (width<=820px),(orientation:portrait){.app{grid-template:"top""stage"55fr"side"45fr/minmax(0,1fr)}.side{border-left:0;border-top:1px solid var(--line)}}@media (orientation:portrait) and (width>=700px){.side{grid-template-columns:1fr 1fr;align-content:start;display:grid}}@media (width<=600px){.topbar{gap:6px;padding:6px 8px}.topbar button{padding:0 10px;font-size:.9rem}.topbar .name{min-width:120px}.cloud{display:none}.hint{font-size:.8rem;bottom:8px;left:8px}.projects-body{padding:10px}.project-list .danger{padding:0 10px;font-size:.85rem}}
