:root { --accent: #5a9fd4; --menu-blue: #0079ff; --menu-back: rgba(60,60,60,0.75); --border: #444; --selected: rgba(90,159,212,0.5); --selected-hover: rgba(90,159,212,1); } @font-face { font-family: 'Russo One'; src: url('../moto/russo-one.ttf'); } /** defaults */ a, a:hover, a:visited { border: none; color: inherit; text-decoration: none; } body, div { font-family: system-ui, Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; position: relative; display: flex; padding: 0; border: 0; margin: 0; white-space: nowrap; } hr { width: 100%; border: 0; margin: 0; padding: 0; height: 0.5px; max-height: 0.5px; border-top: 0.5px solid rgba(0,0,0,0.5); } input { background-color: #eee; border-radius: 3px; border: 1px solid black; } #app { position: fixed; overflow: hidden; flex-direction: column; font-family: sans-serif; font-weight: normal; font-size: larger; background: #0f1116; bottom: 0; right: 0; left: 0; top: 0; } #app.booting #top, #app.booting #app-body { pointer-events: none; } #app-body { flex-grow: 1; } #app-body > div { z-index: 2; } #curtain { z-index: 50000; top: 0; left: 0; right: 0; bottom: 0; position: fixed; background: radial-gradient(circle at 50% 40%, #1a2436 0%, #0f1116 60%, #0a0c11 100%); color: #d7deea; font-family: 'Russo One', sans-serif; font-size: 16px; letter-spacing: 0.08em; text-transform: uppercase; text-shadow: 0 1px 2px rgba(0,0,0,0.35); justify-content: center; align-items: center; } #container { z-index: 1; position: fixed; background: #0f1116; width: 100%; height: 100%; } #container canvas { width: 100%; height: 100%; overflow: hidden; } #top { z-index: 50; color: #eee; font-size: 14px; flex-direction: row; background-color: var(--menu-back); border-bottom: 1px solid var(--border); } .noselect { -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } :-moz-any() { overflow-x: hidden !important; overflow-y: hidden !important; } :-moz-any() { overflow-x: scroll !important; overflow-y: scroll !important; margin-right: -14px !important; margin-bottom: -14px !important; } #modal button { border-radius: 3px; } button { padding: 2px 3px 2px 3px; border: 1px solid rgba(150,150,150,0.5); background-color: rgba(220,220,220,0.75); user-select: none; outline: none; } button:hover { background-color: rgba(220,220,220,1); } /** misc ui **/ .grow { flex-grow: 1; } .hide { display: none; } .pad3 { width: 3px; height: 3px; } .pad5 { width: 5px; height: 5px; } #top-left { margin-left: 5px; flex-direction: row; padding: 0 !important; } .title { cursor: default; align-self: stretch; align-items: center; margin: 4px 0 4px 0; padding: 4px 12px 4px 12px; border-radius: 0; user-select: none; font-weight: bold; color: var(--accent); } .menubar-separator { align-self: stretch; align-items: center; background: rgba(255,255,255,0.2); margin: 5px; width: 1px; } .toolbar-separator { align-self: stretch; align-items: center; background: rgba(255,255,255,0.2); margin: 2px; height: 1px; } .menu, #top-doc-name, #top-mode-label { cursor: default; align-self: stretch; align-items: center; padding: 8px 12px 8px 12px; border: 1px solid transparent; border-radius: 6px; user-select: none; margin: 2px; } .menu hr { border-top: 0.5px solid rgba(255,255,255,0.5); } .menu:hover, .menu-items > div:hover, .tools i:hover { border: 1px solid var(--accent); background-color: rgba(0,0,0,0.5); } .menu:hover .menu-items { display: flex; } .menu-items { display: none; position: absolute; flex-direction: column; border: 1px solid var(--border); border-radius: 6px; background: var(--menu-back); padding: 4px; top: calc(100% + 3px); left: 0; gap: 6px; } /* invisible bridge between menu label and pop menu */ .menu-items::before { content: ""; position: absolute; top: -20px; left: -10px; right: -10px; height: calc(100% + 20px); background: transparent; } .menu-items > div { gap: 15px; border: 1px solid transparent; border-radius: 6px; padding: 4px 8px 4px 8px; } .menu-items .short { gap: 1px; } #top-left:not(:hover) #mode-label { display: flex; } #top-mid { flex-grow: 1; } #top-right { flex-direction: row; margin-right: 5px; padding: 0 !important; } #top-right > div { gap: 8px; } #top-mode-label { color: var(--accent); white-space: nowrap; justify-content: flex-end; text-transform: capitalize; } #top-doc-name { cursor: pointer; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; justify-content: flex-end; border-color: #404040; background-color: #202020; transition: border-color 0.15s, color 0.15s; } #top-doc-name:hover { border-color: var(--accent); background-color: rgba(0,0,0,0.5); } /** specific modal dialogs */ .export { flex-direction: column; font-family: monospace; } .export, .export div { gap: 4px; align-items: center; justify-content: center; } .export input, .export button { font-family: monospace; padding: 3px; } .export button { padding: 4px; } .addact { gap: 4px; } .addact input, .additem input { text-align: center; } .additem { gap: 5px 10px; display: grid; grid-template-columns: 1fr 50px; } /* .additem hr { width: 100%; } */ .additem button, .additem hr, .additem code { grid-column: span 2; text-align: center; } .doc-open-list { display: flex; flex-direction: column; min-width: 420px; max-height: 60vh; overflow: auto; gap: 6px; } .doc-open-row { display: flex; align-items: center; gap: 8px; border: 1px solid var(--menu-border, #bbb); border-radius: 6px; padding: 6px 8px; } .doc-open-row:hover { background-color: var(--menu-blue); } .doc-open-name { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .doc-open-empty { padding: 8px; text-align: center; opacity: 0.7; } .doc-open-new { width: 100%; } .doc-open-del { min-width: 28px; padding: 2px 8px; font-weight: 700; } .image-import { flex-direction: column; gap: 3px; } .image-import label { padding-right: 5px; flex-grow: 1; } .image-import input { text-align: center; } .image-import button { margin: 10px 20px 1px 20px; flex-grow: 1; } /** generic modal dialogs **/ #modal_page { background-color: rgba(0,0,0,0.25); justify-content: center; align-items: center; position: absolute; z-index: 500 !important; bottom: 0; right: 0; left: 0; top: 0; display: none; } #modal_frame { background-color: rgba(30,30,30,0.9); border: 1px solid var(--border); border-radius: 4px; color: white; flex-direction: column; gap: 2px; margin: 0 0 2px 0; padding: 3px; } #modal_frame a { color: var(--accent); } #modal_frame > div { flex-direction: column; padding: 5px; /* compensate for removing padding above */ } #modal_title { color: white; border-radius: 2px; border-bottom: 1px solid rgba(0,0,0,0.2); background-color: rgba(60,60,60,0.7); font-family: 'Russo One', monospace; font-size: smaller; justify-content: center; align-items: center; } #modal_title_close { position: absolute; color: #999; right: 3px; top: 2px; } #modal_title_close:hover { color: #eee; } /** welcome dialog **/ .welcome { font-size: smaller; flex-direction: column; align-items: center; padding: 5px; gap: 5px; } .welcome a { border-radius: 3px; padding: 2px 10px 2px 10px; } .welcome a:hover { background-color: #111; } .welcome .choice { gap: 5px } /** settings dialog **/ .settings { gap: 5px; display: grid; /* background-color: #fff; */ grid: min-content 1fr / min-content 1fr; grid-template-columns: 1fr 1fr 1fr; } .settings > div { display: grid; background-color: rgba(0,0,0,0.1); grid: min-content 1fr / min-content 1fr; white-space: nowrap; align-items: center; border: 1px solid rgba(100,100,100,0.7); border-radius: 3px; padding: 3px; } .settings .header { grid-column: 1 / 3; text-align: center; margin-bottom: 5px; border-radius: 3px; background-color: rgba(100,100,100,0.8); padding: 0; } .settings label { padding: 0 5px 0 3px; } .settings input { font-family: monospace; text-align: center; background: #fff; justify-self: end; } /** spinner animation **/ @keyframes spinner { 0% { transform: translate3d(-50%, -50%, 0) rotate(0deg); } 100% { transform: translate3d(-50%, -50%, 0) rotate(360deg); } } .spin::before { position: absolute; animation: 2.0s linear infinite spinner; animation-play-state: inherit; border: solid 10px #cfd0d1; border-bottom-color: #1c87c9; border-radius: 50%; content: ""; height: 50px; width: 50px; top: 10%; left: 10%; transform: translate3d(-50%, -50%, 0); will-change: transform; } /** common look & feel */ #actions > div, #grouplist > div { border: 1px solid #555; border-radius: 3px; margin: 0 0 2px 0; padding: 3px; background-color: rgba(255,255,255,0.5); } #actions .vsep, #grouplist .vsep { margin: 1px 0 1px 0; border-bottom: 1px dashed gray; } .menu .selected { background-color: var(--selected); } .menu .selected:hover { background-color: var(--selected-hover); } /* .head { color: #000 !important; } */ /** slide in/out logging window **/ #logger { border-top: 1px solid var(--border); border-right: 1px solid var(--border); background-color: var(--menu-back); display: none; color: #ddd; min-width: 300px; flex-direction: column; position: absolute; margin: 0 0 0 1px; bottom: 0; left: 100%; padding: 5px; } #logtext { flex-direction: column; max-height: 8em; min-height: 1em; overflow-y: auto; } #logtext > div { font-family: monospace; font-size: 12px; } #logtext::-webkit-scrollbar { width: 6px; } #logtext::-webkit-scrollbar-track { background: transparent; } #logtext::-webkit-scrollbar-thumb { border-radius: 3px; background-color: #ddd; border: 3px solid rgba(255,255,255,0.1); } /** left menu sketch and object tool menus */ #tools { border-right: 1px solid var(--border); } .tools { align-items: flex-start; background-color: var(--menu-back); padding-top: 2px; } .tools > div { color: #fff; display: grid; grid-template-columns: 1fr; margin: 2px; } .tools i { padding: 9px; border: 1px solid transparent; border-radius: 6px; /* border-bottom: 1px solid var(--border); */ } .tool > div { display: none; position: absolute; padding-left: 10px; left: 100%; bottom: 0; top: 0; place-items: center; /* Center the single grid item */ height: 100%; width: 100%; } .tool label:before { content: ''; position: absolute; left: -2px; /* Adjust to position the caret */ top: 50%; transform: translateY(-50%); border-width: 6px; border-style: solid; border-color: transparent #ddd transparent transparent; } .tool label { font-size: 12px !important; background-color: var(--menu-back); border: 1px solid var(--border); border-radius: 4px; padding: 4px 6px 4px 6px; } .tool:hover > div { display: grid; } #script { margin: 5px 0px 5px 5px; /* margin-top: 5px; margin-left: 5px; */ flex-direction: column; justify-content: end; color: white; height: calc(100% - 10px); } #script-header { padding: 3px 5px 3px 5px; background-color: #333; border-top-left-radius: 3px; border-top-right-radius: 3px; border-top: 1px solid #999; border-left: 1px solid #999; border-right: 1px solid #999; flex-direction: row; gap: 3px; } #script-header button { border-radius: 3px; } #script-header .close { font-weight: bold; line-height: 1; } #script-editor { color: white; background-color: #222; outline: none; height: 100%; resize: none; } #script-error { flex-direction: column; font-family: monospace; } /** group/model buttons top/right of workspace **/ #grouplist { position: absolute; margin: 3px 3px 0 0; right: 0; top: 0; } #grouplist .selected { background-color: var(--selected); } #grouplist .selected:hover { background-color: var(--selected-hover); } #grouplist, #grouplist div { flex-direction: column; gap: 2px; } #grouplist .group { font-weight: bold; padding: 3px; } #grouplist .models { display: grid; grid-template-columns: auto min-content; max-height: 200px; overflow-y: auto; gap: 1px; } #grouplist .models .square { display: flex; align-items: center; justify-content: center; margin: 0; } #grouplist .models .square > svg { aspect-ratio: 1; max-height: 20px; color: #333; } #grouplist .models > div { flex-direction: row; } #grouplist .models button { text-align: left; } /** selection info bottom/right of workspace **/ #selectlist { font-size: smaller; position: absolute; margin: 0 3px 3px 0; bottom: 0; right: 0; gap: 2px; } #selectlist > .side { position: relative; width: 1.75em; display: none; } #selectlist > .side > div { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(-90deg); padding-bottom: 2px; } #selectlist > div { flex-direction: column; gap: 2px; } #selectlist > button, #selectlist > div > button { border-radius: 3px; } #selectlist label { border-radius: 3px; font-family: monospace; text-align: right; padding: 2px; background-color: rgba(0,0,0,0.05); } #selectlist .top { display: block; font-weight: bold; font-size: smaller; text-align: center; } #selectlist .side { font-weight: bold; font-size: smaller; align-items: center; justify-content: flex-end; } #selectlist .grid { background-color: rgba(255,255,255,0.8); border: 1px solid rgba(0,0,0,0.15); border-radius: 3px; padding: 3px; display: grid; flex-grow: 1; gap: 2px 2px; grid: min-content 1fr 1fr / min-content 1fr 1fr 1fr; } #selectlist .grid0 { display: flex; flex-grow: 1; flex-direction: column; justify-content: center; align-items: center; gap: 5px; } #selectlist .grid1 { grid: min-content 1fr / min-content 1fr; } #selectlist .grid2 { grid: min-content 1fr 1fr / min-content 1fr 1fr; } .grid .ungrouped { background-color: rgba(128,128,128,0.5) !important; } .grid .ungrouped:hover { color: #fff !important; } .tempedit, .rename { gap: 3px; } .tempedit input { text-align: center; } .editable { color: #05a; cursor: default; } .editable:hover { color: #000; background-color: rgba(0,128,255,0.5) !important; } #pinner-box { position: absolute; z-index: 5000; left: 50%; bottom: 50%; transform: translate(-50%, 50%); } #pinner { z-index: 5000; display: none; width: 50px; height: 50px; background-color: rgba(255,255,255,0.15); border: 12px solid rgba(255,255,255,0.25); border-radius: 50%; border-top-color: rgba(255,255,255,0.6); animation: spin 1.5s linear infinite; } @keyframes spin { to { transform: rotate(360deg) } } /* CMMS patch (not upstream): commit 913977ec made this stylesheet dark-only - it baked the dark palette into the base rules and deleted every .dark selector. The 3D scene follows the CMMS light/dark theme via set_darkmode() (src/main/mesh.js); this re-lights the surrounding chrome when the CMMS theme is light, keyed on #app NOT carrying the .dark class set_darkmode() toggles. Additive and scoped - the freestanding app is always dark, so #app:not(.dark) never matches there. Not exhaustive - transient surfaces (boot curtain, spinner) stay dark. */ #app:not(.dark) { --accent: #2563eb; --menu-blue: #2563eb; --menu-back: rgba(248,250,252,0.97); --border: #cbd5e1; background: #f1f5f9; color: #1e293b; } #app:not(.dark) #container { background: #f1f5f9; } #app:not(.dark) #top { color: #1e293b; } #app:not(.dark) #top-doc-name { border-color: #cbd5e1; background-color: #e2e8f0; } #app:not(.dark) #top-doc-name:hover { background-color: rgba(0,0,0,0.08); } #app:not(.dark) #modal_frame { background-color: rgba(248,250,252,0.97); color: #1e293b; } #app:not(.dark) #modal_title { color: #1e293b; background-color: rgba(226,232,240,0.9); } #app:not(.dark) #modal_title_close { color: #64748b; } #app:not(.dark) #modal_title_close:hover { color: #1e293b; } #app:not(.dark) .menu-items > div:hover { color: #1e293b; } #app:not(.dark) #logger { color: #334155; }