* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

@font-face {
    font-family: 'Pretendard';
    src: url('/static/fonts/PretendardVariable.woff2') format('woff2-variations');
    font-weight: 45 920;
    font-style: normal;
    font-display: swap;
}

:root {
    /* How tall the drawing viewer stands in the page. */
    --viewer-height: clamp(480px, 76vh, 1000px);
    color-scheme: dark;

    /* Dark, one tone with the drawing (direction B layout, dark palette —
       2026-09-16: a light page around the black CAD canvas read as a hole
       in paper, so the whole page went dark instead). Surfaces step up
       from the page to the cards; the canvas sits a shade below the page. */
    --bg-base: #0f1116;
    --bg-surface: #171a21;
    --bg-raised: #1e222b;
    --bg-inset: #13161c;
    --canvas-bg: #0b0d12;

    --border-color: #262a34;
    --border-strong: #353a47;

    --text-primary: #e8eaf0;
    --text-secondary: #a2a7b5;
    /* the type scale (D-3, 2026-09-25): seven sizes for the whole app — hint · label · body · emphasis · title · page · headline.
       Every font-size in this file is one of these; a new rule picks a token, never a pixel */
    --fs-0: 11.5px; --fs-1: 12.5px; --fs-2: 14px; --fs-3: 15px; --fs-4: 18px; --fs-5: 28px; --fs-6: 52px;
    --text-muted: #858b9c;   /* D-1: 5.4:1 on the page, 4.5:1 on a raised card (was #6f7484, 4.0:1) */

    --accent: #7c9cff;
    --accent-hover: #93adff;
    --accent-soft: rgba(124, 156, 255, 0.12);
    --accent-ring: rgba(124, 156, 255, 0.3);

    --success: #4ccf93;
    --danger: #f26d78;
    /* Amber: the "look here" colour, readable as text on the dark surfaces
       and as a wash behind a card. */
    --warning: #e0b04f;
    --warning-soft: rgba(224, 176, 79, 0.16);

    /* Numbers are set in a monospace face so columns of counts and
       lengths line up digit for digit. */
    /* Numbers sit in the text face with tabular figures — a monospace beside
       Korean text read as two typefaces fighting. Code and handles keep a mono. */
    --font-mono: 'Pretendard', -apple-system, 'Segoe UI', sans-serif;
    --font-code: 'Cascadia Mono', 'IBM Plex Mono', Consolas, 'Courier New', monospace;

    --radius-sm: 6px;
    --radius: 10px;
    --radius-lg: 14px;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

/* A hidden attribute wins over any class that sets display (trap #19). */
[hidden] { display: none !important; }


body {
    font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
        'Helvetica Neue', 'Malgun Gothic', sans-serif;
    background-color: var(--bg-base);
    background-image:
        radial-gradient(ellipse 80% 50% at 50% -20%, rgba(124, 156, 255, 0.10), transparent);
    background-repeat: no-repeat;
    color: var(--text-primary);
    line-height: 1.55;
    letter-spacing: -0.01em;           /* Pretendard sets Korean a touch loose at UI sizes */
    font-size: var(--fs-3);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    font-feature-settings: "tnum" 1, "ss05" 1;   /* tabular figures everywhere, cleaner ㄱ·ㅋ */
}

/* App shell: a top bar, then the sidebar and the main column. The main
   column is wide enough for the symbol-count tables (one column per
   legend item) to fit without a horizontal scrollbar in the common case. */
.app-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.app-body {
    flex: 1;
    display: flex;
    align-items: stretch;
    min-height: 0;
}

/* Top bar */
.topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 18px;
    height: 56px;
    padding: 0 24px;
    background: var(--bg-inset);
    border-bottom: 1px solid var(--border-color);
}

.topbar-brand {
    font-size: var(--fs-2);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
    white-space: nowrap;
}

.topbar-project {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 10px 5px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--bg-surface);
}

.topbar-project-label {
    font-size: var(--fs-1);
    color: var(--text-muted);
}

.topbar-select {
    background: transparent;
    border: none;
    color: var(--text-primary);
    font-size: var(--fs-2);
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    padding-right: 4px;
}

.topbar-select:focus { outline: none; }
.topbar-select option { background: var(--bg-surface); color: var(--text-primary); font-weight: 400; }

.topbar-spacer { flex: 1; }

.topbar-updated {
    font-size: var(--fs-1);
    color: var(--text-muted);
    white-space: nowrap;
}

.topbar-upload { position: relative; }
.topbar-upload .btn { padding: 7px 14px; font-size: var(--fs-2); }

/* "Which discipline?" — the drop-down under the upload button on the project dashboard. */
.topbar-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 200px;
    padding: 6px;
    background: var(--bg-raised);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    z-index: 40;
}

.topbar-menu-title {
    padding: 6px 10px 8px;
    font-size: var(--fs-1);
    color: var(--text-muted);
}

.topbar-menu a {
    display: block;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-2);
    color: var(--text-primary);
    text-decoration: none;
}

.topbar-menu a:hover { background: var(--accent-soft); }

/* Sidebar: the disciplines of the current project */
.sidebar {
    position: sticky;
    top: 56px;
    align-self: flex-start;
    width: 224px;
    flex: none;
    max-height: calc(100vh - 56px);
    overflow-y: auto;
    padding: 18px 10px 20px;
    background: var(--bg-inset);
    border-right: 1px solid var(--border-color);
}

.sidebar-heading {
    padding: 0 10px 10px;
    font-size: var(--fs-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }

.sidebar-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-2);
    color: var(--text-secondary);
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}

.sidebar-row:hover { background: var(--bg-raised); color: var(--text-primary); }
.sidebar-row.active { background: var(--accent-soft); color: var(--text-primary); }
.sidebar-row-muted { color: var(--text-muted); }

.sidebar-name {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-count {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--fs-1);
    font-weight: 500;
    color: var(--text-muted);
}

.sidebar-row.active .sidebar-count { color: var(--text-secondary); }

.sidebar-badge {
    min-width: 16px;
    padding: 0 5px;
    border-radius: 8px;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 16px;
    text-align: center;
    color: var(--warning);
    background: rgba(224, 176, 79, 0.14);
}

.sidebar-add { margin-top: 16px; padding: 0 4px; }
.sidebar-add > summary {
    padding: 6px 6px;
    font-size: var(--fs-1);
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
}
.sidebar-add > summary::-webkit-details-marker { display: none; }
.sidebar-add > summary:hover { color: var(--text-primary); }
.sidebar-add-note { padding: 4px 6px 8px; font-size: var(--fs-0); line-height: 1.5; color: var(--text-muted); }
.sidebar-hidden { padding: 10px 0 0; border-top: 1px solid var(--border-color); margin-top: 12px; font-size: var(--fs-1); }
.sidebar-hidden-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.sidebar-hidden-row a { color: var(--text-muted); text-decoration: none; }
.sidebar-hidden-row a:hover { color: var(--text); }

.new-item-row-compact { flex-direction: column; gap: 6px; margin-bottom: 0; }
.new-item-row-compact input { padding: 8px 10px; font-size: var(--fs-2); }
.new-item-row-compact .btn { padding: 8px 10px; font-size: var(--fs-2); }

/* Flash the drop zone the top-bar button scrolled to. */
.upload-area-flash { box-shadow: 0 0 0 3px var(--accent-ring); border-color: var(--accent) !important; }

/* Breadcrumb navigation */
.breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 0 16px;
    font-size: var(--fs-2);
    color: var(--text-muted);
    flex-wrap: wrap;
}

.breadcrumb[hidden] { display: none; }

.breadcrumb a {
    color: var(--text-secondary);
    text-decoration: none;
    padding: 4px 10px;
    border-radius: var(--radius-sm);
    transition: background 0.15s, color 0.15s;
}

.breadcrumb a:hover {
    background: var(--bg-raised);
    color: var(--text-primary);
}

.breadcrumb .crumb-sep {
    color: var(--border-strong);
}

/* Main Content */
.main-content {
    flex: 1;
    min-width: 0;
    max-width: 1400px;
    padding: 24px 28px 0;
}

.section {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 28px 32px;
    margin-bottom: 24px;
    box-shadow: var(--shadow);
}

.section h2 {
    font-size: var(--fs-4);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin-bottom: 22px;
    color: var(--text-primary);
}

.section h3 {
    font-size: var(--fs-2);
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin: 28px 0 14px;
    color: var(--text-muted);
}

.section-note {
    color: var(--text-secondary);
    font-size: var(--fs-2);
    margin-bottom: 20px;
}

/* The small line beside a section title — counts, not prose. */
.title-meta { margin-left: 12px; font-size: var(--fs-2); font-weight: 400; color: var(--text-muted); font-family: var(--font-mono); }

/* Section heading row with an action button on the right */
.dashboard-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 16px;
}

.dashboard-header h2,
.dashboard-header h3 {
    margin-bottom: 0;
    margin-top: 0;
}

/* Row of "new item" input + create button (projects, disciplines) */
.new-item-row {
    display: flex;
    gap: 10px;
    margin-bottom: 22px;
}

.new-item-row input {
    flex: 1;
    padding: 11px 14px;
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    font-size: var(--fs-2);
    color: var(--text-primary);
    transition: border-color 0.15s, box-shadow 0.15s;
}

.new-item-row input::placeholder {
    color: var(--text-muted);
}

.new-item-row input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}

/* Clickable card list (projects, disciplines, drawings, versions) */
.item-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.item-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 20px;
    background: var(--bg-raised);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}

.item-card-body { flex: 1; min-width: 0; }

/* Always visible — a control you can't find is not a control. It stays
   muted so it doesn't compete with the card itself, and only turns red
   under the cursor, which is where the warning actually belongs. */
.btn-delete {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 7px 12px;
    font-size: var(--fs-2);
    line-height: 1;
    color: var(--text-secondary);
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}

.btn-delete:hover {
    color: var(--danger);
    background: rgba(242, 109, 120, 0.12);
    border-color: rgba(242, 109, 120, 0.45);
}

.btn-delete:focus-visible {
    outline: 2px solid var(--accent-ring);
    outline-offset: 1px;
}

.item-card:hover {
    border-color: var(--accent);
    background: var(--bg-raised);
    transform: translateY(-1px);
}

.item-card-current {
    border-color: rgba(76, 207, 147, 0.45);
    background: rgba(76, 207, 147, 0.06);
    cursor: default;
}

.item-card-current:hover {
    transform: none;
    border-color: rgba(76, 207, 147, 0.45);
}

.item-card-title {
    font-weight: 600;
    font-size: var(--fs-3);
    color: var(--text-primary);
}

.item-card-meta {
    font-size: var(--fs-2);
    color: var(--text-muted);
    margin-top: 4px;
}

/* Symbol list (legend confirm screen) */
.form-section {
    margin: 24px 0;
    padding: 22px;
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
}

.form-section h3 {
    margin-top: 0;
}

/* Legend review list: read-only rows by default, one row expands to edit */
.symbol-list {
    margin-bottom: 18px;
}

.review-notice {
    font-size: var(--fs-2);
    color: var(--warning);
    background: rgba(224, 176, 79, 0.08);
    border: 1px solid rgba(224, 176, 79, 0.22);
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.review-notice-ok {
    color: var(--success);
    background: rgba(76, 207, 147, 0.07);
    border-color: rgba(76, 207, 147, 0.22);
}

.symbol-review-head,
.symbol-row-main {
    display: grid;
    grid-template-columns: 44px minmax(0, 2fr) minmax(0, 1.6fr) 92px 64px;
    align-items: center;
    gap: 14px;
}

.symbol-review-head {
    padding: 0 14px 8px;
    font-size: var(--fs-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.symbol-row {
    background: var(--bg-raised);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    margin-bottom: 6px;
    transition: border-color 0.15s;
}

.symbol-row.is-editing {
    border-color: var(--accent);
}

.symbol-row-main {
    padding: 10px 14px;
    cursor: pointer;
}

.symbol-row-main:hover {
    background: rgba(124, 156, 255, 0.05);
    border-radius: var(--radius);
}

.symbol-row-label {
    font-size: var(--fs-2);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.symbol-row-blocks {
    font-size: var(--fs-1);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.symbol-row-blocks code {
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 2px 7px;
    color: var(--text-secondary);
    font-size: var(--fs-1);
}

.muted {
    color: var(--text-muted);
}

.status-badge {
    font-size: var(--fs-0);
    font-weight: 600;
    text-align: center;
    padding: 4px 8px;
    border-radius: 999px;
    border: 1px solid transparent;
}

.status-ok {
    color: var(--success);
    background: rgba(76, 207, 147, 0.1);
    border-color: rgba(76, 207, 147, 0.25);
}

.status-guess {
    color: var(--warning);
    background: rgba(224, 176, 79, 0.1);
    border-color: rgba(224, 176, 79, 0.25);
}

.status-warn {
    color: var(--danger);
    background: rgba(242, 109, 120, 0.1);
    border-color: rgba(242, 109, 120, 0.25);
}

.symbol-row-edit-btn {
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    padding: 5px 10px;
    font-size: var(--fs-1);
    cursor: pointer;
    font-family: inherit;
    transition: border-color 0.15s, color 0.15s;
}

.symbol-row-edit-btn:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}

.symbol-row-edit {
    border-top: 1px solid var(--border-color);
    padding: 16px;
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 18px;
    align-items: start;
}

.edit-field label {
    display: block;
    font-size: var(--fs-0);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.edit-field input {
    width: 100%;
    padding: 8px 12px;
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--fs-2);
    color: var(--text-primary);
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.edit-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}

.edit-inline {
    display: flex;
    gap: 8px;
}

.edit-inline .btn {
    padding: 8px 14px;
    font-size: var(--fs-2);
    white-space: nowrap;
}

.symbol-row-edit .block-names {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

/* Placeholder for a symbol we couldn't draw (no block matched) */
.symbol-icon-empty {
    filter: none;
    opacity: 1;
    color: var(--text-muted);
    font-size: var(--fs-3);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-sm);
}

.empty-state {
    padding: 28px;
    text-align: center;
    background: var(--bg-inset);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius);
    color: var(--text-muted);
    font-size: var(--fs-2);
}

.block-tag {
    background: var(--accent-soft);
    border: 1px solid rgba(124, 156, 255, 0.35);
    color: var(--accent-hover);
    padding: 4px 6px 4px 11px;
    border-radius: 999px;
    font-size: var(--fs-1);
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.block-tag button {
    background: none;
    border: none;
    color: var(--accent-hover);
    cursor: pointer;
    font-size: var(--fs-2);
    line-height: 1;
    padding: 2px 4px;
    border-radius: 999px;
    opacity: 0.7;
    transition: opacity 0.15s, background 0.15s;
}

.block-tag button:hover {
    opacity: 1;
    background: rgba(124, 156, 255, 0.2);
}

.btn-remove-symbol {
    background: transparent;
    color: var(--danger);
    border: 1px solid rgba(242, 109, 120, 0.35);
    padding: 6px 14px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--fs-1);
    font-weight: 600;
    transition: background 0.15s;
}

.btn-remove-symbol:hover {
    background: rgba(242, 109, 120, 0.12);
}

/* Buttons */
.btn {
    padding: 10px 20px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-size: var(--fs-2);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
    font-family: inherit;
}

.btn:active {
    transform: translateY(1px);
}

.btn-primary {
    background: var(--text-primary);
    color: var(--bg-base);
}

.btn-primary:hover {
    background: #ffffff;
}

.btn-secondary {
    background: var(--bg-raised);
    border-color: var(--border-strong);
    color: var(--text-secondary);
}

.btn-secondary:hover {
    background: var(--bg-surface);
    border-color: var(--accent);
    color: var(--text-primary);
}

.button-group {
    display: flex;
    gap: 12px;
    margin-top: 28px;
}

.button-group button {
    flex: 1;
}

/* Upload Area */
.upload-area {
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    padding: 44px 32px;
    text-align: center;
    background: var(--bg-inset);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.upload-area:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.upload-area.drag-over {
    border-color: var(--accent);
    background: rgba(124, 156, 255, 0.16);
}

/* Compact variant used for "도면 업로드/교체" on the dashboard */
.upload-area-compact {
    padding: 22px 24px;
    margin-bottom: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    flex-wrap: wrap;
}

.upload-area-compact .upload-icon {
    font-size: var(--fs-5);
    margin-bottom: 0;
}

.upload-area-compact p {
    margin: 0;
}

.upload-icon {
    font-size: var(--fs-6);
    margin-bottom: 12px;
    opacity: 0.85;
}

.upload-area p {
    margin: 8px 0;
    color: var(--text-secondary);
    font-size: var(--fs-2);
}

.text-small {
    font-size: var(--fs-1);
    color: var(--text-muted);
}

/* Selected file list */
#bootstrapFileInfo {
    margin: 18px 0;
    padding: 16px 18px;
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--success);
    border-radius: var(--radius);
    font-size: var(--fs-2);
    color: var(--text-secondary);
}

.file-list {
    margin-top: 8px;
    padding-left: 20px;
    color: var(--text-primary);
    font-size: var(--fs-2);
}

.file-list li {
    margin: 3px 0;
}

/* Stat cards */
.summary-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 14px;
    margin-bottom: 28px;
}

.summary-card {
    position: relative;
    background: var(--bg-raised);
    border: 1px solid var(--border-color);
    padding: 20px 22px;
    border-radius: var(--radius);
    overflow: hidden;
}

/* A thin accent bar per card instead of full-bleed gradients — reads
   cleaner on a dark surface and keeps the numbers legible. */
.summary-card::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--accent);
}

.summary-card:nth-child(2)::before { background: #b581f5; }
.summary-card:nth-child(3)::before { background: #3ecf8e; }
.summary-card:nth-child(4)::before { background: var(--warning); }

.summary-value {
    font-family: var(--font-mono);
    font-size: var(--fs-5);
    font-weight: 650;
    letter-spacing: -0.03em;
    line-height: 1.2;
    color: var(--text-primary);
}

.summary-label {
    font-size: var(--fs-1);
    font-weight: 500;
    color: var(--text-muted);
    margin-top: 2px;
}

/* Tables */
.table-container {
    overflow-x: auto;
    margin-bottom: 24px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    background: var(--bg-inset);
}

/* Frozen header row and first column.
   A sticky header cannot outlive its scroll container, and these tables
   scroll sideways inside .table-container — so the container itself
   becomes the scroll box (its own vertical scroll, capped just under the
   top bar) and the header sticks to its top, the first column to its
   left. The top bar (56 px) is outside, so no offset is needed inside. */
.table-container.table-frozen {
    max-height: calc(100vh - 56px - 32px);
    overflow: auto;
}
.table-frozen thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--bg-raised);
    box-shadow: 0 1px 0 var(--border-strong);
}
.table-frozen th:first-child,
.table-frozen td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--bg-inset);
    box-shadow: 1px 0 0 var(--border-color);
}
.table-frozen thead th:first-child { z-index: 4; background: var(--bg-raised); }
.table-frozen tfoot td:first-child { background: var(--bg-inset); }
.table-frozen tbody tr:hover td:first-child { background: var(--bg-raised); }
.table-frozen tfoot tr.pivot-total td {
    position: sticky;
    bottom: 0;
    z-index: 2;
    background: var(--bg-inset);
    box-shadow: 0 -1px 0 var(--border-strong);
}
.table-frozen tfoot tr.pivot-total td:first-child { z-index: 4; }

table {
    /* Let the table grow past the container width when there are many
       symbol columns — .table-container scrolls it horizontally — instead
       of squeezing every column down to fit, which is what made headers
       wrap into unreadable vertical letter-stacks. */
    width: max-content;
    min-width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-2);
}

th {
    background: var(--bg-raised);
    padding: 12px 8px;
    text-align: center;
    vertical-align: bottom;
    font-weight: 600;
    font-size: var(--fs-1);
    letter-spacing: 0;
    border-bottom: 1px solid var(--border-strong);
    color: var(--text-secondary);
    word-break: keep-all;
    overflow-wrap: break-word;
    line-height: 1.35;
    /* Narrow enough that a typical legend (10-15 symbols) fits without a
       horizontal scrollbar; wide enough that headers wrap into a couple
       of lines rather than one letter per line. `.table-container` still
       scrolls if a legend really is huge. */
    min-width: 72px;
    max-width: 140px;
}

/* Plan/drawing name column: wider, left-aligned, reads like a label not
   a value. (Deliberately NOT `position: sticky` — combined with
   `border-collapse: collapse` that renders unreliably across browsers.) */
th:first-child,
td:first-child {
    text-align: left;
    min-width: 150px;
    max-width: none;
    color: var(--text-primary);
    font-weight: 500;
}
/* The symbol headers stack icon · name · pill, so the plan-name header
   sits mid-height and centred like them; the cells under it stay left. */
th:first-child { vertical-align: middle; text-align: center; }


td {
    padding: 10px 12px;
    text-align: center;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* Count cells of the symbol pivot tables; the roll-up tables pick their
   own numeric cells (.num) so dates and labels stay in the text face. */
table:not(.rollup-table) td:not(:first-child) {
    font-family: var(--font-mono);
    font-size: var(--fs-2);
    font-weight: 500;
}

tbody tr:last-child td {
    border-bottom: none;
}

tbody tr:hover td {
    background: rgba(124, 156, 255, 0.06);
}

/* A zero reads as "checked and empty": faded, so the counts stand out.
   Counted cells carry a tint that grows with the count (--heat). */
td.cell-zero { color: var(--border-strong); text-align: center; }
td.cell-heat { background: rgba(124, 156, 255, var(--heat, 0)); color: var(--text-primary); }
td.cell-locate-row { cursor: pointer; }
td.cell-locate-row:hover { color: var(--accent); }
tfoot tr.pivot-total td { border-top: 1px solid var(--border-strong); font-weight: 700; color: var(--text-primary); background: var(--bg-inset); }
tfoot tr.pivot-total td:not(:first-child) { font-family: var(--font-mono); }
.summary-grid-3 { grid-template-columns: repeat(3, minmax(160px, 1fr)); }
.summary-grid-4 { grid-template-columns: repeat(4, minmax(160px, 1fr)); }
@media (max-width: 1100px) { .summary-grid-4 { grid-template-columns: repeat(2, minmax(160px, 1fr)); } }
.summary-meta { margin: -14px 0 12px; font-size: var(--fs-1); }
.pm-cards .summary-value { font-size: var(--fs-5); letter-spacing: -0.02em; }
.pm-cards .summary-card { padding: 16px 18px; }
.pm-cards .summary-unit { font-size: var(--fs-2); font-weight: 500; color: var(--text-muted); margin-left: 2px; }
.pm-cards .summary-sep { color: var(--text-muted); font-weight: 400; margin: 0 4px; }
.pm-cards .summary-sub { margin-left: 6px; }
.pm-cards .summary-input { width: 44px; padding: 1px 4px; font: inherit; font-size: var(--fs-1); background: var(--bg-inset); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; text-align: right; }
.pm-cards .summary-link { margin-left: 8px; color: var(--accent); text-decoration: none; }
.pm-cards .summary-link:hover { text-decoration: underline; }
.pm-cards .trust-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 8px; vertical-align: 2px; background: var(--text-muted); }
.pm-cards .trust-dot.is-ok { background: var(--success); box-shadow: 0 0 0 3px rgba(76, 207, 147, 0.18); }
.pm-cards .trust-dot.is-warn { background: var(--warning); box-shadow: 0 0 0 3px rgba(255, 176, 46, 0.18); }
.pm-cards .trust-dot.is-bad { background: var(--danger); box-shadow: 0 0 0 3px rgba(242, 109, 120, 0.18); }
.pm-cards .summary-label b { color: var(--text-primary); font-weight: 600; }

/* Symbol shape icon, rendered from the actual DXF block geometry.
   The backend draws those SVGs as black strokes on a transparent
   background, so invert them to stay visible on a dark surface. */
/* the device icon (U-78): the drawing's own block symbol, drawn white with a stroke that stays 1.7px at any size
   (the DXF's hairline vanished when scaled), on a rounded tile in the family's colour — the colour the viewer marks
   that device with, so a tile reads the same in the table, the device list and the legend */
.symbol-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin: 0 auto 4px;
    border-radius: 7px;
    background: color-mix(in srgb, var(--tile, #8a94a6) 18%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tile, #8a94a6) 60%, transparent);
    padding: 3px;
    box-sizing: border-box;
}

.symbol-icon svg {
    width: 100%;
    height: 100%;
    filter: invert(1);
    opacity: 0.95;
}
.symbol-icon svg path, .sym-icon svg path { stroke-width: 1.7px !important; vector-effect: non-scaling-stroke; }
.symbol-icon svg rect[fill="#ffffff"] { display: none; }

th .symbol-label {
    display: block;
    font-weight: 500;
    font-size: var(--fs-1);
    line-height: 1.3;
    max-width: 110px;
    white-space: normal;
    margin: 0 auto;
}

.table-footnote {
    padding: 10px 14px;
    border-top: 1px solid var(--border-color);
    font-size: var(--fs-1);
    color: var(--text-muted);
}

.link-btn {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--accent);
    cursor: pointer;
    text-decoration: underline;
}

.link-btn:hover {
    color: var(--accent-hover);
}

/* Click-to-sort column headers */
th.sortable {
    cursor: pointer;
    user-select: none;
    transition: background 0.15s, color 0.15s;
}

th.sortable:hover {
    background: var(--bg-surface);
    color: var(--text-primary);
}

th.is-sorted {
    color: var(--accent);
    background: var(--accent-soft);
}

/* Spinner */
.spinner {
    text-align: center;
    padding: 40px;
    color: var(--text-muted);
}

.spinner-inner {
    border: 3px solid var(--border-color);
    border-top-color: var(--accent);
    border-radius: 50%;
    width: 36px;
    height: 36px;
    animation: spin 0.8s linear infinite;
    margin: 0 auto 18px;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Messages */
.error {
    background: rgba(242, 109, 120, 0.1);
    border: 1px solid rgba(242, 109, 120, 0.3);
    border-left: 3px solid var(--danger);
    color: #ffa8ae;
    padding: 14px 18px;
    border-radius: var(--radius);
    margin-top: 20px;
    font-size: var(--fs-2);
}

.warning {
    background: rgba(224, 176, 79, 0.08);
    border: 1px solid rgba(224, 176, 79, 0.25);
    border-left: 3px solid var(--warning);
    color: #f3cd8c;
    padding: 14px 18px;
    border-radius: var(--radius);
    margin-bottom: 18px;
    font-size: var(--fs-2);
    line-height: 1.6;
}

.warning div + div {
    margin-top: 6px;
}

/* Footer */
.footer {
    text-align: center;
    padding: 24px 0;
    margin-top: 16px;
    border-top: 1px solid var(--border-color);
    color: var(--text-muted);
    font-size: var(--fs-2);
}

/* Scrollbars */
::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border: 3px solid var(--bg-base);
    border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
    background: #46516b;
}

/* Responsive */
@media (max-width: 768px) {
    .app-body { flex-direction: column; }
    .sidebar { position: static; width: auto; max-height: none; border-right: none; border-bottom: 1px solid var(--border-color); }
    .main-content { padding: 16px 16px 0; }
    .topbar { gap: 10px; padding: 0 16px; }
    .topbar-brand, .topbar-updated { display: none; }

    .section {
        padding: 20px 18px;
    }

    .symbol-item {
        grid-template-columns: 1fr;
    }

    .summary-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .button-group {
        flex-direction: column;
    }

    .new-item-row {
        flex-direction: column;
    }

    table {
        font-size: var(--fs-1);
    }

    th, td {
        padding: 8px;
    }
}

/* 계통도 대조 — 설계 수량(계통도)과 집계 수량을 나란히 보여주는 참고 표 */
.riser-check {
    margin: 16px 0;
    padding: 14px 16px;
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    background: var(--bg-raised);
}
.riser-title { font-weight: 600; margin-bottom: 4px; color: var(--text-primary); }
.riser-note {
    font-size: var(--fs-1);
    color: var(--text-muted);
    margin-bottom: 10px;
    line-height: 1.55;
}
.riser-na { color: var(--text-muted); font-size: var(--fs-0); }
.riser-missing th, .riser-missing td { color: var(--text-muted); }
.riser-ok { color: var(--success); }
.riser-diff { color: var(--warning); }


/* 집계 방식 안내 — 시트별 합과 총합이 다른 이유 */
.counting-note {
    margin: 14px 0;
    padding: 12px 16px;
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--text-secondary);
    font-size: var(--fs-2);
    line-height: 1.6;
}
.counting-note strong { color: var(--text-primary); }
.counting-note em { color: var(--text-primary); font-style: normal; font-weight: 600; }

/* 확인 필요 — 도면과 집계가 어긋나는 항목들 */
.review-items {
    margin: 16px 0;
    padding: 14px 16px;
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--warning);
    border-radius: var(--radius);
    background: var(--bg-raised);
}
.review-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 4px;
}
.review-head strong { color: var(--text-primary); }
.review-note {
    font-size: var(--fs-1);
    color: var(--text-muted);
    margin-bottom: 10px;
}
.btn-csv {
    flex: none;
    padding: 6px 12px;
    font-size: var(--fs-1);
    color: var(--text-secondary);
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    text-decoration: none;
    transition: color 0.15s, border-color 0.15s;
}
.btn-csv:hover { color: var(--accent); border-color: var(--accent); }
.review-kind {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 2px;
    font-size: var(--fs-0);
    font-weight: 600;
    white-space: nowrap;
}
.review-unassigned { color: var(--warning); background: rgba(224, 176, 79, 0.12); }
.review-unmapped { color: var(--text-secondary); background: var(--bg-inset); }
.review-embedded { color: var(--warning); background: rgba(224, 176, 79, 0.12); }
.review-shared_block { color: var(--warning); background: rgba(224, 176, 79, 0.12); }
.review-label_shape { color: var(--danger); background: rgba(242, 109, 120, 0.12); }
.review-count { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.review-detail { white-space: normal; color: var(--text-secondary); font-size: var(--fs-1); }

/* The generic table rules are shaped for the symbol summary — a narrow
   second column for totals, max-content width so many symbol columns
   scroll sideways. On the review list those same rules stacked the
   symbol name one syllable per line and pushed the explanation off the
   right edge. This table is prose, not a grid: fixed layout, full width,
   left-aligned, and the explanation column takes whatever is left. */
.review-table-wrap { overflow-x: visible; }
.review-table {
    width: 100%;
    min-width: 0;
    table-layout: fixed;
}
.review-table th,
.review-table td {
    text-align: left;
    vertical-align: top;
    min-width: 0;
    max-width: none;
    padding: 10px 10px;
    word-break: keep-all;
    overflow-wrap: anywhere;
    font-variant-numeric: normal;
}
.review-table td { color: var(--text-secondary); }
.review-table th:nth-child(1), .review-table td:nth-child(1) { width: 128px; }
.review-table th:nth-child(2), .review-table td:nth-child(2) { width: 22%; color: var(--text-primary); font-weight: 500; }
.review-table th:nth-child(3), .review-table td:nth-child(3) { width: 14%; }
.review-table th:nth-child(4), .review-table td:nth-child(4) { width: 64px; text-align: right; font-variant-numeric: tabular-nums; }
.review-table th:nth-child(5), .review-table td:nth-child(5) { width: auto; }
.review-table td.review-detail { line-height: 1.5; }
@media (max-width: 720px) {
    .review-table th:nth-child(3), .review-table td:nth-child(3) { display: none; }
    .review-table th:nth-child(1), .review-table td:nth-child(1) { width: 96px; }
}

.review-no_equipment_blocks { color: var(--danger); background: rgba(242, 109, 120, 0.12); }


/* 백그라운드 작업 진행 표시 */
.job-progress {
    margin: 12px 0;
    padding: 12px 14px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    background: var(--bg-raised);
}
.job-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}
.job-message { font-size: var(--fs-2); color: var(--text-primary); }
.job-percent {
    font-size: var(--fs-2);
    font-weight: 600;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}
.job-track {
    height: 6px;
    border-radius: 3px;
    background: var(--bg-inset);
    overflow: hidden;
}
.job-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 3px;
    transition: width 0.4s ease;
}
.job-eta { margin-top: 6px; font-size: var(--fs-1); color: var(--text-muted); }

.review-needs_recheck { color: var(--accent); background: var(--accent-soft); }
/* U-119: the guesses and the questions — informational, not a warning */
.review-assumed_height { color: var(--accent); background: var(--accent-soft); }
.review-estimated_route { color: var(--text-secondary); background: var(--bg-inset); }
.review-designer_question { color: #6ea8f5; background: rgba(110, 168, 245, 0.12); }
.rollup-review-own { cursor: default; }
/* R-41: the 보기 on a riser run, lit while its path is in the viewer */
.riser-see { margin-right: 6px; padding: 0 7px; font-size: var(--fs-0); line-height: 18px; white-space: nowrap; vertical-align: middle; }
.cable-marks-table.riser-runs-table .length-row { grid-template-columns: 210px 1fr 130px 90px; }
.riser-see.is-on { color: #4fc3e6; border-color: #4fc3e6; }

/* 도면 뷰어 */
.viewer-wrap { display: grid; grid-template-columns: 280px 1fr; gap: 14px; margin: 12px 0 20px; }
.viewer-select {
    width: 100%; padding: 9px 10px; font-size: var(--fs-2);
    color: var(--text-primary); background: var(--bg-inset);
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
}
.viewer-scale { margin: 8px 0; font-size: var(--fs-1); color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* the side column is exactly as tall as the canvas (U-111): the sheet index takes what it needs up to 45 %, the
   device list the rest, each scrolling on its own — the row never grows past the drawing, so no dark strip under it */
.viewer-side { display: flex; flex-direction: column; height: var(--viewer-height); min-height: 0; }
.viewer-side .sheet-index { flex: 0 1 auto; max-height: 45%; overflow-y: auto; }
.viewer-side .viewer-scale { flex: none; }
.viewer-panel {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; border-top: 1px solid var(--border-color); padding-top: 8px;
}
.viewer-layers { margin-top: 6px; }
/* symbol / cable rows in the side panel */
.side-head {
    display: flex; align-items: center; justify-content: space-between;
    font-size: var(--fs-1); font-weight: 600; padding: 2px 2px 6px;
}
.side-head .hint, .side-group > summary .hint, .sym-name .hint { font-weight: 400; font-size: var(--fs-1); color: var(--text-muted); }
.btn-tiny { padding: 2px 8px; font-size: var(--fs-0); }
.side-note { font-size: var(--fs-0); color: var(--text-muted); line-height: 1.5; margin: 6px 2px; }
.sym-row {
    display: grid; grid-template-columns: auto auto 1fr auto; gap: 8px;   /* checkbox · icon tile · name · count (the colour dot went into the tile, U-78) */
    align-items: center; padding: 5px 2px; font-size: var(--fs-2); cursor: pointer; border-radius: 4px;
}
.sym-row:hover { background: var(--bg-inset); }
.sym-row.is-on { background: var(--bg-inset); }
.sym-row.is-empty .sym-name, .sym-row.is-empty .sym-count { color: var(--text-muted); }
.sym-row.is-empty .sym-icon { opacity: 0.45; }
.sym-swatch {
    width: 12px; height: 12px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
    font-size: 9px; line-height: 1; color: #1b1b1b; font-weight: 700; box-shadow: 0 0 0 1px rgba(0,0,0,0.35) inset;
}
.sym-icon { width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 7px; padding: 3px; box-sizing: border-box;
    background: color-mix(in srgb, var(--tile, #8a94a6) 18%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tile, #8a94a6) 60%, transparent); }
.sym-icon svg { width: 100%; height: 100%; filter: invert(1); }
.sym-row .sym-swatch { display: none; }   /* the tile carries the colour now (U-78) */
.sym-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cable-by-floor-table tr.riser td.sheet { color: var(--text-muted); font-style: italic; }
.verdict { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: var(--fs-0); font-weight: 600; background: var(--bg-inset); color: var(--text-muted); border: 1px solid var(--border-color); }
.verdict.is-ok { color: var(--success); border-color: rgba(76, 207, 147, 0.45); }
.verdict.is-ask { color: #5ec3f5; border-color: rgba(94, 195, 245, 0.45); }
.verdict.is-warn { color: var(--warning); border-color: rgba(255, 176, 46, 0.4); }
.verdict.is-bad { color: var(--danger); border-color: rgba(242, 109, 120, 0.45); }
.note-row { padding: 6px 4px; border-top: 1px solid var(--border-color); font-size: var(--fs-1); }
.note-row .note-line { margin: 2px 0; }
.note-row .note-q { margin-top: 3px; color: var(--text-primary); }
.check-notes summary .btn { margin-left: 8px; }
.sym-row.sym-sub { padding-left: 22px; }
.sym-row.sym-sub .sym-name { color: var(--text-muted); }
.sym-row.sym-sub.is-on .sym-name, .sym-row.sym-sub:not(.is-empty) .sym-name { color: var(--text); }
/* In the viewer list the fold pill sits inline after the name (the table
   version is a block under the header and wrapped these rows to two lines). */
.sym-row .pivot-fold { display: inline-block; margin: 0 0 0 6px; padding: 1px 6px; font-size: 10.5px; vertical-align: 1px; }
.sym-row .sym-name { display: flex; align-items: center; min-width: 0; }
.sym-row .sym-name .pivot-fold { flex: none; }
.sym-count { font-family: var(--font-mono); font-size: var(--fs-1); font-variant-numeric: tabular-nums; }
.side-group { margin-top: 8px; border-top: 1px solid var(--border-color); padding-top: 6px; }
.side-group > summary, .layer-group > summary {
    cursor: pointer; font-size: var(--fs-1); font-weight: 600; padding: 4px 2px; list-style: revert; user-select: none;
}
.side-group > summary:hover, .layer-group > summary:hover { color: var(--accent); }
.layer-group { border-top: 1px solid var(--border-color); padding-top: 6px; }
.layer-group[open] > summary { margin-bottom: 4px; }
.layer-note { font-size: var(--fs-0); color: var(--text-muted); line-height: 1.5; margin-bottom: 8px; }
.layer-row {
    display: grid; grid-template-columns: auto 1fr auto auto; gap: 6px;
    align-items: center; padding: 4px 2px; font-size: var(--fs-1); cursor: pointer;
}
.layer-row:hover { background: var(--bg-inset); }
.layer-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.layer-count, .layer-size { font-size: var(--fs-0); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.layer-heavy .layer-size { color: var(--warning); }
.layer-missing-xref {
    background: var(--bg-inset); border: 1px solid var(--danger);
    border-radius: 6px; padding: 9px 10px; margin-bottom: 9px;
    font-size: var(--fs-0); line-height: 1.55;
}
.layer-missing-xref > summary {
    cursor: pointer; list-style: revert; user-select: none; line-height: 1.5;
}
.layer-missing-xref[open] > summary { margin-bottom: 4px; }
.layer-only { color: var(--text-muted); font-size: 10.5px; }
.layer-missing-xref .missing-src {
    margin-top: 5px; font-family: ui-monospace, Consolas, monospace;
    font-size: var(--fs-0); color: var(--text-muted); word-break: break-all;
}
.layer-missing-xref .missing-hint { margin-top: 6px; color: var(--text-muted); }
.layer-background-off {
    background: var(--bg-inset); border: 1px solid var(--warning);
    border-radius: 6px; padding: 9px 10px; margin-bottom: 9px;
    font-size: var(--fs-1); line-height: 1.5;
}
.btn-show-background {
    margin-top: 7px; width: 100%; padding: 6px 10px; cursor: pointer;
    background: var(--warning); color: #1b1b1b; border: none;
    border-radius: 5px; font-size: var(--fs-1); font-weight: 600;
}
.btn-show-background:disabled { opacity: 0.6; cursor: default; }
.layer-aux { margin-top: 8px; border-top: 1px solid var(--border-color); padding-top: 6px; }
.layer-aux > summary {
    cursor: pointer; font-size: var(--fs-0); color: var(--text-muted);
    padding: 4px 2px; list-style: revert; user-select: none;
}
.layer-aux > summary:hover { color: var(--text-primary); }
.layer-aux .layer-row { opacity: 0.75; }
.xref-picker { margin-top: 10px; }
.xref-status { display: block; font-size: var(--fs-0); color: var(--text-muted); margin-top: 5px; }
.btn-plain {
    background: none; border: 1px dashed var(--border-color); color: var(--text-muted);
    padding: 5px 10px; border-radius: 5px; cursor: pointer; font-size: var(--fs-1);
}
.btn-plain:hover { color: var(--text-primary); border-color: var(--text-muted); }
.viewer-main { position: relative; min-width: 0; }   /* a grid item may shrink below the canvas's pixel width (fullscreen exit) */
.viewer-canvas {
    /* The drawing is the point of this screen, so it takes the height the
       window can spare rather than a fixed 560px box. */
    position: relative;
    height: var(--viewer-height);
    border: 1px solid var(--border-color);
    border-radius: var(--radius); background: var(--canvas-bg); overflow: hidden;
}
/* a scroll-to (a count clicked, a fold opened) lands below the sticky top bar and menu, with the block's title in view
   (U-61: the viewer used to land with its top under the bars) */
#screenDashboard > *, #screenDisciplines > * { scroll-margin-top: 124px; }
#screenDashboard > .viewer-wrap { scroll-margin-top: 162px; }   /* the 도면 보기 title comes along */
/* the toolbar (U-57): one row at the top right, the buttons in flow — no per-button offsets to keep in step */
.viewer-toolbar { position: absolute; right: 12px; top: 12px; z-index: 2; display: flex; gap: 6px; align-items: center; }
.viewer-fs-btn {
    padding: 6px 11px; font-size: var(--fs-1); cursor: pointer; white-space: nowrap;
    color: var(--text-primary); background: var(--bg-raised);
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
}
.viewer-fs-btn:hover { border-color: var(--text-muted); }
.viewer-spot-btn.is-on { background: var(--text-primary); color: var(--bg-base); border-color: var(--text-primary); }
.viewer-print-menu {
    position: absolute; right: 12px; top: 48px; z-index: 6; width: 300px; padding: 10px 12px; font-size: var(--fs-1);
    background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: 0 6px 20px rgba(0, 0, 0,0.18);
    display: flex; flex-direction: column; gap: 6px;
}
.viewer-print-menu label { display: flex; gap: 6px; align-items: center; cursor: pointer; }
.viewer-print-actions { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.viewer-measure-btn.is-on { background: var(--warning); color: #1b1b1b; border-color: var(--warning); }
.viewer-measure-panel {
    position: absolute; right: 12px; top: 50px; z-index: 2;
    width: 268px; max-height: 60%; overflow-y: auto;
    padding: 10px 12px; font-size: var(--fs-1); line-height: 1.6;
    color: var(--text-primary); background: var(--bg-raised);
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
}
.measure-total { font-size: var(--fs-4); font-weight: 600; font-variant-numeric: tabular-nums; }
.measure-meta { color: var(--text-muted); font-size: var(--fs-0); margin-top: 3px; word-break: break-all; }
.measure-segs { margin-top: 8px; border-top: 1px solid var(--border-color); padding-top: 6px; }
.measure-segs div {
    display: flex; justify-content: space-between; gap: 10px;
    font-variant-numeric: tabular-nums; font-size: var(--fs-0);
}
.measure-note { margin-top: 7px; color: var(--warning); font-size: var(--fs-0); }
.viewer-area-btn.is-on { background: var(--danger, #ff4d4f); color: #fff; border-color: var(--danger, #ff4d4f); }
.area-exclusions { margin-top: 8px; font-size: var(--fs-1); }
.area-exclusions .length-row { grid-template-columns: 1fr 160px 90px 70px; }
.area-exclusions .btn-tiny { padding: 1px 6px; }
.viewer-calib-btn.is-on { background: var(--warning); color: #1b1b1b; border-color: var(--warning); }

.length-section { margin: 18px 0 8px; }
.length-file { margin-bottom: 14px; }
.length-file > h4 {
    font-size: var(--fs-2); margin-bottom: 6px;
    display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
}
.length-file > h4 span { font-variant-numeric: tabular-nums; color: var(--text-muted); font-weight: 400; }
.length-rows { border: 1px solid var(--border-color); border-radius: var(--radius-sm); overflow: hidden; }
.length-row {
    display: grid; grid-template-columns: 1fr 90px 140px; gap: 10px;
    padding: 5px 10px; font-size: var(--fs-1); font-variant-numeric: tabular-nums;
    border-bottom: 1px solid var(--border-color);
}
.length-row:last-child { border-bottom: none; }
.length-row span:not(:first-child) { text-align: right; color: var(--text-muted); font-family: var(--font-mono); font-size: var(--fs-1); }
.length-row.is-total { background: var(--bg-inset); font-weight: 600; }
.length-row.is-total span { color: var(--text-primary); }
.length-aux { border-top: 1px solid var(--border-color); }
.length-aux > summary {
    cursor: pointer; padding: 6px 10px; font-size: var(--fs-0);
    color: var(--text-muted); list-style: revert; user-select: none;
}
.length-calib {
    margin-bottom: 10px; padding: 8px 11px; font-size: var(--fs-1); line-height: 1.6;
    background: var(--bg-inset); border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
}
.length-calib.is-on { border-color: var(--warning); }
.length-advanced > summary {
    cursor: pointer; font-size: var(--fs-1); color: var(--text-muted);
    padding: 8px 0; list-style: revert; user-select: none;
}
.length-advanced > summary:hover { color: var(--text-primary); }
.length-advanced[open] > summary { margin-bottom: 8px; }
.cable-rest > summary { cursor: pointer; padding: 6px 10px; font-size: var(--fs-0); color: var(--text-muted); list-style: revert; }
.cable-block { margin-bottom: 16px; }
.cable-block > h4 { font-size: var(--fs-2); margin-bottom: 6px; color: var(--text-primary); }
.cable-sched { border: 1px solid var(--border-color); border-radius: var(--radius-sm); overflow: hidden; }
.cable-sched .length-row { grid-template-columns: 56px 1fr 120px; }
.cable-meta { font-size: var(--fs-0); color: var(--text-muted); margin-bottom: 6px; }
.cable-styles { border: 1px solid var(--border-color); border-radius: var(--radius-sm); overflow: auto; max-height: calc(100vh - 56px - 32px); }
.cable-style.is-head { position: sticky; top: 0; z-index: 2; background: var(--bg-raised); color: var(--text-muted); font-weight: 600; cursor: default; }
.cable-style.is-head:hover { background: var(--bg-raised); }
.cable-style {
    display: grid; grid-template-columns: 18px 1fr 70px 100px 130px 150px 86px;
    gap: 8px; align-items: center; padding: 5px 10px; font-size: var(--fs-1);
    border-bottom: 1px solid var(--border-color); cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.cable-style:last-child { border-bottom: none; }
.cable-style:hover { background: var(--bg-inset); }
.cable-style.is-focused { background: rgba(255, 212, 94, 0.10); }
.cable-style .swatch { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--border-color); }
.cable-style .num { text-align: right; color: var(--text-muted); font-family: var(--font-mono); font-size: var(--fs-1); }
.cable-style .hint { color: var(--text-muted); font-size: var(--fs-0); }
.cable-style select {
    width: 100%; padding: 3px 6px; font-size: var(--fs-1);
    color: var(--text-primary); background: var(--bg-inset);
    border: 1px solid var(--border-color); border-radius: 4px;
}
.badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: var(--fs-0); text-align: center; }
.badge-confirmed { background: rgba(76, 207, 147, 0.16); color: #7fe0b2; }
.badge-suggested { background: rgba(255, 212, 94, 0.18); color: var(--warning); }
.badge-recheck { background: rgba(255, 140, 60, 0.2); color: #ff9e5e; }
.badge-unconfirmed { background: var(--bg-inset); color: var(--text-muted); }
.cable-aux { border-top: 1px solid var(--border-color); }
.cable-aux > summary { cursor: pointer; padding: 6px 10px; font-size: var(--fs-0); color: var(--text-muted); list-style: revert; }
.cable-totals { border: 1px solid var(--border-color); border-radius: var(--radius-sm); overflow: hidden; }
.cable-totals .length-row { grid-template-columns: 56px 1fr 90px 140px; }
.length-calib button {
    margin-left: 8px; padding: 3px 9px; font-size: var(--fs-0); cursor: pointer;
    color: var(--text-primary); background: var(--bg-raised);
    border: 1px solid var(--border-color); border-radius: 4px;
}

/* Full screen: the wrapper leaves the page flow and covers the window.
   The layer panel stays — picking layers is most of what the viewer is
   for — and only the canvas grows. */
.viewer-wrap.is-fullscreen {
    position: fixed; inset: 0; z-index: 900; margin: 0;
    padding: 12px; gap: 12px; background: var(--bg-base);
}
.viewer-wrap.is-fullscreen .viewer-canvas { height: calc(100vh - 24px); }

/* Wizard docked to the right of the viewer — in the page or fullscreen. */
.viewer-wrap.has-wizard { grid-template-columns: 280px 1fr 380px; }
.wizard-panel {
    display: flex; flex-direction: column; gap: 12px; min-width: 0;
    padding: 16px 16px 14px; background: var(--bg-surface); border: 1px solid var(--border-color);
    border-radius: var(--radius); overflow-y: auto;
}
.viewer-wrap.is-fullscreen .wizard-panel { max-height: calc(100vh - 24px); }
.wizard-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.wizard-title { font-size: var(--fs-3); font-weight: 700; }
.wizard-count { font-family: var(--font-mono); font-weight: 600; color: var(--text-secondary); margin-left: 6px; }
.wizard-progress { height: 6px; border-radius: 3px; background: var(--bg-inset); border: 1px solid var(--border-color); overflow: hidden; }
.wizard-progress-fill { height: 100%; background: var(--accent); }
.wizard-tally { font-size: var(--fs-1); color: var(--text-muted); font-family: var(--font-mono); }
.wizard-style { padding: 12px 14px; background: var(--bg-raised); border: 1px solid var(--border-color); border-radius: var(--radius-sm); display: flex; flex-direction: column; gap: 6px; }
.wizard-style-name { display: flex; align-items: center; gap: 8px; font-size: var(--fs-2); }
.wizard-style-name .swatch { width: 16px; height: 16px; border-radius: 4px; border: 1px solid var(--border-strong); flex: none; }
.wizard-style-meta { font-size: var(--fs-1); color: var(--text-secondary); }
.wizard-suggest { font-size: var(--fs-2); color: var(--warning); }
.wizard-note { font-size: var(--fs-1); color: var(--text-muted); line-height: 1.5; }
.wizard-where { font-size: var(--fs-1); color: var(--text-secondary); line-height: 1.6; }
.wizard-where b { color: var(--text-primary); }
.wizard-next-sheet { margin-left: 6px; padding: 2px 8px; font-size: var(--fs-1); }
.wizard-open-drawing { display: block; width: 100%; text-align: left; margin: 4px 0; padding: 6px 8px; font-size: var(--fs-1); }
.wizard-actions { display: flex; flex-direction: column; gap: 8px; }
.wizard-note-input { width: 100%; padding: 7px 10px; background: var(--bg-inset); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); font-size: var(--fs-1); }
.wizard-note-input:focus { outline: none; border-color: var(--accent); }
.cable-note { display: inline-block; margin-left: 6px; font-size: var(--fs-0); color: var(--text-secondary); }
.wizard-confirm { display: flex; gap: 8px; }
.wizard-confirm select { flex: 1; min-width: 0; }
.wizard-confirm .btn { padding: 8px 18px; }
.wizard-none { width: 100%; }
.wizard-skip { width: 100%; padding: 8px; }
.wizard-nav { display: flex; justify-content: space-between; gap: 8px; margin-top: auto; }
.wizard-nav .btn-plain { padding: 6px 12px; }
.wizard-keys { font-size: var(--fs-0); color: var(--text-muted); }
.wizard-filters { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: var(--fs-1); color: var(--text-secondary); }
.wizard-filters label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.wizard-withdraw { margin-left: 8px; padding: 2px 8px; font-size: var(--fs-0); }
.wizard-more { margin-top: 8px; }
.wizard-done { font-size: var(--fs-2); line-height: 1.7; }
.cable-block-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
/* mark-based quantities (안성IDC 자동제어) */
.cable-marks-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 10px; }
.cable-marks-grid .cable-totals .length-row { grid-template-columns: 1fr 120px 130px; }
.cable-marks-table .length-row { grid-template-columns: 48px 1fr 60px 150px; }
.cable-marks-table .length-row > span:nth-child(2) { text-align: left; font-family: var(--font-mono, monospace); font-size: var(--fs-1); }
.cable-marks .length-row.is-head { font-weight: 600; color: var(--text-secondary); background: var(--bg-raised); }
.cable-mark-sheet { border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 6px 10px; margin-top: 8px; }
.cable-mark-sheet > summary { cursor: pointer; font-size: var(--fs-2); }
.cable-mark-sheet-name { font-weight: 600; text-decoration: underline dotted; }
.cable-notes { margin: 6px 0 0 18px; font-size: var(--fs-1); color: var(--text-secondary); }
.cable-style-fold { margin-top: 12px; }
.cable-by-floor { margin: 6px 0 12px; }
.qty-tabs { display: flex; gap: 4px; margin: 18px 0 8px; border-bottom: 1px solid var(--border-color); }
.qty-tab { background: none; border: none; border-bottom: 2px solid transparent; padding: 8px 14px; font-size: var(--fs-2); font-weight: 600; color: var(--text-secondary); cursor: pointer; }
.qty-tab:hover { color: var(--text-primary); }
.qty-tab.is-on { color: var(--text-primary); border-bottom-color: var(--accent, #4d8dff); }
.qty-tab-figure { margin-left: 6px; font-weight: 400; font-size: var(--fs-2); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.qty-pane { min-height: 40px; }
.cable-floor-simple .length-row { grid-template-columns: 1fr 160px; }
.cable-by-floor-scroll { overflow-x: auto; border: 1px solid var(--border-color); border-radius: var(--radius-sm); }
.cable-by-floor-table { border-collapse: collapse; font-size: var(--fs-2); min-width: 100%; }
.cable-by-floor-table th, .cable-by-floor-table td { padding: 6px 10px; border-bottom: 1px solid var(--border-color); white-space: nowrap; }
.cable-by-floor-table th { background: var(--bg-raised); color: var(--text-secondary); font-weight: 600; text-align: right; }
/* cable names are long (AWG #20 SHIELD 0.5mm²/6C x 2): wrap the column heads instead of running them into each other */
.cable-by-floor-table tr:nth-child(2) th:not(.sheet) { white-space: normal; overflow-wrap: anywhere; max-width: 150px; min-width: 96px; vertical-align: bottom; line-height: 1.25; }
/* the sheet column stays put while the cable columns scroll: opaque
   (an undefined token made it transparent and the numbers showed through),
   above the cells, wide enough for the longest title */
.cable-by-floor-table th.sheet, .cable-by-floor-table td.sheet {
    text-align: left; position: sticky; left: 0; z-index: 2;
    background: var(--bg-surface); min-width: 300px; max-width: 360px;
    border-right: 1px solid var(--border-color); box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.6);
    overflow: hidden; text-overflow: ellipsis;
}
.cable-by-floor-table th.sheet { background: var(--bg-raised); z-index: 3; }
.cable-by-floor-table tr.total td.sheet { background: var(--bg-raised); }
.cable-by-floor-table th.grp:first-child { position: static; }
.cable-by-floor-table th.grp { text-align: center; border-left: 1px solid var(--border-color); }
.cable-by-floor-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.cable-by-floor-table .trunk { background: rgba(80, 140, 255, 0.06); }
.cable-by-floor-table .branch { background: rgba(255, 200, 60, 0.06); }
.cable-by-floor-table .conduit { background: rgba(120, 220, 120, 0.06); }
.cable-by-floor-table tr.total td { border-top: 2px solid var(--border-color); }
.run-assign-panel { top: 50px; right: 12px; width: 320px; }
.run-assign-nav { float: right; display: inline-flex; align-items: center; gap: 4px; }
.run-assign-pos { min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }
.run-swatch { display: inline-block; width: 18px; height: 6px; border-radius: 3px; vertical-align: middle; margin-right: 4px; }
.run-assign-panel select { width: 100%; margin: 6px 0; }
.run-assign-panel .run-assign-actions { display: flex; gap: 6px; align-items: center; }
.run-assign-panel .run-assign-list { max-height: 160px; overflow-y: auto; margin-top: 6px; border-top: 1px solid var(--border-color); padding-top: 6px; }
.run-assign-panel .run-assign-list div { display: flex; justify-content: space-between; gap: 6px; }
.btn-runs { margin-left: 8px; }
.cable-style-fold > summary { cursor: pointer; font-size: var(--fs-2); color: var(--text-secondary); margin-bottom: 8px; }
@media (max-width: 1200px) { .cable-marks-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 900px) { .cable-marks-grid { grid-template-columns: 1fr; } }
.cable-block-head h4 { margin-bottom: 0; }
.btn-wizard { padding: 7px 14px; font-size: var(--fs-2); white-space: nowrap; }
.viewer-wrap.is-fullscreen .viewer-side { height: calc(100vh - 24px); }
.viewer-legend {
    position: absolute; left: 12px; top: 12px; z-index: 5; min-width: 180px; max-width: 320px;
    padding: 8px 10px; font-size: var(--fs-1); background: rgba(19, 22, 28, 0.92); border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm); box-shadow: 0 6px 20px rgba(0, 0, 0,0.18);
}
.legend-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-weight: 600; margin-bottom: 4px; }
.legend-spot { font-weight: 400; font-size: var(--fs-0); color: var(--text-muted); display: inline-flex; gap: 4px; align-items: center; cursor: pointer; }
.legend-row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 7px; align-items: center; padding: 3px 0; cursor: default; }
.legend-row:hover { background: rgba(255,255,255,0.05); }
.legend-row.is-empty .legend-name, .legend-row.is-empty .legend-count { color: var(--text-muted); }
.legend-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legend-count { font-family: var(--font-mono); font-size: var(--fs-0); }
.legend-line { border-radius: 2px; width: 14px; height: 6px; }
.legend-off { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: var(--fs-2); line-height: 1; padding: 0 2px; }
.legend-off:hover { color: var(--text-primary); }
.viewer-status {
    position: absolute; left: 12px; bottom: 12px;
    padding: 7px 12px; font-size: var(--fs-1);
    color: var(--text-primary); background: var(--bg-raised);
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
}
@media (max-width: 900px) { .viewer-wrap { grid-template-columns: 1fr; } }

/* 집계 표에서 도면 위치로 보내는 칸 */
td.cell-locate { cursor: pointer; }   /* clickable, but no underline on a hundred numbers (U-51): the hover says it */
td.cell-locate:hover { color: var(--accent); background: rgba(124, 156, 255, 0.12); }
td.cell-locate:hover { color: var(--accent); background: var(--accent-soft); }
td.cell-locate-total strong { text-decoration: underline dotted var(--text-muted); }

/* A locate in progress: the table's cells still take the click (the last
   one wins), but the cursor says the viewer is busy. */
body.is-locating td.cell-locate { cursor: progress; }
body.is-locating #viewerCanvas { cursor: progress; }
/* the CAD crosshair (U-123): the overlay canvas over the stage, and no system cursor while it is drawn */
.viewer-canvas canvas.viewer-crosshair { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 3; }
.viewer-canvas.has-crosshair, .viewer-canvas.has-crosshair * { cursor: none; }
.viewer-canvas.is-panning, .viewer-canvas.is-panning * { cursor: grabbing; }   /* U-124: wheel button held */

/* The folded review block on the dashboard. Same fold as the advanced
   length table, plus a count so the line says how much is waiting. */
.review-fold > summary { font-size: var(--fs-2); color: var(--text-secondary); }
.review-fold[open] > summary { color: var(--text-primary); }
.fold-badge {
    display: inline-block; min-width: 18px; padding: 1px 7px; margin-left: 4px;
    border-radius: 9px; font-size: var(--fs-0); font-weight: 600; text-align: center;
    color: var(--warning); background: rgba(224, 176, 79, 0.14);
}
.review-empty { padding: 8px 0 4px; font-size: var(--fs-1); color: var(--text-muted); }
.review-fold .review-items, .review-fold .riser-check, .review-fold .warning, .review-fold .counting-note { margin-top: 10px; }

/* Project roll-up: one discipline per line, numbers right-aligned,
   the whole line clickable like the cards it replaced. */
.rollup-table { width: 100%; min-width: 0; table-layout: auto; }
.rollup-table th, .rollup-table td { text-align: left; min-width: 0; max-width: none; padding: 10px 10px; white-space: nowrap; }
.rollup-table th.num, .rollup-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rollup-table td.num { font-family: var(--font-mono); font-size: var(--fs-2); }
.rollup-table td:nth-child(n+2) { color: var(--text-secondary); }
.rollup-table th.sortable { cursor: pointer; user-select: none; }
.rollup-table th.sortable:hover { color: var(--text-primary); }
.rollup-table th.sort-active { color: var(--text-primary); }
/* Status line under the project title */
.status-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: -6px 0 22px; font-size: var(--fs-2); color: var(--text-secondary); }
/* 현황 face (L-2) */
.project-header { margin: 4px 0 16px; }
.project-header h2 { margin-bottom: 0; font-size: var(--fs-5); font-weight: 700; letter-spacing: -0.02em; }
.project-header h2 .title-meta { margin-left: 14px; font-size: var(--fs-2); }
.title-mode { font-size: var(--fs-2); font-weight: 500; color: var(--text-muted); margin-left: 6px; }
.status-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 18px; }
.chip { padding: 2px 9px; border-radius: 999px; font-size: var(--fs-0); background: var(--bg-inset); border: 1px solid var(--border-color); color: var(--text-secondary); }
.chip-muted { color: var(--text-muted); border-style: dashed; }
.big-numbers { display: grid; grid-template-columns: repeat(4, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
.big-number { padding: 14px 16px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-raised); }
.big-number.is-amber { border-color: var(--warning); }
.big-label { font-size: var(--fs-2); color: var(--text-muted); }
.big-value { font-family: var(--font-mono); font-size: var(--fs-5); font-weight: 600; line-height: 1.3; margin: 4px 0 2px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.big-number.is-amber .big-value { color: var(--warning); }
.big-sub { font-size: var(--fs-2); color: var(--text-muted); line-height: 1.45; }
.alert-cards { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 12px; margin-bottom: 14px; }
.alert-card { padding: 12px 14px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-raised); font-size: var(--fs-1); min-width: 0; }
.alert-card.is-amber { border-left: 3px solid var(--warning); }
.alert-head { font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.alert-count { font-family: var(--font-mono); font-size: var(--fs-1); padding: 0 7px; border-radius: 999px; background: var(--bg-inset); color: var(--text-secondary); }
.alert-card.is-amber .alert-count { background: var(--warning); color: #1b1b1b; }
.alert-line { padding: 5px 6px; margin: 0 -6px; border-radius: 4px; cursor: pointer; line-height: 1.45; }
.alert-line:hover { background: var(--bg-inset); }
.alert-line-muted { color: var(--text-muted); }
.alert-when { font-family: var(--font-mono); font-size: var(--fs-0); color: var(--text-muted); margin-right: 6px; }
.alert-bits { display: block; font-family: var(--font-mono); font-size: var(--fs-0); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.alert-labels { display: block; font-size: var(--fs-0); color: var(--text-muted); }
.alert-empty, .alert-foot { font-size: var(--fs-1); color: var(--text-muted); }
.alert-foot { margin-top: 8px; border-top: 1px dashed var(--border-color); padding-top: 6px; }
.alert-more { display: inline-block; margin-top: 6px; font-size: var(--fs-1); color: var(--accent); text-decoration: none; }
.upload-history { margin: 0 0 22px; font-size: var(--fs-1); }
.history-head { display: flex; align-items: center; gap: 10px; font-weight: 600; margin-bottom: 4px; }
.history-head .alert-more { margin-top: 0; font-weight: 400; }
.history-line { padding: 2px 0; color: var(--text-secondary); }
.system-status { margin: 4px 0 18px; font-size: var(--fs-1); color: var(--text-secondary); }
/* project-level upload (U-1) */
.project-upload { border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 12px 14px 14px; margin-bottom: 18px; background: var(--bg-raised); }
.project-upload .dashboard-header { margin-bottom: 8px; }
.plan-table { width: 100%; border-collapse: collapse; font-size: var(--fs-1); margin-top: 10px; }
.plan-table th, .plan-table td { padding: 6px 8px; border-bottom: 1px solid var(--border-color); text-align: left; vertical-align: top; }
.plan-table select { font-size: var(--fs-1); padding: 3px 6px; background: var(--bg-inset); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; }
.plan-exact { color: var(--success, #69f0ae); }
.plan-warn { color: var(--warning); }
.plan-refs { font-size: var(--fs-0); color: var(--text-muted); line-height: 1.5; }
.plan-actions { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.report-card { border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 10px 12px; margin-top: 10px; background: var(--bg-inset); font-size: var(--fs-1); }
.report-card h4 { margin: 0 0 6px; font-size: var(--fs-2); }
.report-card table { border-collapse: collapse; margin-top: 4px; }
.report-card td, .report-card th { padding: 2px 8px; text-align: left; font-size: var(--fs-1); }
.report-card td.num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.report-delta-up { color: var(--success, #69f0ae); }
.report-delta-down { color: var(--danger); }
.report-move { cursor: pointer; padding: 2px 6px; margin: 0 -6px; border-radius: 4px; }
.report-move:hover { background: rgba(255,255,255,0.05); }
.report-none { color: var(--text-muted); }
.system-status b { color: var(--text-primary); font-weight: 600; }
.cable-recheck-why { font-size: var(--fs-0); color: var(--warning); }
.cable-recheck-rule { border-left: 2px solid var(--border-strong); padding-left: 8px; }
@media (max-width: 1100px) { .big-numbers { grid-template-columns: repeat(2, minmax(150px, 1fr)); } .alert-cards { grid-template-columns: 1fr; } }
.status-strip b { color: var(--text-primary); font-weight: 600; }
.status-sep { color: var(--border-strong); }
.status-link { color: var(--text-secondary); text-decoration: none; }
.status-link:hover { color: var(--text-primary); }
.status-pct { font-family: var(--font-mono); font-weight: 600; margin-left: 2px; }
.status-pct.is-grey { color: var(--text-muted); }
.status-pct.is-amber { color: var(--warning); }
.status-pct.is-green { color: var(--success); }

/* Segmented toggle (기호 개수 | 케이블 m) */
.seg { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); overflow: hidden; }
.seg-btn { padding: 5px 12px; border: none; background: transparent; color: var(--text-muted); font-size: var(--fs-1); font-family: inherit; cursor: pointer; }
.seg-btn + .seg-btn { border-left: 1px solid var(--border-strong); }
.seg-btn:hover { color: var(--text-primary); }
.seg-btn.is-active { background: var(--accent-soft); color: var(--text-primary); }

/* Floor × discipline grid */
.floor-table th.floor-disc { cursor: pointer; }
.floor-table th.floor-disc:hover { color: var(--text-primary); }
.floor-table th.floor-disc-nodict { color: var(--text-muted); font-weight: 400; }
.floor-table td.floor-name { color: var(--text-primary); font-weight: 500; }
.floor-table td.floor-none { color: var(--border-strong); }
.floor-table td.floor-zero { color: var(--text-muted); }
.floor-table td.floor-uncomputed { color: var(--text-muted); font-family: inherit; font-size: var(--fs-1); }
.floor-table td.floor-cable { border-left: 1px solid var(--border-color); color: var(--text-primary); }
.floor-table th:last-child { border-left: 1px solid var(--border-color); }
.floor-table tr.floor-unresolved td { color: var(--warning); }

/* Export panel under the top bar */
.topbar-export { min-width: 340px; }
.export-warn { margin: 6px 0; padding: 8px 10px; border-radius: var(--radius-sm); font-size: var(--fs-1); line-height: 1.5;
    color: var(--warning); background: var(--warning-soft); }
.export-row { display: flex; align-items: center; gap: 8px; padding: 6px 10px; font-size: var(--fs-2); color: var(--text-secondary); flex-wrap: wrap; }
.export-sheets { margin: 4px 0 6px; padding: 0 10px 0 28px; font-size: var(--fs-1); line-height: 1.7; color: var(--text-secondary); }
.export-sheets b { color: var(--text-primary); font-weight: 600; }
.export-row .btn { padding: 7px 16px; text-decoration: none; }
/* the download is a button, not a menu link: `.topbar-menu a` would paint its text in the menu's text colour (white
   on the white button, U-79) */
.topbar-menu a.btn-primary { display: inline-block; color: var(--bg-base); font-size: var(--fs-2); }
.topbar-menu a.btn-primary:hover { background: #ffffff; }

/* Decisions backup fold */
.decisions-body { display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }
/* project settings (P3-1) */
.settings-body { display: flex; flex-direction: column; gap: 12px; padding-top: 8px; font-size: var(--fs-1); }
.settings-note, .settings-followup-note { color: var(--text-secondary); line-height: 1.55; }
.settings-row { border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 10px 12px; background: var(--bg-raised); }
.settings-row.is-over { border-left: 3px solid var(--accent); }
.settings-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.settings-kind { font-size: var(--fs-0); padding: 1px 7px; border-radius: 999px; background: var(--bg-inset); color: var(--text-muted); }
.settings-kind.kind-reparse, .settings-kind.kind-riser, .settings-kind.kind-rebuild { color: var(--warning); border: 1px solid var(--warning); background: transparent; }
.settings-help { font-size: var(--fs-0); color: var(--text-muted); margin-bottom: 6px; line-height: 1.5; }
.settings-help code { font-family: var(--font-code); font-size: var(--fs-0); }
.settings-input { display: flex; gap: 8px; align-items: flex-start; }
.settings-input input[type=text], .settings-input input[type=number], .settings-input textarea {
    flex: 1; font-family: var(--font-code); font-size: var(--fs-1); padding: 6px 8px; color: var(--text-primary);
    background: var(--bg-inset); border: 1px solid var(--border-color); border-radius: var(--radius-sm); }
.settings-input textarea { min-height: 96px; resize: vertical; }
.settings-checks { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.settings-checks label { display: inline-flex; gap: 5px; align-items: center; cursor: pointer; }
.settings-preview { margin-top: 6px; }
.settings-preview-box { border-top: 1px dashed var(--border-color); padding-top: 6px; }
.settings-table { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: var(--fs-1); }
.settings-table th, .settings-table td { padding: 3px 6px; border-bottom: 1px solid var(--border-color); text-align: left; }
.settings-table td.num, .settings-table th.num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.settings-table tr.is-changed td { background: var(--accent-soft); }
.settings-changed { margin-top: 6px; font-size: var(--fs-1); line-height: 1.5; }
.settings-error { color: var(--danger); font-size: var(--fs-1); }
.settings-actions { display: flex; align-items: center; gap: 10px; }
.settings-followup { margin-top: 4px; }
.settings-followup-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 4px; }
/* confirmation modal */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.modal[hidden] { display: none; }   /* the class's display:flex would otherwise beat the hidden attribute */
.modal-box { background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 18px 20px; max-width: 520px; width: calc(100% - 32px); box-shadow: 0 12px 40px rgba(0, 0, 0,0.25); }
.modal-title { font-size: var(--fs-3); font-weight: 600; margin-bottom: 8px; }
.modal-text { font-size: var(--fs-2); line-height: 1.6; color: var(--text-secondary); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.modal-input { display: block; width: 100%; margin-top: 12px; padding: 8px 10px; font: inherit; font-size: var(--fs-2); color: var(--text-primary);
    background: var(--bg-inset); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.modal-input:focus { outline: none; border-color: var(--accent); }
.modal-actions .btn-danger { background: var(--danger, #d9534f); border-color: var(--danger, #d9534f); color: #fff; }
/* toasts (U-121): what alert() used to say, at the bottom, gone by itself */
.toast-host { position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 1200; pointer-events: none; }
.toast { pointer-events: auto; max-width: min(720px, calc(100vw - 32px)); padding: 10px 16px; border-radius: var(--radius-sm); font-size: var(--fs-2); line-height: 1.5;
    color: var(--text-primary); background: var(--bg-raised); border: 1px solid var(--border-strong); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    cursor: pointer; animation: toast-in .18s ease-out; }
.toast-ok { border-color: var(--success); }
.toast-error { border-color: var(--danger, #d9534f); }
.toast.is-out { opacity: 0; transition: opacity .25s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.decisions-body code { font-family: var(--font-code); font-size: var(--fs-0); color: var(--text-secondary); }
.decisions-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.decisions-row .btn { padding: 7px 14px; font-size: var(--fs-2); text-decoration: none; }
.decisions-import-label { cursor: pointer; }
.decisions-mirror label { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 320px; font-size: var(--fs-2); color: var(--text-secondary); }
.decisions-mirror input { flex: 1; padding: 7px 10px; background: var(--bg-inset); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); font-size: var(--fs-2); }
.decisions-list summary { font-size: var(--fs-1); color: var(--text-muted); cursor: pointer; }
.decisions-table td { white-space: normal; font-size: var(--fs-1); }
.decisions-table tr.decisions-overwrite td { color: var(--warning); }
.decisions-table tr.decisions-same td { color: var(--text-muted); }

.rollup-table tr.rollup-total td { border-top: 1px solid var(--border-strong); color: var(--text-primary); }
.rollup-review-line { padding: 4px 0; cursor: pointer; color: var(--text-secondary); }

/* The floor list on the discipline screen: rows drive the viewer above,
   the history unfolds under its row. */
.drawing-table tr.drawing-row { cursor: pointer; }
.drawing-table tr.drawing-row:hover td { background: rgba(124, 156, 255, 0.08); }
.drawing-table tr.drawing-row.is-shown td { background: var(--accent-soft); }
.drawing-table tr.drawing-row.is-shown .drawing-name { color: var(--text-primary); font-weight: 600; }
.drawing-table td.drawing-name { white-space: normal; }
.drawing-table td.drawing-actions { text-align: right; white-space: nowrap; }
.drawing-table td.drawing-actions .btn-history { margin-right: 8px; }
.drawing-table tr.version-row td { padding: 6px 10px 12px 28px; background: var(--bg-inset); white-space: normal; }
.drawing-table .version-list .item-card-meta { white-space: normal; word-break: break-all; }
.drawing-table .version-list { gap: 6px; }
.drawing-table .version-list .item-card { padding: 10px 14px; cursor: default; }
.drawing-table .version-list .item-card:hover { transform: none; }
.drawing-table .version-list .item-card-title { font-size: var(--fs-2); }
.rollup-review-line:hover { color: var(--text-primary); }

/* Revision comparison */
.diff-pick { font-size: var(--fs-1); color: var(--text-secondary); margin: 6px 0 12px; }
.diff-pick select { margin: 0 4px; }
.diff-item { padding: 5px 8px; border-radius: var(--radius-sm); cursor: pointer; font-size: var(--fs-1); color: var(--text-secondary); }
.diff-item:hover { background: rgba(124, 156, 255, 0.08); color: var(--text-primary); }
.diff-kind { display: inline-block; min-width: 16px; text-align: center; font-weight: 700; }
.diff-plus, .diff-plus .diff-kind { color: var(--success, #4ade80); }
.diff-minus, .diff-minus .diff-kind { color: var(--danger); }
.diff-move .diff-kind { color: var(--warning); }
.length-row.is-head { color: var(--text-muted); font-size: var(--fs-0); }
/* Diff tables have four columns: label, before, after, change. */
.diff-labels .length-row, .diff-cables .length-row { grid-template-columns: 1fr 90px 90px 200px; }
.diff-cables .length-row { grid-template-columns: 1fr 110px 200px 110px; }
.diff-overlay-toggle { margin-left: 14px; font-size: var(--fs-1); color: var(--text-secondary); cursor: pointer; }
.diff-legend { display: block; margin-top: 6px; font-size: var(--fs-0); color: var(--text-muted); }
.diff-legend i { font-style: normal; font-weight: 700; margin: 0 2px 0 8px; }
.diff-files-changed { margin-top: 6px; font-size: var(--fs-1); color: var(--warning); }
.diff-files-changed.hint { color: var(--text-muted); }
/* the fold's head: the two revisions, one stat line, the tools — three short rows, nothing else */
.diff-head { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 14px; }
.diff-revs { font-size: var(--fs-2); color: var(--text-primary); }
.diff-stats { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: var(--fs-2); color: var(--text-secondary); }
.diff-stat b { font-family: var(--font-mono); font-size: var(--fs-3); font-weight: 600; color: var(--text-primary); margin-right: 2px; }
.diff-stat.is-zero, .diff-stat.is-zero b { color: var(--text-muted); font-weight: 400; }
.diff-stat b.diff-plus { color: var(--success, #4ade80); }
.diff-stat b.diff-minus { color: var(--danger); }
.diff-stat b.diff-move-c { color: var(--warning); }
.diff-tools { display: flex; flex-wrap: wrap; gap: 4px 0; font-size: var(--fs-1); }
.diff-tools .diff-overlay-toggle:first-child { margin-left: 0; }
/* the device table stays narrow: numbers beside the names, not across the screen */
.diff-labels .length-row { grid-template-columns: minmax(200px, 420px) 90px 90px 110px; justify-content: start; }
.diff-same > summary, .diff-group > summary { cursor: pointer; color: var(--text-muted); font-size: var(--fs-1); padding: 6px 0; }
.diff-group + .diff-group { margin-top: 4px; }
.diff-cables > summary { cursor: pointer; list-style: none; }
.diff-cables > summary h4 { display: inline; }
.diff-cables > summary::before { content: '▸ '; color: var(--text-muted); }
.diff-cables[open] > summary::before { content: '▾ '; }

/* the trunk / branch split under the floors × cables table, folded by default */
.cable-split { margin-top: 10px; }
.cable-split > summary { cursor: pointer; color: var(--text-muted); font-size: var(--fs-1); padding: 4px 0; }
.cable-split[open] > summary { margin-bottom: 6px; }

/* the "지정 ▸" link in the floors × cables table's unassigned column */
.cable-by-floor-table a.floor-assign { color: var(--warning); font-weight: 600; text-decoration: none; white-space: nowrap; }
.cable-by-floor-table a.floor-assign:hover { text-decoration: underline; }

/* a junction where the table and the drops' marks disagree */
.cable-marks-table .length-row.is-warn { color: var(--warning); }

/* sub-typed symbol columns (센서 · TW) under their base column */
th.pivot-sub .symbol-label { font-weight: 400; color: var(--text-muted); }
.pivot-fold {
    display: block; margin: 6px auto 0; padding: 3px 8px;
    font-size: var(--fs-0); line-height: 1; border-radius: 999px;
    border: 1px solid var(--border-strong); background: var(--bg-inset); color: var(--text-muted);
    cursor: pointer;
}
.pivot-fold:hover, .pivot-fold.is-open { color: var(--accent); border-color: var(--accent); }
/* the symbol heads: a 40px icon over the name, the same two slots in every column so nothing bobs; the unfold chevron sits by the name */
th.pivot-head { vertical-align: top; padding-top: 12px; padding-bottom: 10px; }
th.pivot-head .symbol-icon { width: 40px; height: 40px; margin: 0 auto 8px; opacity: 0.9; }
th.pivot-head .symbol-icon-blank { visibility: hidden; }
th.pivot-head .symbol-label { min-height: 36px; max-width: 130px; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 5px; font-size: var(--fs-2); }
th.pivot-head .symbol-kinds { flex-basis: 100%; font-weight: 400; font-size: var(--fs-0); color: var(--text-muted); }
th.pivot-head .pivot-fold { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin: 0; padding: 0; font-size: 10px; line-height: 1; }
th.pivot-sub .symbol-icon { width: 26px; height: 26px; }

/* the symbol pivot: tighter cells so nine block columns fit without a sideways scroll */
#dashboardSummaryTable td { padding: 9px 8px; font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: center; }
#dashboardSummaryTable td:first-child { font-family: inherit; text-align: left; }
#dashboardSummaryTable th { padding: 8px 6px; }
#dashboardSummaryTable th .symbol-label { max-width: none; font-size: var(--fs-2); }
/* the head on one line (U-51): a small icon beside the name, the kinds count as small print */
#dashboardSummaryTable th.pivot-head { vertical-align: middle; padding-top: 11px; padding-bottom: 11px; white-space: nowrap; }
#dashboardSummaryTable th.pivot-head .symbol-icon { display: inline-flex; vertical-align: middle; width: 32px; height: 32px; margin: 0 8px 0 0; padding: 4px; border-radius: 8px; }
#dashboardSummaryTable th.pivot-head .symbol-kinds { font-size: var(--fs-1); }
#dashboardSummaryTable th:first-child { font-size: var(--fs-2); }
#dashboardSummaryTable th.pivot-head .symbol-label { display: inline-flex; min-height: 0; vertical-align: middle; flex-wrap: nowrap; }
#dashboardSummaryTable th.pivot-head .symbol-kinds { flex-basis: auto; }
/* the building groups and the enlarged sheets under their floor */
#dashboardSummaryTable tr.pivot-group td { padding: 12px 8px 4px; font-family: inherit; font-size: var(--fs-1); font-weight: 600; color: var(--text-secondary); text-align: left; background: none; letter-spacing: 0.02em; }
#dashboardSummaryTable tr.pivot-enlarged td:first-child { color: var(--text-secondary); font-weight: 400; padding-left: 22px; }
#dashboardSummaryTable .pivot-indent { color: var(--text-muted); margin-right: 2px; }
/* an unfolded device as a block (U-52): spacer columns either side, the name spanning its kinds with a rule under it,
   the kinds on a second head row in small mono, their cells muted */
#dashboardSummaryTable th.sp, #dashboardSummaryTable td.sp { width: 14px; min-width: 14px; padding: 0; background: none; border-bottom: none; }
#dashboardSummaryTable th.pivot-grp { border-bottom: 1px solid var(--border-strong); background: rgba(124, 156, 255, 0.06); }
#dashboardSummaryTable tr.pivot-kinds th { padding: 4px 6px 6px; font-size: var(--fs-0); font-weight: 500; font-family: var(--font-mono); color: var(--text-muted); text-align: center; white-space: nowrap; background: rgba(124, 156, 255, 0.06); }
#dashboardSummaryTable tr.pivot-kinds th.pivot-kind-all { font-family: inherit; color: var(--text-secondary); font-weight: 600; }
#dashboardSummaryTable td.cell-kind { color: var(--text-muted); font-size: var(--fs-1); background: rgba(124, 156, 255, 0.03); }
#dashboardSummaryTable td.cell-kind.cell-zero { color: var(--border-color); }
#dashboardSummaryTable tfoot td.cell-kind { color: var(--text-secondary); font-weight: 500; }
#dashboardSummaryTable th.pivot-kind.is-sorted, #dashboardSummaryTable th.pivot-kind:hover { color: var(--text-primary); }
#dashboardSummaryTable th.pivot-sub { min-width: 0; }
#dashboardSummaryTable th.pivot-sub .symbol-label { font-size: var(--fs-0); }
#dashboardSummaryTable td:first-child, #dashboardSummaryTable th:first-child { white-space: nowrap; }

/* ---- Tabulator (U-85): the device pivot on the library, dressed in the page's colours ---- */
.table-container.is-tabulator { overflow: visible; background: none; border: none; }
.is-tabulator .tabulator { background: var(--bg-inset); border: 1px solid var(--border-color); border-radius: var(--radius); font-family: inherit; font-size: var(--fs-2); }
.is-tabulator .tabulator .tabulator-header { background: var(--bg-raised); border-bottom: 1px solid var(--border-strong); color: var(--text-primary); font-weight: 600; }
.is-tabulator .tabulator .tabulator-header .tabulator-col { background: var(--bg-raised); border-right: 1px solid var(--border-color); justify-content: center; }   /* the name head level with the icon heads (U-96) */
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover { background: var(--bg-surface); }
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="ascending"] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow,
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="descending"] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow { border-bottom-color: var(--accent); border-top-color: var(--accent); }
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-col-content { padding: 9px 6px; }
/* the sort arrow only on the sorted column — an arrow slot on every head is 25 px × 9 columns of nothing */
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter { display: none; }
.is-tabulator .tabulator .tabulator-header .tabulator-col[aria-sort="ascending"] .tabulator-col-content .tabulator-col-sorter,
.is-tabulator .tabulator .tabulator-header .tabulator-col[aria-sort="descending"] .tabulator-col-content .tabulator-col-sorter { display: flex; }
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { padding-right: 0; }
.is-tabulator .tabulator .tabulator-header .tabulator-col[aria-sort="ascending"] .tabulator-col-title,
.is-tabulator .tabulator .tabulator-header .tabulator-col[aria-sort="descending"] .tabulator-col-title { padding-right: 22px; }
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { white-space: nowrap; }
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols { border-top: 1px solid var(--border-color); }
.is-tabulator .tabulator .tabulator-header .tabulator-col.pivot-grp { background: rgba(124, 156, 255, 0.06); }
.is-tabulator .tabulator .tabulator-header .tabulator-col.pivot-grp .tabulator-col-group-cols .tabulator-col .tabulator-col-title { font-family: var(--font-mono); font-size: var(--fs-0); font-weight: 500; color: var(--text-muted); }
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-header-filter input { background: var(--bg-inset); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); padding: 4px 8px; font-size: var(--fs-2); font-family: inherit; }
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::placeholder { color: var(--text-muted); }
.is-tabulator .tabulator .tabulator-header .tabulator-col .tabulator-header-filter input:focus { outline: none; border-color: var(--accent); }
.is-tabulator .tabulator .tabulator-header .tabulator-col.tabulator-frozen { box-shadow: 1px 0 0 var(--border-strong); }
/* the head cells of the device columns: the same tile + name as before */
.is-tabulator .pivot-head { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; font-size: var(--fs-2); }
.is-tabulator .pivot-head .symbol-icon { display: inline-flex; width: 30px; height: 30px; padding: 4px; border-radius: 8px; opacity: 0.9; flex: none; }
.is-tabulator .pivot-head .symbol-icon-blank { visibility: hidden; }
.is-tabulator .pivot-head .symbol-label { display: inline-flex; align-items: center; gap: 5px; }
.is-tabulator .pivot-head .symbol-kinds { font-weight: 400; font-size: var(--fs-1); color: var(--text-muted); }
.is-tabulator .pivot-head .pivot-fold { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin: 0; padding: 0; font-size: 10px; line-height: 1; }
/* rows */
.is-tabulator .tabulator .tabulator-tableholder { background: var(--bg-inset); }
.is-tabulator .tabulator .tabulator-row { background: var(--bg-inset); border-bottom: 1px solid var(--border-color); min-height: 38px; }
.is-tabulator .tabulator .tabulator-row.tabulator-row-even { background: var(--bg-inset); }
.is-tabulator .tabulator .tabulator-row:hover, .is-tabulator .tabulator .tabulator-row.tabulator-row-even:hover { background: var(--bg-raised); }
.is-tabulator .tabulator .tabulator-row .tabulator-cell { border-right: 1px solid transparent; padding: 9px 8px; color: var(--text-primary); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.pivot-name { font-family: inherit; font-weight: 600; white-space: nowrap; }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.pivot-name.is-enlarged { color: var(--text-secondary); font-weight: 400; padding-left: 22px; }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.tabulator-frozen { background: inherit; box-shadow: 1px 0 0 var(--border-color); }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-zero { color: var(--text-muted); opacity: 0.55; }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-heat { background: rgba(124, 156, 255, var(--heat, 0)); }

.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-locate { cursor: pointer; }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-locate:hover { color: var(--accent); }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-kind { color: var(--text-muted); font-size: var(--fs-1); background: rgba(124, 156, 255, 0.03); }
.is-tabulator .tabulator .tabulator-row .tabulator-cell.cell-manual sup { font-size: 9px; color: var(--accent); margin-left: 2px; }
/* building groups: a small label row, no chevron box */
.is-tabulator .tabulator .tabulator-row.tabulator-group { background: var(--bg-inset); border-bottom: none; padding: 12px 8px 4px; font-size: var(--fs-1); font-weight: 600; color: var(--text-secondary); letter-spacing: 0.02em; min-height: 0; }
.is-tabulator .tabulator .tabulator-row.tabulator-group:hover { background: var(--bg-inset); }
.is-tabulator .tabulator .tabulator-row.tabulator-group.is-blank { display: none; }   /* the floor sheets' group has no head (U-93) */
.is-tabulator .tabulator .tabulator-row.tabulator-group .tabulator-arrow { border-left-color: var(--text-muted); }
.is-tabulator .tabulator .tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow { border-top-color: var(--text-muted); }
/* the totals band */
.is-tabulator .tabulator .tabulator-footer { background: var(--bg-inset); border-top: 1px solid var(--border-strong); color: var(--text-primary); padding: 0; }
.is-tabulator .tabulator .tabulator-footer .tabulator-calcs-holder { background: var(--bg-inset) !important; border-top: none !important; border-bottom: none !important; }
.is-tabulator .tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row { background: var(--bg-inset) !important; font-weight: 600; }
.is-tabulator .tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell { font-family: var(--font-mono); }
.is-tabulator .tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell.pivot-name { font-family: inherit; }
.is-tabulator .tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell.cell-kind { color: var(--text-secondary); font-weight: 500; }
.is-tabulator .tabulator .tabulator-col-resize-handle:hover { background: var(--accent); opacity: 0.3; }
.is-tabulator .table-footnote { padding: 8px 4px 0; }
.is-tabulator .pivot-ruler { position: absolute; visibility: hidden; white-space: nowrap; pointer-events: none; }
/* the floors × cables table (U-88): plain text heads, group heads tinted as before (trunk · conduit · branch) */
.cable-by-floor-tab { margin: 6px 0 10px; }
.cable-by-floor-tab .tabulator { font-size: var(--fs-2); }
.cable-by-floor-tab .cbf-head { font-size: var(--fs-2); font-weight: 600; }
.cable-by-floor-tab .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { font-size: var(--fs-2); white-space: normal; overflow-wrap: anywhere; line-height: 1.25; }
.cable-by-floor-tab .tabulator .tabulator-header .tabulator-col.tabulator-col-group > .tabulator-col-content .tabulator-col-title { white-space: nowrap; }   /* the group's own title only — its children sit inside it */
.cable-by-floor-tab .tabulator .tabulator-header .tabulator-col.cbf-grp.trunk { background: rgba(124, 156, 255, 0.08); }
.cable-by-floor-tab .tabulator .tabulator-header .tabulator-col.cbf-grp.conduit { background: rgba(242, 193, 78, 0.08); }
.cable-by-floor-tab .tabulator .tabulator-header .tabulator-col.cbf-grp.branch { background: rgba(76, 201, 165, 0.08); }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell.cbf-sheet { font-family: inherit; font-weight: 500; white-space: nowrap; }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell.cbf-sheet a { color: var(--text-primary); text-decoration: none; }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell.cbf-sheet a:hover { color: var(--accent); }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell.cbf-sheet.is-riser { color: var(--text-muted); font-style: italic; font-weight: 400; }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell.conduit { color: var(--text-secondary); }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell .floor-assign { color: var(--accent); text-decoration: none; white-space: nowrap; }
.cable-by-floor-tab .tabulator .tabulator-row .tabulator-cell .floor-assign:hover { text-decoration: underline; }
.cable-by-floor-tab .tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell.cbf-sheet { font-family: inherit; }

/* "물어보기" — the chat panel over the local model */
.chat-fab { position: fixed; right: 22px; bottom: 22px; z-index: 40; padding: 10px 16px; border-radius: 999px; border: 1px solid var(--border-color);
    background: var(--text-primary); color: var(--bg-base); font-weight: 700; font-size: var(--fs-2); cursor: pointer; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45); }
.chat-fab:hover { filter: brightness(1.08); }
.chat-panel { position: fixed; right: 22px; bottom: 22px; z-index: 41; width: min(440px, calc(100vw - 44px)); height: min(560px, calc(100vh - 80px));
    display: flex; flex-direction: column; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18); }
.chat-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border-color); }
.chat-head .hint { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-log { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.chat-msg { max-width: 92%; padding: 8px 10px; border-radius: 10px; font-size: var(--fs-2); line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.chat-msg.is-user { align-self: flex-end; background: var(--text-primary); color: var(--bg-base); }
.chat-msg.is-bot { align-self: flex-start; background: var(--bg-inset); border: 1px solid var(--border-color); }
.chat-msg.is-wait { color: var(--text-muted); font-style: italic; }
.chat-msg .chat-tools { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; }
.chat-msg .chat-tool { font-size: var(--fs-0); padding: 1px 7px; border-radius: 999px; border: 1px solid var(--border-color); color: var(--text-muted); }
.chat-msg .chat-tool.is-err { color: var(--danger); }
.chat-msg .chat-fb { margin-top: 4px; font-size: var(--fs-1); }
.chat-msg .chat-fb .link-btn { margin-right: 6px; }
.chat-form { display: flex; gap: 6px; padding: 10px 12px; border-top: 1px solid var(--border-color); }
.chat-form input { flex: 1; padding: 8px 10px; font: inherit; font-size: var(--fs-2); background: var(--bg-inset); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 8px; }

/* =====================================================================
   Direction B (2026-09-16): one column, spacious — dark palette.
   The shell is a top bar, a strip of discipline tabs under it, and a
   page of cards a shade lighter than the page. The dashboard opens on one number — the
   cable length — with the order figure, the trust card and the change
   card to its right; the quantity table, the viewer and the folds sit
   below as cards. Everything here overrides the rules above; the
   components keep their ids and hooks so app.js is untouched.
   ===================================================================== */

body { background-image: none; }

/* Top bar: white, taller, brand in near-black */
.topbar { height: 60px; padding: 0 40px; gap: 16px; background: var(--bg-inset); border-bottom: 1px solid var(--border-color); }
.topbar-brand { display: inline-flex; align-items: center; gap: 9px; font-size: var(--fs-3); font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); }
.topbar-logo { height: 26px; width: auto; display: block; }   /* the three-ring mark (U-114), a little taller than the wordmark's cap height */
.topbar-project { padding: 4px 8px 4px 12px; border-color: var(--border-color); border-radius: var(--radius); }
.topbar-project-label { font-size: var(--fs-1); }
.topbar-select { font-size: var(--fs-3); }
.topbar .btn { padding: 8px 15px; font-size: var(--fs-2); border-radius: var(--radius); }
.topbar .btn-plain { background: var(--bg-surface); border-color: var(--border-color); color: var(--text-primary); }
.topbar .btn-plain:hover { border-color: var(--border-strong); background: var(--bg-raised); }
.topbar-updated { font-size: var(--fs-2); color: var(--text-muted); }

/* The discipline strip: what was a sidebar is now a row of tabs under the
   top bar. Same markup (#sidebar, .sidebar-row, .sidebar-count, .sidebar-badge). */
.app-body { flex-direction: column; }
.sidebar {
    position: sticky; top: 60px; z-index: 29;
    width: auto; max-height: none; align-self: stretch;
    display: flex; align-items: center; gap: 4px;
    height: 46px; padding: 0 40px; overflow: visible;
    background: var(--bg-inset); border-right: none; border-bottom: 1px solid var(--border-color);
}
.sidebar-heading { display: none; }
.sidebar-nav { flex: 1; min-width: 0; flex-direction: row; align-items: center; gap: 2px; overflow-x: auto; scrollbar-width: none; }
.sidebar-nav::-webkit-scrollbar { display: none; }
.sidebar-row {
    flex: none; height: 46px; padding: 0 12px; gap: 6px;
    border-radius: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
    font-size: var(--fs-3); color: var(--text-secondary); white-space: nowrap;
}
.sidebar-row:hover { background: none; color: var(--text-primary); }
/* a site's sections (여수 2BL | 4BL) at the start of the strip, apart from the discipline tabs */
.sidebar-sections { flex: none; display: flex; align-items: center; padding-right: 12px; margin-right: 6px; border-right: 1px solid var(--border-color); }
.sidebar-sections[hidden] { display: none; }
.sidebar-sections .seg-btn { font-size: var(--fs-3); padding: 6px 14px; }
.sidebar-row.active { background: none; color: var(--text-primary); font-weight: 600; border-bottom-color: var(--text-primary); }
.sidebar-row-muted { color: var(--text-muted); }
.sidebar-name { flex: none; }
.sidebar-count { font-size: var(--fs-2); }
.sidebar-add { position: relative; flex: none; margin: 0 0 0 12px; padding: 0; }
.sidebar-add > summary { padding: 2px 8px; font-size: var(--fs-3); line-height: 1; color: var(--text-muted); opacity: 0.45; border: none; border-radius: 999px; white-space: nowrap; }
.sidebar-add > summary:hover, .sidebar-add[open] > summary { opacity: 1; }
.sidebar-add > summary:hover { color: var(--text-primary); border-color: var(--border-strong); }
.sidebar-add[open] > summary { color: var(--text-primary); }
.sidebar-add[open]::after {
    content: ""; position: absolute; right: 0; top: calc(100% + 8px); width: 360px; height: 0;
}
.sidebar-add-panel {
    position: absolute; right: 0; top: calc(100% + 8px); z-index: 35; width: 360px; padding: 14px 16px;
    background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: var(--radius); box-shadow: var(--shadow);
}
.sidebar-add-note { margin: 0 0 10px; padding: 0; font-size: var(--fs-1); color: var(--text-muted); }
.sidebar-add .new-item-row { margin: 0; padding: 0; }

/* Page column: fills the window like the top bar and the tab strip above
   it (a 1440px column left-aligned on a 1900px screen left a third of the
   page empty); only past 1920px does it stop growing and sit centred. */
/* the whole width: on a 2555px screen the old 1920px cap left 317px empty on each side (U-37, "자리 낭비") */
.main-content { width: 100%; max-width: none; margin: 0; padding: 32px 40px 60px; }
.breadcrumb { margin-bottom: 18px; }

/* Screens that are lists (projects, disciplines, bootstrap) stay one card;
   the discipline dashboard is a column of cards on the page instead. */
.section { padding: 26px 28px; border-radius: 14px; }
#screenDashboard.section { background: none; border: none; box-shadow: none; padding: 0; }
#screenDashboard .dashboard-header { margin-bottom: 14px; }
/* the discipline head (U-35): eyebrow · 30px name · meta line, the project page's regime */
#screenDashboard .discipline-header { align-items: flex-start; margin: 4px 0 6px; }
#screenDashboard .dashboard-header.discipline-header h2 { font-size: var(--fs-5); font-weight: 700; letter-spacing: -0.02em; margin: 2px 0 0; line-height: 1.15; }
.page-eyebrow { font-size: var(--fs-1); color: var(--text-muted); letter-spacing: 0.02em; }
.page-meta { margin-top: 6px; font-size: var(--fs-2); color: var(--text-muted); font-family: var(--font-mono); min-height: 16px; }
#screenDashboard .dashboard-header h2 { font-size: var(--fs-5); font-weight: 700; color: var(--text-primary); letter-spacing: -0.02em; }
#screenDashboard .dashboard-header .btn-secondary { padding: 8px 14px; font-size: var(--fs-2); background: var(--bg-surface); border-color: var(--border-color); }
#screenDashboard > h3 { margin: 24px 0 10px; font-size: var(--fs-4); font-weight: 700; letter-spacing: -0.02em; text-transform: none; color: var(--text-primary); }

/* The hero: the one number, three cards to its right */
.dash-hero { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; margin-bottom: 28px; }   /* the two cards end on one line (U-107); each its own height (D-1) */
/* the bill comparison as the row's right card (U-45): the cable table over the device table, both plain inside */
.dash-hero .dash-boq { flex: 2 1 900px; min-width: 0; margin: 0; background: var(--bg-raised); border: 1px solid var(--border-color); border-radius: var(--radius); padding: 16px 18px 12px; }
.dash-hero .dash-boq .boq-head { margin: 0 0 10px; }
.dash-hero .dash-boq .boq-title { font-size: var(--fs-3); font-weight: 700; color: var(--text-primary); margin-right: 4px; }
.dash-hero .dash-boq .boq-cols { grid-template-columns: 1fr; gap: 14px; }
/* the card's pills (U-46) sit on the same segmented track as the 물량표's (U-47) */
.boq-tabs { margin: 2px 0 8px; padding: 0; border: none; border-radius: 0; background: none; }
/* the segmented control (U-103, Ant Design "Segmented" / Radix ToggleGroup look): a dark track, the choices in it,
   and one light thumb that slides (0.22 s) under whichever is chosen — the movement says "switch", so no arrow badge
   (U-75~U-84 are gone). The thumb is a real element placed by syncSegs(); the buttons sit above it. */
.seg { position: relative; display: inline-flex; gap: 0; padding: 3px; border-radius: 9px; background: var(--bg-inset); border: 1px solid var(--border-color); }
.seg .seg-thumb { position: absolute; top: 3px; bottom: 3px; left: 3px; width: 0; border-radius: 7px; background: var(--bg-raised);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--border-strong); transition: left .22s cubic-bezier(.2, .7, .2, 1), width .22s cubic-bezier(.2, .7, .2, 1); pointer-events: none; }
.seg .qty-tab { position: relative; z-index: 1; padding: 5px 14px; border: none; border-radius: 7px; font-size: var(--fs-2); font-weight: 500; color: var(--text-secondary); background: transparent; box-shadow: none; transition: color .15s; cursor: pointer; }   /* the other choice a step brighter than muted (U-104): an option, not a note */
.seg .qty-tab:hover { color: var(--text-primary); background: transparent; }
.seg .qty-tab.is-on { background: transparent; color: var(--text-primary); font-weight: 600; box-shadow: none; }
.seg .qty-tab .qty-tab-figure { color: var(--text-muted); }
.seg .qty-tab.is-on .qty-tab-figure { color: var(--text-secondary); }
#qtyTabs .seg .qty-tab { font-size: var(--fs-3); }
@media (prefers-reduced-motion: reduce) { .seg .seg-thumb { transition: none; } }
/* the ratio bar in the comparison's 합계 (U-47): track = the bill, fill = the drawing, amber when past the bill */
.boq-grid td.gap { white-space: nowrap; }
.gap-bar { display: inline-block; vertical-align: middle; width: 40%; min-width: 48px; max-width: 96px; height: 7px; margin-right: 8px; border-radius: 3px; background: var(--bg-inset); overflow: hidden; }
.gap-bar i { display: block; height: 100%; border-radius: 3px; background: var(--text-muted); }
.gap-bar.is-over i { background: var(--accent); }
.boq-pane { min-width: 0; }
.dash-hero .dash-boq .boq-col { background: none; border: none; padding: 0; }
.dash-hero .dash-boq .boq-col + .boq-col { border-top: 1px solid var(--border-color); padding-top: 12px; }
.dash-hero .dash-boq .rev-col-head { margin-bottom: 4px; }
/* the cards column has a width of its own — a card sized by '100%' of a
   shrink-to-fit flex item collapses to its text and loses the bars */
.dash-hero .dash-cards { flex: 1.5 1 560px; min-width: 0; }
/* the headline is a card like the floors card beside it — same border, same padding, same height — so the two read as one row */
.dash-headline { flex: 1 1 520px; max-width: none; min-width: 0; background: var(--bg-raised); border: 1px solid var(--border-color); border-radius: var(--radius); padding: 16px 18px; }
.dash-hero .dash-cards .summary-card { height: 100%; }
.dash-big { font-size: var(--fs-6); font-weight: 800; letter-spacing: -0.035em; line-height: 1.05; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.dash-big .dash-unit { font-size: var(--fs-5); font-weight: 600; color: var(--text-muted); margin-left: 6px; letter-spacing: -0.01em; }
.dash-big .hint { font-size: var(--fs-5); }
.dash-sub { margin-top: 6px; font-size: var(--fs-3); color: var(--text-secondary); }
.dash-sub b { color: var(--text-primary); font-weight: 600; }
.dash-headline .summary-meta { margin: 10px 0 0; font-size: var(--fs-1); color: var(--text-muted); }
.dash-cards { display: flex; gap: 12px; flex-wrap: wrap; }
.pm-cards .summary-card {
    min-width: 210px; padding: 16px 20px 14px; border-radius: 14px;
    background: var(--bg-surface); border: 1px solid var(--border-color); box-shadow: none;
}
.pm-cards .summary-card::before { display: none; }
.pm-cards .summary-label { font-size: var(--fs-2); font-weight: 500; color: var(--text-muted); margin: 0; text-transform: none; letter-spacing: 0; }
.pm-cards .summary-value { font-size: var(--fs-5); font-weight: 700; letter-spacing: -0.03em; line-height: 1.2; margin-top: 2px; color: var(--text-primary); }
.pm-cards .summary-value .hint { font-size: var(--fs-4); }
.pm-cards .summary-unit { font-size: var(--fs-3); font-weight: 500; color: var(--text-muted); margin-left: 4px; }
.pm-cards .summary-detail { margin-top: 2px; font-size: var(--fs-2); color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 320px; }
.pm-cards .summary-detail b { color: var(--text-primary); font-weight: 600; }
.pm-cards .summary-link { display: inline-block; margin: 2px 0 0; font-size: var(--fs-2); color: var(--accent); }
.pm-cards .summary-input { width: 44px; padding: 0 4px; font-size: var(--fs-2); border-radius: 6px; background: var(--bg-surface); }
.pm-cards .trust-dot { width: 10px; height: 10px; margin-right: 8px; vertical-align: 3px; }
/* Under the number: the top cable styles as share bars. Same bar in the
   floors card, where the widest bar is the heaviest sheet. */
.dash-mix { margin-top: 6px; display: flex; flex-direction: column; gap: 5px; max-width: 560px; }
.dash-headline .mix-bar { background: var(--bg-inset); }
.dash-block-label { margin-top: 14px; font-size: var(--fs-1); font-weight: 600; color: var(--text-muted); letter-spacing: 0.02em; }
.dash-block-label:empty { display: none; }
.mix-row, .floor-row { display: grid; grid-template-columns: minmax(120px, 170px) 1fr 84px 40px; gap: 10px; align-items: center; font-size: var(--fs-2); }
.dash-headline .mix-row { grid-template-columns: minmax(150px, 210px) 1fr 84px 40px; }
.floor-row { grid-template-columns: minmax(150px, 220px) 1fr 84px; cursor: pointer; padding: 2px 4px; margin: 0 -4px; border-radius: 6px; }
.floor-row:hover { background: var(--bg-raised); }
.mix-name, .floor-name { color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mix-row.is-rest .mix-name, .floor-row.is-rest .floor-name { color: var(--text-muted); }
.mix-bar { display: block; height: 8px; border-radius: 4px; background: var(--bg-raised); overflow: hidden; }
.mix-bar i { display: block; height: 100%; border-radius: 4px; background: var(--accent); }
.mix-bar.is-rest i { background: var(--border-strong); }
.mix-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-primary); white-space: nowrap; }
.mix-pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: var(--fs-1); }
.pm-cards .dash-floors { width: 100%; min-width: 0; }
.floor-bars { margin-top: 8px; display: grid; grid-template-columns: 1fr 1fr; column-gap: 28px; row-gap: 10px; align-items: start; }
.floor-col { display: grid; row-gap: 3px; }
.floor-col-head { font-size: var(--fs-2); font-weight: 600; color: var(--text-primary); padding: 0 4px 4px; }
.floor-col-head .hint { font-weight: 400; margin-left: 6px; }
.floor-col-rest { grid-column: 1 / -1; padding-top: 8px; border-top: 1px solid var(--border-color); }
.floor-col-rest .floor-row { width: calc(50% - 14px); }
@media (max-width: 1500px) { .floor-bars { grid-template-columns: 1fr; } .floor-col-rest .floor-row { width: auto; } }
.dash-floors .summary-label .hint { margin-left: 6px; font-weight: 400; }

/* The quantity block as one card: pill tabs in its head, the table inside */
#qtyTabs { margin: 0; padding: 12px 14px 8px; gap: 4px; border: 1px solid var(--border-color); border-bottom: none; border-radius: 14px 14px 0 0; background: var(--bg-surface); }
/* the tabs are the segmented control (.seg, U-103); the pill rules that stood here outranked it by the id (U-105) */
#qtyTabs .seg .qty-tab { padding: 6px 14px; }
.qty-pane { padding: 0 8px 4px; border: 1px solid var(--border-color); border-top: none; border-radius: 0 0 14px 14px; background: var(--bg-surface); margin-bottom: 28px; }
.qty-pane .table-container { margin-bottom: 0; border: none; border-radius: 0; background: none; }
.qty-pane .cable-by-floor-scroll { border: none; border-radius: 0; }
.qty-pane .cable-meta { padding: 6px 6px 0; }
table { font-size: var(--fs-2); }
th { background: var(--bg-surface); padding: 11px 12px; font-size: var(--fs-2); border-bottom: 1px solid var(--border-color); }
td { padding: 11px 12px; }
tr:hover td { background: rgba(255, 255, 255, 0.03); }
.table-container { background: var(--bg-surface); border-radius: 14px; }

/* The viewer as a card: the side panel and the dark canvas share one frame */
.viewer-wrap { gap: 0; margin: 0 0 28px; padding: 10px; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 14px; }
.viewer-wrap .viewer-side { padding-right: 12px; }
.viewer-wrap .viewer-main { position: relative; }
.viewer-canvas { border-radius: 10px; border-color: transparent; }
/* the wheel hint (U-112): a small line at the bottom of the canvas, gone after a second; the armed canvas gets a faint ring */
.viewer-wheel-hint { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%) translateY(6px); padding: 6px 12px; border-radius: 999px;
    background: rgba(20, 22, 28, 0.92); border: 1px solid var(--border-strong); color: var(--text-primary); font-size: var(--fs-1); white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s; z-index: 5; }
.viewer-wheel-hint.is-on { opacity: 1; transform: translateX(-50%) translateY(0); }
.viewer-canvas.is-armed { box-shadow: inset 0 0 0 1px rgba(124, 156, 255, 0.35); }
.viewer-select { background: var(--bg-surface); }
.viewer-wrap.is-fullscreen { padding: 0; border: none; border-radius: 0; }

/* Folded sections as quiet cards */
#screenDashboard .length-section { margin: 0 0 12px; }
#screenDashboard details.length-advanced { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 14px; padding: 0 18px; }
#screenDashboard details.length-advanced > summary { padding: 14px 0; font-size: var(--fs-3); color: var(--text-primary); font-weight: 500; }
#screenDashboard details.length-advanced[open] > summary { border-bottom: 1px solid var(--border-color); margin-bottom: 12px; }
#screenDashboard details.length-advanced[open] { padding-bottom: 14px; }
#cableSection.length-section { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 14px; padding: 6px 18px 14px; }
#cableSection > h3 { margin: 10px 0 12px; font-size: var(--fs-4); font-weight: 700; letter-spacing: -0.02em; text-transform: none; color: var(--text-primary); }
.upload-area-compact { background: var(--bg-surface); border-radius: 14px; }

/* Chat: a docked drawer in the page's colours */
.chat-panel { border-radius: 16px; box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5); }
.chat-fab { border-color: var(--text-primary); }

@media (max-width: 900px) {
    .topbar, .sidebar { padding: 0 16px; }
    .main-content { padding: 20px 16px 40px; }
    .dash-big { font-size: var(--fs-6); }
    .dash-cards { width: 100%; }
    .pm-cards .summary-card { flex: 1 1 160px; min-width: 0; }
}
/* Sheet names in the cable table open the viewer, but a column of blue
   underlines reads as a link farm: text colour, dotted underline like the
   symbol table's rows. */
.cable-by-floor-table td.sheet a { color: var(--text-primary); text-decoration: underline dotted var(--text-muted); text-underline-offset: 3px; }
.cable-by-floor-table td.sheet a:hover { color: var(--accent); }
/* the advisory list of drawn-but-unmapped blocks, folded under the notice */
.drawn-fold { margin-top: 8px; }
.drawn-fold > summary { cursor: pointer; font-size: var(--fs-2); color: var(--text-secondary); }
.drawn-fold > div { padding: 3px 0 0 8px; font-size: var(--fs-2); }

/* hand-entered counts: the list under the review fold and the cell mark */
.manual-counts { margin-top: 14px; }
.manual-add { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.manual-add select, .manual-add input { padding: 6px 8px; font: inherit; font-size: var(--fs-2); background: var(--bg-inset); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: var(--radius-sm); }
td.cell-manual sup { font-size: 10px; color: var(--warning); margin-left: 2px; }
.manual-counts .length-row { grid-template-columns: minmax(240px, 1fr) 70px 3fr auto; gap: 14px; align-items: start; }
.manual-counts .length-row .hint { white-space: normal; text-align: left; }

/* read-only demo (DWG_DEV_READONLY=1): the controls that change data are not offered */
.is-readonly #topbarUploadBtn, .is-readonly #editDictionaryBtn, .is-readonly .upload-area, .is-readonly #uploadHistory,
.is-readonly .btn-delete, .is-readonly [data-manual-del], .is-readonly [data-area-del], .is-readonly .btn-remove-symbol,
.is-readonly details.sidebar-add, .is-readonly #chatFab, .is-readonly #chatPanel, .is-readonly #viewerAreaBtn,
.is-readonly [data-floor-assign], .is-readonly .cable-decide, .is-readonly button[data-decide], .is-readonly .manual-count-form { display: none !important; }

/* project 현황: quantities first */
.dash-section { margin: 4px 0 18px; }
.dash-section-head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 8px; }
.dash-section-head h3 { margin: 0; font-size: var(--fs-4); }
.dash-section-head .hint { font-size: var(--fs-2); }
.dash-section-head .seg { margin-left: auto; }
.discipline-table { width: 100%; }
.discipline-table td.disc-name { font-weight: 600; }
.discipline-table tbody tr[data-id] { cursor: pointer; }
.discipline-table tbody tr[data-id]:hover td { background: var(--bg-hover, rgba(255,255,255,0.04)); }
.discipline-table th, .discipline-table td { white-space: nowrap; width: 1%; }
.discipline-table th:first-child, .discipline-table td:first-child { width: 220px; }
/* the folded detail: no share bar to stretch, so the table keeps to its columns */
.discipline-detail { width: auto; min-width: 60%; }
.discipline-detail th, .discipline-detail td { width: auto; padding-right: 28px; }
.discipline-table th.comp, .discipline-table td.comp { width: auto; min-width: 200px; }
/* the bar's length is the discipline's metres against the largest (as the old share bar), its colours the cable kinds */
.discipline-table td.comp .comp-wrap { display: block; max-width: 640px; }
/* the same hover as the floor chart's bars (U-117): the segment under the pointer glows in its own colour; the bar
   is not clipped so the glow can spill, the rounded ends are on the first and last segment instead */
.discipline-table td.comp .comp-bar { display: flex; height: 8px; border-radius: 4px; background: var(--bg-raised); }
.discipline-table td.comp .comp-bar i { display: block; height: 100%; opacity: .92; transition: box-shadow .2s, opacity .2s; }
.discipline-table td.comp .comp-bar i:first-child { border-radius: 4px 0 0 4px; }
.discipline-table td.comp .comp-bar i:last-child { border-radius: 0 4px 4px 0; }
.discipline-table td.comp .comp-bar i + i { box-shadow: -1px 0 0 var(--bg-surface); }
.discipline-table td.comp .comp-bar i:hover { opacity: 1; box-shadow: 0 0 10px var(--c, rgba(255,255,255,.5)); position: relative; z-index: 1; }
.discipline-table td.main-spec { white-space: nowrap; font-size: var(--fs-2); }
.discipline-table td.main-spec .hint { font-family: var(--font-mono); margin-left: 4px; }
.discipline-table th.share, .discipline-table td.share { width: auto; min-width: 200px; }
.discipline-table td.share .mix-bar { display: inline-block; width: calc(100% - 64px); max-width: 560px; height: 8px; vertical-align: middle; background: var(--bg-raised); border-radius: 4px; overflow: hidden; margin-right: 8px; }
.discipline-table td.share .mix-bar i { display: block; height: 100%; background: var(--accent, #7c9bff); border-radius: 4px; opacity: .9; }
.discipline-table td.share .share-pct { font-family: var(--font-mono); font-size: var(--fs-2); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.discipline-table td.open { color: var(--warning); font-size: var(--fs-2); }
#projectAlertsFold { margin-top: 6px; }
#projectAlertsFold .alert-cards { margin-top: 12px; }

.chip .chip-alias { color: var(--text-muted); font-weight: 400; margin-left: 2px; }
.floor-table tr.floor-riser td { color: var(--text-muted); font-style: italic; }

.spec-table { width: 100%; }
/* the three tables of the project page share one height (the disciplines' table: 11 rows) — the longer ones scroll inside */
#specTable, #floorSummaryStatus { overflow-y: auto; }   /* folded now: the whole table, no inner scroll */
#specTable thead th, #floorSummaryStatus thead th { position: sticky; top: 0; z-index: 2; background: var(--bg-raised); }
#specTable tr.rollup-total td, #floorSummaryStatus tr.rollup-total td { position: sticky; bottom: 0; background: var(--bg-raised); }
.spec-table { table-layout: fixed; }
.spec-table th:nth-child(1) { width: 30%; }
.spec-table th:nth-child(2) { width: 12%; }
.spec-table th:nth-child(3) { width: 7%; }
.spec-table td.spec-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.spec-table td.spec-by { white-space: normal; }
.spec-table td.spec-by { line-height: 1.9; }
.spec-chip { display: inline-block; margin: 0 8px 0 0; color: var(--text-muted); font-size: var(--fs-2); white-space: nowrap; }
.spec-chip b { color: var(--text-secondary); font-weight: 500; font-variant-numeric: tabular-nums; }
.discipline-table td.rev { white-space: nowrap; font-size: var(--fs-2); }
.floor-table tr.floor-group-start td { border-top: 2px solid var(--border-strong); }

/* charts on the project page */
.dash-grid { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 20px; align-items: stretch; }
.dash-grid .dash-section { display: flex; flex-direction: column; margin-bottom: 8px; }
.dash-grid .dash-section > .table-container, .dash-grid .dash-section > .spec-donut { flex: 1; }
.dash-card { padding: 18px 20px 12px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-raised); }
.dash-fold { margin: 6px 0; }
.dash-fold > summary b { color: var(--text-primary); }
.dash-fold > .table-container { margin-top: 10px; }
.discipline-table .spec-dot { margin-right: 9px; }
.spec-donut { display: flex; flex-direction: column; justify-content: center; gap: 18px; align-items: stretch; padding: 18px 20px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-raised); }
.donut-centre { fill: var(--text-primary); font-size: var(--fs-4); font-weight: 600; font-family: var(--font-mono); }
.donut-sub { fill: var(--text-muted); font-size: var(--fs-2); }
.donut-legend { list-style: none; margin: 0; padding: 0; font-size: var(--fs-2); }
.donut-legend li { display: grid; grid-template-columns: 8px minmax(0, 1fr) 90px 42px; gap: 10px; align-items: center; padding: 6px 0; border-top: 1px solid var(--border-color); }
.donut-legend li:first-child { border-top: 0; }
.donut-legend i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.donut-legend .dl-name { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.donut-legend .dl-val { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-primary); }
.donut-legend .dl-pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-muted); }
.spec-donut .donut { align-self: center; }
/* ECharts hosts (U-89) */
.spec-donut .ec-donut { width: 100%; height: 240px; align-self: center; }
.ec-bars { width: 100%; }
.fbars .ec-bars { margin: 0 0 4px; }
.spec-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; vertical-align: middle; }
.big-ring { display: inline-block; vertical-align: -4px; margin-right: 8px; height: 34px; }
.big-ring svg { display: block; }
.fbars-cols { display: grid; grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr)); gap: 0 40px; }
.fbars-cols > .fbars + .fbars { border-left: 1px solid var(--border-color); padding-left: 40px; margin-left: -20px; }
.fbars { display: grid; grid-template-columns: 1fr; gap: 7px; margin: 0 0 14px; align-content: start; }
.fbars-rest { margin-top: 2px; padding-top: 12px; border-top: 1px solid var(--border-color); }
.fb-title { font-size: var(--fs-3); font-weight: 600; color: var(--text-primary); margin: 0 0 8px; }
.fb-title .hint { font-weight: 400; margin-left: 6px; }
.fb-row { display: grid; grid-template-columns: 80px minmax(0, 1fr) 92px; gap: 12px; align-items: center; font-size: var(--fs-2); }
.fbars-rest .fb-row { grid-template-columns: 80px calc((100% - 40px * (var(--cols, 1) - 1)) / var(--cols, 1) - 80px - 92px - 24px) 92px; }
.fb-name { color: var(--text-secondary); white-space: nowrap; }
/* the same thin bar as the disciplines' table: a track, a rounded fill sized by the floor's metres, the fill split by discipline */
.fb-bar { display: block; height: 8px; background: var(--bg-raised); border-radius: 4px; }
.fb-fill { display: flex; height: 100%; border-radius: 4px; overflow: hidden; }
.fb-bar i { display: block; height: 100%; opacity: .92; }
.fb-bar i + i { box-shadow: -1px 0 0 var(--bg-surface); }
.fb-val { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-primary); }
.fb-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 6px 92px; font-size: var(--fs-2); color: var(--text-muted); }
.fb-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
@media (max-width: 1100px) { .dash-grid { grid-template-columns: 1fr; } .fbars-cols { grid-template-columns: 1fr !important; } .fbars-rest .fb-row { grid-template-columns: 80px minmax(0, 1fr) 92px !important; } }

.discipline-table td.headline { white-space: nowrap; }
.floor-table th .th-sub { display: block; font-weight: 400; font-size: var(--fs-1); color: var(--text-muted); }
#bigDevices .big-value { font-size: var(--fs-5); white-space: nowrap; }
#bigDevices .big-sub b { color: var(--text-secondary); font-weight: 500; }
#bigDevices .big-value b { font-family: var(--font-mono); }

.chart-tip { position: fixed; z-index: 60; pointer-events: none; padding: 6px 10px; font-size: var(--fs-2); color: var(--text-primary); background: var(--bg-raised); border: 1px solid var(--border-strong); border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,.4); white-space: nowrap; }   /* the same box as the ECharts tooltip (U-117) */
.donut-arc, .donut-legend li { transition: opacity .12s; cursor: default; }
.donut-arc.is-dim { opacity: .28; }
.donut-legend li.is-dim { opacity: .45; }
.fb-bar i { cursor: default; }
.fb-bar i:hover { opacity: 1; filter: brightness(1.15); }

/* the project page: one step larger than the app's tables, the hint muted everywhere (no base rule existed) */
.hint { color: var(--text-muted); }
#projectStatusView .rollup-table { font-size: var(--fs-2); }
#projectStatusView .rollup-table th, #projectStatusView .rollup-table td { padding: 11px 10px; }

/* a deployed server (DWG_DEV_ADMIN_KEY set): the viewer's page — the keeper's tools are not on it */
.is-user #editDictionaryBtn, .is-user details.sidebar-add,
.is-user #viewerCalibBtn, .is-user #viewerAreaBtn, .is-user #wizardPanel, .is-user #runAssignPanel, .is-user #reviewPanel,
.is-user #reviewSection, .is-user #lengthSection, .is-user #manualCounts, .is-user #areaExclusions,
.is-user #projectReviewSection, .is-user #decisionsSection, .is-user #settingsSection,
.is-user .btn-delete, .is-user [data-manual-del], .is-user [data-area-del], .is-user .btn-remove-symbol,
.is-user [data-floor-assign], .is-user .cable-decide, .is-user button[data-decide], .is-user .manual-count-form,
.is-user [data-ignore-block], .is-user [data-unignore-block], .is-user #chatFab, .is-user #chatPanel { display: none !important; }


/* the strip on top of the project page: only when something asks for a hand */
/* the title row's badges (U-82): small pills at the right, grey for news, amber for what needs a hand */
.title-badges { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.title-badge { padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border-strong); background: var(--bg-raised); color: var(--text-secondary); font-size: var(--fs-1); font-family: inherit; cursor: pointer; white-space: nowrap; }
.title-badge b { color: var(--text-primary); font-weight: 600; margin-left: 2px; }
.title-badge:hover { border-color: var(--text-muted); color: var(--text-primary); }
.title-badge.is-warn { border-color: rgba(240, 169, 94, 0.5); background: rgba(240, 169, 94, 0.1); color: #f0c98a; }
.title-badge.is-warn b { color: #f5d6a5; }
/* a discipline row with open items: an amber dot after the name, the count on hover */
.discipline-table .open-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--warning); margin-left: 6px; vertical-align: middle; }



/* the page opens with its bars filling in and its ring sweeping round (2026-09-18) */
@keyframes bar-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes donut-sweep { from { stroke-dasharray: 0 var(--c); } }
.discipline-table td.comp .comp-bar, .fb-fill, .mix-bar i, .floor-row .mix-bar i { transform-origin: left center; animation: bar-grow .9s cubic-bezier(.2, .7, .2, 1) both; }
.fb-row { --i: 0; }
.fb-row .fb-fill { animation-delay: calc(var(--i) * 35ms); }
.donut-arc { animation: donut-sweep 1.1s cubic-bezier(.2, .7, .2, 1) both; }
@media (prefers-reduced-motion: reduce) { .discipline-table td.comp .comp-bar, .fb-fill, .mix-bar i, .donut-arc { animation: none; } }

/* ---- motion (U-81): a screen rises in block by block; a block filled later fades in over its skeleton ---- */
@keyframes screen-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.section.is-entering > * { animation: screen-in .34s cubic-bezier(.2, .7, .2, 1) both; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes block-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.is-filled { animation: block-in .3s cubic-bezier(.2, .7, .2, 1) both; }
/* the skeleton: grey bars with a slow sheen, the size of what will stand there */
@keyframes skel-sheen { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.skel { display: block; border-radius: 6px; background: linear-gradient(90deg, rgba(255,255,255,.055) 30%, rgba(255,255,255,.11) 50%, rgba(255,255,255,.055) 70%); background-size: 200% 100%; animation: skel-sheen 1.6s linear infinite; }
.skel-inline { display: inline-block; vertical-align: middle; height: 11px; }
.skel-block { padding: 6px 0 2px; }
.skel-line { height: 11px; margin: 9px 0; }
.skel-big { height: 44px; width: 240px; margin: 4px 0 10px; border-radius: 8px; }
.skel-table { padding: 8px 12px; }
.skel-row { display: flex; gap: 14px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--border-color); }
.skel-row:last-child { border-bottom: 0; }
.skel-row.is-head .skel-cell { height: 9px; opacity: .7; }
.skel-cell { height: 12px; flex: 1 1 0; }
.skel-cell.is-name { flex: 2.4 1 0; }
.skel-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.skel-chip { height: 24px; width: 72px; border-radius: 12px; }
.skel-chip:nth-child(2n) { width: 96px; }
.skel-donut { display: flex; align-items: center; gap: 28px; padding: 18px 8px; }
.skel-ring { width: 180px; height: 180px; border-radius: 50%; flex: 0 0 auto; -webkit-mask: radial-gradient(circle, transparent 58%, #000 59%); mask: radial-gradient(circle, transparent 58%, #000 59%); }
.skel-donut .skel-block { flex: 1 1 auto; }
@media (prefers-reduced-motion: reduce) { .section.is-entering > *, .is-filled, .skel { animation: none; } }



/* the floor chart's kinds: the top six as chips, the rest behind one small select; the chip on is the kind on show */
.kind-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.kind-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border-color); background: var(--bg-raised); color: var(--text-secondary); font-size: var(--fs-2); cursor: pointer; font-family: inherit; }
.kind-chip i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.kind-chip .kind-mm { color: var(--text-muted); font-family: var(--font-mono); font-size: var(--fs-1); }
.kind-chip:hover { border-color: var(--border-strong); color: var(--text-primary); }
.kind-chip.is-on { border-color: var(--accent); color: var(--text-primary); background: var(--accent-soft); }
.kind-chip.is-on .kind-mm { color: var(--text-secondary); }
select.kind-chip { appearance: none; -webkit-appearance: none; padding-right: 14px; flex: none; width: auto; max-width: 160px; }
/* a select's open list (D-13): the browser draws it on the select's own background, and a lit chip's is a translucent tint —
   over the browser's white that left light-grey words on pale blue. Every option gets the page's solid colours. */
select option, select optgroup { background-color: var(--bg-surface); color: var(--text-primary); }
select option:checked { background-color: var(--accent); color: #0f1116; }
.spec-donut.is-clickable .donut-arc, .spec-donut.is-clickable .donut-legend li { cursor: pointer; }


/* REV.1 대비 in the viewer: the switch beside 전체화면, the list in the side panel in place of the device list */
.viewer-diff-btn.is-on { background: var(--accent); color: #fff; border-color: var(--accent); }
/* in REV.1 대비 the comparison sits above the device list — the list stays (U-56; it used to be hidden, and the tick
   boxes went missing with it) */
.viewer-panel.is-diff .viewer-diff { margin: 12px 0; padding: 12px 0; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); }
.viewer-diff { font-size: var(--fs-1); color: var(--text-secondary); }
.viewer-diff-head { font-size: var(--fs-2); color: var(--text-primary); margin: 4px 0 8px; }
.viewer-diff .diff-stats { gap: 4px 12px; margin-bottom: 6px; }
.viewer-diff .diff-stat b { font-size: var(--fs-2); }
.viewer-diff .diff-tools { margin-bottom: 10px; }
.viewer-diff .diff-tools .diff-overlay-toggle { margin-left: 0; margin-right: 12px; }
.viewer-diff-title { font-weight: 600; color: var(--text-primary); margin: 6px 0 2px; }
.viewer-diff .diff-item { padding: 4px 6px; font-size: var(--fs-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.viewer-diff .diff-group > summary { padding: 4px 0; }
.viewer-diff-row { display: grid; grid-template-columns: 1fr 70px 40px; gap: 6px; padding: 3px 6px; font-size: var(--fs-1); }
.viewer-diff-row .num { text-align: right; font-family: var(--font-mono); color: var(--text-muted); }
.viewer-diff-sheets { margin: 4px 0 8px; font-size: var(--fs-1); }


/* REV.1 → REV.2: the project table on Home, three columns (cable · devices · floors) on the discipline page */
.rev-compare { margin: 0 0 22px; }
.rev-table td.disc-name { font-weight: 600; }
.rev-table tr.is-muted td { color: var(--text-muted); }
.rev-table th.hl, .rev-table td.hl { border-left: 1px solid var(--border-color); }
.rev-delta.is-up { color: var(--success, #4ade80); }
.rev-delta.is-down { color: var(--danger); }
.rev-delta.is-same { color: var(--text-muted); }
.rev-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: start; }
.rev-col { background: var(--bg-raised); border: 1px solid var(--border-color); border-radius: var(--radius); padding: 12px 14px; min-width: 0; }
.rev-col-head { font-size: var(--fs-2); color: var(--text-primary); margin-bottom: 8px; }
.rev-row { display: grid; grid-template-columns: minmax(0, 1fr) 78px 78px 84px; gap: 6px; padding: 5px 0; border-bottom: 1px solid var(--border-color); font-size: var(--fs-2); align-items: baseline; }
.rev-row:last-child { border-bottom: none; }
.rev-row.is-head { color: var(--text-muted); font-size: var(--fs-0); border-bottom: 1px solid var(--border-color); }
.rev-row .num { text-align: right; font-family: var(--font-mono); color: var(--text-secondary); }
.rev-row .rev-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rev-row.is-same .num { color: var(--text-muted); }
.rev-same > summary { cursor: pointer; color: var(--text-muted); font-size: var(--fs-1); padding: 6px 0 2px; }
.rev-empty { padding: 6px 0; }
@media (max-width: 1100px) { .rev-cols { grid-template-columns: 1fr; } }


/* the confidence line: what share of the number is a drawn line (2026-09-18, 컨설팅 1단계) */
.dash-confidence { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 6px 0 14px; font-size: var(--fs-2); color: var(--text-secondary); }
.conf-part b { color: var(--text-primary); font-family: var(--font-mono); font-weight: 600; }
/* 정산 기준 (S-2): the drawing's own figure one line under the settlement headline */
.dash-settle { margin: 6px 0 0; font-size: var(--fs-2); color: var(--text-secondary); }
.dash-settle b { color: var(--text-primary); font-family: var(--font-mono); font-weight: 600; }
.dash-settle-out { margin-top: 3px; font-size: var(--fs-2); color: var(--warning); cursor: help; }
.mix-name .est { margin-left: 6px; font-size: var(--fs-0); color: var(--text-secondary); border-bottom: 1px dotted var(--text-muted); cursor: help; }   /* D-1: not amber — amber is 확인 필요 */
.boq-grid td.settle { font-weight: 700; }
.boq-grid td.drawn { color: var(--text-secondary); }
.conf-part.is-zero, .conf-part.is-zero b { color: var(--text-muted); font-weight: 400; }
.conf-part.is-warn b { color: var(--warning); }
.conf-part.is-link { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.conf-part.is-link:hover { color: var(--text-primary); }
.discipline-table td.conf, .discipline-table th.conf { width: 84px; }
.conf-pct { font-family: var(--font-mono); color: var(--text-secondary); }
.conf-pct.is-full { color: var(--text-muted); }
.conf-pct.is-warn { color: var(--warning); }


/* 내역서 대조 (컨설팅 2단계) */
/* 내역 대조 block (U-36): the head line, two cards (케이블 | 기기) of paired rows, one fold for the rest */
.boq-block { margin: 0 0 28px; }
.boq-block .boq-head { flex-wrap: wrap; margin: 0 0 12px; font-size: var(--fs-2); }
.boq-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.boq-col { background: var(--bg-raised); border: 1px solid var(--border-color); border-radius: var(--radius); padding: 12px 14px; min-width: 0; overflow-x: auto; }
.boq-col-plain { background: none; border: none; padding: 0; }
.boq-row { display: grid; grid-template-columns: minmax(0, 1fr) 84px 84px 118px; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-color); font-size: var(--fs-2); align-items: baseline; }
.boq-row:last-child { border-bottom: none; }
.boq-row.is-head { color: var(--text-muted); font-size: var(--fs-0); }
.boq-row .num { text-align: right; font-family: var(--font-mono); color: var(--text-secondary); white-space: nowrap; }
.boq-row .num .rev-delta, .boq-row .num .boq-delta { display: inline-block; min-width: 46px; text-align: right; }
/* the bill gap (U-43): grey is the normal (allowance) direction, amber the one to look at, dim = nothing drawn; bold = a big gap */
.boq-delta { color: var(--text-muted); }
.boq-delta.is-short { color: var(--accent); }   /* D-1: over the bill is a direction, not an alarm */
.boq-delta.is-none { color: var(--text-muted); opacity: 0.55; }
.boq-delta.is-big { font-weight: 700; color: var(--text-secondary); }
.boq-delta.is-short.is-big { color: var(--warning); }
.boq-delta.is-none.is-big { font-weight: 400; }
.boq-row.is-head .num .hint { font-family: var(--font-sans, inherit); font-size: 10.5px; }
.boq-row .boq-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; color: var(--text-primary); }
.boq-row.is-muted .boq-name { color: var(--text-muted); font-weight: 400; }
/* the comparison table (U-44): group heads per building, 내역 muted · 도면 primary, thin rules between groups */
.boq-grid { width: 100%; border-collapse: collapse; font-size: var(--fs-2); }
.boq-grid th, .boq-grid td { padding: 6px 8px; background: none; border-bottom: 1px solid var(--border-color); white-space: nowrap; }
.boq-grid thead th { font-size: var(--fs-1); font-weight: 500; color: var(--text-secondary); text-align: right; }
.boq-grid thead th:first-child { text-align: left; }
.boq-grid thead tr.grps th { font-size: var(--fs-2); font-weight: 600; color: var(--text-secondary); text-align: center; border-bottom: none; padding-bottom: 2px; }
.boq-grid thead tr.grps th:first-child { border-bottom: none; }
.boq-grid td.num { text-align: right; font-family: var(--font-mono); color: var(--text-primary); }
.boq-grid col.c-num { width: 6.5%; }   /* the numbers stay together; the name column takes the slack (fixed layout: it shrinks with an ellipsis) */
.boq-grid col.c-gap { width: 13.5%; }   /* bar + share must fit inside the band (U-108: at 10% the share ran past the tint) */
.boq-grid td.bill, .boq-grid th.bill { color: var(--text-muted); }
/* the groups read as groups (U-48): a gap instead of a hairline between them, a rule under each group's name that
   spans its columns, and the 합계 group on a faint band */
.boq-grid col.c-sp { width: 18px; }
.boq-grid td.sp, .boq-grid th.sp { padding: 0; border-bottom: none; }
.boq-grid thead tr.grps th.grp { border-bottom: 1px solid var(--border-strong); padding: 4px 8px 5px; }
.boq-grid td.tot, .boq-grid th.tot { background: rgba(255, 255, 255, 0.04); }
.boq-grid thead tr.grps th.tot { border-radius: 6px 6px 0 0; }
.boq-grid tbody tr:last-child td.tot:first-of-type { border-radius: 0 0 0 6px; }
.boq-grid { table-layout: fixed; }
.boq-grid td.boq-name, .boq-grid thead th:first-child { width: auto; }
.boq-grid td.gap .boq-delta { display: inline-block; min-width: 48px; text-align: right; }
.boq-grid td.gap, .boq-grid thead th.gap { text-align: center; padding-right: 8px; }   /* bar + share as one group, centred under 차이 (U-109) */
.boq-grid tbody tr:last-child td { border-bottom: none; }
.boq-grid td.boq-name { font-weight: 600; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; }
.boq-grid tr.is-muted td.boq-name, .boq-grid tr.is-muted td.num { color: var(--text-muted); font-weight: 400; }
.boq-grid tr:hover td { background: rgba(255, 255, 255, 0.03); }
.boq-rest { margin-top: 10px; }
.boq-rest > summary { cursor: pointer; list-style: revert; font-size: var(--fs-2); color: var(--text-secondary); padding: 6px 0; user-select: none; }
.boq-rest > summary b { color: var(--text-primary); }
.boq-rest[open] > summary { color: var(--text-primary); }
@media (max-width: 1750px) { .boq-cols { grid-template-columns: 1fr; } }   /* the building columns need the width: one card under the other */

/* The checking blocks under the viewer (U-34): every one a folded card with the same line — title, then the counts in
   muted text — so the page reads title by title: 물량 · 물량표 · 도면 보기 · 확인 */
#screenDashboard .dash-fold-card { margin: 0 0 12px; padding: 0; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 14px; }
#screenDashboard .dash-fold-card > summary { cursor: pointer; list-style: revert; padding: 14px 18px; font-size: var(--fs-3); font-weight: 600; color: var(--text-primary); user-select: none; }
#screenDashboard .dash-fold-card > summary .hint { font-size: var(--fs-2); font-weight: 400; }
#screenDashboard .dash-fold-card > summary:hover { color: var(--text-primary); }
#screenDashboard .dash-fold-card[open] > summary { margin-bottom: 0; border-bottom: 1px solid var(--border-color); }
#screenDashboard .dash-fold-card > *:not(summary) { margin-left: 18px; margin-right: 18px; }
#screenDashboard .dash-fold-card > summary + * { margin-top: 14px; }
#screenDashboard .dash-fold-card > *:last-child { margin-bottom: 16px; }
#screenDashboard .dash-fold-card .upload-area-compact { background: var(--bg-raised); }
#screenDashboard .dash-fold-card > .table-container { background: var(--bg-raised); }
#screenDashboard .dash-fold-card .rev-col { background: var(--bg-raised); }
.boq-upload { margin-left: auto; cursor: pointer; }
.boq-table td.spec { font-weight: 600; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.boq-table td.basis, .boq-table th.basis { text-align: left; max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.boq-table tr.is-muted td { color: var(--text-muted); }
.boq-unmatched { margin-top: 10px; font-size: var(--fs-2); color: var(--text-secondary); display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; }
.boq-chip { display: inline-block; padding: 2px 9px; border: 1px solid var(--border-color); border-radius: 999px; font-size: var(--fs-1); color: var(--text-secondary); }
.boq-chip b { font-family: var(--font-mono); font-weight: 600; color: var(--text-primary); }
.boq-other { margin-top: 6px; }
.boq-foot { margin-top: 8px; }



/* folded REV blocks carry their one line on the summary */
#homeRevFold > summary, #dashRevFold > summary { font-size: var(--fs-2); }
#homeRev, #dashRev { margin: 10px 0 4px; }
#dashRevFold { margin: 4px 0 18px; }
.dash-section-head h3[title] { cursor: help; }


/* 물량 이력 (컨설팅 4단계) */
.history-list { margin-top: 8px; }
.history-row > summary { display: grid; grid-template-columns: 130px minmax(0, 1fr) 110px 110px; gap: 10px; align-items: baseline; padding: 6px 4px; border-bottom: 1px solid var(--border-color); cursor: pointer; font-size: var(--fs-2); list-style: none; }
.history-row > summary::-webkit-details-marker { display: none; }
.history-when { color: var(--text-muted); font-family: var(--font-mono); font-size: var(--fs-1); }
.history-cause { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-total, .history-delta { text-align: right; font-family: var(--font-mono); }
.history-deltas { display: flex; flex-wrap: wrap; gap: 6px 10px; padding: 6px 4px 10px 140px; font-size: var(--fs-1); }
.history-chip b { font-weight: 600; color: var(--text-primary); margin-right: 4px; }


.boq-sub { margin: 12px 0 4px; font-size: var(--fs-2); font-weight: 600; color: var(--text-secondary); }
.boq-more { margin-top: 8px; }
.boq-more > summary { cursor: pointer; font-size: var(--fs-1); }


.boq-none-row > td { padding: 4px 0 0; }
.boq-inner { margin-top: 4px; }

/* the viewer's sheets as floor chips (2026-09-18) */
.sheet-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 8px 0 4px; }
/* the sheet index (U-70): the viewer's own chip row is replaced by this list; group heads like the device table's */
#viewerSheetChips { display: none !important; }
.sheet-index { margin: 0 0 6px; }
.sheet-index .sheet-index-group { margin: 8px 0 0; font-size: var(--fs-0); font-weight: 600; letter-spacing: 0.02em; color: var(--text-muted); }
.sheet-rows { display: flex; flex-direction: column; margin: 2px 0 0; }
.sheet-row { display: flex; align-items: baseline; gap: 8px; width: 100%; padding: 4px 8px; border: none; border-radius: var(--radius-sm); background: none; color: var(--text-primary); font-size: var(--fs-2); font-family: inherit; text-align: left; cursor: pointer; }
.sheet-row:hover { background: rgba(255, 255, 255, 0.05); }
.sheet-row.is-on { background: var(--accent-soft); color: var(--text-primary); box-shadow: inset 2px 0 0 var(--accent); }
.sheet-row.is-under { padding-left: 20px; color: var(--text-secondary); font-size: var(--fs-1); }
.sheet-row-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-row-tail { margin-left: auto; font-size: var(--fs-0); color: var(--text-muted); white-space: nowrap; }
.sheet-row .pivot-indent { color: var(--text-muted); margin-right: 1px; }
.sheet-chip { padding: 3px 9px; border-radius: 999px; border: 1px solid var(--border-color); background: var(--bg-raised); color: var(--text-secondary); font-size: var(--fs-1); cursor: pointer; font-family: inherit; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-chip:hover { border-color: var(--border-strong); color: var(--text-primary); }
.sheet-chip.is-on { border-color: var(--accent); color: var(--text-primary); background: var(--accent-soft); }

/* the phone's own parts of the viewer: absent on a desktop */
.phone-sheetbar, .phone-panel-head, .phone-more-btn, .phone-home, .viewer-fit-btn { display: none; }
/* a tapped device's name (V-8), on the drawing at the tap — phone and PC alike */
.viewer-tip { position: absolute; z-index: 7; transform: translate(-50%, calc(-100% - 12px)); pointer-events: none;
              max-width: 260px; padding: 7px 10px; font-size: var(--fs-2); line-height: 1.35; color: var(--text-primary);
              background: rgba(19, 22, 28, 0.95); border: 1px solid var(--border-strong); border-radius: 8px;
              box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4); white-space: nowrap; }
.viewer-tip b { font-weight: 700; }
.viewer-tip .hint { display: block; font-size: var(--fs-0); }
.viewer-tip .tip-drop { display: block; margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border-color); font-size: var(--fs-1); color: #8cc2ff; }
.viewer-tip .tip-drop .hint { display: inline; }
.viewer-tip::after { content: ""; position: absolute; left: 50%; bottom: -6px; width: 10px; height: 10px; margin-left: -5px;
                     background: inherit; border-right: 1px solid var(--border-strong); border-bottom: 1px solid var(--border-strong); transform: rotate(45deg); }

/* ---------------------------------------------------------------- 폰 (M-1, 2026-09-24)
   PM·현장이 폰으로 숫자와 도면을 본다 — 보기 전용. Last in the file so it wins over the desktop rules above.
   Upload, export and the bill upload are desktop work and are not offered on a phone. */
/* D-1 (2026-09-25 design pass) */
/* 1. the home table's cable cell: the drawing's metres, the settlement one line under when there is one */
.discipline-table td .cell-sub { font-size: var(--fs-1); color: var(--text-secondary); margin-top: 2px; white-space: nowrap; }
/* 3. the folded lines under the home page in groups with a small title; a group whose folds are all hidden hides */
.fold-group { margin: 18px 0 0; }
.fold-group-title { margin: 0 0 4px; font-size: var(--fs-1); font-weight: 700; letter-spacing: 0.04em; color: var(--text-secondary); }
.fold-group:not(:has(details:not([hidden]))) { display: none; }
.fold-group > details + details { margin-top: 4px; }
/* 10. the phone's 물량표: a list of the device types with their totals, not a table cut to its last row */
.pivot-list { display: flex; flex-direction: column; }
.pivot-list-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--border-color); }
.pivot-list-row .symbol-icon { flex: none; width: 30px; height: 30px; margin: 0; }
.pivot-list-name { flex: 1; min-width: 0; font-size: var(--fs-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pivot-list-n { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-3); }
.pivot-list-foot { padding: 8px 4px 0; }

.split-handle, .viewer-collapse-btn, .viewer-restore-btn { display: none; }

/* ---- A안 (D-2, 2026-09-25): the discipline page on a wide screen — numbers in a 720 px column on the left, the viewer
   in the rest of the width, pinned under the tab bar while the left column scrolls. The sheets are a row of chips over
   the drawing, the device list a row of chips under it. Below 1200 px the page stacks as before; the phone has its own. */
@media (min-width: 1200px) and (min-height: 800px) {
    #screenDashboard.section { display: grid; grid-template-columns: var(--left-col, clamp(520px, 38%, 720px)) minmax(0, 1fr); column-gap: 28px; align-items: start; }   /* a laptop keeps the viewer wide; dragged widths set --left-col (D-5) */
    #screenDashboard.section > * { grid-column: 1; min-width: 0; }
    #screenDashboard.section > .viewer-title { display: none; }
    /* no box in a box (D-3): the left column is flat — a rule above each section title, the folds as rules */
    #screenDashboard .dash-headline, #screenDashboard .dash-hero .dash-boq, #screenDashboard .qty-pane, #screenDashboard .table-container,
    #screenDashboard #cableSection, #screenDashboard .dash-fold-card { background: none; border: none; box-shadow: none; border-radius: 0; padding-left: 0; padding-right: 0; }
    #screenDashboard .dash-headline { padding-top: 4px; padding-bottom: 0; }
    #screenDashboard .dash-hero { gap: 22px; margin-bottom: 8px; }
    #screenDashboard .dash-hero .dash-boq { padding: 0; }
    #screenDashboard .dash-hero .dash-boq .boq-head { margin: 0 0 8px; }
    #screenDashboard > h3 { border-top: 1px solid var(--border-color); padding-top: 18px; margin-top: 18px; }
    #screenDashboard > h3:first-of-type { border-top: none; padding-top: 0; }
    #screenDashboard .qty-tabs { margin-top: 0; }
    #screenDashboard .qty-pane { padding: 0; margin-bottom: 8px; }
    #screenDashboard .dash-fold-card { margin: 0; border-top: 1px solid var(--border-color); }
    #screenDashboard .dash-fold-card > summary { padding: 12px 0; }
    #screenDashboard .dash-fold-card[open] > summary { border-bottom: none; }
    #screenDashboard .dash-fold-card > *:not(summary) { padding-left: 0; padding-right: 0; }
    #screenDashboard #cableSection { padding: 0; }
    #screenDashboard details.length-section { background: none; border: none; box-shadow: none; }
    /* the bill grid with only the 합계 columns needs no band round them (D-3) */
    #screenDashboard .boq-grid td.tot, #screenDashboard .boq-grid th.tot, #screenDashboard .boq-grid th.grp.tot { background: none; border-radius: 0; }
    /* the drag handle on the viewer's left edge (D-5): a thin line that shows on hover, the whole gap grabs */
    .split-handle { display: block; position: absolute; left: -22px; top: 0; bottom: 0; width: 16px; cursor: col-resize; z-index: 6; }
    .split-handle::after { content: ''; position: absolute; left: 7px; top: 12%; bottom: 12%; width: 2px; border-radius: 1px; background: var(--border-strong); opacity: 0; transition: opacity .15s; }
    .split-handle::before { content: ''; position: absolute; left: 5px; top: calc(50% - 18px); width: 6px; height: 36px; border-radius: 3px; background: var(--border-strong); }   /* the grip: always there, so the edge reads as draggable */
    .split-handle:hover::after, body.is-resizing .split-handle::after { opacity: 1; background: var(--accent); }
    body.is-resizing { cursor: col-resize; user-select: none; }
    body.is-resizing #viewerWrap .viewer-main { pointer-events: none; }
    /* the 물량표's heads in the narrow column: the icon over a short name, so nine device columns fit */
    .is-tabulator .pivot-head.is-compact { flex-direction: column; width: 52px; height: auto; padding: 2px 0; gap: 3px; }
    .is-tabulator .pivot-head.is-compact .symbol-icon { width: 26px; height: 26px; margin: 0; }
    .is-tabulator .pivot-head.is-compact .symbol-label { flex-direction: column; gap: 0; min-height: 0; max-width: 52px; font-size: var(--fs-0); line-height: 1.2; }
    .is-tabulator .pivot-head.is-compact .symbol-name { display: block; max-width: 52px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .is-tabulator .pivot-head.is-compact .symbol-kinds { font-size: 10.5px; }
    .is-tabulator .pivot-head.is-compact .pivot-fold { width: 16px; height: 16px; }
    #screenDashboard.section > #viewerWrap { grid-column: 2; grid-row: 1 / span 80; align-self: start; position: sticky; top: 118px;
                                              margin: 0; height: calc(100vh - 118px - 20px); box-sizing: border-box; }
    #screenDashboard.section > #viewerWrap.is-fullscreen { position: fixed; inset: 0; top: 0; height: 100vh; width: 100vw; z-index: 900; border-radius: 0; background: var(--bg-base); }   /* the canvas row is 1fr of a fixed height, so the height must be set */
    #viewerWrap.is-fullscreen .viewer-canvas { height: 100%; }
    /* 접기 (D-11): a thin strip the height of the viewer down its left edge — the same shape as the 펼치기 strip that
       replaces the viewer when folded — with the words written down it; the floor rail starts to its right */
    .viewer-collapse-btn { display: flex; align-items: center; justify-content: center; grid-column: 1; grid-row: 1; width: 20px; height: 100%; padding: 0; margin: 0;
                           border: none; border-right: 1px solid var(--border-color); border-radius: 0; background: var(--bg-raised); color: var(--text-muted);
                           font: inherit; font-size: var(--fs-1); font-weight: 600; letter-spacing: 0.08em; writing-mode: vertical-rl; cursor: pointer; }
    .viewer-collapse-btn:hover { background: var(--accent-soft); color: var(--text-primary); }
    /* the arrow stays upright in the vertical text (D-12: it had turned to point down) and carries the accent alone */
    .viewer-collapse-btn .fold-arrow { display: inline-block; writing-mode: horizontal-tb; margin-top: 8px; font-size: 18px; font-weight: 800; line-height: 1; color: var(--accent); }
    .viewer-collapse-btn:hover .fold-arrow { color: #a9bfff; }
    #viewerWrap.is-fullscreen .viewer-collapse-btn { display: none; }   /* leave fullscreen first, then fold */
    #viewerWrap.is-fullscreen { grid-template-columns: 0 148px minmax(0, 1fr) 224px; }

    /* the viewer folded to a strip (D-4): the numbers take the width, a vertical label at the edge brings it back */
    #screenDashboard.section.viewer-hidden { grid-template-columns: minmax(0, 1fr) 44px; column-gap: 16px; }
    #screenDashboard.viewer-hidden .dash-hero { flex-direction: row; gap: 36px; }
    #screenDashboard.viewer-hidden .dash-hero > .dash-headline { flex: 0 1 620px; width: auto; }
    #screenDashboard.viewer-hidden .dash-hero > .dash-boq { flex: 1 1 700px; width: auto; }
    #screenDashboard.viewer-hidden .cable-marks-grid { grid-template-columns: 1fr 1fr 1fr; }
    #screenDashboard.section.viewer-hidden > #viewerWrap { padding: 0; display: flex; align-items: stretch; justify-content: center; }
    #screenDashboard.section.viewer-hidden > #viewerWrap > * { display: none; }
    #screenDashboard.section.viewer-hidden > #viewerWrap > .viewer-restore-btn { display: flex; align-items: center; justify-content: center; }
    .viewer-restore-btn { width: 100%; border: none; border-radius: 12px; background: var(--bg-raised); color: var(--text-secondary); font: inherit; font-size: var(--fs-2); font-weight: 600;
                          writing-mode: vertical-rl; letter-spacing: 0.06em; cursor: pointer; }
    .viewer-restore-btn:hover { background: var(--accent-soft); color: var(--text-primary); }
    #screenDashboard .dash-hero { flex-direction: column; }
    #screenDashboard .dash-hero > * { flex: 1 1 100%; width: 100%; }
    #screenDashboard .dash-hero .dash-boq { flex-basis: auto; }
    #screenDashboard > h3 { margin: 22px 0 8px; }
    /* inside the viewer (D-7 → D-8): the floors as a rail on the left (like an elevator panel), the drawing, the device
       legend docked on the right — nothing floats over the drawing but the toolbar and the count */
    #viewerWrap { display: grid; grid-template-columns: 20px 148px minmax(0, 1fr) 224px; grid-template-rows: minmax(0, 1fr); gap: 0; padding: 0; overflow: hidden; }   /* fold strip · floors · drawing · legend */
    #viewerWrap.has-wizard { grid-template-columns: 20px 148px minmax(0, 1fr) 224px 380px; }
    #viewerWrap .wizard-panel { grid-column: 5; grid-row: 1; }
    #viewerWrap .viewer-side { display: contents; }
    #viewerWrap .viewer-main { grid-row: 1; grid-column: 3; min-height: 0; height: 100%; }
    #viewerWrap .viewer-canvas { height: 100%; border-radius: 0; }
    #viewerWrap .viewer-scale { grid-row: 1; grid-column: 3; align-self: end; justify-self: end; z-index: 5; margin: 0 12px 10px 0;
                                padding: 3px 8px; border-radius: 6px; background: rgba(11, 12, 16, 0.7); font-size: var(--fs-1); color: var(--text-muted); pointer-events: none; }
    /* the floor rail: one row a sheet, top to bottom as the building reads; an enlargement sits under its floor */
    #viewerWrap .sheet-index { grid-row: 1; grid-column: 2; display: flex; flex-direction: column; align-items: stretch; gap: 0; margin: 0; padding: 8px 0; max-height: none;
                               overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; border-right: 1px solid var(--border-color); background: var(--bg-surface); }
    .sheet-index .sheet-rows { display: contents; }
    .sheet-index .sheet-index-group { margin: 10px 0 2px; padding: 0 12px; font-size: var(--fs-0); letter-spacing: 0.04em; color: var(--text-muted); }
    .sheet-row { width: 100%; display: flex; align-items: center; gap: 3px; padding: 7px 10px 7px 11px; border: none; border-left: 3px solid transparent; border-radius: 0;
                 background: none; font-size: var(--fs-2); color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .sheet-row:hover { background: rgba(255, 255, 255, 0.04); color: var(--text-primary); }
    .sheet-row.is-on { background: var(--accent-soft); border-left-color: var(--accent); color: var(--text-primary); font-weight: 700; }
    .sheet-row.is-under { padding-left: 20px; color: var(--text-muted); font-size: var(--fs-1); }
    .sheet-row.is-under.is-on { color: var(--text-primary); }
    .sheet-row .sheet-row-name { overflow: hidden; text-overflow: ellipsis; }
    .sheet-row .pivot-indent { display: inline; color: var(--border-strong); margin-right: 2px; }
    /* the device legend: a row a type — colour bar · icon · name · count; the row is the switch */
    #viewerWrap .viewer-panel { grid-row: 1; grid-column: 4; display: flex; flex-direction: column; max-height: none; overflow-y: auto; overflow-x: hidden;
                                padding: 6px 0 8px; border-top: none; border-left: 1px solid var(--border-color); background: var(--bg-surface); }
    .viewer-panel .viewer-symbols { display: block; }
    .viewer-panel .side-head { display: flex; justify-content: space-between; align-items: center; padding: 6px 12px 8px; font-size: var(--fs-1); color: var(--text-muted); font-weight: 600; }
    .viewer-panel .sym-row { display: grid; grid-template-columns: 4px 24px minmax(0, 1fr) auto; gap: 8px; align-items: center; padding: 5px 12px 5px 8px;
                             border: none; border-radius: 0; background: none; font-size: var(--fs-2); }
    .viewer-panel .sym-row:hover { background: rgba(255, 255, 255, 0.03); }
    .viewer-panel .sym-row.is-on { background: none; }
    .viewer-panel .sym-row input { display: none; }
    .viewer-panel .sym-row .sym-swatch { display: block; width: 4px; height: 22px; border-radius: 2px; opacity: 0.35; font-size: 0; box-shadow: none; }
    .viewer-panel .sym-row.is-on .sym-swatch { opacity: 1; }
    .viewer-panel .sym-row .sym-icon { width: 24px; height: 24px; padding: 3px; }
    .viewer-panel .sym-row .sym-name { color: var(--text-secondary); }
    .viewer-panel .sym-row.is-on .sym-name { color: var(--text-primary); font-weight: 600; }
    .viewer-panel .sym-row .sym-count { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-muted); }
    .viewer-panel .sym-row.is-on .sym-count { color: var(--text-primary); font-weight: 700; }
    .viewer-panel .sym-row.sym-sub { padding-left: 24px; }
    .viewer-panel .sym-row .pivot-fold { margin-left: 4px; padding: 0 3px; font-size: 10.5px; color: var(--text-muted); border: none; background: none; }
    .viewer-panel .side-note { display: none; }
    #viewerWrap .viewer-legend { display: none !important; }
    .viewer-panel .viewer-diff, .viewer-panel .viewer-cables, .viewer-panel .viewer-layers { margin: 4px 12px 0; padding-top: 6px; border-top: 1px solid var(--border-color); }
    .viewer-panel details.side-group > summary, .viewer-panel .viewer-layers > details > summary { padding: 4px 0; border: none; border-radius: 0; background: none; font-size: var(--fs-1); color: var(--text-secondary); }
}

@media (min-width: 1200px) and (min-height: 800px) {
    /* the narrow left column (D-2): the bill grid's number columns keep a fixed width and the name takes what is left;
       the sheet chips wrap into rows instead of running off; the device strip shows its rows; the cable detail scrolls sideways */
    #screenDashboard .boq-grid col.c-num { width: 88px; }
    #screenDashboard .boq-grid col.c-gap { width: 124px; }
    #screenDashboard .boq-grid { font-size: var(--fs-2); }
    #cableSection { overflow-x: auto; }
    #cableSection .cable-marks-table, #cableSection table { min-width: 660px; }
    /* the three per-sheet tables (cable · conduit · branches) one under another — side by side each got 230 px and the
       heads broke a letter a line */
    #screenDashboard .cable-marks-grid { grid-template-columns: 1fr; }
    #screenDashboard .cable-totals .length-row { grid-template-columns: 1fr 120px 130px; }
    #cableSection table th, #cableSection table td { white-space: nowrap; }
}

/* the split on a laptop (1200–1600 px): tighter tabs, a narrower legend */
@media (min-width: 1200px) and (min-height: 800px) and (max-width: 1600px) {
    .sheet-row { padding: 6px 8px 6px 9px; font-size: var(--fs-1); }
    #viewerWrap { grid-template-columns: 20px 132px minmax(0, 1fr) 196px; }
    #viewerWrap.has-wizard { grid-template-columns: 20px 132px minmax(0, 1fr) 196px 380px; }
    .viewer-panel .sym-row { padding: 4px 10px 4px 8px; font-size: var(--fs-1); }
    .viewer-panel .sym-row .sym-icon { width: 20px; height: 20px; }
}

/* D-3: the project list flat like the other pages */
@media (min-width: 900px) {
    #screenProjects.section { background: none; border: none; box-shadow: none; padding: 0; }
}

/* D-3: the home page flat like the discipline page — no page card, no card round the table, ring or chart */
@media (min-width: 900px) {
    #screenDisciplines.section { background: none; border: none; box-shadow: none; padding: 0; }
    #screenDisciplines .dash-card, #screenDisciplines .spec-donut { background: none; border: none; box-shadow: none; padding: 6px 0 0; border-radius: 0; }
    #screenDisciplines .table-container { background: none; border-radius: 0; }
    #screenDisciplines .dash-section { border-top: 1px solid var(--border-color); padding-top: 16px; margin: 14px 0 10px; }
    #screenDisciplines .dash-grid .dash-section, #screenDisciplines .dash-section:first-of-type { border-top: none; padding-top: 0; margin-top: 4px; }
    #screenDisciplines .dash-grid { align-items: start; }
    #screenDisciplines .fold-group { border-top: 1px solid var(--border-color); padding-top: 14px; }
}

/* 케이블 위치 (D-14): the cable's name and figures over the floor rail, its metres beside each floor, the rest dimmed */
.rail-cable { margin: 0 6px 8px; padding: 8px 8px 6px; border-radius: 8px; background: color-mix(in srgb, #5fa8ff 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #5fa8ff 45%, transparent); }
.rail-cable-name { display: flex; align-items: center; gap: 6px; font-size: var(--fs-1); font-weight: 700; color: var(--text-primary); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.rail-cable-name i { flex: none; width: 10px; height: 3px; border-radius: 2px; }
.rail-cable-sum { margin-top: 3px; font-size: var(--fs-1); font-variant-numeric: tabular-nums; color: var(--text-primary); }
.rail-cable-sum .hint { font-size: var(--fs-0); }
.rail-cable-else { margin-top: 2px; font-size: var(--fs-0); color: var(--text-secondary); }
.rail-cable-off { margin-top: 6px; padding: 2px 8px; border: 1px solid var(--border-strong); border-radius: 6px; background: none; color: var(--text-secondary); font: inherit; font-size: var(--fs-0); cursor: pointer; }
.rail-cable-off:hover { color: var(--text-primary); border-color: #5fa8ff; }
.sheet-row .rail-m { margin-left: auto; padding-left: 6px; flex: none; font-size: var(--fs-0); font-weight: 600; color: #8cc2ff; font-variant-numeric: tabular-nums; }
.sheet-row .rail-m.is-shaft { color: #4fc3e6; }
.sheet-index.has-cable .sheet-row.is-dim { opacity: 0.38; }
.mix-row.is-cable { cursor: pointer; border-radius: 4px; }
.mix-row.is-cable:hover { background: rgba(255, 255, 255, 0.04); }
.mix-row.is-cable:hover .mix-name { color: var(--text-primary); text-decoration: underline dotted; }
@media (max-width: 640px), (max-height: 500px) {
    /* D-3: the phone's opened quantities without boxes — a rule above each title */
    #screenDashboard .dash-headline, #screenDashboard .dash-hero .dash-boq, #screenDashboard .qty-pane, #screenDashboard .table-container,
    #screenDashboard #cableSection, #screenDashboard .dash-fold-card { background: none; border: none; box-shadow: none; border-radius: 0; padding-left: 0; padding-right: 0; }
    #screenDashboard > h3 { border-top: 1px solid var(--border-color); padding-top: 14px; margin-top: 14px; }
    #screenDashboard .dash-fold-card { border-top: 1px solid var(--border-color); margin: 0; }
    #screenDashboard .dash-fold-card > summary { padding: 12px 0; }
    #screenDashboard .boq-grid td.tot, #screenDashboard .boq-grid th.tot { background: none; }
    .topbar { gap: 10px; padding: 0 12px; }
    .topbar-brand { font-size: 0; }                          /* the logo stays, the word goes */
    .topbar-brand .topbar-logo { margin-right: 0; }
    .topbar-project { flex: 1 1 auto; min-width: 0; padding: 5px 8px; }
    .topbar-project-label, .topbar-updated, .topbar-upload, .topbar-spacer { display: none; }
    .topbar-select { min-width: 0; width: 100%; text-overflow: ellipsis; }
    .sidebar { padding: 0 8px; }
    .sidebar-row[data-id="all"] { display: none; }            /* no project page on a phone (V-6): the tabs are the disciplines */
    .main-content { padding: 14px 10px 32px; }
    .section { padding: 16px 14px; border-radius: 12px; }
    .title-meta, .project-header h2 .title-meta { display: block; margin: 4px 0 0; }        /* the counts under the project name, not broken beside it */

    /* home: 공종 · 대표 기기 · 케이블 · 도면대로 — the composition bar and the main cable are the desktop's extra */
    .discipline-table th.comp, .discipline-table td.comp, .discipline-table th.main-spec, .discipline-table td.main-spec { display: none; }
    .spec-donut { padding: 14px 12px; }
    .donut-legend li { grid-template-columns: 8px minmax(0, 1fr) 78px 36px; gap: 8px; }

    /* discipline: the quantity card */
    .dash-big { font-size: var(--fs-6); }
    .dash-big .dash-unit { font-size: var(--fs-4); }
    .dash-headline { padding: 14px 12px; }
    .dash-headline .mix-row, .mix-row, .floor-row { grid-template-columns: minmax(0, 1fr) 48px 78px 34px; gap: 8px; font-size: var(--fs-2); }

    /* the bill card: 합계 only (renderDashBoq drops the building groups on a phone); names may wrap */
    .boq-upload { display: none; }
    .boq-grid { font-size: var(--fs-1); }
    .boq-grid th, .boq-grid td { padding: 6px 4px; }
    .boq-grid col.c-num { width: 60px; }
    .boq-grid col.c-gap { width: 50px; }
    .boq-grid td.boq-name { white-space: normal; overflow-wrap: anywhere; font-size: var(--fs-1); }
    .boq-grid .gap-bar { display: none; }
    .boq-grid td.gap .boq-delta { min-width: 0; }

    /* 도면 모드 (V-3): on a phone the discipline page is the drawing. What a PC shows around it — the quantity cards,
       the tables, the checks — opens under it with 물량 · 확인 보기 (#screenDashboard.phone-show-all). */
    :root { --viewer-height: calc(100dvh - 172px); }
    .main-content:has(#screenDashboard:not([hidden])) { padding: 8px 6px 24px; }
    #screenDashboard { padding: 0; border: 0; background: none; box-shadow: none; }
    #screenDashboard:not(.phone-show-all) > :not(#viewerWrap):not(#phoneMoreBtn) { display: none !important; }
    .phone-more-btn { display: block; width: 100%; margin: 10px 0 4px; }
    .viewer-wrap { display: flex; flex-direction: column; gap: 0; margin: 0; position: relative; }
    .viewer-side { height: auto; order: 1; }
    .viewer-side .sheet-index, .viewer-side .viewer-scale, .viewer-op-tool, .viewer-print-btn, .viewer-print-menu,
    #viewerMeasurePanel, #runAssignPanel, #reviewPanel, #wizardPanel { display: none !important; }
    .phone-sheetbar { display: flex; gap: 8px; align-items: center; padding: 2px 0 8px; }
    .phone-sheet-select { flex: 1 1 auto; min-width: 0; padding: 9px 10px; font-size: var(--fs-3); font-weight: 600; font-family: inherit;
                          color: var(--text-primary); background: var(--bg-raised); border: 1px solid var(--border-strong); border-radius: 10px; }
    .phone-panel-btn { flex: none; padding: 9px 12px; font-size: var(--fs-2); font-weight: 600; font-family: inherit; color: var(--text-primary);
                       background: var(--bg-raised); border: 1px solid var(--border-strong); border-radius: 10px; }
    body.phone-panel-open .phone-panel-btn { background: var(--text-primary); color: var(--bg-base); }
    .viewer-canvas { border-radius: 10px; touch-action: none; }   /* the page must not scroll or zoom under a finger on the drawing */
    .viewer-toolbar { top: 58px; right: 8px; gap: 4px; }     /* under the sheet bar, on the drawing */
    .viewer-fs-btn { padding: 6px 8px; font-size: var(--fs-1); }
    .viewer-status { z-index: 6; }                              /* bottom-left of the drawing, as on a PC */
    .viewer-legend { position: absolute; top: 98px; left: 8px; max-width: 62%; min-width: 0; z-index: 5; }
    /* the device · cable · layer list: a panel from the bottom edge, over the drawing, half the screen at most */
    .viewer-panel { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; max-height: 58dvh; overflow-y: auto;
                    padding: 0 14px 18px; border-top: 1px solid var(--border-strong); border-radius: 16px 16px 0 0;
                    background: var(--bg-surface); box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.45);
                    transform: translateY(105%); transition: transform 0.2s ease; }
    body.phone-panel-open .viewer-panel { transform: none; }
    .phone-panel-head { display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; z-index: 1;
                        padding: 12px 0 8px; font-size: var(--fs-2); font-weight: 700; background: var(--bg-surface); }
    .viewer-wrap.is-fullscreen { padding: 8px; }
    .viewer-wrap.is-fullscreen .viewer-canvas { height: calc(100dvh - 76px); }

    /* V-8: the page is the drawing — no top bar (the logo on the tab row goes to the project list), the tab row at the top */
    .topbar { display: none; }
    .sidebar { top: 0; padding: 0 8px 0 4px; }
    .phone-home { display: flex; flex: none; align-items: center; padding: 0 8px 0 6px; height: 46px; }
    .phone-home img { height: 22px; width: auto; }
    :root { --viewer-height: calc(100dvh - 116px); }
    /* the toolbar as 42 px icon buttons (a finger, not a pointer); the label stays in the title */
    .viewer-fit-btn { display: inline-flex; }
    .viewer-collapse-btn { display: none !important; }   /* PC only: the phone has no columns to fold */
    .viewer-fs-btn { font-size: 0; width: 42px; height: 42px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; }
    .viewer-fs-btn::before { content: attr(data-ico); font-size: var(--fs-4); line-height: 1; }
    .viewer-toolbar { gap: 6px; }
}

/* a phone turned sideways (V-8): the tab row, then the drawing to the bottom edge; the sheet bar floats on the drawing */
@media (max-height: 500px) {
    :root { --viewer-height: calc(100dvh - 66px); }
    .phone-sheetbar { position: absolute; top: 6px; left: 6px; z-index: 8; width: min(52%, 340px); padding: 0; }
    .phone-sheet-select, .phone-panel-btn { padding: 7px 9px; font-size: var(--fs-2); background: rgba(28, 32, 40, 0.94); }
    .viewer-toolbar { top: 6px; }
    .viewer-legend { top: 56px; }
    .viewer-panel { left: auto; width: min(420px, 60vw); max-height: 88dvh; border-radius: 16px 0 0 0; }
}

/* U-126: what the bill card compares against — a settlement (accent) or the drawing's raw length (muted) */
.boq-basis { display: inline-block; margin-left: 10px; padding: 2px 9px; border-radius: 999px; font-size: var(--fs-1); line-height: 18px;
             color: var(--text-muted); background: var(--bg-raised); box-shadow: inset 0 0 0 1px var(--border-strong); white-space: nowrap; }
.boq-basis.is-settle { color: var(--text-primary); background: var(--accent-soft); box-shadow: none; }

/* Y-15: how a straight-measured cable was summed — one row per sheet and mark, the expression on its own line so it wraps in the narrow column */
.formula-list { display: flex; flex-direction: column; margin-top: 6px; }
.formula-row { padding: 8px 2px; border-bottom: 1px solid var(--border-color); }
.formula-row:last-child { border-bottom: none; }
.formula-head { color: var(--text-secondary); font-size: 13px; }
.formula-head b { color: var(--text-primary); }
.formula-expr { margin-top: 3px; font-size: 15px; color: var(--text-primary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
