:root {
--viewer-canvas: var(--sx-gray-1);
--viewer-grid: var(--sx-gray-3);
--viewer-grid-soft: var(--sx-gray-2);
--viewer-highlight: var(--sx-blue-6);
--viewer-light-sky: var(--sx-white);
--viewer-light-ground: var(--sx-gray-3);
--viewer-left-width: var(--sx-app-navbar-width);
--viewer-right-width: 320px;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme='light']) {
--viewer-canvas: var(--sx-dark-8);
--viewer-grid: var(--sx-dark-4);
--viewer-grid-soft: var(--sx-dark-5);
--viewer-light-sky: var(--sx-dark-0);
--viewer-light-ground: var(--sx-dark-8);
}
}
:root[data-theme='dark'] {
--viewer-canvas: var(--sx-dark-8);
--viewer-grid: var(--sx-dark-4);
--viewer-grid-soft: var(--sx-dark-5);
--viewer-light-sky: var(--sx-dark-0);
--viewer-light-ground: var(--sx-dark-8);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
overflow: hidden;
font-family: var(--sx-font-sans);
font-size: var(--sx-fs-sm);
line-height: var(--sx-lh-md);
color: var(--sx-color-text);
background: var(--sx-color-chrome);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
button,
input,
select,
textarea {
font-family: inherit;
}
#app {
display: grid;
grid-template-columns: var(--viewer-left-width) minmax(0, 1fr) var(--viewer-right-width);
grid-template-rows: var(--sx-app-header-height) minmax(0, 1fr);
height: 100vh;
}
header {
grid-column: 1 / -1;
display: flex;
align-items: center;
gap: var(--sx-space-sm);
min-width: 0;
padding: 0 var(--sx-space-md);
color: var(--sx-color-on-chrome);
background: var(--sx-color-chrome);
}
header h1 {
display: flex;
align-items: baseline;
gap: 6px;
margin: 0;
font-size: 17px;
font-weight: 800;
letter-spacing: -0.02em;
color: var(--sx-color-on-chrome);
white-space: nowrap;
}
header h1 span {
font-weight: var(--sx-fw-medium);
letter-spacing: 0;
color: var(--sx-blue-4);
}
header .meta {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--sx-fs-compact);
font-weight: var(--sx-fw-medium);
color: var(--sx-color-on-chrome-muted);
}
header label.meta {
flex: none;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
}
header .quality-pill {
display: inline-flex;
align-items: center;
gap: 6px;
flex: none;
height: 20px;
padding: 0 8px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
font-variant-numeric: tabular-nums;
white-space: nowrap;
border-radius: var(--sx-radius-full);
color: var(--sx-color-on-chrome);
background: var(--sx-color-on-chrome-hover);
transition:
background-color var(--sx-duration-fast) var(--sx-ease-standard),
color var(--sx-duration-fast) var(--sx-ease-standard);
}
header .quality-pill::before {
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
background: currentColor;
}
header .quality-pill.scaffold,
header .quality-pill.diagnostic {
color: var(--sx-amber-4);
background: rgba(245, 158, 11, 0.15);
}
header .quality-pill.typed {
color: var(--sx-blue-3);
background: rgba(61, 148, 255, 0.15);
}
header .quality-pill.geometry {
color: var(--sx-green-4);
background: rgba(34, 197, 94, 0.15);
}
header .quality-pill.is-updated {
animation: viewer-settle var(--sx-duration-enter) var(--sx-ease-out);
}
header .mode-select {
flex: none;
height: 30px;
padding: 0 28px 0 10px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-medium);
color: var(--sx-color-on-chrome);
background: transparent
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23909398' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 9l4-4 4 4M16 15l-4 4-4-4'/%3E%3C/svg%3E")
no-repeat right 8px center;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: var(--sx-radius-md);
appearance: none;
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
header .mode-select:hover {
background-color: var(--sx-color-on-chrome-hover);
}
header .mode-select option {
color: var(--sx-black);
}
header .export-btn {
flex: none;
display: inline-flex;
align-items: center;
height: 32px;
padding: 6px 10px;
font-size: var(--sx-fs-sm);
font-weight: var(--sx-fw-medium);
line-height: 1;
color: var(--sx-color-on-chrome);
background: none;
border: 0;
border-radius: var(--sx-radius-md);
white-space: nowrap;
cursor: pointer;
transition:
background-color var(--sx-duration-fast) var(--sx-ease-standard),
color var(--sx-duration-fast) var(--sx-ease-standard);
}
header .export-btn:hover:not(:disabled) {
background: var(--sx-color-on-chrome-hover);
}
header .export-btn:disabled {
color: var(--sx-color-on-chrome-muted);
cursor: not-allowed;
}
header .export-btn.primary {
height: 30px;
padding: 0 14px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-primary-contrast);
background: var(--sx-color-primary);
border-radius: var(--sx-radius-xl);
}
header .export-btn.primary:hover:not(:disabled) {
background: var(--sx-color-primary-hover);
}
header .export-btn.primary:disabled {
color: var(--sx-color-disabled-text);
background: var(--sx-gray-8);
}
header .export-btn:active:not(:disabled) {
transform: translateY(1px);
}
#sidebar-left,
#sidebar-right {
min-width: 0;
overflow-y: auto;
padding: var(--sx-space-md) var(--sx-space-sm) var(--sx-space-sm);
background: var(--sx-color-body);
}
#sidebar-left {
border-right: 1px solid var(--sx-color-border-subtle);
border-top-left-radius: var(--sx-app-sheet-radius);
}
#sidebar-right {
border-left: 1px solid var(--sx-color-border-subtle);
border-top-right-radius: var(--sx-app-sheet-radius);
}
#sidebar-left h2,
#sidebar-right h2 {
margin: var(--sx-space-md) 0 6px;
padding: 0 4px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-bold);
line-height: var(--sx-lh-xs);
color: var(--sx-color-text-secondary);
}
#sidebar-left h2:first-child,
#sidebar-right h2:first-child {
margin-top: 4px;
}
.tree-filter {
margin: 0 0 8px;
}
.tree-filter input {
width: 100%;
height: 32px;
padding: 0 10px;
font-size: var(--sx-fs-compact);
color: var(--sx-color-text);
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border);
border-radius: var(--sx-radius-md);
transition: border-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.tree-filter input::placeholder {
color: var(--sx-color-dimmed);
}
.tree-filter input:focus-visible {
outline: none;
border-color: var(--sx-color-primary);
}
.tree-filter input:disabled {
cursor: not-allowed;
opacity: 0.6;
}
.tree-filter-status {
padding: 4px 4px 0;
font-size: var(--sx-fs-xs);
color: var(--sx-color-dimmed);
}
.tree-filter-status:empty {
display: none;
}
.tree-item[hidden] {
display: none;
}
.tree-node {
display: flex;
align-items: center;
min-height: 28px;
padding: 4px 8px;
font-size: var(--sx-fs-compact);
font-weight: var(--sx-fw-medium);
line-height: var(--sx-lh-xs);
color: var(--sx-color-text);
overflow-wrap: anywhere;
border-radius: var(--sx-radius-md);
cursor: pointer;
user-select: none;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.tree-node:hover {
background: var(--sx-color-selected-hover);
}
.tree-node.selected,
.tree-node:focus-visible {
background: var(--sx-color-selected);
color: var(--sx-color-text);
}
.tree-node.tree-project {
font-weight: var(--sx-fw-bold);
color: var(--sx-color-title);
}
.tree-node.tree-storey {
font-weight: var(--sx-fw-semibold);
}
.tree-node.tree-storey-empty {
font-weight: var(--sx-fw-regular);
color: var(--sx-color-dimmed);
}
.tree-node.tree-storey-unassigned {
color: var(--sx-color-warning);
}
.tree-node.tree-category {
font-weight: var(--sx-fw-semibold);
}
.tree-caret {
display: inline-flex;
flex: none;
align-self: flex-start;
align-items: center;
justify-content: center;
width: 16px;
height: 1lh;
margin: 0 4px 0 -4px;
border-radius: var(--sx-radius-sm);
}
.tree-caret::before {
content: '';
width: 6px;
height: 6px;
border: solid var(--sx-color-dimmed);
border-width: 0 1.75px 1.75px 0;
transform: translateX(-1px) rotate(-45deg);
transition: transform var(--sx-duration-base) var(--sx-ease-standard);
}
.tree-node[aria-expanded='true'] > .tree-caret::before {
transform: translateY(-1px) rotate(45deg);
}
.tree-caret-none::before {
content: none;
}
.tree-caret:not(.tree-caret-none):hover {
background: var(--sx-color-selected-hover);
}
.tree-text {
display: flex;
flex: 1 1 auto;
flex-direction: column;
min-width: 0;
}
.tree-detail {
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-regular);
color: var(--sx-color-dimmed);
}
.tree-node.tree-storey-unassigned .tree-detail {
color: inherit;
}
.tree-count {
flex: none;
padding-left: 8px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-regular);
font-variant-numeric: tabular-nums;
color: var(--sx-color-dimmed);
}
.tree-children {
margin-left: 12px;
padding-left: 6px;
border-left: 1px solid var(--sx-color-border-subtle);
}
.tree-children[hidden] {
display: none;
}
.category-toggle {
display: flex;
align-items: center;
gap: 8px;
min-height: 30px;
padding: 4px 8px;
font-size: var(--sx-fs-compact);
font-weight: var(--sx-fw-medium);
border-radius: var(--sx-radius-md);
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.category-toggle:hover {
background: var(--sx-color-selected-hover);
}
.category-toggle .tree-count {
margin-left: auto;
}
.category-empty {
padding: 4px 8px;
font-size: var(--sx-fs-xs);
color: var(--sx-color-dimmed);
}
.category-toggle:focus-within {
background: var(--sx-color-selected);
}
.category-toggle input {
appearance: none;
display: inline-grid;
place-items: center;
flex: none;
width: 16px;
height: 16px;
margin: 0;
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border-strong);
border-radius: var(--sx-radius-sm);
cursor: pointer;
transition:
background-color var(--sx-duration-fast),
border-color var(--sx-duration-fast);
}
.category-toggle input:checked {
background: var(--sx-color-primary);
border-color: var(--sx-color-primary);
}
.category-toggle input:checked::after {
content: '';
width: 8px;
height: 5px;
border: solid #fff;
border-width: 0 0 2px 2px;
transform: translateY(-1px) rotate(-45deg);
}
#viewport {
position: relative;
min-width: 0;
min-height: 0;
overflow: hidden;
background: var(--viewer-canvas);
}
#viewport canvas {
position: absolute;
inset: 0;
display: block;
width: 100%;
height: 100%;
}
#dropzone {
position: absolute;
inset: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: safe center;
overflow-y: auto;
padding: var(--sx-space-6) var(--sx-space-md);
background: var(--sx-color-body);
color: var(--sx-color-text);
transition: background-color var(--sx-duration-base) var(--sx-ease-standard);
}
#dropzone.drag-over {
background: var(--sx-color-selected-hover);
box-shadow: inset 0 0 0 2px var(--sx-color-primary);
}
#dropzone.hidden {
display: none;
}
#dropzone .big {
margin-bottom: 6px;
font-size: var(--sx-h3);
font-weight: var(--sx-fw-bold);
line-height: var(--sx-h3-lh);
color: var(--sx-color-title);
text-align: center;
}
#dropzone .hint {
max-width: 440px;
font-size: var(--sx-fs-sm);
line-height: var(--sx-lh-sm);
color: var(--sx-color-dimmed);
text-align: center;
}
#dropzone .hint a {
color: var(--sx-color-link);
font-weight: var(--sx-fw-medium);
text-decoration: none;
}
#dropzone .hint a:hover {
text-decoration: underline;
}
#pick-file {
display: inline-flex;
align-items: center;
justify-content: center;
height: 36px;
margin-top: var(--sx-space-lg);
padding: 0 18px;
font-size: var(--sx-fs-sm);
font-weight: var(--sx-fw-semibold);
line-height: 1;
color: var(--sx-color-primary-contrast);
background: var(--sx-color-primary);
border: 1px solid transparent;
border-radius: var(--sx-radius-xl);
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
#pick-file:hover {
background: var(--sx-color-primary-hover);
}
#pick-file:active {
transform: translateY(1px);
}
#demo-gallery {
width: min(720px, 92%);
margin-top: var(--sx-space-xl);
text-align: left;
}
#demo-gallery h2 {
margin: 0 0 4px;
font-size: var(--sx-h4);
font-weight: var(--sx-fw-bold);
line-height: var(--sx-h4-lh);
color: var(--sx-color-title);
}
#demo-gallery .gallery-attribution {
margin-bottom: var(--sx-space-sm);
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-dimmed);
}
#demo-list {
display: grid;
gap: 8px;
max-height: min(42vh, 360px);
overflow-y: auto;
}
.demo-card {
position: relative;
display: grid;
grid-template-columns: 72px 1fr;
gap: var(--sx-space-sm);
align-items: start;
width: 100%;
padding: var(--sx-space-sm);
font: inherit;
color: inherit;
text-align: left;
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-default);
cursor: pointer;
transition:
border-color var(--sx-duration-fast) var(--sx-ease-standard),
background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.demo-card:hover:not(:disabled) {
background: var(--sx-color-selected-hover);
border-color: var(--sx-blue-2);
}
.demo-card:active:not(:disabled) {
background: var(--sx-color-selected);
}
.demo-card:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.demo-card:focus-visible {
border-color: var(--sx-color-primary);
}
.demo-card img {
width: 72px;
height: 40px;
object-fit: cover;
background: var(--sx-color-surface-muted);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-md);
transition: opacity var(--sx-duration-base) var(--sx-ease-standard);
}
.demo-card:disabled img,
.demo-card[aria-busy='true'] img {
opacity: 0.5;
}
.demo-card .demo-title {
font-size: var(--sx-fs-sm);
font-weight: var(--sx-fw-semibold);
line-height: var(--sx-lh-xs);
color: var(--sx-color-text);
}
.demo-card .demo-meta {
margin-top: 2px;
font-size: 11px;
line-height: var(--sx-lh-xs);
color: var(--sx-color-dimmed);
white-space: pre-line;
}
.demo-card .demo-quality,
.demo-badge {
display: inline-flex;
align-items: center;
height: 20px;
padding: 0 8px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
border-radius: var(--sx-radius-full);
white-space: nowrap;
}
.demo-card .demo-quality {
margin-top: 6px;
color: var(--sx-color-warning);
background: var(--sx-color-warning-light);
}
.demo-card .demo-quality.geometry {
color: var(--sx-color-success);
background: var(--sx-color-success-light);
}
.demo-card .demo-quality.reference {
color: var(--sx-color-primary);
background: var(--sx-color-primary-light);
}
.demo-badge {
margin-left: 8px;
vertical-align: 1px;
color: var(--sx-color-primary);
background: var(--sx-color-primary-light);
}
.demo-card[data-demo-real='true'] {
border-color: var(--sx-color-border);
}
.demo-card[aria-busy='true'] {
cursor: progress;
border-color: var(--sx-blue-2);
}
.demo-card[aria-busy='true'] .demo-title {
color: var(--sx-color-dimmed);
}
.demo-card[aria-busy='true']::before,
.demo-card[aria-busy='true']::after {
content: '';
position: absolute;
bottom: -1px;
height: 2px;
}
.demo-card[aria-busy='true']::before {
left: var(--sx-space-sm);
right: var(--sx-space-sm);
background: var(--sx-color-surface-muted);
}
.demo-card[aria-busy='true']::after {
left: var(--sx-space-sm);
width: 33%;
background: var(--sx-color-primary);
animation: viewer-sweep 1.4s var(--sx-ease-standard) infinite;
}
.demo-card.is-flagged {
animation: viewer-flag 1.1s var(--sx-ease-standard) 2;
}
#load-overlay {
position: absolute;
inset: 0;
z-index: 11;
display: grid;
place-items: center;
background: var(--sx-loading-veil);
backdrop-filter: blur(2px);
}
#load-overlay.hidden {
display: none;
}
.load-card {
width: min(420px, 84%);
padding: var(--sx-space-md);
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-default);
box-shadow: var(--sx-shadow-md);
animation: viewer-enter var(--sx-duration-enter) var(--sx-ease-out) both;
}
#load-step {
font-size: var(--sx-fs-sm);
font-weight: var(--sx-fw-semibold);
line-height: var(--sx-lh-sm);
color: var(--sx-color-text);
}
.sweep-rail {
position: relative;
height: 8px;
overflow: hidden;
background: var(--sx-color-surface-muted);
border-radius: var(--sx-radius-full);
}
.sweep-rail::after {
content: '';
position: absolute;
inset: 0 auto 0 0;
width: 33%;
background: var(--sx-color-primary);
border-radius: inherit;
animation: viewer-sweep 1.4s var(--sx-ease-standard) infinite;
}
.load-card .sweep-rail {
margin: var(--sx-space-sm) 0 var(--sx-space-xs);
}
#load-metrics {
display: flex;
justify-content: space-between;
gap: var(--sx-space-sm);
font-size: var(--sx-fs-xs);
color: var(--sx-color-dimmed);
font-variant-numeric: tabular-nums;
}
.load-privacy {
margin-top: var(--sx-space-xs);
padding-top: var(--sx-space-xs);
font-size: var(--sx-fs-xs);
color: var(--sx-color-dimmed);
border-top: 1px solid var(--sx-color-border-subtle);
}
#scaffold-note {
position: absolute;
inset: 0;
z-index: 8;
display: grid;
place-items: center;
pointer-events: none;
animation: viewer-enter var(--sx-duration-enter) var(--sx-ease-out) both;
}
#scaffold-note.hidden {
display: none;
}
.note-card {
width: min(460px, 86%);
padding: var(--sx-space-sm) var(--sx-space-md);
pointer-events: auto;
color: var(--sx-color-text);
background:
linear-gradient(var(--sx-color-warning-light), var(--sx-color-warning-light)),
var(--sx-color-surface);
border-radius: var(--sx-radius-default);
box-shadow: var(--sx-shadow-sm);
}
.note-title {
margin: 0 0 2px;
font-size: var(--sx-fs-sm);
font-weight: var(--sx-fw-bold);
color: var(--sx-color-warning);
}
.note-card p {
max-width: 58ch;
margin: 0;
font-size: var(--sx-fs-sm);
line-height: var(--sx-lh-sm);
}
.note-actions {
display: flex;
gap: 8px;
margin-top: var(--sx-space-sm);
}
.note-btn {
display: inline-flex;
align-items: center;
height: 30px;
padding: 0 14px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
line-height: 1;
color: var(--sx-color-primary-contrast);
background: var(--sx-color-primary);
border: 1px solid transparent;
border-radius: var(--sx-radius-xl);
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.note-btn:hover {
background: var(--sx-color-primary-hover);
}
.note-btn:active {
transform: translateY(1px);
}
.note-btn.quiet {
color: var(--sx-color-text);
background: var(--sx-color-surface);
border-color: var(--sx-color-border);
}
.note-btn.quiet:hover {
background: var(--sx-color-hover);
}
#toast-region {
position: absolute;
right: var(--sx-space-sm);
bottom: var(--sx-space-sm);
z-index: 12;
display: grid;
gap: 8px;
justify-items: end;
pointer-events: none;
}
.toast {
display: flex;
align-items: flex-start;
gap: 10px;
max-width: min(360px, 62%);
padding: var(--sx-space-sm) var(--sx-space-sm) var(--sx-space-sm) 14px;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-text);
overflow-wrap: anywhere;
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-default);
box-shadow: var(--sx-shadow-lg);
animation: viewer-toast-in var(--sx-duration-enter) var(--sx-ease-out) both;
}
.toast::before {
content: '';
flex: none;
width: 8px;
height: 8px;
margin-top: 4px;
border-radius: 50%;
background: var(--sx-color-primary);
}
.toast.ok::before {
background: var(--sx-color-success);
}
.toast.bad::before {
background: var(--sx-color-danger);
}
.toast.leaving {
animation: viewer-toast-out var(--sx-duration-base) var(--sx-ease-standard) both;
}
#status {
position: absolute;
bottom: var(--sx-space-sm);
left: var(--sx-space-sm);
max-width: min(520px, calc(100% - 24px));
padding: 6px 10px;
overflow: hidden;
overflow-wrap: anywhere;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-dimmed);
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border);
border-radius: var(--sx-radius-md);
transition:
border-color var(--sx-duration-fast) var(--sx-ease-standard),
color var(--sx-duration-fast) var(--sx-ease-standard);
}
#status.is-busy {
color: var(--sx-color-text);
border-color: var(--sx-blue-2);
}
#status.is-busy::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 40%;
height: 2px;
background: var(--sx-color-primary);
animation: viewer-sweep 1.4s var(--sx-ease-standard) infinite;
}
.status-panel {
display: grid;
margin-bottom: var(--sx-space-xs);
}
.status-row {
display: grid;
grid-template-columns: 10px 88px 1fr;
gap: 8px;
align-items: start;
padding: 8px 4px;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
border-bottom: 1px solid var(--sx-color-border-subtle);
animation: viewer-enter var(--sx-duration-base) var(--sx-ease-out) both;
animation-delay: calc(var(--row-i, 0) * 22ms);
}
.status-dot {
width: 8px;
height: 8px;
margin-top: 4px;
border-radius: 50%;
background: var(--sx-color-border-strong);
transition: background-color var(--sx-duration-base) var(--sx-ease-standard);
}
.status-dot.ok {
background: var(--sx-color-success);
}
.status-dot.warn {
background: var(--sx-color-warning);
}
.status-dot.bad {
background: var(--sx-color-danger);
}
.status-label {
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-text);
}
.status-value {
color: var(--sx-color-dimmed);
font-variant-numeric: tabular-nums;
overflow-wrap: anywhere;
}
.side-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
height: 30px;
margin: 4px 0 8px;
padding: 0 14px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
line-height: 1;
color: var(--sx-color-text);
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border);
border-radius: var(--sx-radius-xl);
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.side-btn:hover:not(:disabled) {
background: var(--sx-color-hover);
}
.side-btn:active:not(:disabled) {
transform: translateY(1px);
}
.side-btn:disabled {
color: var(--sx-color-disabled-text);
background: var(--sx-color-disabled);
border-color: transparent;
cursor: not-allowed;
}
#diagnostics-details {
margin-bottom: var(--sx-space-sm);
font-size: var(--sx-fs-xs);
color: var(--sx-color-dimmed);
background: var(--sx-color-surface);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-md);
overflow: hidden;
}
#diagnostics-details summary {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
font-weight: var(--sx-fw-medium);
color: var(--sx-color-text);
list-style: none;
cursor: pointer;
}
#diagnostics-details summary::-webkit-details-marker {
display: none;
}
#diagnostics-details summary::after {
content: '';
width: 6px;
height: 6px;
margin-right: 2px;
border: solid var(--sx-color-dimmed);
border-width: 0 1.75px 1.75px 0;
transform: translateY(-2px) rotate(45deg);
transition: transform var(--sx-duration-base) var(--sx-ease-standard);
}
#diagnostics-details[open] summary::after {
transform: translateY(1px) rotate(-135deg);
}
#diagnostics-json {
max-height: 260px;
margin: 0 12px 12px;
padding: 10px 12px;
overflow: auto;
font-family: inherit;
font-size: 11px;
line-height: 1.6;
color: var(--sx-color-text);
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: anywhere;
background: var(--sx-color-surface-subtle);
border: 1px solid var(--sx-color-border-subtle);
border-radius: var(--sx-radius-md);
}
.mvp-workflow {
margin: 0 0 var(--sx-space-sm);
padding: 10px 12px;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-sm);
color: var(--sx-color-dimmed);
background: var(--sx-color-surface-subtle);
border-radius: var(--sx-radius-md);
}
.mvp-workflow strong {
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-text);
}
.support-matrix {
display: grid;
gap: 2px;
margin-bottom: var(--sx-space-sm);
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
}
.support-row {
display: grid;
grid-template-columns: 78px 1fr;
gap: 8px;
padding: 8px 4px;
border-bottom: 1px solid var(--sx-color-border-subtle);
}
.support-row .k {
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-text);
}
.support-row .v {
color: var(--sx-color-dimmed);
}
.support-link {
display: inline-flex;
align-items: center;
padding: 6px 4px 0;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-medium);
color: var(--sx-color-link);
text-decoration: none;
}
.support-link:hover {
text-decoration: underline;
}
#info {
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-dimmed);
}
.info-group {
margin-top: 8px;
padding: 8px 12px;
background: var(--sx-color-surface-subtle);
border-radius: var(--sx-radius-md);
}
.info-group:first-child {
margin-top: 0;
}
.info-group-storey,
.info-group-material {
background: var(--sx-color-selected-hover);
}
.info-group-gap {
background: var(--sx-color-warning-light);
}
.info-group-title {
padding-bottom: 4px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-text);
}
.info-row {
display: grid;
grid-template-columns: 110px 1fr;
gap: 8px;
padding: 4px 0;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
border-bottom: 1px solid var(--sx-color-border-subtle);
}
.info-group .info-row:last-child {
border-bottom: none;
}
.info-row .k {
color: var(--sx-color-dimmed);
}
.info-row .v {
color: var(--sx-color-text);
font-variant-numeric: tabular-nums;
word-break: break-all;
overflow-wrap: anywhere;
}
.info-row .v.num {
word-break: normal;
}
.info-gap-note {
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-text);
}
.info-details > summary {
list-style: none;
cursor: pointer;
}
.info-details > summary::-webkit-details-marker {
display: none;
}
.info-details > summary::before {
content: '';
display: inline-block;
width: 5px;
height: 5px;
margin: 0 8px 2px 1px;
border: solid var(--sx-color-dimmed);
border-width: 0 1.75px 1.75px 0;
transform: rotate(-45deg);
transition: transform var(--sx-duration-base) var(--sx-ease-standard);
}
.info-details[open] > summary::before {
transform: rotate(45deg);
}
.info-details > summary:hover {
color: var(--sx-color-primary);
}
.info-relations {
display: grid;
gap: 2px;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid var(--sx-color-border-subtle);
}
.info-relations-title {
padding: 0 4px 2px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-text);
}
.info-relation {
display: block;
width: 100%;
min-height: 30px;
padding: 6px 8px;
font: inherit;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-medium);
color: var(--sx-color-link);
text-align: left;
background: none;
border: 0;
border-radius: var(--sx-radius-md);
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.info-layer {
width: 100%;
margin: 0;
font: inherit;
font-size: var(--sx-fs-xs);
text-align: left;
background: none;
border: 0;
border-bottom: 1px solid var(--sx-color-border-subtle);
border-radius: 0;
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
.info-layer .k {
color: var(--sx-color-link);
}
.info-layer:hover {
background: var(--sx-color-selected-hover);
}
.info-layer[aria-pressed='true'] {
background: var(--sx-color-selected);
}
.info-layer[aria-pressed='true'] .k {
color: var(--sx-color-text);
}
.info-relation:hover {
background: var(--sx-color-selected-hover);
}
.info-relation[aria-pressed='true'] {
color: var(--sx-color-text);
background: var(--sx-color-selected);
}
.schedule-total {
padding: 0 4px;
font-size: var(--sx-fs-xs);
line-height: var(--sx-lh-xs);
color: var(--sx-color-dimmed);
font-variant-numeric: tabular-nums;
}
.schedule-groups {
display: grid;
}
.schedule-groups:not(:empty) {
margin: 8px 0 4px;
border-top: 1px solid var(--sx-color-border-subtle);
}
.schedule-row {
display: grid;
grid-template-columns: 1fr auto 60px;
align-items: baseline;
gap: 8px;
width: 100%;
padding: 7px 8px;
font: inherit;
font-size: var(--sx-fs-compact);
text-align: left;
color: var(--sx-color-text);
background: transparent;
border: 0;
border-bottom: 1px solid var(--sx-color-border-subtle);
}
.schedule-row .schedule-type {
overflow: hidden;
font-weight: var(--sx-fw-medium);
text-overflow: ellipsis;
white-space: nowrap;
}
.schedule-row .schedule-count {
color: var(--sx-color-dimmed);
text-align: right;
font-variant-numeric: tabular-nums;
}
.schedule-row .schedule-verb {
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-medium);
color: var(--sx-color-link);
text-align: right;
}
button.schedule-row {
cursor: pointer;
transition: background-color var(--sx-duration-fast) var(--sx-ease-standard);
}
button.schedule-row:hover {
background: var(--sx-color-selected-hover);
}
button.schedule-row[aria-pressed='true'] {
background: var(--sx-color-selected);
}
button.schedule-row[aria-pressed='true'] .schedule-count {
color: var(--sx-color-text);
}
.skip-link {
position: absolute;
top: -56px;
left: 8px;
z-index: var(--sx-z-max);
display: inline-flex;
align-items: center;
height: 30px;
padding: 0 14px;
font-size: var(--sx-fs-xs);
font-weight: var(--sx-fw-semibold);
color: var(--sx-color-primary-contrast);
text-decoration: none;
background: var(--sx-color-primary);
border-radius: var(--sx-radius-xl);
}
.skip-link:focus {
top: 13px;
}
:focus-visible {
outline: var(--sx-focus-outline);
outline-offset: 2px;
}
button:focus:not(:focus-visible),
a:focus:not(:focus-visible),
summary:focus:not(:focus-visible),
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
.tree-node:focus:not(:focus-visible),
.demo-card:focus:not(:focus-visible) {
outline: none;
}
@keyframes viewer-sweep {
from {
transform: translateX(-100%);
}
to {
transform: translateX(300%);
}
}
@keyframes viewer-enter {
from {
opacity: 0;
transform: translateY(2px);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes viewer-toast-in {
from {
opacity: 0;
transform: translateY(6px);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes viewer-toast-out {
from {
opacity: 1;
}
to {
opacity: 0;
transform: translateY(4px);
}
}
@keyframes viewer-settle {
from {
box-shadow: 0 0 0 0 rgba(24, 129, 255, 0.4);
}
to {
box-shadow: 0 0 0 6px rgba(24, 129, 255, 0);
}
}
@keyframes viewer-flag {
0%,
100% {
box-shadow: 0 0 0 0 rgba(24, 129, 255, 0);
}
40% {
box-shadow: 0 0 0 2px var(--sx-color-primary);
}
}
@media (max-width: 960px) {
body {
overflow: auto;
}
#app {
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto auto minmax(42vh, 52vh) auto;
height: auto;
min-height: 100vh;
}
header {
flex-wrap: wrap;
row-gap: 8px;
height: auto;
min-height: var(--sx-app-header-height);
padding: 12px 16px;
}
#sidebar-left {
order: 3;
max-height: 36vh;
border-right: none;
border-top: 1px solid var(--sx-color-border-subtle);
border-radius: 0;
}
#viewport {
order: 2;
min-height: 42vh;
border-radius: var(--sx-app-sheet-radius) var(--sx-app-sheet-radius) 0 0;
}
#sidebar-right {
order: 4;
border-left: none;
border-top: 1px solid var(--sx-color-border-subtle);
border-radius: 0;
}
#demo-gallery {
width: min(100%, 560px);
}
}
@media (max-width: 560px) {
header h1 {
font-size: 15px;
}
header .meta {
width: 100%;
}
#dropzone .big {
font-size: var(--sx-h4);
}
.support-row,
.status-row,
.info-row {
grid-template-columns: 1fr;
gap: 2px;
}
.schedule-row {
grid-template-columns: 1fr auto;
}
.schedule-row .schedule-verb {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 1ms !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-duration: 1ms !important;
transition-delay: 0ms !important;
}
.demo-card:active:not(:disabled),
header .export-btn:active:not(:disabled),
.side-btn:active:not(:disabled),
.note-btn:active,
#pick-file:active {
transform: none;
}
.sweep-rail::after,
.demo-card[aria-busy='true']::after,
#status.is-busy::after {
width: 100%;
animation: none;
transform: none;
}
}