/* =========================================================
   itechnicalearning â€” Data Structures track + Visualizers
   Loaded only on the DSA pages (see @push('styles')).
   Uses the colour variables from app.css.
   ---------------------------------------------------------
   1. Track page
   2. Topic page header
   3. Visualizer layout
   4. Array drawing (cells and states)
   5. Controls and playback
   6. Side panels (explanation, code, complexity)
   7. Topic sections (how it works, pseudocode, complexity, practice)
   8. Classroom mode
   9. Responsive
   ========================================================= */

/* Show code exactly as typed: no ">=" â†’ "â‰¥" or "--" â†’ "â€”" font ligatures */
.code-view,
.pseudo-code,
.viz-input,
.var-pill,
.topic-tagline,
.key-facts span {
    font-variant-ligatures: none;
}

:root {
    --mono: "JetBrains Mono", Consolas, "Courier New", monospace;
    --viz-anim: 0.45s;           /* animation length, changed by the speed buttons */
    --cell-size: 56px;
    --green-bg: #DCFCE7;
    --green-text: #166534;
    --red-bg: #FEE2E2;
    --red-text: #991B1B;
}

.viz[data-speed="slow"] { --viz-anim: 0.7s; }
.viz[data-speed="fast"] { --viz-anim: 0.22s; }


/* ---------- 1. Track page ---------- */
.dsa-hero {
    position: relative;
    overflow: hidden;
    padding: 40px 0 72px;
    background: var(--background);
}

.dsa-hero::before {
    content: "";
    position: absolute;
    top: -160px;
    right: -140px;
    width: 560px;
    height: 560px;
    border-radius: 50%;
    background: var(--background-alt);
}

.dsa-hero-grid {
    position: relative;
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: 56px;
    align-items: center;
}

.dsa-hero h1 {
    font-size: 3rem;
}

.dot-live {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--primary);
    box-shadow: 0 0 0 4px var(--primary-light);
}

/* Looping preview card */
.dsa-preview {
    padding: 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

.dsa-preview-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 24px;
    font-family: var(--mono);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-dark);
}

.preview-cells {
    display: flex;
    justify-content: center;
    gap: 8px;
}

.preview-cell {
    text-align: center;
}

.preview-cell span {
    display: grid;
    place-items: center;
    width: 58px;
    height: 58px;
    border: 2px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    font-family: var(--mono);
    font-weight: 700;
    color: var(--text-dark);
    animation: preview-scan 6s infinite;
}

.preview-cell small {
    display: block;
    margin-top: 6px;
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--text-secondary);
}

/* Each cell lights up in turn; the 4th (index 3) turns green */
.preview-cell:nth-child(1) span { animation-name: preview-miss-1; }
.preview-cell:nth-child(2) span { animation-name: preview-miss-2; }
.preview-cell:nth-child(3) span { animation-name: preview-miss-3; }
.preview-cell:nth-child(4) span { animation-name: preview-hit; }
.preview-cell:nth-child(5) span { animation-name: none; }

@keyframes preview-miss-1 {
    0%, 4%    { background: var(--surface); border-color: var(--border); }
    6%, 18%   { background: var(--primary); border-color: var(--primary); }
    20%, 90%  { background: var(--background-alt); border-color: var(--border); color: var(--text-secondary); }
    100%      { background: var(--surface); }
}
@keyframes preview-miss-2 {
    0%, 20%   { background: var(--surface); border-color: var(--border); }
    22%, 34%  { background: var(--primary); border-color: var(--primary); }
    36%, 90%  { background: var(--background-alt); border-color: var(--border); color: var(--text-secondary); }
    100%      { background: var(--surface); }
}
@keyframes preview-miss-3 {
    0%, 36%   { background: var(--surface); border-color: var(--border); }
    38%, 50%  { background: var(--primary); border-color: var(--primary); }
    52%, 90%  { background: var(--background-alt); border-color: var(--border); color: var(--text-secondary); }
    100%      { background: var(--surface); }
}
@keyframes preview-hit {
    0%, 52%   { background: var(--surface); border-color: var(--border); }
    54%, 64%  { background: var(--primary); border-color: var(--primary); }
    66%, 90%  { background: var(--green-bg); border-color: var(--success); transform: translateY(-4px); }
    100%      { background: var(--surface); }
}

.preview-steps {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin-top: 22px;
}

.preview-steps span {
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.preview-steps span.ok {
    background: var(--green-bg);
    color: var(--green-text);
    font-weight: 700;
}

/* Learn â†’ Visualize â†’ ... loop */
.dsa-loop-section {
    padding: 28px 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.dsa-loop {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: loop;
}

.dsa-loop li {
    position: relative;
    padding: 14px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    text-align: center;
    counter-increment: loop;
}

.dsa-loop li::before {
    content: counter(loop);
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    margin: 0 auto 6px;
    border-radius: 50%;
    background: var(--primary-light);
    font-size: 0.72rem;
    font-weight: 800;
    color: var(--primary-text);
}

.dsa-loop li:nth-child(4)::before { background: var(--primary); color: var(--text-dark); }

.dsa-loop strong {
    display: block;
    font-size: 0.92rem;
    color: var(--text-dark);
}

.dsa-loop span {
    font-size: 0.78rem;
    color: var(--text-secondary);
}

/* Modules + aside */
.dsa-modules-layout {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 40px;
    align-items: start;
}

.module-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.module-item {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 14px;
    padding: 22px 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.module-current {
    border: 2px solid var(--primary);
    box-shadow: var(--shadow-md);
}

.module-soon {
    background: var(--background-soft);
}

.module-status {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    background: var(--surface);
    font-weight: 800;
    color: var(--text-secondary);
}

.module-current .module-status {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--text-dark);
}

.module-body {
    flex: 1;
    min-width: 0;
}

.module-number {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.module-body h3 {
    margin: 2px 0 6px;
    font-size: 1.2rem;
}

.module-body p {
    margin-bottom: 12px;
    font-size: 0.93rem;
    color: var(--text-secondary);
}

.module-soon .module-body h3 {
    color: var(--text-primary);
}

.topic-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.topic-chips li {
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.module-action {
    flex-shrink: 0;
    align-self: center;
}

.soon-badge {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 999px;
    background: var(--background-alt);
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--text-secondary);
    white-space: nowrap;
}

.dsa-aside {
    position: sticky;
    top: calc(var(--header-height) + 24px);
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.big-progress {
    margin-bottom: 16px;
}

.big-progress .progress-bar {
    height: 12px;
}

.side-note-left {
    margin: 0 0 18px;
    font-size: 0.88rem;
    color: var(--text-secondary);
}

.side-card-flat {
    box-shadow: none;
    background: var(--background-soft);
}

.side-card-flat .side-note-left {
    margin: 14px 0 0;
}


/* ---------- 2. Topic page header ---------- */
/* Compact header so the visualizer is visible without scrolling on a laptop */
.topic-header {
    padding: 22px 0 28px;
}

.topic-header .breadcrumb {
    margin-bottom: 16px;
}

.topic-header .eyebrow {
    margin-bottom: 6px;
}

.topic-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 20px;
    margin-bottom: 10px;
}

.topic-title-row h1 {
    margin: 0;
    font-size: 2.4rem;
}

.topic-tagline {
    font-family: var(--mono);
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--primary-text);
}

.topic-lead {
    max-width: 880px;
    margin: 0 0 16px;
    font-size: 1.02rem;
    color: var(--text-secondary);
}

.topic-lead strong {
    color: var(--text-dark);
}

/* Three key facts in one row of chips */
.key-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.key-facts li {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 8px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--primary);
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
}

.key-facts strong {
    color: var(--text-dark);
}

.key-facts span {
    font-family: var(--mono);
    font-size: 0.8rem;
    color: var(--text-secondary);
}

/* Section tabs: pinned under the navbar while scrolling */
.topic-nav-bar {
    position: sticky;
    top: var(--header-height);
    z-index: 50;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--border);
}

.topic-nav {
    display: flex;
    gap: 4px;
    overflow-x: auto;
}

.topic-nav a {
    padding: 13px 16px 11px;
    border-bottom: 3px solid transparent;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text-secondary);
    white-space: nowrap;
}

.topic-nav a:hover {
    color: var(--text-dark);
}

/* "active" is set by dsa-topic.js for the section you are reading */
.topic-nav a.active {
    border-bottom-color: var(--primary);
    color: var(--text-dark);
}

/* When jumping to a section, stop below the navbar + section tabs */
main section[id] {
    scroll-margin-top: calc(var(--header-height) + 56px);
}


/* ---------- 3. Visualizer layout ---------- */
.viz-section {
    padding: 20px 0 24px;
}

.viz {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

.viz-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    padding: 10px 20px;
    border-bottom: 1px solid var(--border);
    background: var(--background-soft);
}

.viz-title {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    color: var(--text-dark);
}

.viz-op-badge {
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--primary-light);
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--primary-text);
    white-space: nowrap;
}

.btn-sm {
    padding: 8px 14px;
    font-size: 0.85rem;
}

.btn-sm svg {
    width: 16px;
    height: 16px;
}

.viz-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
}

.viz-main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border-right: 1px solid var(--border);
}

/* Data input (Apply / Random) sits inside the toolbar and may wrap */
.viz-input-row {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-width: 260px;
}

.viz-input-row .viz-input-wide {
    min-width: 130px;
}

.viz-input-row .viz-input {
    height: 36px;
}

.viz-classroom-btn {
    margin-left: auto;
}

.field-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.viz-input {
    width: 110px;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.92rem;
    color: var(--text-dark);
}

.viz-input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(255, 178, 0, 0.2);
}

.viz-input-wide {
    flex: 1;
    min-width: 180px;
}

.viz-stage {
    position: relative;
    padding: 12px 20px 10px;
    background:
        radial-gradient(var(--border) 1px, transparent 1px) 0 0 / 18px 18px,
        var(--background-soft);
    border-bottom: 1px solid var(--border);
}

.stage-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 20px;
    margin-bottom: 8px;
    font-family: var(--mono);
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.stage-meta strong {
    color: var(--text-dark);
}

.stage-status {
    margin-left: auto;
    padding: 3px 10px;
    border-radius: 999px;
    font-weight: 700;
}

.stage-status:empty {
    display: none;
}

.stage-status.is-error   { background: var(--red-bg);   color: var(--red-text); }
.stage-status.is-success { background: var(--green-bg); color: var(--green-text); }


/* ---------- 4. Array drawing ---------- */
.array-view {
    display: flex;
    gap: 8px;
    padding: 4px 4px 8px;
    overflow-x: auto;
}

/* Centre the cells, but still allow scrolling to index 0 if they don't fit
   (justify-content: center would hide the left side when overflowing) */
.array-view .slot:first-child { margin-left: auto; }
.array-view .slot:last-child  { margin-right: auto; }

.slot {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-shrink: 0;
}

.slot-pointer {
    height: 22px;
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--primary-text);
    white-space: nowrap;
}

.cell {
    display: grid;
    place-items: center;
    width: var(--cell-size);
    height: var(--cell-size);
    border: 2px solid var(--border-strong);
    border-radius: 10px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-dark);
    transition: background var(--viz-anim), border-color var(--viz-anim), transform var(--viz-anim), opacity var(--viz-anim);
}

.cell.empty {
    border-style: dashed;
    border-color: var(--border);
    background: transparent;
}

.slot-index {
    margin-top: 8px;
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-primary);
}

.slot-address {
    font-family: var(--mono);
    font-size: 0.66rem;
    color: var(--text-secondary);
}

/* Cell states (set by the frames) */
.cell.target {
    border-style: dashed;
    border-color: var(--primary);
    background: var(--primary-light);
}

.cell.active {
    border-color: var(--primary);
    background: var(--primary);
    transform: translateY(-6px);
    box-shadow: 0 8px 16px rgba(255, 178, 0, 0.35);
}

.cell.compare {
    border-color: var(--primary);
    background: var(--primary-light);
    transform: translateY(-6px);
    box-shadow: 0 0 0 4px rgba(255, 178, 0, 0.25);
}

.cell.found,
.cell.new {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
}

.cell.new {
    animation: cell-pop var(--viz-anim) ease-out;
}

.cell.found {
    transform: translateY(-4px);
}

.cell.removing {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.cell.moved-right,
.cell.moved-left {
    border-color: var(--primary);
    background: var(--primary-light);
}

.cell.moved-right { animation: slide-from-left var(--viz-anim) ease-out; }
.cell.moved-left  { animation: slide-from-right var(--viz-anim) ease-out; }

.cell.ghost {
    border-style: dashed;
    opacity: 0.45;
}

.cell.checked {
    background: var(--background-alt);
    border-color: var(--border);
    color: var(--text-secondary);
}

.cell.visited {
    border-color: #86EFAC;
    background: #F0FDF4;
    color: var(--green-text);
}

.cell.freed {
    border-color: var(--danger);
    animation: fade-slot calc(var(--viz-anim) * 2) ease-out forwards;
}

@keyframes cell-pop {
    0%   { transform: scale(0.4); opacity: 0; }
    70%  { transform: scale(1.1); opacity: 1; }
    100% { transform: scale(1); }
}

@keyframes slide-from-left {
    from { transform: translateX(calc(-1 * (var(--cell-size) + 8px))); }
    to   { transform: translateX(0); }
}

@keyframes slide-from-right {
    from { transform: translateX(calc(var(--cell-size) + 8px)); }
    to   { transform: translateX(0); }
}

@keyframes fade-slot {
    from { border-color: var(--danger); }
    to   { border-color: var(--border); }
}

.array-output {
    margin: 14px auto 0;
    max-width: max-content;
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    background: var(--dark-section);
    font-family: var(--mono);
    font-size: 0.9rem;
    color: #fff;
}

.array-output span {
    margin-right: 8px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--primary);
}

.viz-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 16px;
    margin-top: 16px;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.viz-legend li {
    display: flex;
    align-items: center;
    gap: 6px;
}

.lg {
    width: 14px;
    height: 14px;
    border-radius: 4px;
    border: 2px solid;
}

.lg-active   { background: var(--primary); border-color: var(--primary); }
.lg-compare  { background: var(--primary-light); border-color: var(--primary); }
.lg-found    { background: var(--green-bg); border-color: var(--success); }
.lg-removing { background: var(--red-bg); border-color: var(--danger); }
.lg-empty    { border-style: dashed; border-color: var(--border-strong); }

/* Legend lines for arrows (linked list) */
.lg-line {
    width: 22px;
    height: 0;
    border-top: 3px solid;
}

.lg-line-new { border-color: var(--primary-hover); }
.lg-line-cut { border-color: var(--danger); border-top-style: dashed; }


/* ---------- 4b. Linked list drawing (SVG) ---------- */
.ll-stage {
    padding: 4px 0;
}

.ll-svg {
    display: block;
    width: 100%;
    height: auto;
    max-height: 340px;
    overflow: visible;
    font-family: var(--mono);
}

.ll-svg.is-vertical {
    max-height: none;
    max-width: 360px;
    margin: 0 auto;
}

/* Every node / label / NULL box slides to its new place */
.ll-node,
.ll-ptr,
.ll-null {
    transition: transform var(--viz-anim) ease;
}

.ll-inner {
    transform-box: fill-box;
    transform-origin: center;
}

.ll-box {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 2;
    transition: fill var(--viz-anim), stroke var(--viz-anim);
}

.ll-divider {
    stroke: var(--border-strong);
    stroke-width: 2;
}

.ll-value {
    font-size: 17px;
    font-weight: 700;
    fill: var(--text-dark);
}

.ll-dot {
    fill: var(--text-secondary);
}

.ll-nullmark {
    display: none;
    font-size: 17px;
    font-weight: 700;
    fill: var(--text-secondary);
}

/* next = NULL: show âˆ… instead of the dot */
.ll-node.is-null .ll-dot      { display: none; }
.ll-node.is-null .ll-nullmark { display: block; }

/* Doubly lists: the "prev" part works the same way */
.ll-pdot {
    fill: var(--text-secondary);
}

.ll-pnullmark {
    display: none;
    font-size: 17px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.ll-node.prev-null .ll-pdot      { display: none; }
.ll-node.prev-null .ll-pnullmark { display: block; }

/* Singly | Doubly | Circular switch (in the toolbar) */
.ll-type-switch {
    display: flex;
    flex-shrink: 0;
    gap: 2px;
    margin-right: 6px;
    padding: 3px;
    border-radius: var(--radius-sm);
    background: var(--text-dark);
}

.ll-type-btn {
    padding: 6px 12px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: 0.85rem;
    font-weight: 700;
    color: #CBD5E1;
    cursor: pointer;
}

.ll-type-btn:hover {
    color: #fff;
}

.ll-type-btn.active {
    background: var(--primary);
    color: var(--text-dark);
}

.ll-caption {
    display: none;
    font-size: 11px;
    fill: var(--text-secondary);
}

.ll-node.show-captions .ll-caption {
    display: block;
}

/* Node states */
.ll-node.active .ll-box   { fill: var(--primary); stroke: var(--primary); }
.ll-node.active .ll-divider { stroke: rgba(17, 24, 39, 0.35); }
.ll-node.compare .ll-box  { fill: var(--primary-light); stroke: var(--primary); stroke-width: 3; }
.ll-node.new .ll-box,
.ll-node.found .ll-box    { fill: var(--green-bg); stroke: var(--success); }
.ll-node.new .ll-value,
.ll-node.found .ll-value  { fill: var(--green-text); }
.ll-node.removing .ll-box { fill: var(--red-bg); stroke: var(--danger); }
.ll-node.removing .ll-value { fill: var(--red-text); }
.ll-node.checked .ll-box  { fill: var(--background-alt); stroke: var(--border); }
.ll-node.checked .ll-value { fill: var(--text-secondary); }
.ll-node.visited .ll-box  { fill: #F0FDF4; stroke: #86EFAC; }

.ll-node.lifted .ll-box {
    stroke-dasharray: 6 4;
}

.ll-node.lifted.removing .ll-inner {
    opacity: 0.8;
}

/* Appear / disappear */
.ll-enter .ll-inner,
.ll-ptr.ll-enter {
    animation: ll-pop var(--viz-anim) ease-out;
}

.ll-exit .ll-inner {
    animation: ll-fade 0.4s ease-in forwards;
}

@keyframes ll-pop {
    from { opacity: 0; transform: scale(0.5); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes ll-fade {
    to { opacity: 0; transform: scale(0.6); }
}

/* Arrows */
.ll-link {
    fill: none;
    stroke: #64748B;
    stroke-width: 2.2;
}

.ll-link.new {
    stroke: var(--primary-hover);
    stroke-width: 3.2;
}

.ll-link.cut {
    stroke: var(--danger);
    stroke-dasharray: 6 5;
}

/* Only arrows that changed fade in, after the nodes have moved */
.ll-link.link-enter {
    animation: ll-link-in calc(var(--viz-anim) * 0.8) ease-out calc(var(--viz-anim) * 0.5) both;
}

@keyframes ll-link-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.mk-normal { fill: #64748B; }
.mk-new    { fill: var(--primary-hover); }
.mk-cut    { fill: var(--danger); }

/* NULL box */
.ll-null rect {
    fill: var(--background-alt);
    stroke: var(--border-strong);
    stroke-width: 2;
    stroke-dasharray: 5 4;
}

.ll-null text {
    font-size: 13px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.ll-empty {
    font-family: var(--font-family);
    font-size: 15px;
    fill: var(--text-secondary);
}

/* Pointer labels (head, temp, curr...) */
.ll-ptr rect {
    fill: var(--primary-light);
    stroke: var(--primary);
    stroke-width: 1.5;
}

.ll-ptr text {
    font-size: 12px;
    font-weight: 700;
    fill: var(--text-dark);
}

.ll-ptr .ll-tip {
    fill: var(--primary);
}

.ll-ptr.ptr-head rect {
    fill: var(--text-dark);
    stroke: var(--text-dark);
}

.ll-ptr.ptr-head text {
    fill: #fff;
}

.ll-ptr.ptr-head .ll-tip {
    fill: var(--text-dark);
}

.viz-select {
    width: 150px;
    cursor: pointer;
}


/* ---------- 4b-2. Polynomial drawing (SVG) ----------
   Reuses the linked list node / arrow / pointer styles above. */
.poly-intro {
    max-width: 780px;
    margin-bottom: 18px;
}

.poly-intro h2 {
    margin: 4px 0 8px;
    font-size: 1.55rem;
}

.poly-intro p {
    color: var(--text-secondary);
    line-height: 1.65;
}

.poly-intro code {
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.9em;
}

/* Two polynomial boxes in the toolbar: wide enough for "3x^3 + 2x + 5", and "P(x)" keeps its lower-case x */
.poly-section .viz-input-row .viz-input-wide {
    flex: 1 1 210px;
    min-width: 210px;
}

.poly-section .viz-input-row .field-label {
    font-size: 0.85rem;
    letter-spacing: 0;
    text-transform: none;
}

.poly-stage {
    padding: 4px 0;
    overflow-x: auto;      /* a long result scrolls on small screens instead of shrinking */
}

.poly-svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
    font-family: var(--mono);
}

.poly-row-title {
    font-family: var(--font-family);
    font-size: 15px;
    font-weight: 600;
    fill: var(--text-dark);
}

.poly-row-name {
    font-weight: 800;
}

.poly-node .ll-value {
    font-size: 15px;
}

.poly-caption {
    display: block;
}

/* The term being worked on, e.g. "term +12xâµ" */
.poly-chip rect {
    fill: var(--primary-light);
    stroke: var(--primary);
    stroke-width: 1.5;
}

.poly-chip text {
    font-family: var(--mono);
    font-size: 13px;
    font-weight: 700;
    fill: var(--text-dark);
}


/* ---------- 4c. Stack drawing ---------- */
:root {
    --st-slot-h: 29px;
    --st-cell-w: 96px;
}

/* Three columns: status | the stack | bracket tape + legend */
.stack-stage {
    display: grid;
    grid-template-columns: 170px 1fr 200px;
    gap: 16px;
    align-items: center;
}

.stack-info {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.info-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 0.85rem;
}

.info-item span {
    color: var(--text-secondary);
}

.info-item strong {
    font-family: var(--mono);
    color: var(--text-dark);
}

.st-status.is-empty { color: var(--text-secondary); }
.st-status.is-full  { color: var(--red-text); }

.returned-box {
    padding: 8px 12px;
    border: 2px solid var(--primary);
    border-radius: var(--radius-sm);
    background: var(--primary-light);
    text-align: center;
    animation: cell-pop var(--viz-anim) ease-out;
}

.returned-box span {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--primary-text);
}

.returned-box strong {
    font-family: var(--mono);
    font-size: 1.3rem;
    color: var(--text-dark);
}

/* The stack itself: an open-topped container */
.stack-column {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 10px 0 26px;
}

.stack-box {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px 8px;
    border: 3px solid var(--text-dark);
    border-top: 0;
    border-radius: 0 0 14px 14px;
    background: var(--surface);
}

.st-slot {
    display: flex;
    align-items: center;
    gap: 8px;
}

.st-cell {
    display: grid;
    place-items: center;
    width: var(--st-cell-w);
    height: var(--st-slot-h);
    border: 2px solid var(--border-strong);
    border-radius: 8px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-dark);
    transition: background var(--viz-anim), border-color var(--viz-anim);
}

.st-cell.empty {
    border-style: dashed;
    border-color: var(--border);
    background: transparent;
}

.st-cell.ghost {
    border-style: dashed;
    border-color: var(--border);
    background: var(--background-alt);
    color: var(--text-secondary);
    font-style: italic;
    opacity: 0.55;
}

.st-cell.target {
    border-style: dashed;
    border-color: var(--primary);
    background: var(--primary-light);
}

.st-cell.active {
    border-color: var(--primary);
    background: var(--primary);
}

.st-cell.found,
.st-cell.new {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
}

.st-cell.new {
    animation: st-slide-in var(--viz-anim) ease-out;
}

.st-cell.removing {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.st-cell.lift-out {
    animation: st-lift-out var(--viz-anim) ease-in forwards;
}

.st-index {
    width: 16px;
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--text-secondary);
}

@keyframes st-slide-in {
    from { transform: translateX(70px); opacity: 0.3; }
    to   { transform: translateX(0); opacity: 1; }
}

@keyframes st-lift-out {
    0%   { transform: translateY(0); opacity: 1; }
    100% { transform: translateY(-30px); opacity: 0; }
}

/* "top â†’" pointer on the left of the box (slides up and down) */
.top-pointer {
    position: absolute;
    top: 0;
    right: calc(50% + (var(--st-cell-w) + 44px) / 2 + 10px);
    padding: 3px 10px;
    border: 1.5px solid var(--primary);
    border-radius: 999px;
    background: var(--primary-light);
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-dark);
    white-space: nowrap;
    transition: transform var(--viz-anim) ease;
}

.top-pointer.is-active {
    background: var(--primary);
}

.top-pointer.is-error {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.top-pointer.is-empty {
    border-style: dashed;
}

/* Value waiting to be pushed, on the right of the box */
.stack-incoming {
    position: absolute;
    top: 0;
    left: calc(50% + (var(--st-cell-w) + 44px) / 2 + 12px);
    display: grid;
    place-items: center;
    width: 64px;
    height: var(--st-slot-h);
    border: 2px dashed var(--success);
    border-radius: 8px;
    background: var(--green-bg);
    font-family: var(--mono);
    font-weight: 700;
    color: var(--green-text);
    transition: transform var(--viz-anim) ease;
    animation: cell-pop var(--viz-anim) ease-out;
}

.stack-incoming::before {
    content: "\2190";   /* â† arrow: "goes in here" */
    position: absolute;
    left: -16px;
    color: var(--success);
}

.stack-incoming.is-error {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
    animation: st-shake 0.4s ease-in-out;
}

.stack-incoming.is-error::before {
    content: "\2715";   /* âœ• */
    color: var(--danger);
}

@keyframes st-shake {
    0%, 100% { margin-left: 0; }
    25% { margin-left: -6px; }
    75% { margin-left: 6px; }
}

.stack-bottom-label {
    margin-top: 4px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

/* Right column: bracket tape + legend */
.stack-side {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.bracket-tape {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.tape-label {
    display: block;
    margin-bottom: 6px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.tape-chars {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
}

.tape-char {
    display: grid;
    place-items: center;
    width: 22px;
    height: 28px;
    border: 1.5px solid var(--border);
    border-radius: 5px;
    font-family: var(--mono);
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text-dark);
    transition: transform 0.2s;
}

.tape-char.skip    { color: var(--text-secondary); border-color: transparent; }
.tape-char.pushed  { border-color: var(--primary); background: var(--primary-light); }
.tape-char.ok      { border-color: var(--success); background: var(--green-bg); color: var(--green-text); }
.tape-char.bad     { border-color: var(--danger); background: var(--red-bg); color: var(--red-text); }
.tape-char.current { outline: 2px solid var(--text-dark); transform: translateY(-3px); }

.viz-legend-vertical {
    flex-direction: column;
    align-items: flex-start;
    margin-top: 0;
}

.viz-input-expr {
    width: 150px !important;
}


/* ---------- 4d. Queue drawing (linear row + circular ring) ---------- */
:root {
    --q-cell: 46px;
}

/* Status on the left, the queue on the right */
.queue-stage {
    display: grid;
    grid-template-columns: 196px 1fr;
    gap: 16px;
    align-items: center;
}

/* Status panel in two columns to save height */
.queue-stage .stack-info {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
}

.queue-stage .info-item {
    flex-direction: column;
    align-items: flex-start;
    padding: 4px 10px;
}

.queue-stage .returned-box,
.q-mini {
    grid-column: 1 / -1;
}

.queue-main {
    position: relative;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The ring needs room around it for the "front" labels outside it */
.queue-main.is-circular {
    min-height: 270px;
}

/* Colour legend inside the status panel */
.q-legend {
    grid-column: 1 / -1;
    justify-content: flex-start;
    gap: 4px 10px;
    margin-top: 4px;
    font-size: 0.72rem;
}

/* Linear: one row, with a caption line underneath */
.q-linear {
    display: flex;
    flex-direction: column;
    gap: 56px;             /* room for the rear pointer under the row */
    padding-right: 64px;   /* room for the value waiting to join */
}

.q-row {
    display: flex;
    gap: 5px;
}

.q-caption {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-secondary);
}

.q-cell {
    position: relative;
    display: grid;
    place-items: center;
    width: var(--q-cell);
    height: 44px;
    border: 2px solid var(--border-strong);
    border-radius: 9px;
    background: var(--surface);
    font-family: var(--mono);
    font-weight: 700;
    color: var(--text-dark);
    transition: background var(--viz-anim), border-color var(--viz-anim);
}

.q-idx {
    position: absolute;
    bottom: -18px;
    font-size: 0.7rem;
    color: var(--text-secondary);
}

.q-cell.empty {
    border-style: dashed;
    border-color: var(--border);
    background: transparent;
}

/* Linear queue: slots before front that can never be used again */
.q-cell.wasted {
    border-style: dashed;
    border-color: var(--border-strong);
    background: repeating-linear-gradient(135deg, var(--background-alt) 0 6px, transparent 6px 12px);
    color: var(--text-secondary);
    opacity: 0.8;
}

.q-cell.wasted .q-value {
    text-decoration: line-through;
    font-weight: 500;
}

.q-cell.wasted-hl {
    border-color: var(--danger);
    border-style: dashed;
}

.q-cell.target {
    border-style: dashed;
    border-color: var(--primary);
    background: var(--primary-light);
}

.q-cell.active  { border-color: var(--primary); background: var(--primary); }
.q-cell.found,
.q-cell.new     { border-color: var(--success); background: var(--green-bg); color: var(--green-text); }
.q-cell.new     { animation: cell-pop var(--viz-anim) ease-out; }
.q-cell.removing { border-color: var(--danger); background: var(--red-bg); color: var(--red-text); }
.q-cell.lift-out { animation: st-lift-out var(--viz-anim) ease-in forwards; }

/* Circular: the same cells placed on a ring by JavaScript */
.q-ring {
    position: relative;
    width: 224px;
    height: 224px;
}

.q-ring::before {
    content: "";
    position: absolute;
    inset: 26px;
    border: 2px dashed var(--border);
    border-radius: 50%;
}

.q-ring .q-cell {
    position: absolute;
    width: 46px;
    height: 40px;
    margin-left: -23px;   /* left / top are the centre of the cell */
    margin-top: -20px;
}

.q-ring .q-idx {
    bottom: auto;
    top: -2px;
    right: 3px;
    font-size: 0.6rem;
}

.q-ring-center {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    transform: translate(-50%, -50%);
    font-size: 1.6rem;
    line-height: 1;
    color: var(--border-strong);
}

.q-ring-center small {
    margin-top: 2px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

/* front / rear pointers (moved by JavaScript) */
.q-pointer {
    position: absolute;
    top: 0;
    left: 0;
    padding: 2px 9px;
    border: 1.5px solid var(--primary);
    border-radius: 999px;
    background: var(--primary-light);
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--text-dark);
    white-space: nowrap;
    transition: transform var(--viz-anim) ease;
    z-index: 2;
}

.q-pointer.q-rear {
    border-color: var(--text-dark);
    background: var(--text-dark);
    color: #fff;
}

.q-pointer.is-active {
    box-shadow: 0 0 0 3px rgba(255, 178, 0, 0.45);
}

.q-pointer.q-front.is-active {
    background: var(--primary);
}

.q-pointer.is-error {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.q-pointer.is-empty {
    border-style: dashed;
    opacity: 0.75;
}

.q-incoming {
    left: 0;
    width: 52px;
    height: 40px;
}

/* Circular: small "as an array" strip */
.q-mini {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.q-mini-cells {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}

.q-mini-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 2px 0;
    border: 1px dashed var(--border);
    border-radius: 4px;
    font-family: var(--mono);
}

.q-mini-cell.in {
    border-style: solid;
    border-color: var(--primary);
    background: var(--primary-light);
}

.q-mini-cell b {
    min-height: 12px;
    font-size: 0.6rem;
    color: var(--text-dark);
}

.q-mini-cell i {
    font-size: 0.55rem;
    font-style: normal;
    font-weight: 700;
    color: var(--text-secondary);
}

.lg-wasted {
    border-style: dashed;
    border-color: var(--border-strong);
    background: repeating-linear-gradient(135deg, var(--background-alt) 0 3px, transparent 3px 6px);
}


/* ---------- 4d-2. Queue topics: priority queue + double-ended queue ---------- */

/* Many operation tabs (the deque has eight): they wrap onto a second row instead of scrolling */
.op-tabs.op-tabs-wrap {
    flex-wrap: wrap;
    overflow-x: visible;
}

.op-tabs.op-tabs-wrap .op-tab {
    white-space: nowrap;
}

/* A tab that this kind of queue does not allow (e.g. Insert Front in an input-restricted deque) */
.op-tab:disabled,
.op-tab.is-disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.pq-rule {
    width: 240px;
}

/* ----- Priority queue: a row of slots, every item is a value with its priority ----- */
.pq-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 200px;
    padding: 4px 4px 6px;
}

.pq-incoming {
    align-self: flex-start;
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    padding: 4px 12px;
    border: 2px solid var(--success);
    border-radius: 10px;
    background: var(--green-bg);
    font-family: var(--mono);
    color: var(--green-text);
    animation: cell-pop var(--viz-anim) ease-out;
}

.pq-incoming.is-error {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.pq-incoming-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    opacity: 0.8;
}

.pq-incoming b {
    font-size: 1.1rem;
}

.pq-incoming i {
    padding: 0 6px;
    border: 1px solid currentColor;
    border-radius: 8px;
    font-size: 0.78rem;
    font-style: normal;
    font-weight: 700;
}

.pq-row {
    display: flex;
    gap: 6px;
}

.pq-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    width: 58px;
    padding-top: 24px;
}

.pq-marker {
    position: absolute;
    top: 0;
    left: 50%;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--text-dark);
    font: 700 0.68rem var(--mono);
    color: #fff;
    white-space: nowrap;
    transform: translateX(-50%);
}

.pq-marker.is-best {
    background: var(--primary);
    color: var(--text-dark);
}

.pq-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    width: 56px;
    height: 62px;
    border: 2px solid var(--border-strong);
    border-radius: 10px;
    background: var(--surface);
    font-family: var(--mono);
    transition: background var(--viz-anim), border-color var(--viz-anim);
}

.pq-value {
    font-size: 1.05rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--text-dark);
}

.pq-prio {
    min-height: 15px;
    padding: 0 7px;
    border-radius: 8px;
    background: var(--background-alt);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-secondary);
}

.pq-cell.empty {
    border-style: dashed;
    border-color: var(--border);
    background: transparent;
}

.pq-cell.empty .pq-prio {
    background: none;
}

.pq-cell.target   { border-style: dashed; border-color: var(--primary); background: var(--primary-light); }
.pq-cell.compare  { border-color: var(--primary); background: var(--primary-light); }
.pq-cell.active   { border-color: var(--primary); background: var(--primary); }
.pq-cell.found,
.pq-cell.new      { border-color: var(--success); background: var(--green-bg); }
.pq-cell.new      { animation: cell-pop var(--viz-anim) ease-out; }
.pq-cell.removing { border-color: var(--danger); background: var(--red-bg); }
.pq-cell.lift-out { animation: st-lift-out var(--viz-anim) ease-in forwards; }

.pq-cell.active .pq-prio,
.pq-cell.found .pq-prio,
.pq-cell.new .pq-prio,
.pq-cell.removing .pq-prio,
.pq-cell.compare .pq-prio {
    background: var(--surface);
}

.pq-idx {
    font: 0.7rem var(--mono);
    color: var(--text-secondary);
}

.pq-caption {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-secondary);
}

.pq-next-item strong {
    font-family: var(--mono);
    font-size: 0.9rem;
}

/* Narrow screens: eight slots must fit the width, so every slot is smaller */
@media (max-width: 620px) {
    .pq-row {
        gap: 3px;
    }

    .pq-slot {
        width: 36px;
    }

    .pq-cell {
        width: 34px;
        height: 54px;
        border-radius: 8px;
    }

    .pq-value {
        font-size: 0.82rem;
    }

    .pq-prio {
        min-height: 13px;
        padding: 0 4px;
        font-size: 0.6rem;
    }

    .pq-marker {
        padding: 1px 5px;
        font-size: 0.58rem;
    }

    .pq-rule {
        width: 100%;
    }
}

/* ---------- 4e. Tree drawing (binary search tree, SVG) ---------- */
/* Status on the left, the tree on the right */
.tree-stage {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 16px;
    align-items: center;
}

/* Status panel: nodes / height / root in one compact row */
.tree-info {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}

.tree-info .info-item {
    flex-direction: column;
    align-items: flex-start;
    padding: 3px 8px;
    font-size: 0.78rem;
}

.tree-info .returned-box,
.tree-info .tree-aux,
.tree-info .tree-legend {
    grid-column: 1 / -1;
}

.tree-info .returned-box {
    padding: 4px 10px;
}

.tree-info .returned-box strong {
    font-size: 1.1rem;
}

.tree-legend {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 8px;
}

.lg-visited {
    background: #F0FDF4;
    border-color: #86EFAC;
}

.tree-main {
    min-width: 0;
}

.tree-canvas {
    width: 100%;
}

.tree-svg {
    display: block;
    width: 100%;
    overflow: visible;
    font-family: var(--mono);
}

/* Nodes (moved by JavaScript; only colours use CSS transitions) */
.tr-inner {
    transform-box: fill-box;
    transform-origin: center;
}

.tr-circle {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 2;
    transition: fill var(--viz-anim), stroke var(--viz-anim);
}

.tr-value {
    font-weight: 700;
    fill: var(--text-dark);
}

.tr-node.active .tr-circle   { fill: var(--primary); stroke: var(--primary); }
.tr-node.path .tr-circle     { fill: var(--primary-light); stroke: var(--primary); }
.tr-node.compare .tr-circle  { fill: var(--primary-light); stroke: var(--primary-hover); stroke-width: 3; stroke-dasharray: 4 3; }
.tr-node.visited .tr-circle  { fill: #F0FDF4; stroke: #86EFAC; }
.tr-node.new .tr-circle,
.tr-node.found .tr-circle    { fill: var(--green-bg); stroke: var(--success); stroke-width: 3; }
.tr-node.new .tr-value,
.tr-node.found .tr-value     { fill: var(--green-text); }
.tr-node.removing .tr-circle { fill: var(--red-bg); stroke: var(--danger); stroke-width: 3; }
.tr-node.removing .tr-value  { fill: var(--red-text); }

.tr-enter .tr-inner {
    animation: ll-pop var(--viz-anim) ease-out;
}

.tr-exit .tr-inner {
    animation: ll-fade 0.4s ease-in forwards;
}

/* Lines between parents and children */
.tr-edge {
    stroke: #94A3B8;
    stroke-width: 2.2;
    stroke-linecap: round;
}

.tr-edge.path { stroke: var(--primary); stroke-width: 3.2; }
.tr-edge.new  { stroke: var(--success); stroke-width: 3.2; }
.tr-edge.cut  { stroke: var(--danger); stroke-dasharray: 6 5; }

.tr-edge.tr-null-link {
    stroke: var(--border-strong);
    stroke-dasharray: 4 4;
}

/* Extended binary trees: an external node is a small grey square, joined by a dashed line */
.tr-node .tr-square {
    fill: var(--background-alt);
    stroke: var(--text-secondary);
}

.tr-edge-ext {
    stroke: var(--border-strong);
    stroke-dasharray: 4 3;
}

/* Threaded binary trees: dashed arrows from a NULL pointer to the inorder successor (blue, right)
   or predecessor (purple, left) */
.tr-thread {
    fill: none;
    stroke-width: 2.2;
    stroke-dasharray: 5 4;
    stroke-linecap: round;
}

.tr-thread-r { stroke: #2563EB; }
.tr-thread-l { stroke: #9333EA; }
.tr-thread.new { stroke-width: 3.4; stroke-dasharray: none; }
.tr-thread-null { opacity: 0.75; }

.tr-thread-mk-r { fill: #2563EB; }
.tr-thread-mk-l { fill: #9333EA; }

.tr-thread-label {
    font-size: 9px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.lg-square {
    border-radius: 3px;
    background: var(--background-alt);
    border-color: var(--text-secondary);
}

.lg-line-thread-r,
.lg-line-thread-l {
    border-top-style: dashed;
}

.lg-line-thread-r { border-color: #2563EB; }
.lg-line-thread-l { border-color: #9333EA; }

/* "What kind of tree is this?" (Variants page): one row per kind */
.tv-class {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.tv-class li {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 3px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.tv-class li b {
    font-size: 1rem;
    color: var(--text-secondary);
}

.tv-class li.is-yes {
    border-color: var(--success);
    background: var(--green-bg);
}

.tv-class li.is-yes b { color: var(--green-text); }
.tv-class li.is-no b  { color: var(--danger); }

/* Dashed NULL spot */
.tr-null rect {
    fill: var(--background-alt);
    stroke: var(--border-strong);
    stroke-width: 1.5;
    stroke-dasharray: 4 3;
}

.tr-null text {
    font-size: 10px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.tr-empty {
    font-family: var(--font-family);
    font-size: 15px;
    fill: var(--text-secondary);
}

/* Pointer labels (curr, succ, node) */
.tr-ptr rect { fill: var(--text-dark); }
.tr-ptr .tr-tip { fill: var(--text-dark); }
.tr-ptr text {
    font-size: 11px;
    font-weight: 700;
    fill: #fff;
}

.tr-ptr.ptr-succ rect,
.tr-ptr.ptr-succ .tr-tip { fill: var(--primary-hover); }
.tr-ptr.ptr-succ text    { fill: var(--text-dark); }

/* The key travelling down the tree */
.tr-key rect {
    fill: var(--primary-light);
    stroke: var(--primary-hover);
    stroke-width: 2;
}

.tr-key text {
    font-size: 13px;
    font-weight: 700;
    fill: var(--text-dark);
}

/* Traversal output (under the tree) + call stack / queue (status panel) */
.tree-tape {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.tree-tape .tape-label {
    flex-shrink: 0;
    max-width: 70px;
    margin-bottom: 0;
    line-height: 1.2;
}

.tr-chip {
    width: auto;
    min-width: 26px;
    height: 24px;
    padding: 0 3px;
    font-size: 0.78rem;
}

.tree-output {
    margin-top: 6px;
}

/* One line only: when it is full, the oldest values scroll off to the left */
.tree-output .tape-chars {
    flex-wrap: nowrap;
    min-width: 0;
    overflow: hidden;
}

.tree-output .tr-chip {
    flex-shrink: 0;
}

/* In the narrow status panel the label sits above the values */
.tree-aux {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}

.tree-aux .tape-label {
    max-width: none;
}

/* "Level order" needs a little more room than the default select */
.tree-order-select {
    width: 172px;
}

/* Variants + Expression pages: the select boxes in the toolbar and the Values box */
.tv-example-select,
.ex-example-select {
    width: 190px;
}

.ex-notation-select {
    width: 100px;
}

.ex-values-input {
    width: 170px;
}

.tr-tape-empty {
    font-size: 0.8rem;
    line-height: 26px;
    color: var(--text-secondary);
}


/* ---------- 4f. Tree family switch + building a tree from traversals ---------- */
.tree-family {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin-top: 14px;
}

.tree-family-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.tree-family-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.tree-family-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-dark);
    text-decoration: none;
}

a.tree-family-item:hover {
    border-color: var(--primary);
    background: var(--primary-light);
}

.tree-family-item.is-active {
    border-color: var(--text-dark);
    background: var(--text-dark);
    color: #fff;
}

.tree-family-item.is-soon {
    color: var(--text-secondary);
    border-style: dashed;
}

.tree-family-item small {
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--text-secondary);
}

/* Fields for the two traversals */
.seq-input {
    width: 150px !important;
}

/* The two traversals under the tree */
.seq-tapes {
    display: grid;
    gap: 3px;
    margin-top: 4px;
}

/* Compact rows: two of them sit under the tree */
.seq-tape {
    padding: 2px 8px;
}

.seq-tape .tr-chip {
    height: 22px;
}

.seq-tape .tape-label {
    width: 70px;
}

.seq-tape .tape-chars {
    flex-wrap: nowrap;
    min-width: 0;
}

.seq-tape .tr-chip {
    flex-shrink: 0;
    transition: background var(--viz-anim), border-color var(--viz-anim), opacity var(--viz-anim);
}

.tr-chip.seq-pick  { border-color: var(--text-dark); background: var(--primary); transform: translateY(-2px); }
.tr-chip.seq-done  { border-color: var(--border); color: var(--text-secondary); opacity: 0.55; }
.tr-chip.seq-out   { opacity: 0.35; }
.tr-chip.seq-range { border-color: var(--primary); }
.tr-chip.seq-root  { border-color: var(--primary-hover); background: var(--primary); }
.tr-chip.seq-left  { border-color: #60A5FA; background: #DBEAFE; }
.tr-chip.seq-right { border-color: #A78BFA; background: #EDE9FE; }

/* Colour key for the inorder row (in the status panel) */
.lg-left  { border-color: #60A5FA; background: #DBEAFE; }
.lg-root  { border-color: var(--primary-hover); background: var(--primary); }
.lg-right { border-color: #A78BFA; background: #EDE9FE; }


/* ---------- 4g. AVL: balance factor badges ---------- */
.tr-badge rect {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 1.2;
}

.tr-badge text {
    font-size: 10px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.tr-badge.ok rect   { stroke: var(--primary); }
.tr-badge.ok text   { fill: var(--primary-text); }
.tr-badge.bad rect  { fill: var(--danger); stroke: var(--danger); }
.tr-badge.bad text  { fill: #fff; }

/* Legend: a sample badge + its meaning on one full-width line */
.tree-legend .legend-wide {
    grid-column: 1 / -1;
}

.bf-sample {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 14px;
    margin-right: 4px;
    padding: 0 4px;
    border: 1.2px solid var(--primary);
    border-radius: 7px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.6rem;
    font-weight: 700;
    color: var(--primary-text);
}


/* ---------- 4h. Huffman: edge bits, counts, code table, bit rows ---------- */
/* 0 / 1 next to every edge */
.tr-bit {
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.tr-bit.path,
.tr-bit.new {
    fill: var(--primary-text);
    font-size: 12.5px;
}

/* Letter counts on the leaves */
.tr-badge.freq rect { fill: var(--text-dark); stroke: var(--text-dark); }
.tr-badge.freq text { fill: #fff; }

.freq-sample {
    display: inline-grid;
    place-items: center;
    min-width: 16px;
    height: 14px;
    margin-right: 4px;
    padding: 0 4px;
    border-radius: 7px;
    background: var(--text-dark);
    font-family: var(--mono);
    font-size: 0.6rem;
    font-weight: 700;
    color: #fff;
}

/* Code table in the status panel: "A 0", "B 110", ... */
.code-table {
    gap: 4px;
}

.code-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 0 4px;
    border: 1.5px solid var(--border);
    border-radius: 5px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.7rem;
    color: var(--text-dark);
}

.code-chip b {
    color: var(--primary-text);
}

.code-chip.is-current {
    border-color: var(--text-dark);
    background: var(--primary);
}

.code-chip.is-current b {
    color: var(--text-dark);
}

/* Rows under the tree stay on one line; the current chip is scrolled into view */
.seq-tape .tape-chars {
    overflow: hidden;
}

/* Bits: narrow chips so a whole message fits */
.tape-chars.is-bits {
    gap: 1px;
}

.tape-chars.is-bits .tr-chip {
    min-width: 13px;
    padding: 0 1px;
    font-size: 0.72rem;
}

.bits-input {
    width: 260px !important;
    font-family: var(--mono);
    letter-spacing: 0.04em;
}


/* ---------- 4i. B-tree drawing (multi-key nodes) ---------- */
.bt-svg {
    font-family: var(--mono);
}

.bt-inner {
    transform-box: fill-box;
    transform-origin: center;
}

.bt-box {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 2;
    transition: fill var(--viz-anim), stroke var(--viz-anim);
}

.bt-cell {
    fill: transparent;
    transition: fill var(--viz-anim);
}

.bt-key {
    font-weight: 700;
    fill: var(--text-dark);
}

.bt-divider {
    stroke: var(--border);
    stroke-width: 1.5;
}

.bt-empty-key {
    font-size: 10px;
    fill: var(--text-secondary);
}

/* Whole-node states */
.bt-node.active .bt-box   { stroke: var(--primary); stroke-width: 3; fill: var(--primary-light); }
.bt-node.path .bt-box     { stroke: var(--primary); }
.bt-node.compare .bt-box  { stroke: var(--primary-hover); stroke-dasharray: 5 3; }
.bt-node.new .bt-box,
.bt-node.found .bt-box    { stroke: var(--success); stroke-width: 3; fill: var(--green-bg); }
.bt-node.removing .bt-box { stroke: var(--danger); stroke-width: 3; fill: var(--red-bg); }

/* Single-key states */
.bt-cell.compare  { fill: var(--primary); }
.bt-cell.found,
.bt-cell.new      { fill: var(--success); }
.bt-key.found,
.bt-key.new       { fill: #fff; }
.bt-cell.removing { fill: var(--danger); }
.bt-key.removing  { fill: #fff; }
.bt-cell.moving   { fill: var(--text-dark); }
.bt-key.moving    { fill: var(--primary); }

.bt-enter .bt-inner { animation: ll-pop var(--viz-anim) ease-out; }
.bt-exit .bt-inner  { animation: ll-fade 0.4s ease-in forwards; }

.bt-edge {
    stroke: #94A3B8;
    stroke-width: 2;
}

.bt-edge.path { stroke: var(--primary); stroke-width: 3; }
.bt-edge.new  { stroke: var(--success); stroke-width: 3; }

/* B+ tree: leaf-to-leaf arrows */
.bt-link {
    stroke: var(--primary-hover);
    stroke-width: 2;
    stroke-dasharray: 4 3;
}

.bt-arrow-head { fill: var(--primary-hover); }

.bt-empty {
    font-family: var(--font-family);
    font-size: 15px;
    fill: var(--text-secondary);
}

.bt-ptr rect { fill: var(--text-dark); }
.bt-ptr text {
    font-size: 10.5px;
    font-weight: 700;
    fill: #fff;
}


/* B+ tree: inner nodes are only signposts (lighter, dashed) */
.bt-node.is-guide .bt-box {
    fill: var(--background-alt);
    stroke-dasharray: 5 3;
}

.bt-node.is-guide .bt-key {
    fill: var(--text-secondary);
    font-style: italic;
}

.bt-node.is-guide.active .bt-box,
.bt-node.is-guide.path .bt-box {
    fill: var(--primary-light);
}

.guide-sample {
    display: inline-grid;
    place-items: center;
    min-width: 22px;
    height: 15px;
    margin-right: 4px;
    border: 1.5px dashed var(--border-strong);
    border-radius: 4px;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.62rem;
    font-style: italic;
    color: var(--text-secondary);
}


/* ---------- 4j. Graph drawing + adjacency list / matrix ---------- */
/* The graph and "Stored as" side by side */
.graph-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 162px;
    gap: 10px;
    align-items: start;
}

.graph-svg {
    display: block;
    width: 100%;
    overflow: visible;
    font-family: var(--mono);
}

.g-edge {
    stroke: #94A3B8;
    stroke-width: 2.2;
    transition: stroke var(--viz-anim), stroke-width var(--viz-anim);
}

.g-edge.tree  { stroke: var(--primary); stroke-width: 3.4; }
.g-edge.check { stroke: var(--text-dark); stroke-width: 2.6; stroke-dasharray: 6 4; }
.g-edge.path  { stroke: var(--success); stroke-width: 4; }

.g-head       { fill: #94A3B8; }
.g-head.tree  { fill: var(--primary); }
.g-head.check { fill: var(--text-dark); }
.g-head.path  { fill: var(--success); }

.g-vertex circle {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 2;
    transition: fill var(--viz-anim), stroke var(--viz-anim);
}

.g-vertex > text {
    font-size: 15px;
    font-weight: 700;
    fill: var(--text-dark);
}

.g-vertex.current circle  { fill: var(--primary); stroke: var(--primary); }
.g-vertex.frontier circle { fill: var(--primary-light); stroke: var(--primary); stroke-dasharray: 4 3; }
.g-vertex.visited circle  { fill: #F0FDF4; stroke: #86EFAC; }
.g-vertex.path circle     { fill: var(--green-bg); stroke: var(--success); stroke-width: 3; }
.g-vertex.path > text     { fill: var(--green-text); }
.g-vertex.is-target circle { stroke: var(--text-dark); stroke-width: 3; }

.g-badge rect { fill: var(--text-dark); }
.g-badge text {
    font-size: 10px;
    font-weight: 700;
    fill: #fff;
}

.g-badge-sample {
    display: inline-grid;
    place-items: center;
    min-width: 16px;
    height: 14px;
    margin-right: 4px;
    padding: 0 4px;
    border-radius: 7px;
    background: var(--text-dark);
    font-family: var(--mono);
    font-size: 0.6rem;
    font-weight: 700;
    color: #fff;
}

.g-select {
    width: 80px;
}

/* "Stored as": adjacency list or matrix */
.adj-panel {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.adj-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    margin-bottom: 6px;
}

.adj-head .tape-label {
    margin: 0;
    white-space: nowrap;
    font-size: 0.62rem;
}

.adj-switch {
    display: flex;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}

.adj-view-btn {
    padding: 1px 5px;
    border: 0;
    background: transparent;
    font-size: 0.66rem;
    font-weight: 700;
    color: var(--text-secondary);
    cursor: pointer;
}

.adj-view-btn.active {
    background: var(--text-dark);
    color: #fff;
}

.adj-list {
    display: grid;
    gap: 1px;
    font-family: var(--mono);
    font-size: 0.7rem;
}

.adj-row {
    display: flex;
    flex-wrap: nowrap;          /* one line per vertex keeps the panel short */
    align-items: center;
    gap: 2px;
    padding: 0 4px;
    line-height: 16px;
    white-space: nowrap;
    overflow: hidden;
    border-radius: 4px;
}

.adj-row b {
    color: var(--text-dark);
}

.adj-row.is-row {
    background: var(--primary-light);
}

.adj-arrow,
.adj-none {
    color: var(--text-secondary);
}

.adj-item {
    padding: 0 3px;
    border-radius: 3px;
    color: var(--text-dark);
}

.adj-item.is-cell {
    background: var(--text-dark);
    color: #fff;
}

.adj-matrix {
    border-collapse: collapse;
    font-family: var(--mono);
    font-size: 0.64rem;
}

.adj-matrix th,
.adj-matrix td {
    width: 12px;
    height: 15px;
    padding: 0;
    text-align: center;
}

.adj-matrix th {
    color: var(--text-secondary);
}

.adj-matrix td {
    color: var(--border-strong);
}

.adj-matrix td.on {
    color: var(--text-dark);
    font-weight: 700;
}

.adj-matrix tr.is-row td,
.adj-matrix th.is-col {
    background: var(--primary-light);
}

.adj-matrix td.is-cell {
    background: var(--text-dark);
    color: #fff;
}

@media (max-width: 640px) {
    .graph-row {
        grid-template-columns: 1fr;
    }
}


/* ---------- 4k. Graph pages: weights, side panels, tables ---------- */
.g-edge.reject { stroke: var(--danger); stroke-width: 3; stroke-dasharray: 3 5; }
.g-edge.dim    { stroke: #CBD5E1; }
.g-head.reject { fill: var(--danger); }
.g-head.dim    { fill: #CBD5E1; }

/* The weight of an edge, on a small label in the middle of the line */
.g-weight rect {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 1.2;
    transition: fill var(--viz-anim), stroke var(--viz-anim);
}

.g-weight text {
    font-size: 10.5px;
    font-weight: 700;
    fill: var(--text-dark);
}

.g-weight.tree rect,
.g-weight.path rect   { fill: var(--primary-light); stroke: var(--primary); }
.g-weight.reject rect { fill: var(--red-bg); stroke: var(--danger); }
.g-weight.check rect  { fill: var(--text-dark); stroke: var(--text-dark); }
.g-weight.check text  { fill: #fff; }

.g-vlabel {
    font-size: 10px;
    font-weight: 700;
    fill: var(--text-secondary);
}

.g-vertex.reject circle { fill: var(--red-bg); stroke: var(--danger); }

.g-edges-input { min-width: 170px; }
.g-example-select { width: 150px; }

/* Panels under the drawing (distance matrix, sorted edges, ...) */
.g-panels {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.g-panels:empty { display: none; }

.g-panel {
    flex: 1 1 190px;
    min-width: 0;
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    overflow-x: auto;
}

.g-panel.is-wide { flex: 2 1 300px; }

.g-panel-title {
    margin-bottom: 5px;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.g-panel-note {
    margin: 5px 0 0;
    font-size: 0.72rem;
    color: var(--text-secondary);
}

/* Tables: distance matrix, adjacency matrix, incidence matrix, vertex tables */
.g-table {
    border-collapse: collapse;
    font-family: var(--mono);
    font-size: 0.72rem;
}

.g-table th,
.g-table td {
    min-width: 24px;
    height: 22px;
    padding: 0 6px;
    text-align: center;
    border: 1px solid var(--border);
}

.g-table th {
    background: var(--background-soft);
    font-weight: 700;
    color: var(--text-secondary);
}

.g-table .g-corner { background: transparent; border-color: transparent; }
.g-table td { color: var(--text-dark); }
.g-table td.zero { color: var(--border-strong); }
.g-table td.inf { color: var(--text-secondary); }
.g-table td.on { background: #F0FDF4; font-weight: 700; }
.g-table td.done { background: #F0FDF4; }

/* highlights while an algorithm runs */
.g-table tr.row-hl td,
.g-table td.pivot { background: var(--primary-light); }
.g-table th.col-hl,
.g-table th.pivot { background: var(--primary); color: var(--text-dark); }
.g-table td.leg { background: var(--primary-light); box-shadow: inset 0 0 0 2px var(--primary); }
.g-table td.cmp { background: var(--text-dark); color: #fff; }
.g-table td.new { background: var(--green-bg); color: var(--green-text); font-weight: 700; box-shadow: inset 0 0 0 2px var(--success); }
.g-table td.hl  { background: var(--text-dark); color: #fff; }

/* An adjacency list written out */
.g-list {
    display: grid;
    gap: 3px;
    font-family: var(--mono);
    font-size: 0.78rem;
}

.g-list-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 3px;
    padding: 1px 4px;
    border-radius: 5px;
}

.g-list-row > b { min-width: 14px; color: var(--text-dark); }
.g-list-row.row-hl { background: var(--primary-light); }
.g-list-arrow,
.g-list-none { color: var(--text-secondary); }

.g-item {
    padding: 1px 6px;
    border: 1px solid var(--border-strong);
    border-radius: 5px;
    background: var(--surface);
    color: var(--text-dark);
}

.g-item.hl { background: var(--text-dark); border-color: var(--text-dark); color: #fff; }

/* Kruskal: the sorted edges and the disjoint sets */
.g-edgelist,
.g-sets {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.g-edgechip {
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.72rem;
    color: var(--text-dark);
}

.g-edgechip b { margin-left: 5px; }
.g-edgechip.current  { background: var(--primary); border-color: var(--primary); }
.g-edgechip.accepted { background: var(--green-bg); border-color: var(--success); color: var(--green-text); }
.g-edgechip.rejected { background: var(--red-bg); border-color: var(--danger); color: var(--red-text); text-decoration: line-through; }
.g-edgechip.skipped  { opacity: 0.45; }

.g-set {
    padding: 2px 9px;
    border: 1.5px solid var(--primary);
    border-radius: 8px;
    background: var(--primary-light);
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--text-dark);
}

/* "What kind of graph is this?" (Directed / Undirected page) */
.g-props {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 5px;
}

.g-prop {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px;
    padding: 3px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.g-prop b { font-size: 1rem; color: var(--text-secondary); }
.g-prop.is-yes { border-color: var(--success); background: var(--green-bg); }
.g-prop.is-yes b { color: var(--green-text); }
.g-prop.is-no b { color: var(--danger); }

/* Representations page: the tabs for the structure */
.rep-tabs {
    display: flex;
    gap: 2px;
    padding: 3px;
    border-radius: var(--radius-sm);
    background: var(--text-dark);
}

.rep-tab {
    padding: 6px 12px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: 0.85rem;
    font-weight: 700;
    color: #CBD5E1;
    cursor: pointer;
}

.rep-tab:hover { color: #fff; }
.rep-tab.active { background: var(--primary); color: var(--text-dark); }

@media (max-width: 640px) {
    .g-panels { flex-direction: column; }
}


/* ---------- 4k-2. Stack topics: expression conversion + Tower of Hanoi ---------- */

/* ----- Expression conversion ----- */
.cv-expr {
    width: 250px;
}

.cv-example {
    width: 200px;
}

/* Six conversions: the tabs wrap onto a second row instead of scrolling */
.op-tabs.cv-tabs {
    flex-wrap: wrap;
    overflow-x: visible;
}

.op-tabs.cv-tabs .op-tab {
    white-space: nowrap;
}

.cv-stage {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.cv-row {
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.cv-row .tape-label {
    margin-bottom: 4px;
}

.cv-count {
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
}

.cv-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    min-height: 36px;
}

.cv-chip {
    display: inline-grid;
    place-items: center;
    min-width: 30px;
    height: 34px;
    padding: 0 7px;
    border: 1.5px solid var(--border-strong);
    border-radius: 7px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-dark);
    transition: background var(--viz-anim), border-color var(--viz-anim), opacity var(--viz-anim), transform var(--viz-anim);
}

.cv-chip.cur {
    border-color: var(--text-dark);
    background: var(--primary);
    transform: translateY(-3px);
}

.cv-chip.done {
    border-color: var(--border);
    color: var(--text-secondary);
    opacity: 0.5;
}

.cv-chip.new {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
    animation: cell-pop var(--viz-anim) ease-out;
}

.cv-none {
    font-size: 0.85rem;
    font-style: italic;
    color: var(--text-secondary);
}

.cv-main {
    display: grid;
    grid-template-columns: minmax(200px, 54%) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

.cv-stack-col {
    min-width: 0;
}

.cv-stack-col .tape-label {
    margin-bottom: 4px;
}

.cv-stack-box {
    justify-content: flex-end;
    min-height: 150px;
    width: 100%;
}

.cv-slot {
    display: flex;
    align-items: center;
    gap: 8px;
}

.cv-slot .cv-cell {
    margin-right: auto;
}

.cv-top-tag {
    flex-shrink: 0;
    width: 42px;
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 700;
    text-align: right;
    color: var(--primary-text);
}

.cv-cell {
    flex: 0 1 auto;
    width: auto;
    min-width: 130px;
    max-width: calc(100% - 52px);
    height: auto;
    min-height: 34px;
    padding: 4px 12px;
    font-size: 0.95rem;
    text-align: center;
    overflow-wrap: anywhere;
}

/* a long piece such as ((a + b) * (c − d)) gets smaller text instead of many lines */
.cv-cell.long {
    font-size: 0.78rem;
    line-height: 1.2;
    padding: 3px 8px;
}

/* five or more pieces on the stack: smaller cells, so even the deepest stack stays on screen */
.cv-stack-box.is-deep {
    gap: 2px;
    padding: 4px 8px;
}

.cv-stack-box.is-deep .cv-cell {
    min-height: 24px;
    padding: 1px 10px;
    font-size: 0.82rem;
    line-height: 1.15;
    border-width: 1.5px;
}

.cv-empty {
    padding: 8px;
    text-align: center;
    font-style: italic;
    color: var(--text-secondary);
}

.cv-bottom {
    margin-top: 3px;
    text-align: center;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.cv-side {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

.cv-result {
    text-align: left;
}

.cv-result strong {
    display: block;
    font-size: 1.05rem;
    line-height: 1.4;
    overflow-wrap: anywhere;
}

.cv-legend {
    flex-wrap: wrap;
}

/* ----- Tower of Hanoi ----- */
.hn-stage {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) 190px minmax(260px, 1.25fr);
    gap: 12px;
    align-items: start;
}

.hn-col {
    min-width: 0;
}

.hn-col .tape-label {
    margin-bottom: 4px;
}

.hn-pegs,
.hn-tree {
    display: block;
    width: 100%;
    height: auto;
}

.hn-tree {
    overflow: visible;
}

.hn-base { fill: var(--border-strong); }
.hn-rod  { fill: #9CA3AF; }

.hn-peg-name {
    font: 700 15px var(--mono);
    fill: var(--text-dark);
}

.hn-peg-role {
    font: 700 10.5px var(--mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    fill: var(--text-secondary);
}

.hn-peg-role.from { fill: #2563EB; }
.hn-peg-role.to   { fill: #15803D; }
.hn-peg-role.via  { fill: #8F5F00; }

.hn-disk {
    transition: transform 0.55s cubic-bezier(0.4, 0.1, 0.2, 1);
}

.hn-disk rect {
    stroke: rgba(17, 24, 39, 0.45);
    stroke-width: 1.5;
}

.hn-disk text {
    font: 800 12px var(--mono);
    fill: #111827;
    pointer-events: none;
}

.hn-d1 rect { fill: #FDBA74; }
.hn-d2 rect { fill: #93C5FD; }
.hn-d3 rect { fill: #C4B5FD; }
.hn-d4 rect { fill: #86EFAC; }

.hn-disk.moved rect {
    stroke: var(--text-dark);
    stroke-width: 3;
}

.hn-moves {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
}

.hn-move {
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    font: 600 0.72rem var(--mono);
    color: var(--text-secondary);
}

.hn-move.last {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
}

.hn-moves-none {
    font-size: 0.82rem;
    font-style: italic;
    color: var(--text-secondary);
}

.hn-stack {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 4px;
    min-height: 96px;
    padding: 8px;
    border: 3px solid var(--text-dark);
    border-top: 0;
    border-radius: 0 0 12px 12px;
    background: var(--surface);
}

.hn-call {
    padding: 5px 6px;
    border: 2px solid var(--border-strong);
    border-radius: 7px;
    background: var(--surface);
    font: 700 0.74rem var(--mono);
    text-align: center;
    white-space: nowrap;
}

.hn-call.top {
    border-color: var(--text-dark);
    background: var(--primary);
}

.hn-stack-empty {
    padding: 6px;
    text-align: center;
    font-size: 0.82rem;
    font-style: italic;
    color: var(--text-secondary);
}

.hn-edge {
    stroke: var(--border-strong);
    stroke-width: 2;
    stroke-dasharray: 4 4;
    transition: stroke 0.3s;
}

.hn-edge.called {
    stroke: #94A3B8;
    stroke-dasharray: none;
}

.hn-node rect {
    stroke-width: 2;
    transition: fill 0.3s, stroke 0.3s;
}

.hn-node text {
    font-family: var(--mono);
    transition: opacity 0.3s;
}

.hn-node-n    { font-size: 12.5px; font-weight: 700; fill: var(--text-dark); }
.hn-node-move { font-size: 10.5px; fill: var(--text-secondary); }

.hn-node.future rect   { fill: var(--surface); stroke: var(--border-strong); stroke-dasharray: 4 3; }
.hn-node.future text   { opacity: 0.45; }
.hn-node.active rect   { fill: var(--primary-light); stroke: var(--primary); }
.hn-node.move rect     { fill: var(--green-bg); stroke: var(--success); }
.hn-node.done rect     { fill: var(--background-alt); stroke: #94A3B8; }

.hn-badge {
    opacity: 0;
    transition: opacity 0.3s;
}

.hn-badge.shown {
    opacity: 1;
}

.hn-badge circle { fill: var(--text-dark); }
.hn-badge text   { font: 800 11px var(--mono); fill: #fff; }

.hn-legend {
    flex-wrap: wrap;
    margin-top: 4px;
}

.hn-lg-done {
    background: var(--background-alt);
    border-color: #94A3B8;
}

@media (max-width: 760px) {
    .hn-stage,
    .cv-main {
        grid-template-columns: 1fr;
    }

    /* one column: the drawings would otherwise grow as wide as the screen */
    .hn-pegs {
        max-width: 420px;
        margin: 0 auto;
    }

    .hn-tree {
        max-width: 520px;
        margin: 0 auto;
    }

    .cv-expr,
    .cv-example {
        width: 100%;
    }
}

/* ---------- 4k. Searching ---------- */
.search-stage {
    display: grid;
    gap: 10px;
}

/* Status in one row */
.search-info {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 120px)) minmax(0, 220px);
    gap: 8px;
}

.search-info .info-item {
    flex-direction: column;
    align-items: flex-start;
    padding: 3px 10px;
}

.search-info .returned-box {
    padding: 3px 10px;
}

.search-info .returned-box strong {
    font-size: 1.05rem;
}

/* Cells sized by JavaScript (--s-cell) so all of them fit the width */
.search-view {
    gap: var(--s-gap, 5px);
    padding-top: 2px;
    padding-left: 18px;
    padding-right: 18px;
}

/* Pointer labels may be wider than a cell: let them overflow instead of widening the slot */
.search-view .slot {
    width: var(--s-cell, 44px);
}

.search-view .cell {
    width: var(--s-cell, 44px);
    height: var(--s-cell, 44px);
    border-radius: 8px;
    font-size: calc(var(--s-cell, 44px) * 0.36);
}

.search-view .slot-pointer {
    height: 20px;
    font-size: 0.66rem;
    display: flex;
    justify-content: center;
    width: var(--s-cell, 44px);
    overflow: visible;
}

.search-view .slot-index {
    margin-top: 6px;
    font-size: 0.72rem;
}

/* Binary search: the part that can still hold the key, and the part ruled out */
.cell.range {
    border-color: var(--primary);
}

.cell.out {
    border-style: dashed;
    border-color: var(--border);
    background: var(--background-alt);
    color: var(--text-secondary);
    opacity: 0.45;
}

/* Jump search: blocks tinted one after another */
.cell.blk-odd:not(.compare):not(.found):not(.out) {
    background: #EEF2FF;
}

.lg-range {
    border-color: var(--primary);
}

.lg-out {
    border-style: dashed;
    border-color: var(--border);
    background: var(--background-alt);
    opacity: 0.6;
}

@media (max-width: 640px) {
    .search-info {
        grid-template-columns: repeat(3, 1fr);
    }

    .search-view {
        padding-left: 8px;
        padding-right: 8px;
    }

    .search-info .returned-box {
        grid-column: 1 / -1;
    }
}


/* ---------- 4l. Sorting ---------- */
.sort-stage {
    display: grid;
    gap: 8px;
}

/* Heap sort: the tree on the right of the bars */
.sort-stage.aux-side {
    grid-template-columns: minmax(0, 1fr) 250px;
    align-items: end;
}

.sort-stage.aux-side .sort-top {
    grid-column: 1 / -1;
}

/* Status row + legend side by side */
.sort-top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
}

.sort-info {
    flex: 1 1 420px;
}

.sort-legend {
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 2px 12px;
    margin: 0;
    font-size: 0.72rem;
}

.lg-swap  { background: #FEE2E2; border-color: var(--danger); }
.lg-pivot { background: var(--text-dark); border-color: var(--text-dark); }

/* The bars */
.sort-bars {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    padding: 0 6px;
}

.sort-slot {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.sort-ptr {
    height: 14px;
    font-family: var(--mono);
    font-size: 0.66rem;
    font-weight: 700;
    color: var(--primary-text);
    white-space: nowrap;
}

.sort-bar-wrap {
    display: flex;
    align-items: flex-end;
    width: 100%;
    max-width: 56px;
    height: 84px;
}

.sort-bar {
    width: 100%;
    border: 2px solid var(--border-strong);
    border-bottom-width: 0;
    border-radius: 6px 6px 0 0;
    background: #E2E8F0;
    transition: height var(--viz-anim), background var(--viz-anim), border-color var(--viz-anim);
}

.sort-bar.compare { background: var(--primary); border-color: var(--primary-hover); }
.sort-bar.swap    { background: #FECACA; border-color: var(--danger); }
.sort-bar.new     { background: #FDE68A; border-color: var(--primary-hover); }
.sort-bar.key,
.sort-bar.pivot   { background: var(--text-dark); border-color: var(--text-dark); }
.sort-bar.sorted  { background: #86EFAC; border-color: var(--success); }
.sort-bar.part    { background: #DCFCE7; border-color: #86EFAC; }
.sort-bar.left    { background: #DBEAFE; border-color: #60A5FA; }
.sort-bar.right   { background: #EDE9FE; border-color: #A78BFA; }
.sort-bar.dim     { opacity: 0.3; }

.sort-bar.is-hole {
    border: 2px dashed var(--border-strong);
    border-bottom-width: 0;
    background: transparent;
}

.sort-value {
    margin-top: 2px;
    padding-top: 2px;
    width: 100%;
    border-top: 2px solid var(--border-strong);
    text-align: center;
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-dark);
}

.sort-value.dim { opacity: 0.4; }

.sort-value .digit {
    padding: 0 1px;
    border-radius: 3px;
    background: var(--primary);
    color: var(--text-dark);
}

.sort-index {
    font-family: var(--mono);
    font-size: 0.64rem;
    color: var(--text-secondary);
}

/* Extra views */
.sort-aux {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.sort-hold {
    display: flex;
    align-items: center;
    gap: 10px;
}

.sort-hold .tape-label {
    margin: 0;
}

.hold-chip {
    padding: 2px 12px;
    border: 2px solid var(--text-dark);
    border-radius: 6px;
    background: var(--text-dark);
    font-family: var(--mono);
    font-weight: 700;
    color: #fff;
}

/* Merge: temp cells line up with the bars above */
.sort-temp {
    display: grid;
    grid-template-columns: 40px 1fr;
    align-items: center;
    gap: 6px;
}

.sort-temp .tape-label {
    margin: 0;
}

.sort-temp-row {
    display: flex;
    gap: 6px;
    margin-left: -46px;
    padding: 0 6px 0 52px;
}

.temp-cell {
    flex: 1 1 0;
    min-width: 0;
    height: 24px;
    border: 1.5px solid var(--border-strong);
    border-radius: 5px;
    text-align: center;
    font-family: var(--mono);
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 21px;
    color: var(--text-dark);
}

.temp-cell.out   { border-color: transparent; }
.temp-cell.empty { border-style: dashed; border-color: var(--border); }
.temp-cell.new   { border-color: var(--primary-hover); background: #FDE68A; }

/* Radix / bucket: one column per bucket */
.sort-buckets {
    display: grid;
    gap: 4px;
}

.bucket {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 40px;
    border: 1.5px solid var(--border);
    border-top: 0;
    border-radius: 0 0 6px 6px;
    background: var(--background-alt);
}

.bucket.is-active {
    border-color: var(--primary);
    background: var(--primary-light);
}

.bucket-items {
    display: flex;
    flex-wrap: wrap-reverse;
    justify-content: center;
    gap: 2px;
    padding: 2px;
}

.bucket-chip {
    padding: 0 2px;
    line-height: 1.25;
    border: 1px solid var(--border-strong);
    border-radius: 3px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--text-dark);
}

.bucket-chip.new {
    border-color: var(--primary-hover);
    background: #FDE68A;
}

.bucket-label {
    border-top: 1px solid var(--border);
    text-align: center;
    font-family: var(--mono);
    font-size: 0.64rem;
    font-weight: 700;
    color: var(--text-secondary);
}

/* Heap sort: the heap part of the array drawn as a tree */
.heap-svg {
    display: block;
    width: 100%;
    font-family: var(--mono);
}

.heap-edge {
    stroke: #94A3B8;
    stroke-width: 1.6;
}

.heap-node circle {
    fill: var(--surface);
    stroke: var(--border-strong);
    stroke-width: 1.6;
}

.heap-node text {
    font-size: 9.5px;
    font-weight: 700;
    fill: var(--text-dark);
}

.heap-node.compare circle { fill: var(--primary); stroke: var(--primary-hover); }
.heap-node.swap circle    { fill: #FECACA; stroke: var(--danger); }
.heap-node.key circle     { fill: var(--text-dark); stroke: var(--text-dark); }
.heap-node.key text       { fill: #fff; }

.heap-note {
    display: block;
    font-size: 0.66rem;
    color: var(--text-secondary);
    text-align: right;
}

.sort-tabs .op-tab {
    padding-left: 10px;
    padding-right: 10px;
}

@media (max-width: 640px) {
    .sort-bars,
    .sort-temp-row {
        gap: 3px;
    }

    .sort-stage.aux-side {
        grid-template-columns: 1fr;
    }

    .sort-bar-wrap {
        height: 90px;
    }

    .sort-value {
        font-size: 0.66rem;
    }
}


/* ---------- 4m. Heaps ---------- */
/* Index badges on the heap tree */
.tr-badge.idx rect { fill: var(--background-alt); stroke: var(--border-strong); }
.tr-badge.idx text { fill: var(--text-secondary); }

.idx-sample {
    display: inline-grid;
    place-items: center;
    min-width: 16px;
    height: 14px;
    margin-right: 4px;
    padding: 0 4px;
    border: 1.2px solid var(--border-strong);
    border-radius: 7px;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.6rem;
    font-weight: 700;
    color: var(--text-secondary);
}

/* The array under the tree */
.heap-array-tape {
    margin-top: 4px;
    padding-top: 2px;
    padding-bottom: 2px;
}

.heap-array {
    display: flex;
    gap: 3px;
    min-width: 0;
    overflow: hidden;
}

.heap-slot {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 0 auto;
}

.heap-cell {
    min-width: 28px;
    padding: 0 3px;
    border: 1.5px solid var(--border-strong);
    border-radius: 5px;
    background: var(--surface);
    text-align: center;
    font-family: var(--mono);
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 19px;
    color: var(--text-dark);
    transition: background var(--viz-anim), border-color var(--viz-anim);
}

.heap-cell.compare  { border-color: var(--primary); background: var(--primary-light); }
.heap-cell.swap     { border-color: var(--primary-hover); background: var(--primary); }
.heap-cell.new,
.heap-cell.found    { border-color: var(--success); background: var(--green-bg); color: var(--green-text); }
.heap-cell.removing { border-color: var(--danger); background: var(--red-bg); color: var(--red-text); }

.heap-idx {
    font-family: var(--mono);
    font-size: 0.6rem;
    color: var(--text-secondary);
}

@media (max-width: 640px) {
    .heap-array {
        flex-wrap: wrap;
    }

    .heap-cell {
        min-width: 22px;
        font-size: 0.7rem;
    }
}


/* ---------- 4n. Introduction: count the steps ---------- */
/* Work area and growth chart side by side */
.intro-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
    gap: 14px;
    align-items: center;
}

.work-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.work-grid {
    display: grid;
    gap: 2px;
    max-width: 230px;
}

.work-cell {
    display: grid;
    place-items: center;
    min-width: 26px;
    height: 26px;
    padding: 0 3px;
    border: 1.5px solid var(--border-strong);
    border-radius: 5px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-secondary);
    transition: background var(--viz-anim), border-color var(--viz-anim);
}

.work-grid .work-cell {
    min-width: 0;
    height: auto;
    aspect-ratio: 1;
    border-radius: 3px;
    border-width: 1px;
}

.work-cell.is-done {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
}

.work-cell.is-current {
    border-color: var(--primary-hover);
    background: var(--primary);
    color: var(--text-dark);
}

.work-note {
    margin: 6px 0 0;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

/* Halving loop: one bar per value of n */
.work-halves {
    display: grid;
    gap: 4px;
}

.half-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--mono);
    font-size: 0.8rem;
}

.half-bar {
    height: 16px;
    border-radius: 4px;
    background: #DCFCE7;
    border: 1.5px solid #86EFAC;
}

.half-row.is-current .half-bar {
    background: var(--primary);
    border-color: var(--primary-hover);
}

/* Compare: the step counts for the current n */
.growth-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--mono);
    font-size: 0.78rem;
}

.growth-table th,
.growth-table td {
    padding: 3px 6px;
    border-bottom: 1px solid var(--border);
    text-align: left;
}

.growth-table td:last-child,
.growth-table th:last-child {
    text-align: right;
}

.g-swatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-right: 6px;
    border-radius: 2px;
    background: currentColor;
    vertical-align: -1px;
}

/* Growth-rate colours (chart lines, labels, table swatches) */
.g-c1    { color: #16A34A; stroke: #16A34A; fill: #16A34A; }
.g-logn  { color: #0891B2; stroke: #0891B2; fill: #0891B2; }
.g-n     { color: #2563EB; stroke: #2563EB; fill: #2563EB; }
.g-nlogn { color: #7C3AED; stroke: #7C3AED; fill: #7C3AED; }
.g-n2    { color: #D97706; stroke: #D97706; fill: #D97706; }
.g-exp   { color: #DC2626; stroke: #DC2626; fill: #DC2626; }

.intro-chart svg {
    display: block;
    width: 100%;
    font-family: var(--mono);
}

.intro-chart .ax {
    stroke: var(--border-strong);
    stroke-width: 1.5;
}

.intro-chart .ax-label {
    font-size: 10px;
    fill: var(--text-secondary);
}

.intro-chart .curve {
    fill: none;
    stroke-width: 2.2;
    stroke-linejoin: round;
}

.intro-chart .curve.is-active {
    stroke-width: 4;
}

.intro-chart .is-faint {
    opacity: 0.25;
}

.intro-chart .curve-label {
    font-size: 10.5px;
    font-weight: 700;
    stroke: none;
}

.intro-chart .steps-dot {
    fill: var(--primary);
    stroke: var(--text-dark);
    stroke-width: 2;
}

.steps-dot-sample {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-right: 5px;
    border: 2px solid var(--text-dark);
    border-radius: 50%;
    background: var(--primary);
    vertical-align: -1px;
}

@media (max-width: 640px) {
    .intro-main {
        grid-template-columns: 1fr;
    }
}


/* ---------- Topic extras: node structure card, comparison table ---------- */
.structure-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    align-items: center;
    margin-bottom: 24px;
    padding: 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--primary);
    border-radius: var(--radius);
}

.structure-card p {
    margin: 0;
    color: var(--text-secondary);
}

.structure-code {
    margin: 0;
    padding: 16px 18px;
    border-radius: var(--radius-sm);
    background: var(--dark-section);
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 0.85rem;
    line-height: 1.7;
    font-variant-ligatures: none;
    color: #E2E8F0;
}

.compare-title {
    margin: 40px 0 16px;
    font-size: 1.3rem;
}

.compare-note {
    margin: 10px 0 0;
    font-size: 0.88rem;
    color: var(--text-secondary);
}

.compare-table td:first-child {
    font-weight: 700;
    color: var(--text-dark);
}

/* (two classes, so it wins over ".complexity-table td { white-space: nowrap }" further down) */
.complexity-table.compare-table td {
    white-space: normal;
}

.next-card-next {
    align-items: flex-end;
    text-align: right;
    border-color: var(--primary);
    background: var(--primary-light);
}

a.next-card-next:hover {
    border-color: var(--primary-hover);
    background: #FFE9B0;
}


/* ---------- 5. Controls, narration and playback ---------- */

/* Operation tabs + fields on one row */
.viz-controls {
    padding: 10px 20px;
    border-bottom: 1px solid var(--border);
}

.op-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px 18px;
}

.op-tabs {
    display: flex;
    gap: 4px;
    padding: 4px;
    background: var(--background-alt);
    border-radius: var(--radius-sm);
    overflow-x: auto;
}

.op-tab {
    padding: 8px 12px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    white-space: nowrap;
}

.op-tab:hover {
    color: var(--text-dark);
}

.op-tab.active {
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    color: var(--text-dark);
}

.op-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px 14px;
}

.op-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.op-field .viz-input {
    width: 76px;
    height: 38px;
}

.op-field .viz-select {
    width: 124px;
}

/* AVL "Rotate": the case names are longer ("LR — left, then right") */
.op-field[data-field="case"] .viz-select {
    width: 200px;
}

.op-error {
    margin: 8px 0 0;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    background: var(--red-bg);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--red-text);
}

/* Narration: what is happening? (compact strip under the drawing) */
.viz-narration {
    padding: 10px 20px;
    border-bottom: 1px solid var(--border);
    border-left: 4px solid var(--primary);
    background: var(--surface);
}

.viz-narration.is-error   { border-left-color: var(--danger); }
.viz-narration.is-success { border-left-color: var(--success); }

.narration-text {
    min-height: 3em;          /* two lines, so the layout does not jump */
    margin: 0 0 8px;
    font-size: 0.98rem;
    line-height: 1.5;
    color: var(--text-primary);
}

.narration-text strong {
    margin-right: 6px;
    color: var(--text-dark);
}

.viz-narration.is-error strong   { color: var(--red-text); }
.viz-narration.is-success strong { color: var(--green-text); }

.narration-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
}

.stat-chips {
    display: flex;
    gap: 6px;
    margin-left: auto;
}

.stat-chip {
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--background-soft);
    font-size: 0.78rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.stat-chip strong {
    margin-left: 2px;
    font-family: var(--mono);
    color: var(--text-dark);
}

/* Playback bar */
.viz-playback {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 18px;
    padding: 10px 20px;
}

.viz-playback.is-idle .step-counter {
    font-family: var(--font-family);
    font-weight: 600;
    color: var(--text-secondary);
}

.viz-playback.is-idle .step-progress {
    display: none;
}

.playback-buttons {
    display: flex;
    gap: 6px;
}

.pb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 40px;
    padding: 0 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
}

.pb-icon {
    width: 40px;
    padding: 0;
    font-size: 1.05rem;
}

.pb-btn:hover:not(:disabled) {
    border-color: var(--text-primary);
}

.pb-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Play is the main button: gold, like every primary action on the site */
.pb-play {
    min-width: 128px;
    border-color: var(--primary);
    background: var(--primary);
    color: var(--text-dark);
}

.pb-play:hover:not(:disabled) {
    border-color: var(--primary-hover);
    background: var(--primary-hover);
}

.pb-play.is-playing {
    border-color: var(--text-dark);
    background: var(--text-dark);
    color: #fff;
}

.pb-next {
    border-color: var(--text-dark);
    color: var(--text-dark);
}

.playback-info {
    flex: 1;
    min-width: 140px;
}

.step-counter {
    display: block;
    margin-bottom: 6px;
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-dark);
}

.step-progress {
    height: 6px;
    border-radius: 999px;
    background: var(--background-alt);
    overflow: hidden;
}

.step-progress span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 999px;
    background: var(--primary);
    transition: width 0.25s;
}

.speed-control {
    display: flex;
    align-items: center;
    gap: 4px;
}

.speed-btn {
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
}

.speed-btn.active {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--text-dark);
}


/* ---------- 6. Side panels ---------- */
.viz-side {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--background-soft);
}

.viz-panel {
    padding: 18px 20px;
    border-bottom: 1px solid var(--border);
}

.viz-panel:last-child {
    border-bottom: 0;
}

.panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}

.panel-label {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.panel-step {
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--text-secondary);
}

/* Variable pills (i, n, pos...) in the narration strip */
.var-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 0;
}

.var-pill {
    display: inline-flex;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-family: var(--mono);
    font-size: 0.78rem;
}

.var-pill span {
    padding: 3px 7px;
    background: var(--background-alt);
    color: var(--text-secondary);
}

.var-pill strong {
    padding: 3px 8px;
    color: var(--text-dark);
}

/* Code panel */
.code-tabs {
    display: flex;
    gap: 2px;
}

.code-tab {
    padding: 4px 9px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--text-secondary);
    cursor: pointer;
}

.code-tab.active {
    background: var(--dark-section);
    color: #fff;
}

.code-view {
    margin: 0;
    padding: 12px 0;
    border-radius: var(--radius-sm);
    background: var(--dark-section);
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 0.76rem;
    line-height: 1.75;
    color: #E2E8F0;
}

.code-line {
    display: flex;
    min-width: max-content;
    padding-right: 14px;
    border-left: 3px solid transparent;
    transition: background 0.15s;
}

.code-line.active {
    border-left-color: var(--primary);
    background: rgba(255, 178, 0, 0.18);
}

.code-num {
    width: 30px;
    flex-shrink: 0;
    padding-right: 10px;
    text-align: right;
    color: #5B6B85;
    user-select: none;
}

.code-text {
    white-space: pre;
}

.tok-keyword { color: #FFC94D; font-weight: 700; }
.tok-number  { color: #7DD3FC; }
.tok-string  { color: #86EFAC; }
.tok-comment { color: #7F8EA8; font-style: italic; }

/* Complexity panel */
.complexity-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
}

.cx-item {
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.cx-item span {
    display: block;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.cx-item strong {
    display: block;
    margin: 2px 0 6px;
    font-family: var(--mono);
    font-size: 0.85rem;
    color: var(--text-dark);
}

/* Little bar: short for O(1), long for O(n) */
.cx-item i {
    display: block;
    height: 4px;
    border-radius: 2px;
    background: var(--background-alt);
    position: relative;
    overflow: hidden;
}

.cx-item i::after {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 2px;
}

.cx-fast i::after { width: 20%; background: var(--success); }
.cx-slow i::after { width: 75%; background: var(--primary); }

.shortcut-hint {
    margin: 12px 0 0;
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

kbd {
    display: inline-block;
    min-width: 22px;
    padding: 1px 6px;
    border: 1px solid var(--border-strong);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.75rem;
    text-align: center;
    color: var(--text-dark);
}


/* ---------- 7. Topic sections ---------- */
.how-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}

.how-card {
    padding: 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: 4px solid var(--primary);
    border-radius: var(--radius);
}

.how-card ol {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: how;
}

.how-card li {
    position: relative;
    padding: 6px 0 6px 32px;
    font-size: 0.92rem;
    color: var(--text-primary);
    counter-increment: how;
}

.how-card li::before {
    content: counter(how);
    position: absolute;
    left: 0;
    top: 7px;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-dark);
}

/* Pseudocode */
.pseudo-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

.pseudo-tabs {
    display: flex;
    gap: 4px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
}

.pseudo-tab {
    padding: 8px 14px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    white-space: nowrap;
}

.pseudo-tab.active {
    background: var(--primary-light);
    color: var(--text-dark);
}

.pseudo-code {
    padding: 20px 0;
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 0.95rem;
    line-height: 1.9;
}

.pseudo-line {
    display: flex;
    min-width: max-content;
    padding-right: 20px;
}

.pseudo-num {
    width: 48px;
    flex-shrink: 0;
    padding-right: 16px;
    text-align: right;
    color: var(--border-strong);
    user-select: none;
}

.pseudo-text {
    white-space: pre;
    color: var(--text-dark);
}

/* Complexity table */
.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.complexity-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.complexity-table th,
.complexity-table td {
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
    text-align: left;
    white-space: nowrap;
}

/* Long operation names (e.g. "Polynomial: multiply (m and n terms)") may wrap */
.complexity-table:not(.compare-table) td:first-child {
    min-width: 200px;
    white-space: normal;
}

.complexity-table th {
    background: var(--background-soft);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.complexity-table tr:last-child td {
    border-bottom: 0;
}

.complexity-table code {
    font-family: var(--mono);
    font-weight: 700;
    color: var(--text-dark);
}

.speed-meter {
    display: inline-block;
    position: relative;
    width: 60px;
    height: 6px;
    margin-right: 8px;
    border-radius: 3px;
    background: var(--background-alt);
    vertical-align: middle;
    overflow: hidden;
}

.speed-meter span {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 3px;
}

.speed-1 span { width: 20%; background: var(--success); }
.speed-2 span { width: 75%; background: var(--primary); }

/* Practice */
.practice-score {
    padding: 8px 16px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--border);
    font-weight: 700;
    color: var(--text-dark);
    white-space: nowrap;
}

.practice-card {
    margin-bottom: 16px;
    padding: 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.practice-card.is-correct { border-color: #86EFAC; }
.practice-card.is-wrong   { border-color: #FCA5A5; }

.practice-num {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.practice-card h3 {
    margin: 6px 0 16px;
    font-size: 1.08rem;
    line-height: 1.45;
}

.practice-options {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.practice-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 0.93rem;
    text-align: left;
    color: var(--text-primary);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.practice-option:hover:not(:disabled) {
    border-color: var(--primary);
    background: var(--primary-light);
}

.practice-option:disabled {
    cursor: default;
}

.practice-letter {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: var(--background-alt);
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 700;
}

.practice-option.correct {
    border-color: var(--success);
    background: var(--green-bg);
    color: var(--green-text);
}

.practice-option.wrong {
    border-color: var(--danger);
    background: var(--red-bg);
    color: var(--red-text);
}

.practice-feedback {
    margin: 14px 0 0;
    padding: 12px 14px;
    border-left: 4px solid var(--primary);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    background: var(--primary-light);
    font-size: 0.92rem;
}

/* Next topic */
.next-topic {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.next-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 22px 24px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

a.next-card:hover {
    border-color: var(--border-strong);
    background: var(--background-soft);
}

.next-card small {
    font-size: 0.82rem;
    color: var(--text-secondary);
}

.next-card strong {
    font-size: 1.15rem;
    color: var(--text-dark);
}

.next-card-soon {
    align-items: flex-end;
    text-align: right;
    background: var(--background-soft);
}

.next-card-soon .soon-badge {
    margin-top: 6px;
}


/* ---------- 8. Classroom mode (projector) ---------- */
body.classroom-mode {
    background: var(--background-soft);
    /* Cells grow with the screen so all 10 fit: ~64px on a laptop, up to 96px on a projector */
    --cell-size: clamp(56px, calc((100vw - 580px) / 11), 96px);
}

body.classroom-mode .site-header,
body.classroom-mode .site-footer,
body.classroom-mode .topic-nav-bar,
body.classroom-mode main > section:not(.viz-section) {
    display: none;
}

body.classroom-mode .viz-section {
    padding: 4px 0;
}

/* A page with two visualizers: only the one classroom mode was started from stays */
body.classroom-scoped .viz-section:not(.is-classroom-target),
body.classroom-mode .poly-intro {
    display: none;
}

body.classroom-mode .viz-section .container {
    max-width: none;
    padding: 0 12px;
}

/* The key hints are for the teacher, not the room: the space is better used by the lesson */
body.classroom-mode .shortcut-hint {
    display: none;
}

body.classroom-mode .viz-body {
    grid-template-columns: minmax(0, 1fr) 420px;
}

body.classroom-mode .viz-title strong {
    font-size: 1.25rem;
}

body.classroom-mode .viz-stage {
    padding: 8px 24px 6px;
}

body.classroom-mode .viz-controls {
    padding: 6px 20px;
}

/* The whole lesson (controls, drawing, explanation, buttons) should fit one screen:
   drawings are scaled to the screen height instead of growing with the screen width */
body.classroom-mode .viz-stage svg {
    max-height: max(200px, calc(100vh - 400px));
}

/* Graph pages also have a table under the drawing, so the drawing gets less */
body.classroom-mode .graph-canvas svg {
    max-height: max(170px, calc(100vh - 590px));
}

/* Short screens (small laptops): a little tighter still */
@media (min-width: 961px) and (max-height: 720px) {
    body.classroom-mode .graph-canvas svg {
        max-height: max(130px, calc(100vh - 510px));
    }

    html body.classroom-mode .viz-narration {
        padding: 5px 20px;
    }

    html body.classroom-mode .narration-text {
        min-height: 2.7em;
    }

    /* Graph pages: the drawing and its table side by side instead of one above the other */
    body.classroom-mode .tree-main:has(> .g-panels > .g-panel:only-child) {
        display: grid;
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
        gap: 10px;
        align-items: start;
    }

    body.classroom-mode .tree-main:has(> .g-panels > .g-panel:only-child) .g-panels {
        margin-top: 0;
    }

    body.classroom-mode .tree-main:has(> .g-panels > .g-panel:only-child) .graph-canvas svg {
        max-height: max(200px, calc(100vh - 400px));
    }

    body.classroom-mode .g-table th,
    body.classroom-mode .g-table td {
        height: 20px;
    }

    html body.classroom-mode {
        --st-slot-h: 32px;
    }

    /* Expression conversion: a little tighter (the deepest stack has 8 pieces) */
    html body.classroom-mode .cv-stage {
        gap: 6px;
    }

    html body.classroom-mode .cv-chips {
        min-height: 30px;
    }

    html body.classroom-mode .cv-chip {
        height: 30px;
    }

    html body.classroom-mode .cv-stack-box {
        min-height: 96px;
    }

    html body.classroom-mode .cv-stack-box.is-deep .cv-cell {
        min-height: 20px;
    }
}

/* The code / complexity column takes its height from the lesson next to it (height 0 + min-height 100%
   of the grid row) and scrolls by itself, so a long code listing never makes the page taller */
body.classroom-mode .viz-side {
    height: 0;
    min-height: 100%;
    overflow-y: auto;
}

body.classroom-mode .cell {
    font-size: 1.5rem;
    border-radius: 14px;
}

body.classroom-mode .slot-pointer,
body.classroom-mode .slot-index {
    font-size: 1rem;
}

body.classroom-mode .slot-pointer {
    height: 26px;
}

/* Bigger stack slots for the projector */
body.classroom-mode {
    --st-slot-h: 42px;
    --st-cell-w: 120px;
}

body.classroom-mode .st-cell {
    font-size: 1.3rem;
}

/* The linked list drawing may use up to ~45% of the screen height */
body.classroom-mode .ll-svg {
    max-height: 45vh;
}

/* Bigger narration text for the back of the classroom */
body.classroom-mode .narration-text {
    font-size: 1.1rem;
    margin-bottom: 4px;
}

body.classroom-mode .viz-narration {
    padding: 8px 20px;
}

body.classroom-mode .code-view {
    font-size: 0.85rem;
}

body.classroom-mode .pb-btn {
    height: 44px;
    padding: 0 20px;
    font-size: 1.05rem;
}

body.classroom-mode .pb-icon {
    width: 44px;
    padding: 0;
}

body.classroom-mode .step-counter {
    font-size: 1rem;
}

body.classroom-mode .viz-toolbar .btn {
    border-color: var(--text-dark);
}

/* Previous / Play / Next stay on screen even when the drawing is tall enough to scroll
   ('clip' keeps the rounded corners without making .viz a scroll container, which would break sticky) */
body.classroom-mode .viz {
    overflow: clip;
}

body.classroom-mode .viz-playback {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 14px rgba(0, 0, 0, 0.06);
}


/* ---------- 9. Responsive ---------- */
@media (max-width: 1180px) {
    /* Stack stage: narrower side columns so the stack has room */
    .stack-stage {
        grid-template-columns: 130px 1fr 150px;
        gap: 10px;
    }

    /* Queue stage: status panel on top (one row), the queue underneath */
    .queue-stage {
        grid-template-columns: 1fr;
    }

    .queue-stage .stack-info {
        grid-template-columns: repeat(4, 1fr);
    }

    .queue-main {
        min-height: 230px;
    }

    /* Classroom button: icon only, to save space in the toolbar */
    .viz-classroom-btn span {
        display: none;
    }

    :root { --cell-size: 50px; }

    .viz-body,
    body.classroom-mode .viz-body {
        grid-template-columns: minmax(0, 1fr) 350px;
    }

    .how-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .dsa-loop {
        grid-template-columns: repeat(4, 1fr);
    }
}

@media (max-width: 960px) {
    .dsa-hero-grid,
    .dsa-modules-layout {
        grid-template-columns: 1fr;
        gap: 32px;
    }

    .dsa-aside {
        position: static;
    }

    .dsa-hero h1 {
        font-size: 2.5rem;
    }

    /* Mobile order: visualization â†’ controls â†’ explanation â†’ code */
    .viz-body,
    body.classroom-mode .viz-body {
        grid-template-columns: 1fr;
    }

    .viz-main {
        border-right: 0;
    }

    .viz-side {
        border-top: 1px solid var(--border);
    }

    /* Stacked layout: the code column sits under the lesson at its natural height */
    body.classroom-mode .viz-side {
        height: auto;
        min-height: 0;
        overflow-y: visible;
    }
}

/* Stack stage on narrow screens: the stack first, then status + tape side by side */
/* Queue row on phones: narrower slots so all 8 fit */
@media (max-width: 640px) {
    :root {
        --q-cell: 30px;
    }

    .q-linear {
        padding-right: 58px;
    }

    .q-row {
        gap: 3px;
    }

    .q-linear .q-cell {
        height: 36px;
        font-size: 0.78rem;
    }

    .q-incoming {
        width: 38px;
        height: 34px;
    }

    .q-caption {
        font-size: 0.62rem;
    }

    .queue-stage .stack-info {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 700px) {
    .stack-stage {
        grid-template-columns: 1fr 1fr;
    }

    .stack-column {
        grid-column: 1 / -1;
        order: -1;
    }

    .viz-legend-vertical {
        display: none;   /* colours are explained by the narration on small screens */
    }
}

@media (max-width: 640px) {
    .topic-title-row h1 {
        font-size: 2rem;
    }

    .key-facts li {
        width: 100%;
    }

    .topic-nav a {
        padding-left: 12px;
        padding-right: 12px;
    }

    /* All 10 slots fit the screen width (about 28px each on a 375px phone) */
    :root { --cell-size: clamp(26px, calc((100vw - 96px) / 10), 40px); }

    .op-tab {
        padding: 8px 4px;
        font-size: 0.8rem;
    }

    body.classroom-mode { --cell-size: 44px; }

    .dsa-hero h1 {
        font-size: 2rem;
    }

    .preview-cell span {
        width: 46px;
        height: 46px;
    }

    .dsa-loop {
        grid-template-columns: repeat(2, 1fr);
    }

    .dsa-loop li:last-child {
        grid-column: 1 / -1;
    }

    .module-item {
        flex-wrap: wrap;
        gap: 14px;
        padding: 18px;
    }

    .module-body {
        flex-basis: calc(100% - 52px);
    }

    .module-action {
        width: 100%;
        padding-left: 52px;
    }

    .viz-toolbar {
        padding: 12px 14px;
    }

    /* Hide the long label on the classroom button */
    .viz-toolbar .btn span {
        display: none;
    }

    .viz-narration,
    .viz-controls,
    .viz-playback,
    .viz-panel {
        padding-left: 14px;
        padding-right: 14px;
    }

    .viz-stage {
        padding: 18px 8px 14px;
    }

    .array-view {
        justify-content: flex-start;
        gap: 4px;
    }

    .cell {
        font-size: 0.8rem;
        border-radius: 7px;
    }

    .slot-pointer {
        font-size: 0.7rem;
    }

    .slot-index {
        font-size: 0.7rem;
    }

    .slot-address {
        font-size: 0.55rem;
    }

    @keyframes slide-from-left {
        from { transform: translateX(calc(-1 * (var(--cell-size) + 4px))); }
        to   { transform: translateX(0); }
    }

    @keyframes slide-from-right {
        from { transform: translateX(calc(var(--cell-size) + 4px)); }
        to   { transform: translateX(0); }
    }

    .op-tabs,
    .op-form {
        width: 100%;
    }

    .op-tab {
        flex: 1;
    }

    .op-field {
        flex: 1;
    }

    .op-field .viz-input,
    .op-field .viz-select,
    .op-field[data-field="case"] .viz-select {
        width: 100%;
    }

    /* "Where" needs a little more room for "Beginning" / "Position" */
    .op-field[data-field="where"] {
        flex: 1.5;
    }

    .viz-input-row {
        flex-basis: 100%;
        flex-wrap: wrap;
        min-width: 0;
        order: 3;
    }

    .ll-type-switch {
        width: 100%;
        margin-right: 0;
    }

    .ll-type-btn {
        flex: 1;
    }

    .viz-input-row .viz-input {
        min-width: 0;
    }

    .viz-narration {
        padding: 10px 14px;
    }

    .narration-text {
        font-size: 0.92rem;
    }

    .stat-chips {
        margin-left: 0;
    }

    .playback-buttons {
        width: 100%;
    }

    .pb-btn {
        flex: 1;
        justify-content: center;
        padding: 0 8px;
    }

    /* Icons only on small phones, except Play */
    .pb-btn:not(.pb-play) span {
        display: none;
    }

    .speed-control {
        width: 100%;
    }

    .speed-btn {
        flex: 1;
    }

    .complexity-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .how-grid,
    .practice-options,
    .next-topic {
        grid-template-columns: 1fr;
    }

    .next-card-soon,
    .next-card-next {
        align-items: flex-start;
        text-align: left;
    }

    .structure-card {
        grid-template-columns: 1fr;
        padding: 18px;
    }

    .viz-select {
        width: 100%;
    }
}

/* Respect users who prefer less motion */
@media (prefers-reduced-motion: reduce) {
    .cell,
    .preview-cell span {
        animation: none !important;
        transition: none !important;
    }
}

/* ---------- Tree stage: classroom and smaller screens ---------- */
body.classroom-mode .tr-key text {
    font-size: 14px;
}

@media (max-width: 1180px) {
    /* Status panel on top (one row), the tree underneath */
    .tree-stage {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .tree-info {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 6px;
    }

    .tree-info .returned-box {
        grid-column: auto;
        padding: 2px 8px;
    }

    .tree-info .tree-aux {
        grid-column: 1 / -1;
        flex-direction: row;
        align-items: center;
    }

    .tree-info .returned-box strong {
        font-size: 1rem;
    }

    .tree-legend {
        grid-column: 1 / -1;
        display: flex;
        flex-wrap: wrap;
        margin-top: 0;
    }
}

@media (max-width: 640px) {
    .tree-info {
        grid-template-columns: repeat(3, 1fr);
    }

    /* All values of both traversals stay visible on a phone */
    .seq-tape .tape-chars {
        flex-wrap: wrap;
    }

    .tree-info .returned-box {
        grid-column: 1 / -1;
    }
}

/* =========================================================
   Assessment progress: module quiz status, final exam card,
   quiz call-to-action on topic pages
   ========================================================= */
.module-done .module-status {
    border-color: var(--success);
    background: var(--success);
    color: #fff;
}

.module-body .module-quiz-status {
    margin: -4px 0 10px;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--primary-text);
}

.module-body .module-quiz-status.is-passed {
    color: var(--success);
}

.module-action {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.module-quiz-link {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--primary-text);
}

.final-card.is-open {
    border: 2px solid var(--primary);
}

.final-card.is-done {
    border: 2px solid var(--success);
}

.final-card .btn {
    margin-top: 4px;
}

.quiz-cta-section {
    padding-bottom: 0;
}

.quiz-cta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 24px 28px;
    border: 2px solid var(--primary);
    border-radius: var(--radius);
    background: var(--primary-light);
}

.quiz-cta.is-passed {
    border-color: var(--success);
    background: #F0FDF4;
}

.quiz-cta h2 {
    margin: 4px 0 6px;
    font-size: 1.4rem;
}

.quiz-cta p {
    margin: 0;
    color: var(--text-secondary);
}

@media (max-width: 700px) {
    .quiz-cta {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* Visitors (not logged in): sign-up prompts */
.quiz-cta-actions {
    display: grid;
    justify-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.quiz-cta-login {
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--primary-text);
}

.guest-card .btn + .btn {
    margin-top: 8px;
}

/* Part heading inside a long module list (C Programming) */
.module-list .module-part {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 18px 0 2px;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-dark);
}

.module-list .module-part:first-child {
    margin-top: 0;
}

.module-list .module-part span {
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--primary-light);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-dark);
}
