/* CPRI application styles (Module 001).
   Kept minimal; layout and components come from the bundled Bootstrap 5. */

.cpri-body {
    background-color: var(--bs-body-bg);
}

.navbar-brand .text-info {
    letter-spacing: .2px;
}

main .card {
    transition: transform .12s ease-in-out;
}

main .card:hover {
    transform: translateY(-2px);
}

code {
    word-break: break-all;
}

/* ---- CarbonPlus PLS SEM — static model preview (v0.8.2) ----------------------
   The interactive canvas is deferred. This is a server-rendered SVG preview with no
   JavaScript, so there is nothing to load and nothing that can fail silently. */
/* The canvas is the primary surface: the side columns are given a readable fixed range so the
   variables panel stops clipping its dropdown, and everything left over goes to the canvas. */
.cpri-grid--model { display: grid; grid-template-columns: minmax(300px, 340px) minmax(0, 1fr) minmax(260px, 300px); gap: 1.25rem; align-items: start; }
@media (max-width: 1500px) { .cpri-grid--model { grid-template-columns: minmax(280px, 320px) minmax(0, 1fr); } }
@media (max-width: 1200px) { .cpri-grid--model { grid-template-columns: 1fr; } }

.pls-preview-frame { padding: .5rem; background: var(--cpri-surface, #fff); border-radius: 8px; }
/* The viewBox is computed server-side to frame the whole model, and
   preserveAspectRatio keeps it centred, so the model always fills the workspace. */
.pls-model-preview { display: block; width: 100%; height: clamp(520px, 66vh, 900px); }

.pls-preview-box { fill: var(--cpri-surface, #fff); stroke: var(--cpri-border, #9ca3af); stroke-width: 2; }
.pls-preview-head { fill: var(--cpri-accent-soft, #eef2ff); stroke: none; }
.pls-preview-node.is-reflective .pls-preview-box { stroke: var(--cpri-accent, #4338ca); }
.pls-preview-node.is-formative .pls-preview-box { stroke: var(--cpri-accent, #4338ca); stroke-width: 4; }
/* Mode-not-selected is signalled by a dashed border AND the label text, not colour. */
.pls-preview-node.is-unspecified .pls-preview-box { stroke-dasharray: 7 4; }

.pls-preview-name { font-size: 16px; font-weight: 600; fill: var(--cpri-text, #111827); }
.pls-preview-mode { font-size: 11px; fill: var(--cpri-text-muted, #6b7280); }
.pls-preview-indicator { fill: var(--cpri-surface, #fff); stroke: var(--cpri-border, #9ca3af); stroke-width: 1; }
.pls-preview-indicator-label { font-size: 12px; fill: var(--cpri-text, #111827); }

.pls-edge--structural { stroke: var(--cpri-accent, #4338ca); stroke-width: 3; fill: none; stroke-linecap: round; }
.pls-arrowhead--structural { fill: var(--cpri-accent, #4338ca); }

.cpri-scroll--tall { max-height: 20rem; overflow-y: auto; }

/* PLS008: emphasises a diagonal / own-construct cell without relying on colour alone. */
.cpri-cell-strong { font-weight: 700; text-decoration: underline; }

/* ==========================================================================
   PLS020 v0.21.2 — model canvas and result diagram
   The canvas is absolutely positioned HTML cards over an SVG line layer: the
   builder script drags ordinary elements, and SVG draws only the edges.
   ========================================================================== */

.pls-model-viewport {
    position: relative;
    overflow: auto;
    height: 620px;
    background:
        linear-gradient(90deg, rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0 / 40px 40px,
        linear-gradient(rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0 / 40px 40px;
    border-top: 1px solid rgba(0, 0, 0, .08);
}

.pls-model-scene {
    position: relative;
    width: 3000px;
    height: 2200px;
    transform-origin: 0 0;
}

/* The edge layer must never intercept a pointer: every drag begins on a card. */
.pls-model-edges {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.pls-model-edge { stroke: #334155; stroke-width: 2; }
.pls-model-arrowhead { fill: #334155; }

.pls-construct-card {
    position: absolute;
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
    overflow: hidden;
}

.pls-construct-card.is-dragging {
    box-shadow: 0 6px 18px rgba(0, 0, 0, .22);
    z-index: 20;
}

.pls-construct-card.is-selected { border-color: #2563eb; }

.pls-construct-drag-handle {
    cursor: grab;
    padding: .5rem .65rem;
    background: #eff6ff;
    border-bottom: 1px solid #dbeafe;
    font-weight: 600;
    /* A drag must never begin by selecting the label text. */
    user-select: none;
    touch-action: none;
}

.pls-construct-drag-handle:focus-visible { outline: 2px solid #2563eb; outline-offset: -2px; }
.pls-construct-card.is-dragging .pls-construct-drag-handle { cursor: grabbing; }

.pls-construct-meta { padding: .35rem .65rem; font-size: .78rem; color: #64748b; }

/* Many indicators must not make a card too tall to drag comfortably. */
.pls-construct-items {
    margin: 0;
    padding: 0 .65rem .5rem 1.4rem;
    max-height: 168px;
    overflow-y: auto;
    font-size: .78rem;
}

.pls-construct-empty { padding: 0 .65rem .5rem; font-size: .78rem; color: #94a3b8; }

.cpri-canvas-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    align-items: center;
    margin-bottom: .5rem;
}

.cpri-list-plain { list-style: none; margin: 0; padding: 0; }
.cpri-list-plain > li { margin-bottom: .35rem; font-size: .82rem; }

.cpri-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

/* Result diagram: read-only, server-rendered, scales to its container. */
.pls-result-figure { width: 100%; height: auto; display: block; }
.pls-result-construct { fill: #eff6ff; stroke: #1d4ed8; stroke-width: 2; }
.pls-result-construct-label { font-size: 13px; font-weight: 600; fill: #0f172a; }
.pls-result-r2 { font-size: 12px; fill: #1d4ed8; font-weight: 600; }
.pls-result-path { stroke: #334155; stroke-width: 2; fill: none; }
.pls-result-path-label { font-size: 11px; fill: #0f172a; font-weight: 600; }
.pls-result-arrowhead { fill: #334155; }
.pls-result-indicator { fill: #fff; stroke: #94a3b8; stroke-width: 1; }
.pls-result-indicator-label { font-size: 10px; fill: #334155; }
.pls-result-measure { stroke: #94a3b8; stroke-width: 1; }
.pls-result-loading { font-size: 9px; fill: #64748b; }

/* Card width lives here, not inline: the only inline style on a card is its position, so a
   coordinate is the single thing the drag engine ever writes into markup. */
/* v0.21.5: information cards are no longer the notation. Kept only so any residual
   markup degrades gracefully rather than overlapping the diagram. */
.pls-construct-card { width: 230px; }
/* Mode is carried by a border treatment AND the label text, never colour alone. */
.pls-construct-card.is-formative .pls-construct-drag-handle { border-bottom-width: 3px; }
.pls-construct-card.is-unspecified { border-style: dashed; }

/* Prepared variables: a compact stacked row rather than a spreadsheet in a sidebar, so nothing
   clips and no horizontal scrolling is needed. */
.pls-var-cell { display: flex; flex-direction: column; gap: .1rem; }
.pls-var-name { font-weight: 600; }
.pls-var-meta { font-size: .72rem; color: #64748b; }
.pls-var-owner { font-size: .74rem; color: #1d4ed8; font-weight: 600; }
tr[data-pls-eligible="0"] .pls-var-name { color: #94a3b8; font-weight: 500; }
/* The destination selector must show a full construct name, never a truncated one. */
#pls-bulk-form .cpri-select, #bulk-construct { width: 100%; max-width: 100%; }

/* Model editor tool modes. The cursor differs per mode so the pointer states what it will do. */
.pls-model-scene[data-pls-active-tool="connect"] { cursor: crosshair; }
.pls-model-scene[data-pls-active-tool="delete"] { cursor: not-allowed; }
.pls-model-scene[data-pls-active-tool="add"] { cursor: copy; }

/* A 2px line cannot be clicked reliably, so a wide transparent line takes the hit. */
.pls-model-edge-hit { stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }
.pls-model-edges { pointer-events: none; }
.pls-model-edge-hit, .pls-model-edge { pointer-events: stroke; }
.pls-model-edge.is-selected { stroke: #2563eb; stroke-width: 3.5; }
.pls-model-edge-preview { stroke: #2563eb; stroke-width: 2; stroke-dasharray: 6 4; pointer-events: none; }

.pls-construct-card.is-connect-source { outline: 2px solid #2563eb; outline-offset: 2px; }
.pls-construct-card.is-connect-target { outline: 2px dashed #2563eb; outline-offset: 2px; }

.pls-model-properties {
    border-top: 1px solid rgba(0, 0, 0, .08);
    padding: .65rem .9rem;
    background: #f8fafc;
    font-size: .82rem;
}
.pls-model-properties p { margin: 0 0 .3rem; }
.cpri-btn--danger { background: #b91c1c; color: #fff; border-color: #991b1b; }

/* ==========================================================================
   PLS020 v0.21.5 — professional SEM notation
   A latent construct is a compact circle with its name beneath it; each
   assigned indicator is a separate rectangle placed beside it. Indicators are
   siblings in the scene, never content inside the construct.
   ========================================================================== */

.pls-latent-node {
    position: absolute;
    width: 132px;
    margin-left: -66px;               /* the stored coordinate is the node CENTRE */
    margin-top: -46px;
    text-align: center;
    z-index: 3;
}

.pls-latent-circle {
    width: 92px;
    height: 92px;
    margin: 0 auto;
    border-radius: 50%;
    background: #eff6ff;
    border: 2px solid #1d4ed8;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    user-select: none;
    touch-action: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}

.pls-latent-circle:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }
.pls-latent-node.is-dragging .pls-latent-circle { cursor: grabbing; box-shadow: 0 6px 16px rgba(0, 0, 0, .25); }
.pls-latent-node.is-selected .pls-latent-circle { border-width: 4px; }

/* Mode is carried by the border treatment AND the badge letter, never colour alone. */
.pls-latent-node.is-formative .pls-latent-circle { border-style: double; border-width: 4px; }
.pls-latent-node.is-unspecified .pls-latent-circle { border-style: dashed; }
.pls-latent-node.is-hoc .pls-latent-circle { border-width: 3px; background: #eef2ff; }

.pls-latent-badge { font-size: .8rem; font-weight: 700; color: #1d4ed8; }
.pls-latent-label { margin-top: .3rem; font-size: .8rem; font-weight: 600; color: #0f172a; }
.pls-latent-warning { font-size: .68rem; color: #b45309; }

.pls-latent-node.is-connect-source .pls-latent-circle { outline: 3px solid #2563eb; outline-offset: 3px; }
.pls-latent-node.is-connect-target .pls-latent-circle { outline: 3px dashed #2563eb; outline-offset: 3px; }
.pls-latent-node.is-drop-target .pls-latent-circle { outline: 3px solid #15803d; outline-offset: 4px; }

/* Separate indicator rectangles. */
.pls-indicator-node {
    position: absolute;
    width: 74px;
    height: 22px;
    margin-top: -11px;
    line-height: 20px;
    text-align: center;
    font-size: .68rem;
    background: #fff;
    border: 1px solid #64748b;
    border-radius: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    z-index: 2;
}

.pls-model-measures {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
}

.pls-model-measure-line { stroke: #94a3b8; stroke-width: 1.4; }
.pls-model-measure-arrow { fill: #94a3b8; }

/* Drag-and-drop from the indicator palette. */
.pls-var-name[draggable="true"] { cursor: grab; }
.pls-model-viewport.is-drop-active { outline: 2px dashed #15803d; outline-offset: -4px; }
.pls-drag-ghost {
    position: fixed;
    pointer-events: none;
    background: #0f172a;
    color: #fff;
    font-size: .72rem;
    padding: .2rem .45rem;
    border-radius: 3px;
    z-index: 2000;
}

/* Click-to-place and drop dialogs. */
.pls-canvas-dialog {
    position: absolute;
    z-index: 50;
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .2);
    padding: .75rem;
    width: 260px;
}
.pls-canvas-dialog h3 { font-size: .85rem; margin: 0 0 .4rem; }


/* ==========================================================================
   Rebuilt model canvas — one SVG world.
   ========================================================================== */

svg.pls-model-viewport {
    display: block;
    width: 100%;
    height: 620px;
    background:
        linear-gradient(90deg, rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0 / 40px 40px,
        linear-gradient(rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0 / 40px 40px;
    border-top: 1px solid rgba(0, 0, 0, .08);
    touch-action: none;
}

.pls-latent-node .pls-latent-circle {
    fill: #eff6ff;
    stroke: #1d4ed8;
    stroke-width: 2;
    cursor: grab;
}
.pls-latent-node.is-dragging .pls-latent-circle { cursor: grabbing; }
.pls-latent-node.is-selected .pls-latent-circle { stroke-width: 4; }
.pls-latent-node.is-formative .pls-latent-circle { stroke-width: 4; stroke-dasharray: none; }
.pls-latent-node.is-unspecified .pls-latent-circle { stroke-dasharray: 6 4; }
.pls-latent-node.is-hoc .pls-latent-circle { fill: #eef2ff; stroke-width: 3; }
.pls-latent-node.is-connect-source .pls-latent-circle { stroke: #2563eb; stroke-width: 5; }
.pls-latent-node.is-connect-target .pls-latent-circle { stroke: #2563eb; stroke-dasharray: 5 3; stroke-width: 4; }
.pls-latent-node.is-drop-target .pls-latent-circle { stroke: #15803d; stroke-width: 5; }
.pls-latent-circle:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }

text.pls-latent-badge { font-size: 13px; font-weight: 700; fill: #1d4ed8; }
text.pls-latent-label { font-size: 13px; font-weight: 600; fill: #0f172a; }
text.pls-latent-warning { font-size: 10px; fill: #b45309; }

.pls-indicator-box { fill: #fff; stroke: #64748b; stroke-width: 1; }
text.pls-indicator-text { font-size: 10px; fill: #334155; }

/* CarbonPlus MCDM — table-driven setup. */
.cpri-input--tiny { width: 5.5rem; display: inline-block; }
.cpri-grid--two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; }
@media (max-width: 1100px) { .cpri-grid--two { grid-template-columns: 1fr; } }

/* CarbonPlus MCDM — matrices and the cause-effect map. */
.mcdm-matrix th[scope="row"] { font-weight: 600; background: #f8fafc; }
.mcdm-matrix td.is-diagonal { background: #e2e8f0; text-align: center; color: #64748b; }
.cpri-input--cell { width: 3.4rem; text-align: center; padding: .15rem .2rem; }
.mcdm-map { width: 100%; height: auto; display: block; }
.mcdm-axis { stroke: #94a3b8; stroke-width: 1.2; }
text.mcdm-axis-label { font-size: 12px; fill: #475569; }
.mcdm-point { fill: #bfdbfe; stroke: #1d4ed8; stroke-width: 2; }
.mcdm-point.is-cause { fill: #bbf7d0; stroke: #15803d; }
.mcdm-point.is-effect { fill: #e2e8f0; stroke: #475569; }
text.mcdm-point-label { font-size: 12px; font-weight: 600; fill: #0f172a; }
.cpri-facts dt { font-weight: 600; font-size: .8rem; margin-top: .35rem; }
.cpri-facts dd { margin: 0 0 .2rem; font-size: .78rem; }
tr.is-current { background: #eff6ff; }
.cpri-nowrap { white-space: nowrap; }

/* CarbonPlus MCDM — cause-effect relationship map. */
.mcdm-ce-map { width: 100%; height: auto; display: block; background: #fff; }
.mcdm-ce-bg { fill: #ffffff; }
.mcdm-ce-grid { stroke: #e2e8f0; stroke-width: 1; }
.mcdm-ce-axis { stroke: #475569; stroke-width: 1.5; }
.mcdm-ce-zero { stroke: #0f172a; stroke-width: 2.4; }
.mcdm-ce-mean { stroke: #0f172a; stroke-width: 2.4; stroke-dasharray: 8 5; }
text.mcdm-ce-tick { font-size: 11px; fill: #64748b; }
text.mcdm-ce-axis-title { font-size: 14px; font-weight: 600; fill: #0f172a; }
text.mcdm-ce-refline-label { font-size: 11px; font-weight: 600; fill: #0f172a; }
text.mcdm-ce-quadrant { font-size: 10px; fill: #94a3b8; }
text.mcdm-ce-label { font-size: 12px; font-weight: 700; fill: #0f172a; }
text.mcdm-ce-legend-text { font-size: 12px; fill: #334155; }
.mcdm-ce-marker.is-cause, .mcdm-ce-swatch.is-cause { fill: #bbf7d0; stroke: #15803d; stroke-width: 2; }
.mcdm-ce-marker.is-effect, .mcdm-ce-swatch.is-effect { fill: #dbeafe; stroke: #1d4ed8; stroke-width: 2; }
.mcdm-ce-marker.is-neutral, .mcdm-ce-swatch.is-neutral { fill: #e2e8f0; stroke: #475569; stroke-width: 2; }
.cpri-select--cell { width: 4.6rem; padding: .1rem .2rem; font-size: .75rem; }
.cpri-checkbox { display: inline-flex; align-items: center; gap: .3rem; margin-right: .8rem; font-size: .8rem; }
