/*
 * Custom CSS
 * Project-specific styles only - use Bootstrap utilities for layout/spacing.
 */

/* Example: Custom color overrides */
:root {
    --bs-primary: #0d6efd;
}

/* Example: Form feedback spacing */
.invalid-feedback {
    display: block;
}

/* Example: Card hover effect */
.card-hover:hover {
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    transition: box-shadow 0.2s ease;
}

/* ==========================================================================
   PROJ-1: Token visualization
   Project-specific styles for the colored token chips. Bootstrap has no
   multi-color badge palette, so a custom 8-color set is defined here.
   ========================================================================== */

#token-output {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    max-height: 320px;
    overflow-y: auto;
}

.token-badge {
    display: inline-block;
    padding: 0.3rem 0.55rem;
    border-radius: 0.4rem;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.875rem;
    line-height: 1.2;
    color: #1a1a1a;
    white-space: pre-wrap;
    word-break: break-word;
    border: 1px solid rgba(0, 0, 0, 0.12);
}

/* ==========================================================================
   PROJ-2: Temperature slider (mobile fix)
   On Android Chrome a horizontal drag on the range thumb can be hijacked by
   page scrolling, leaving the value stuck at the default. Letting the browser
   keep the slider gesture (no double-tap-zoom delay) makes dragging reliable
   on touch devices.
   ========================================================================== */
#temperature-slider {
    touch-action: manipulation;
}

/* ==========================================================================
   PROJ-5: Explanations & tooltips
   A single attribute on <body> toggles ALL "?" help icons at once. No JS
   loop required — one CSS rule hides every .explanation-trigger instantly.
   ========================================================================== */

/* "?" help icon button — looks like an inline icon, behaves like a button. */
.explanation-trigger {
    border: 0;
    background: transparent;
    padding: 0 0.15rem;
    color: var(--bs-secondary, #6c757d);
    line-height: 1;
    cursor: pointer;
    vertical-align: baseline;
}

.explanation-trigger:hover,
.explanation-trigger:focus-visible {
    color: var(--bs-primary, #0d6efd);
}

/* Toggle OFF: hide every help icon at once via the body attribute. */
body[data-explanations="off"] .explanation-trigger {
    display: none;
}

/* Inline glossary terms get a subtle dotted underline to signal "hover me".
   Always visible (not affected by the toggle) — terms must remain readable. */
.glossary-term {
    border-bottom: 1px dotted currentColor;
    cursor: help;
}

/* Keep long popover/tooltip text inside the viewport on small screens. */
.popover {
    max-width: 320px;
}

/* 8-color fixed palette - chosen for readability with dark text. */
.token-c0 { background-color: #ffd6a5; }
.token-c1 { background-color: #caffbf; }
.token-c2 { background-color: #9bf6ff; }
.token-c3 { background-color: #bdb2ff; }
.token-c4 { background-color: #ffc6ff; }
.token-c5 { background-color: #fdffb6; }
.token-c6 { background-color: #a0c4ff; }
.token-c7 { background-color: #ffadad; }

/* ============================================================== */
/* PROJ-11: Context Window Visualizer                             */
/* ============================================================== */

/* Segmented context bar. Bootstrap .progress + .progress-bar handle
   the structure; these only set the segment colours + overflow state. */
.ctx-seg-system  { background-color: #0d6efd; }   /* blue  - system */
.ctx-seg-history { background-color: #198754; }   /* green - history */
.ctx-seg-current { background-color: #fd7e14; }   /* orange - current */
.ctx-seg-free    { background-color: #adb5bd; }   /* grey  - free */

.ctx-progress.ctx-progress-overflow {
    outline: 2px solid var(--bs-danger, #dc3545);
}
.ctx-progress.ctx-progress-overflow .progress-bar { filter: saturate(1.4); }

/* Legend colour swatches. */
.ctx-swatch {
    display: inline-block;
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 2px;
    vertical-align: -1px;
    margin-right: 0.25rem;
}

/* Conversation turn enter / drop animations. */
.ctx-turn-text { word-break: break-word; }
.ctx-turn-enter { animation: ctx-turn-in 0.35s ease-out; }
@keyframes ctx-turn-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.ctx-turn-dropped {
    opacity: 0.45;
    text-decoration: line-through;
    transition: opacity 0.3s ease;
}

/* "How to read this chart" details panel. */
.ctx-heat-howto {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
    background-color: var(--bs-light, #f8f9fa);
}
.ctx-heat-howto > summary {
    cursor: pointer;
    user-select: none;
    list-style: revert;        /* keep the disclosure triangle visible */
}
.ctx-heat-howto[open] > summary { margin-bottom: 0.25rem; }

/* "show more / show less" link in conversation thread. */
.ctx-turn-toggle {
    font-size: 0.85rem;
    text-decoration: underline;
}

/* ---- Heatmap (CSS grid, no chart library) ---- */
.ctx-heat-grid-scroll { overflow-x: auto; }

.ctx-heat-grid {
    position: relative;
    display: grid;
    grid-template-columns: max-content repeat(var(--ctx-cols, 6), minmax(56px, 1fr));
    gap: 2px;
    min-width: 420px;
}

.ctx-heat-corner,
.ctx-heat-colhead,
.ctx-heat-rowhead {
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0.4rem 0.5rem;
    background-color: var(--bs-light, #f8f9fa);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}
.ctx-heat-rowhead { justify-content: flex-end; white-space: nowrap; }

/* Highlight the row that matches the selected model's context limit. */
.ctx-heat-rowhead-limit {
    background-color: var(--bs-warning-bg-subtle, #fff3cd);
    color: var(--bs-warning-text-emphasis, #664d03);
    border-left: 3px solid var(--bs-warning, #ffc107);
}
.ctx-heat-cell-limit {
    outline: 1px dashed rgba(0, 0, 0, 0.55);
    outline-offset: -2px;
}
/* Interpolated (estimated) cells get a subtle diagonal stripe overlay so the
   user can tell they are not part of the published benchmark data. */
.ctx-heat-cell-est {
    background-image: linear-gradient(
        135deg,
        rgba(255, 255, 255, 0.18) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.18) 50%,
        rgba(255, 255, 255, 0.18) 75%,
        transparent 75%,
        transparent
    );
    background-size: 8px 8px;
    background-blend-mode: overlay;
}

.ctx-heat-cell {
    min-height: 2.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 600;
    color: #1b1b1b;
    cursor: pointer;
    border-radius: 2px;
    transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.ctx-heat-cell:hover,
.ctx-heat-cell:focus-visible {
    transform: scale(1.05);
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.35);
    outline: none;
    z-index: 2;
}
.ctx-heat-cell-selected {
    box-shadow: 0 0 0 3px var(--bs-dark, #212529);
    z-index: 3;
}
.ctx-heat-cell-na {
    background-color: #e9ecef;
    color: #adb5bd;
    cursor: not-allowed;
}

/* Colour scale legend bar. */
.ctx-heat-scale {
    display: inline-block;
    width: 160px;
    height: 0.85rem;
    border-radius: 3px;
    background: linear-gradient(
        to right,
        hsl(0, 75%, 55%),
        hsl(55, 75%, 55%),
        hsl(130, 75%, 55%)
    );
}

/* "You are here" horizontal marker overlaying the grid. */
.ctx-heat-youarehere {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 2px dashed var(--bs-dark, #212529);
    pointer-events: none;
    z-index: 4;
}
.ctx-heat-youarehere-label {
    position: absolute;
    right: 0;
    top: -0.7rem;
    background: var(--bs-dark, #212529);
    color: #fff;
    font-size: 0.7rem;
    line-height: 1.2;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    white-space: nowrap;
}

/* ==========================================================================
   PROJ-8: System Prompts Demo
   Project-specific styles for the LLM response panels and the JSON
   transparency view. Bootstrap covers cards / spinners / alerts already.
   ========================================================================== */

/* LLM response body: preserve whitespace + wrap long lines (no horizontal
   scroll). Inherits Bootstrap's <pre> reset but adds readability tweaks. */
.sp-response-text {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: var(--bs-font-sans-serif, sans-serif);
    font-size: 0.95rem;
    line-height: 1.5;
    margin: 0;
    color: var(--bs-body-color, #212529);
    background: transparent;
}

/* JSON preview in the collapsible transparency panel: monospace, soft
   background, capped height with scroll for very long prompts. */
.sp-json-preview {
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.75rem 1rem;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.8125rem;
    line-height: 1.4;
    max-height: 320px;
    overflow: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    color: var(--bs-body-color, #212529);
}

/* ==========================================================================
   PROJ-9: Function Calling Demo
   Stage-based cards reveal sequentially. Each stage is a Bootstrap card.
   JSON blocks reuse the .sp-json-preview look-and-feel via .fc-json.
   ========================================================================== */

/* Active tool-schema JSON block — visible at all times, updates live. */
.fc-json {
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.75rem 1rem;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.8125rem;
    line-height: 1.4;
    max-height: 280px;
    overflow: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    color: var(--bs-body-color, #212529);
    margin: 0;
}

/* Highlighted tool_calls JSON in stage 2 — visually distinct from
   the plain request JSON so the user immediately spots the tool call. */
.fc-json-toolcall {
    background: #fff5e1;
    border-color: #fd7e14;
    color: #5a3a00;
}

/* Stage card: subtle left border in the stage's accent colour so the
   linear flow (1 -> 2 -> 3 -> 4) reads at a glance. */
.fc-stage { border-left: 4px solid transparent; }
.fc-stage-1 { border-left-color: #0d6efd; }
.fc-stage-2 { border-left-color: #fd7e14; }
.fc-stage-3 { border-left-color: #6f42c1; }
.fc-stage-4 { border-left-color: #198754; }

/* Hidden stages stay collapsed (display:none); JS toggles .fc-stage-hidden. */
.fc-stage-hidden { display: none; }

/* Follow-up "round" cards (multi-step / recursive tool calls). Shares the
   stage-3 purple accent so the chain of rounds reads as one continuous
   loop, but a slightly tinted background separates each round visually. */
.fc-stage-round {
    background-color: #faf7ff;
}

/* Final LLM answer body — same readability tweaks as PROJ-8 .sp-response-text. */
.fc-answer-text {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: var(--bs-font-sans-serif, sans-serif);
    font-size: 0.95rem;
    line-height: 1.5;
    margin: 0;
    color: var(--bs-body-color, #212529);
    background: transparent;
}

/* Inline parameter row inside the custom-tool form. Bootstrap grid + flex
   handle most of it; this just keeps each row's "remove" button aligned. */
.fc-param-row .fc-param-remove {
    white-space: nowrap;
}

/* Compact close button used inside the active-tool badges. Bootstrap's
   default .btn-close is sized for modals/alerts — shrink it so it sits
   comfortably next to the tool name inside a small badge. */
.fc-active-tool-close {
    width: 0.55rem;
    height: 0.55rem;
    padding: 0.35rem;
    background-size: 0.6em;
    opacity: 0.6;
}
.fc-active-tool-close:hover {
    opacity: 1;
}

/* ==========================================================================
   PROJ-10: Temperature & Sampling Visualizer
   Custom styles for the live probability bars and logits table. Bootstrap
   covers cards / spinners / buttons / form-range already.
   ========================================================================== */

/* Container for the live bar list. Each bar is a flex row: token | bar | %. */
#tmp-bars-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* One probability row. Grid layout keeps token label, bar and percentage
   aligned even when the token text is very wide or empty. */
.tmp-bar-row {
    display: grid;
    grid-template-columns: minmax(4rem, 9rem) 1fr minmax(3.5rem, 4.5rem);
    align-items: center;
    column-gap: 0.75rem;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.875rem;
}

/* Token label cell — preserve whitespace so a space token reads visually
   (rendered as the middle-dot for clarity in the .tmp-token-display span). */
.tmp-bar-token {
    white-space: pre;
    overflow: hidden;
    text-overflow: ellipsis;
    direction: ltr;
}

/* Bar track + fill: Bootstrap's progress component would work but the
   single-line width here is dynamic per row, so a simple div pair is leaner. */
.tmp-bar-track {
    background: var(--bs-light, #f0f1f3);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    height: 1.5rem;
    overflow: hidden;
    position: relative;
}

.tmp-bar-fill {
    background: linear-gradient(90deg, #0d6efd 0%, #6610f2 100%);
    height: 100%;
    width: 0%;
    /* Smooth slider response — feels responsive but not jumpy. */
    transition: width 180ms ease-out;
}

/* Highlight the winning (most-likely) token so users see the greedy
   choice instantly even when the bar is tiny. */
.tmp-bar-row-winner .tmp-bar-fill {
    background: linear-gradient(90deg, #198754 0%, #20c997 100%);
}

.tmp-bar-pct {
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--bs-secondary-color, #6c757d);
}

/* Logits table — narrower font, tabular numerals so columns align cleanly. */
.tmp-logits-table {
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.tmp-logits-table th { font-weight: 600; }

.tmp-logits-table td.tmp-logit-token,
.tmp-logits-table th.tmp-logit-token {
    font-family: var(--bs-font-monospace, monospace);
}

/* Generated text output — same readability tweaks as PROJ-8 / PROJ-9. */
.tmp-generated-text {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: var(--bs-font-sans-serif, sans-serif);
    font-size: 0.95rem;
    line-height: 1.5;
    margin: 0;
    color: var(--bs-body-color, #212529);
    background: transparent;
}

/* Softmax formula block — display math style. */
.tmp-formula {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 1rem;
    text-align: center;
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.9rem 1rem;
    margin: 0;
    overflow-x: auto;
}

/* ============================================================== */
/* PROJ-12: RAG Demo — 5-step walkthrough + 2D scatter plot       */
/* ============================================================== */

/* --- Stepper ---------------------------------------------------- */
.rag-stepper {
    margin: 0;
    padding: 0;
}

.rag-step {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.7rem;
    border-radius: 999px;
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    color: var(--bs-secondary, #6c757d);
    font-size: 0.875rem;
    white-space: nowrap;
}

.rag-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--bs-secondary, #6c757d);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
}

.rag-step-active {
    background: var(--bs-primary, #0d6efd);
    color: #fff;
    border-color: var(--bs-primary, #0d6efd);
}

.rag-step-active .rag-step-num {
    background: #fff;
    color: var(--bs-primary, #0d6efd);
}

.rag-step-done {
    background: #d1e7dd;
    color: #0a3622;
    border-color: #a3cfbb;
}

.rag-step-done .rag-step-num {
    background: var(--bs-success, #198754);
    color: #fff;
}

/* --- Doc cards & badges ----------------------------------------- */
.rag-doc-color-badge {
    font-weight: 600;
    color: #fff;
}

.rag-doc-dot {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    margin-right: 0.3rem;
    vertical-align: middle;
}

/* --- Chunking preview ------------------------------------------- */
.rag-chunked-doc {
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    padding-bottom: 0.6rem;
}

.rag-chunked-doc:last-child {
    border-bottom: none;
}

.rag-chunk-stack {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.rag-chunk-pill {
    display: inline-block;
    padding: 0.25rem 0.5rem;
    border-radius: 0.4rem;
    background: #ffffff;
    border: 2px solid #ccc;
    font-size: 0.825rem;
    line-height: 1.35;
    color: #212529;
    max-width: 100%;
    word-wrap: break-word;
}

/* --- Vectors list (step 3) -------------------------------------- */
.rag-vectors-list {
    max-height: 360px;
    overflow-y: auto;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.5rem;
    background: var(--bs-light, #f8f9fa);
}

.rag-vector-row {
    padding: 0.45rem 0.5rem;
    border-bottom: 1px dashed #dee2e6;
}

.rag-vector-row:last-child {
    border-bottom: none;
}

.rag-vector-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rag-vector-numbers {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.75rem;
    word-break: break-all;
    white-space: normal;
}

/* --- Canvas scatter plot ---------------------------------------- */
.rag-plot-wrapper {
    position: relative;
    width: 100%;
    height: 340px;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    background: #ffffff;
    overflow: hidden;
}

.rag-plot-wrapper canvas {
    width: 100%;
    height: 100%;
    display: block;
}

/* --- three.js host: the renderer creates its own <canvas> inside ---- */
.rag-three-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* The OrbitControls fallback (mouse drag) needs the host to
       receive pointer events even though it's transparent. */
    cursor: grab;
    touch-action: none;
}

.rag-three-canvas:active {
    cursor: grabbing;
}

/* Slight gradient background so the 3D space reads as "depth" rather
   than a flat page background. */
.rag-plot-3d {
    background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
}

.rag-3d-hint {
    position: absolute;
    bottom: 6px;
    right: 8px;
    color: var(--bs-secondary, #6c757d);
    background: rgba(255, 255, 255, 0.7);
    padding: 1px 6px;
    border-radius: 0.25rem;
    pointer-events: none;
    font-size: 0.7rem;
}

.rag-tooltip {
    position: absolute;
    pointer-events: none;
    background: rgba(33, 37, 41, 0.92);
    color: #fff;
    font-size: 0.75rem;
    padding: 0.3rem 0.5rem;
    border-radius: 0.25rem;
    max-width: 240px;
    z-index: 10;
    line-height: 1.3;
}

/* --- Retrieval result cards ------------------------------------- */
.rag-result-card {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-left-width: 4px;
    border-radius: 0.375rem;
    padding: 0.55rem 0.7rem;
    background: #fff;
}

/* --- JSON preview (augmented prompt) ---------------------------- */
.rag-json-preview {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.8rem;
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.6rem 0.8rem;
    margin: 0;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 320px;
    overflow-y: auto;
}

/* --- LLM response panels (mirrors PROJ-8) ----------------------- */
.rag-response-text {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: var(--bs-font-sans-serif, sans-serif);
    font-size: 0.95rem;
    line-height: 1.5;
    margin: 0;
    color: var(--bs-body-color, #212529);
    background: transparent;
}

/* ==================================================================== */
/*  PROJ-13: AI Watermarking demo                                       */
/* ==================================================================== */

/* --- The two colour schemes -------------------------------------------
   The whole feature hangs on one colour distinction, and red-vs-green is
   the worst possible pair for it: roughly 8 % of men cannot separate the
   two reliably. The literature calls the lists "green" and "red", so the
   TERMS stay and only the COLOURS become switchable.

   Scheme 2 uses the Okabe-Ito blue/orange pair, which stays separable
   under all three common forms of colour vision deficiency because the
   tones also differ clearly in lightness. Contrast values are computed
   against WCAG 2.1.

   Colour is never the only carrier: every tile also gets a symbol
   (.wm-tile-sym) and a border style (solid vs dashed). */

.wm-scheme-classic {
    --wm-green-bg:     #D1E7DD;   /* vs. #0A3622 ~ 10.4:1 */
    --wm-green-fg:     #0A3622;
    --wm-green-line:   #0A3622;
    --wm-green-strong: #198754;   /* bars + curves, no text on top */
    --wm-red-bg:       #F8D7DA;   /* vs. #58151C ~ 10.2:1 */
    --wm-red-fg:       #58151C;
    --wm-red-line:     #58151C;
    --wm-red-strong:   #B02A37;
}

.wm-scheme-contrast {
    --wm-green-bg:     #CFE2FF;   /* vs. #052C65 ~ 10.3:1 */
    --wm-green-fg:     #052C65;
    --wm-green-line:   #052C65;
    --wm-green-strong: #0072B2;   /* ~5.2:1 vs. white */
    --wm-red-bg:       #FFE5D0;   /* vs. #663300 ~ 8.5:1 */
    --wm-red-fg:       #663300;
    --wm-red-line:     #663300;
    --wm-red-strong:   #D55E00;   /* ~3.9:1 vs. white */
}

/* --- Step indicator ---------------------------------------------- */
.wm-stepper {
    margin: 0;
    padding: 0;
}

.wm-step {
    border-radius: 999px;
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    overflow: hidden;
}

.wm-step-btn {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    background: transparent;
    border: 0;
    color: var(--bs-secondary, #6c757d);
    font-size: 0.875rem;
    white-space: nowrap;
}

.wm-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--bs-secondary, #6c757d);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
}

.wm-step-active {
    background: var(--bs-primary, #0d6efd);
    border-color: var(--bs-primary, #0d6efd);
}

.wm-step-active .wm-step-btn {
    color: #fff;
}

.wm-step-active .wm-step-num {
    background: #fff;
    color: var(--bs-primary, #0d6efd);
}

/* --- Vocabulary grid (step 1) ------------------------------------ */
.wm-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.wm-tile {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.5rem;
    border-radius: 0.35rem;
    font-size: 0.875rem;
    line-height: 1.3;
    transition: background-color 0.18s ease, border-color 0.18s ease;
}

.wm-tile-green {
    background: var(--wm-green-bg);
    color: var(--wm-green-fg);
    border: 2px solid var(--wm-green-line);   /* solid = green list */
}

.wm-tile-red {
    background: var(--wm-red-bg);
    color: var(--wm-red-fg);
    border: 2px dashed var(--wm-red-line);    /* dashed = red list */
}

/* The symbol carries the same information as the colour, so the grid
   still reads correctly in greyscale, on a printout or on a badly
   calibrated projector. */
.wm-tile-sym {
    font-size: 0.7rem;
    line-height: 1;
}

/* Every tile that changed sides gets a subtle ring. With gamma 0.5 that is
   roughly half the grid, so this must stay quiet enough not to drown the
   colours it is meant to annotate. */
.wm-tile-flip {
    outline: 2px dotted var(--bs-secondary, #6c757d);
    outline-offset: 2px;
}

/* The one tile named in the sentence below the grid - the one to point at
   when explaining that the colouring is contextual. */
.wm-tile-flip-pick {
    outline: 3px solid var(--bs-warning, #ffc107);
    outline-offset: 2px;
    font-weight: 600;
}

/* --- Token flow (steps 2-5) -------------------------------------- */
.wm-tokens {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 3px;
    align-items: baseline;
    line-height: 1.9;
}

.wm-token {
    padding: 0.05rem 0.3rem;
    border-radius: 0.25rem;
    font-size: 0.95rem;
    border: 1px solid transparent;
    white-space: pre-wrap;
}

.wm-token-green {
    background: var(--wm-green-bg);
    color: var(--wm-green-fg);
    border-color: var(--wm-green-line);
    border-style: solid;
}

.wm-token-red {
    background: var(--wm-red-bg);
    color: var(--wm-red-fg);
    border-color: var(--wm-red-line);
    border-style: dashed;
}

/* Punctuation and the first h tokens carry no colour: there is no
   context to hash yet, so they are not scored either. */
.wm-token-neutral {
    color: var(--bs-secondary, #6c757d);
    background: transparent;
}

.wm-token-prompt {
    background: var(--bs-light, #f8f9fa);
    color: var(--bs-secondary-color, #6c757d);
    border-color: var(--bs-border-color, #dee2e6);
    border-style: dotted;
}

.wm-token-current {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: 1px;
}

/* --- Distribution bars (step 2) ---------------------------------- */
.wm-dist {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-height: 2rem;
}

.wm-bar-row {
    display: grid;
    grid-template-columns: minmax(4.5rem, 7rem) 1fr minmax(3rem, auto);
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
}

.wm-bar-token {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--bs-font-monospace, monospace);
}

.wm-bar-track {
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.2rem;
    height: 0.95rem;
    overflow: hidden;
}

.wm-bar-fill {
    height: 100%;
    background: var(--bs-secondary, #6c757d);
    transition: width 0.15s ease;
}

.wm-bar-fill-green {
    background: var(--wm-green-strong);
}

.wm-bar-fill-red {
    background: var(--wm-red-strong);
}

.wm-bar-value {
    font-family: var(--bs-font-monospace, monospace);
    text-align: right;
}

/* --- Metric tiles ------------------------------------------------- */
.wm-metric {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.4rem 0.6rem;
    background: var(--bs-light, #f8f9fa);
    height: 100%;
}

.wm-metric-label {
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bs-secondary, #6c757d);
}

.wm-metric-value {
    display: block;
    font-size: 1.1rem;
    font-weight: 600;
    font-family: var(--bs-font-monospace, monospace);
}

/* --- z gauge ------------------------------------------------------ */
.wm-gauge {
    position: relative;
    height: 1.4rem;
    background: var(--bs-light, #f8f9fa);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.3rem;
    overflow: hidden;
}

.wm-gauge-fill {
    height: 100%;
    width: 0;
    background: var(--bs-secondary, #6c757d);
    transition: width 0.2s ease;
}

.wm-gauge-fill.is-detected {
    background: var(--wm-green-strong);
}

.wm-gauge-fill.is-weak {
    background: var(--bs-warning, #ffc107);
}

/* The threshold marker is a line, not a colour change, so it survives
   greyscale printing. */
.wm-gauge-threshold {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: #212529;
    left: 50%;
}

/* --- Canvas charts ------------------------------------------------ */
.wm-canvas-wrap {
    position: relative;
    width: 100%;
    height: 220px;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    background: #fff;
    overflow: hidden;
}

.wm-canvas-wrap canvas {
    width: 100%;
    height: 100%;
    display: block;
}

/* --- Diff panes (step 4) / duel panes (step 5) -------------------- */
.wm-diff-pane,
.wm-duel-pane {
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.5rem;
    background: #fff;
}

.wm-op-replaced {
    text-decoration: underline wavy;
    font-weight: 600;
}

.wm-op-inserted {
    outline: 2px dotted var(--bs-primary, #0d6efd);
    outline-offset: 1px;
}

.wm-op-moved {
    font-style: italic;
}

/* --- Formula ------------------------------------------------------ */
.wm-formula {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 1.05rem;
    background: var(--bs-light, #f8f9fa);
    border-left: 4px solid var(--bs-info, #0dcaf0);
    padding: 0.5rem 0.8rem;
    border-radius: 0.25rem;
}

/* --- Presentation view --------------------------------------------
   Scales up what the room has to read from a projector and removes the
   prose that only helps someone sitting at their own screen. */
.wm-presentation .wm-hide-in-presentation {
    display: none !important;
}

.wm-presentation .wm-token,
.wm-presentation .wm-tile {
    font-size: 1.25rem;
}

.wm-presentation .wm-metric-value {
    font-size: 1.75rem;
}

.wm-presentation .wm-metric-label {
    font-size: 0.85rem;
}

.wm-presentation .wm-bar-row {
    font-size: 1rem;
}

.wm-presentation .wm-canvas-wrap {
    height: 320px;
}

.wm-presentation .wm-step-btn {
    font-size: 1.05rem;
}

/* On a narrow screen the presentation view must scale DOWN instead of
   overflowing — the toggle has to stay usable on a laptop too. */
@media (max-width: 767.98px) {
    .wm-presentation .wm-token,
    .wm-presentation .wm-tile {
        font-size: 1rem;
    }

    .wm-presentation .wm-metric-value {
        font-size: 1.25rem;
    }

    .wm-presentation .wm-canvas-wrap {
        height: 220px;
    }
}

/* --- System preferences ------------------------------------------- */
@media (prefers-contrast: more) {
    .wm-tile,
    .wm-token-green,
    .wm-token-red {
        border-width: 3px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .wm-tile,
    .wm-bar-fill,
    .wm-gauge-fill {
        transition: none;
    }
}

/* ==========================================================================
   PROJ-14: n-gram order trace
   Which backoff stage produced each generated word. The order is carried by
   the UNDERLINE STYLE, not by colour: the token background is already used
   by the PROJ-13 green/red lists, and a colour-only channel would exclude
   readers with a colour vision deficiency. Underline style also survives a
   greyscale printout and a badly calibrated projector.
   ========================================================================== */

.ngram-trace-token {
    padding: 0 0.05rem;
    text-underline-offset: 0.22em;
}

/* Order 3 (4-gram) - the longest context, the most solid line. */
.ngram-order-3 {
    text-decoration: underline solid 2px;
}

/* Order 2 (trigram). */
.ngram-order-2 {
    text-decoration: underline dashed 2px;
}

/* Order 1 (bigram) - least context of the three. */
.ngram-order-1 {
    text-decoration: underline dotted 2px;
}

/* Order 0: no context at all, drawn from the frequency list. Marked as an
   absence (struck through, muted) because that is what it is - the model had
   nothing to go on. */
.ngram-order-0 {
    color: var(--bs-secondary, #6c757d);
    text-decoration: line-through 1px;
}

@media (prefers-contrast: more) {
    .ngram-order-3,
    .ngram-order-2,
    .ngram-order-1 {
        text-decoration-thickness: 3px;
    }
}

/* ==========================================================================
   PROJ-15: Skills-Demo (Skills vs. Functions)
   Bootstrap covers cards, badges, list-groups, alerts and forms. These rules
   only add the box-graphic look: the dashed skill container, the building
   block states (idle / active / done / unused) and the code/terminal panes.
   ========================================================================== */

/* Skill picker: a radio (.btn-check) whose <label> is a whole card. */
.sk-skill-card {
    cursor: pointer;
    border-width: 2px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.sk-skill-card:hover {
    border-color: var(--bs-primary-border-subtle);
}
.btn-check:checked + .sk-skill-card {
    border-color: var(--bs-primary);
    background-color: var(--bs-primary-bg-subtle);
    box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.15);
}
.btn-check:focus-visible + .sk-skill-card {
    outline: 3px solid var(--bs-primary);
    outline-offset: 2px;
}
.btn-check:disabled + .sk-skill-card {
    cursor: not-allowed;
    opacity: 0.65;
}

/* The big skill container — dashed so it reads as "a box around blocks". */
.sk-skill-box {
    border: 3px dashed var(--bs-primary);
    border-radius: 0.75rem;
    background-color: rgba(13, 110, 253, 0.03);
}

/* Building blocks inside the container. */
.sk-block {
    border: 2px solid var(--bs-border-color);
    border-radius: 0.5rem;
    background-color: var(--bs-body-bg);
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
.sk-block:last-child {
    margin-bottom: 0 !important;
}
.sk-block-active {
    border-color: #fd7e14;
    background-color: #fff8f0;
    box-shadow: 0 0 0 0.25rem rgba(253, 126, 20, 0.25);
}
.sk-block-done {
    border-color: var(--bs-success);
}
/* "Not used": still visible, but clearly de-emphasised. */
.sk-block-unused {
    border-style: dashed;
    background-color: var(--bs-tertiary-bg);
}
.sk-block-unused .sk-block-icon,
.sk-block-unused h4 {
    color: var(--bs-secondary-color);
}

/* Single function call rows inside the function block. */
.sk-call {
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
}
.sk-call-active {
    border-color: #fd7e14;
    background-color: #fff5e1;
}
.sk-call-done {
    border-color: var(--bs-success-border-subtle);
}
.sk-call-signature {
    word-break: break-all;
}

/* Instructions text keeps line breaks but uses the normal UI font. */
.sk-instructions {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: var(--bs-font-sans-serif, sans-serif);
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--bs-body-color);
}

/* Code and terminal panes (display only — nothing is executed). */
.sk-code,
.sk-terminal {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.8125rem;
    line-height: 1.45;
    border-radius: 0.375rem;
    padding: 0.75rem 1rem;
    max-height: 260px;
    overflow: auto;
}
.sk-code {
    background-color: #1e1e2e;
    color: #e6e6e6;
    white-space: pre;
}
.sk-code code {
    color: inherit;
}
.sk-terminal {
    background-color: #0c0c0c;
    color: #b5f0a4;
    white-space: pre-wrap;
}
.sk-terminal code {
    color: inherit;
}
.sk-terminal-idle {
    color: #adb5bd;
    font-style: italic;
}

/* Reference "Function" box: one solid block, deliberately not a container. */
.sk-function-box {
    border: 2px solid var(--bs-secondary);
}

/* Hybrid: a block the LLM never called in a finished conversation. */
.sk-block-skipped {
    border-style: dashed;
}
.sk-block-skipped .sk-block-icon,
.sk-block-skipped h4 {
    color: var(--bs-secondary-color);
}

/* Hybrid: one round of tool calls (same accent as PROJ-9 follow-up rounds). */
.sk-round {
    border-left: 4px solid #6f42c1;
}
.sk-tool-call {
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
}
.sk-tool-call-error {
    border-color: var(--bs-danger-border-subtle);
    background-color: var(--bs-danger-bg-subtle);
}
.sk-tool-call-signature {
    word-break: break-all;
}
.sk-result-input {
    font-size: 0.8125rem;
}

@media (prefers-reduced-motion: reduce) {
    .sk-skill-card,
    .sk-block {
        transition: none;
    }
}
