/* ── REVIEWER SCREEN ── */
#reviewer-screen {
    padding: 24px 16px 80px;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
    font-family: "Lexend Deca", sans-serif;
    color: var(--text-mid);
    background-color: var(--bg);
    line-height: 1.6;
    overflow-x: hidden;
    min-height: calc(100vh - 69px);
    min-height: calc(100svh - 69px);
    box-sizing: border-box;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.reviewer-content {
    display: block;
    width: 100%;
    max-width: 100%;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

/* ============================================================
   Definition card — "index card & washi tape" template
   A kraft-toned card, pinned at a slight angle by two tape
   strips, sitting on the dark canvas like a real card someone
   set down. Tilt and tape colors are set per-topic via
   --tilt / --tape-a / --tape-b custom properties (see
   js/card-theme.js) so each topic gets a stable, distinct look.
   ============================================================ */
.def-card {
    position: relative;
    background-color: #F4EAD3;
    color: #4B4230;
    padding: 34px 22px 26px;
    margin: 26px auto 56px;
    width: 100%;
    max-width: 560px;
    box-sizing: border-box;
    border-radius: 2px 10px 3px 8px / 8px 3px 10px 2px;
    /* Lightened box-shadow blur for low-end GPU performance */
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
    /* Smooth padding and layout transitions for fluid collapse/expand */
    transition: padding 0.28s cubic-bezier(0.2, 0, 0, 1), margin-bottom 0.28s cubic-bezier(0.2, 0, 0, 1);
    /* Contain layout & style recalculations so collapse does not trigger full-page reflow thrash */
    contain: layout style;
}

/* Tape strips — compact, subtle, hardware-accelerated styling */
.def-tape {
    position: absolute;
    width: 62px;
    height: 22px;
    opacity: 0.78;
    /* Lightweight flat inset & drop shadow for fast GPU compositing */
    box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.35),
        inset 0 -1px 1px rgba(0, 0, 0, 0.08),
        0 1px 2px rgba(0, 0, 0, 0.15);
    pointer-events: none;
    overflow: hidden;
}

.def-tape-a {
    top: -10px;
    left: 28px;
    /* Compact repeating gradient */
    background: repeating-linear-gradient(45deg,
            var(--tape-a) 0 6px,
            rgba(0, 0, 0, 0.07) 6px 12px);
    background-color: var(--tape-a);
    transform: rotate(-5deg);
}

.def-tape-b {
    top: auto;
    left: auto;
    right: 24px;
    bottom: -8px;
    width: 52px;
    height: 18px;
    background: repeating-linear-gradient(45deg,
            var(--tape-b) 0 6px,
            rgba(0, 0, 0, 0.07) 6px 12px);
    background-color: var(--tape-b);
    transform: rotate(6deg);
}

/* ------------------------------------------------------------------------
   Highlight-card variant — for topics flagged "hl": true (must-remember /
   exam-critical concepts). Swaps the two tape strips for a single small
   pin that looks pierced through the paper: a soft radial shadow cast
   down-right, a dark puncture dot, and a glossy highlight on the pinhead.
   Deliberately small/quiet — the ==term== highlight inside the body is
   meant to carry the emphasis, the pin just marks the card as special.
   ------------------------------------------------------------------------ */
.def-card--pin {
    padding-top: 30px;
}

.def-pin {
    position: absolute;
    top: -9px;
    left: 50%;
    width: 22px;
    height: 22px;
    transform: translateX(-50%);
    pointer-events: none;
    z-index: 2;
}

.def-pin::before {
    /* cast shadow on the paper, offset down-right so the pin reads as
       sitting above the surface rather than flat against it */
    content: "";
    position: absolute;
    top: 12px;
    left: 4.5px;
    width: 11px;
    height: 5.5px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.25);
}

.def-pin::after {
    /* the pinhead itself: base color + radial sheen for a glossy dome look */
    content: "";
    position: absolute;
    top: 1px;
    left: 2.5px;
    width: 11.2px;
    height: 11.2px;
    border-radius: 50%;
    background: #a8493a;
    background-image:
        radial-gradient(circle at 30% 28%, rgba(238, 173, 160, 0.85) 0, transparent 35%),
        radial-gradient(circle at 65% 75%, rgba(113, 42, 31, 0.45) 0, transparent 60%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* the puncture point — a dark dot just above the pinhead's center,
   suggesting the pin's point has gone into the card */
.def-card--pin::before {
    content: "";
    position: absolute;
    top: 6px;
    left: 50%;
    width: 2px;
    height: 2px;
    transform: translateX(-6px);
    border-radius: 50%;
    background: #2a1a14;
    z-index: 3;
}

/* Inline highlighter-marker term, e.g. ==the new oil== in a topic body.
   Handwritten face + a solid highlighter-yellow block, matching the
   picked "B2" direction: card + pin + highlight, no tape. */
.def-highlight {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    background: #E8C640;
    color: #3F3312;
    padding: 1px 5px;
    border-radius: 2px 6px 2px 6px;
    box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.08);
}

/* Topic heading — the "term" — set in a marker-style hand font */
.def-term {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: clamp(1.5rem, 5vw, 1.9rem);
    color: #3F5D4E;
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    overflow-wrap: break-word;
    word-break: break-word;
    transition: margin-bottom 0.28s cubic-bezier(0.2, 0, 0, 1), padding-top 0.28s cubic-bezier(0.2, 0, 0, 1);
}

/* ── Card top bar: Slide badge + collapse button, pinned to top-right ── */
.card-top-bar {
    position: absolute;
    top: 10px;
    right: 12px;
    display: flex;
    align-items: center;
    gap: 4px;
    z-index: 4;
}

/* Slide source badge */
.def-card .slide-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.65rem;
    font-weight: 500;
    font-family: "Lexend Deca", sans-serif;
    color: #4B4230;
    background: rgba(75, 66, 48, 0.12);
    border: 1px solid rgba(202, 202, 202, 0.18);
    border-radius: 6px;
    padding: 2px 8px;
    letter-spacing: 0.03em;
    white-space: nowrap;
    line-height: 1.6;
    user-select: none;
}

/* Collapse / expand arrow button */
.card-collapse-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 50%;
    background: rgba(75, 66, 48, 0.08);
    color: #4B4230;
    cursor: pointer;
    padding: 0;
    flex-shrink: 0;
    transition: background 0.18s ease;
    -webkit-tap-highlight-color: transparent;
}

.card-collapse-btn:hover {
    background: rgba(75, 66, 48, 0.18);
}

.card-collapse-btn svg {
    display: block;
    /* Arrow points down (chevron-down) by default = "card is open, click to collapse" */
    transition: transform 0.28s cubic-bezier(0.2, 0, 0, 1);
}

/* When collapsed: arrow flips up to signal "click to expand" */
.def-card.is-collapsed .card-collapse-btn svg {
    transform: rotate(-180deg);
}

/* ══════════════════════════════════════════════════════════════════
   COLLAPSE ANIMATION — Fluid CSS Grid Accordion
   ══════════════════════════════════════════════════════════════════
   card-body-outer  → grid container, drives height transition
   card-body-inner  → min-height: 0 clip container
   Tapes/pin        → opacity fade
   ══════════════════════════════════════════════════════════════════ */

/* The single animated wrapper */
.card-body-outer {
    display: grid;
    grid-template-rows: 1fr;
    /* expanded state */
    opacity: 1;
    transition: grid-template-rows 0.28s cubic-bezier(0.2, 0, 0, 1), opacity 0.22s ease;
}

/* Inner clip — must have min-height:0 or grid row can't collapse to 0 */
.card-body-inner {
    overflow: hidden;
    min-height: 0;
}

/* Collapsed: row collapses to zero height + fade out */
.def-card.is-collapsed .card-body-outer {
    grid-template-rows: 0fr;
    opacity: 0;
    pointer-events: none;
    /* prevent ghost taps on hidden content */
}

/* Tapes & pin: opacity fade, no layout change needed */
.def-card .def-tape,
.def-card .def-pin {
    transition: opacity 0.22s ease;
}

.def-card.is-collapsed .def-tape,
.def-card.is-collapsed .def-pin {
    opacity: 0;
}

/* Collapsed card: compact strip — only Slide badge + heading visible */
.def-card.is-collapsed {
    padding-top: 10px;
    padding-bottom: 14px;
}

/* Heading stays fully visible; just drop its bottom margin when collapsed */
.def-card.is-collapsed .def-term {
    margin-bottom: 0;
    padding-top: 32px;
    /* push below the top-bar */
}

/* Related sub-term inside the same card (e.g. "Ethernet Cable" under "Ethernet") */
.def-subterm {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: clamp(1.15rem, 3.8vw, 1.3rem);
    color: #8A4B32;
    margin: 22px 0 6px;
    padding-top: 18px;
    border-top: 2px dashed #C9B98F;
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Definition / paragraph text — kept in a clean, legible face on purpose:
   the card is handmade, the reading experience still has to be effortless */
.def-body {
    font-family: "Lexend Deca", sans-serif;
    font-weight: 400;
    font-size: clamp(1.02rem, 3.5vw, 1.1rem);
    line-height: 1.65;
    margin-bottom: 8px;
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Bullet list, same card — hand-drawn checkmark marker instead of a
   plain disc. The check is a sketched SVG stroke (not a filled icon)
   in the card's deep-green accent, sized and weighted to read as a
   quiet "you know this" cue rather than a to-do checkbox. Positioned
   via ::before on the <li> so it never fights the text baseline. */
.def-bullets {
    list-style: none;
    padding-left: 0;
    margin: 4px 0 10px;
}

.def-bullets li {
    font-family: "Lexend Deca", sans-serif;
    font-weight: 400;
    font-size: clamp(1.02rem, 3.5vw, 1.1rem);
    line-height: 1.65;
    margin-bottom: 6px;
    padding-left: 24px;
    position: relative;
    overflow-wrap: break-word;
    word-break: break-word;
}

.def-bullets li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.32em;
    width: 15px;
    height: 15px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M3 10 L8 15 L17 4' stroke='%233F5D4E' stroke-width='2.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 15px 15px;
}

/* Nested term line — a bolded inline label followed by its description,
   for enumeration members that introduce their own key term (e.g.
   "Server Provisioning:" inside a "Server Installation and Configuration"
   list entry). Deliberately NOT a block heading like .def-subterm: no
   border, no extra vertical rhythm, no underline — it stays part of the
   same flowing entry so it doesn't read as a new numbered member.
   Selected via item type "term" (compact "d") — see js/renderer.js. */
.def-term-inline {
    margin: 10px 0 8px;
}

.def-term-inline b {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    color: #8A4B32;
}

/* ============================================================
   List / Types card — a numbered-entry variant of the same kraft
   card, for topics that are enumerations (e.g. "8 types of
   switches") rather than a single definition. No tape, no pin:
   a faint dashed "stitch" runs down the left edge instead, like
   a hand-bound notebook holding the list together as one spine.
   Deliberately kept low-opacity — a texture cue, not a line meant
   to be read — so the numerals and entry titles carry the focus.
   Selected via topic.list (see js/renderer.js appendTopic()).
   ============================================================ */
.def-card--list {
    padding-left: 34px;
}

.def-card--list::before {
    content: "";
    position: absolute;
    left: 16px;
    top: 14px;
    bottom: 14px;
    width: 0;
    border-left: 2px dashed rgba(75, 66, 48, 0.16);
}

.list-item {
    padding: 14px 0;
}

.list-item+.list-item {
    border-top: 1px dashed #C9B98F;
}

.list-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.list-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 2px solid #8A4B32;
    color: #8A4B32;
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    flex-shrink: 0;
}

.list-title {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: clamp(1.05rem, 3.6vw, 1.2rem);
    color: #3F5D4E;
}

.list-body {
    padding-left: 36px;
}

.list-body .def-body,
.list-body .def-bullets {
    margin-bottom: 0;
}

/* ============================================================
   Timeline card — a chronological variant of the same kraft
   card, for topics that are a sequence of dated milestones
   (e.g. "Evolution of Ethernet"). No tape, no pin, matching the
   List card's quiet-chrome rule: a thin spine runs down the left
   with a small dot per entry, both kept deliberately low-opacity
   so they read as background structure, not something meant to
   be looked at directly — the year/heading and body copy carry
   the focus. Selected via topic.timeline (see js/renderer.js
   appendTopic()).
   ============================================================ */
.def-card--timeline {
    padding-left: 26px;
}

.timeline-item {
    position: relative;
    padding: 14px 0 14px 26px;
}

/* Vertical spine line centered behind the dots */
.timeline-item:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 10px;
    top: 24px;
    bottom: -24px;
    width: 1.5px;
    background: rgba(63, 93, 78, 0.22);
    border-radius: 1px;
    pointer-events: none;
}

.timeline-item+.timeline-item {
    border-top: 1px dashed rgba(201, 185, 143, 0.5);
}

/* Subtle, translucent timeline dot — quiet background cue that doesn't distract from reading */
.timeline-dot {
    position: absolute;
    left: 6px;
    top: 20px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #3F5D4E;
    box-shadow: 0 0 0 2.5px #F4EAD3, 0 0 0 4px rgba(63, 93, 78, 0.18);
    opacity: 0.55;
    z-index: 1;
}

.timeline-date {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: clamp(1.05rem, 3.6vw, 1.2rem);
    color: #8A4B32;
    margin-bottom: 4px;
}

.timeline-body {
    padding-right: 4px;
}

.timeline-body .def-body,
.timeline-body .def-bullets {
    margin-bottom: 0;
}

/* ============================================================
   Table card — a horizontally swipeable strip of flashcards, for
   topics that are genuinely tabular (rows with several columns
   each, e.g. "OSI Model Layers"). Deliberately NOT a literal
   <table>: on a phone that either forces sideways scroll of the
   whole page or squashes columns unreadably. Instead each row
   becomes its own kraft flashcard; the row's other columns render
   as label/value lines (via the "d" nested-term item type,
   reusing .def-term-inline). A dot strip below the track shows
   swipe progress — the active dot stretches into a thin pill via
   is-active, matching the same quiet-chrome rule as the List and
   Timeline spines. Selected via topic.table (see js/renderer.js
   appendTopic() / wireTableCard()).
   ============================================================ */
.table-wrap {
    margin: 8px 0 4px;
    position: relative;
}

.table-track {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    padding: 4px 2px 10px;
    margin: 0 -2px;
    scrollbar-width: none;
    user-select: none;
    contain: layout paint style;
    will-change: scroll-position;
}

.table-track::-webkit-scrollbar {
    display: none;
}

.table-track.is-dragging {
    cursor: grabbing;
}

/* ── Table nav arrows — desktop / pointer devices only ── */
.table-nav-btn {
    display: none;
}

@media (hover: hover) and (pointer: fine) {
    .table-nav-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 50%;
        transform: translateY(-60%);
        width: 28px;
        height: 28px;
        border-radius: 50%;
        border: none;
        background: rgba(75, 66, 48, 0.18);
        color: #4B4230;
        cursor: pointer;
        z-index: 3;
        padding: 0;
        transition: background 0.18s ease, opacity 0.2s ease;
        opacity: 0.75;
        pointer-events: auto;
        -webkit-tap-highlight-color: transparent;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
    }

    .table-nav-btn:hover {
        background: rgba(75, 66, 48, 0.32);
        opacity: 1;
    }

    .table-nav-btn.is-hidden {
        opacity: 0 !important;
        pointer-events: none !important;
    }

    .table-nav-prev {
        left: 4px;
    }

    .table-nav-next {
        right: 4px;
    }
}

.table-flashcard {
    flex: 0 0 82%;
    max-width: 260px;
    min-width: 0;
    background: #EAE0C7;
    border-radius: 3px 12px 3px 12px / 12px 3px 12px 3px;
    box-shadow: inset 0 0 0 1px rgba(75, 66, 48, 0.1);
    padding: 14px 14px 12px;
}

@media (min-width: 480px) {
    .table-flashcard {
        flex-basis: 45%;
    }
}

.table-flash-title {
    margin: 0 0 8px;
}

.table-flashcard .def-term-inline,
.table-flashcard .def-body {
    font-size: 0.92rem;
    margin: 8px 0;
}

.table-flashcard .def-bullets li {
    font-size: 0.92rem;
}

.table-flashcard .def-term-inline:first-child,
.table-flashcard .def-body:first-child {
    margin-top: 0;
}

.table-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.table-dot {
    width: 6px;
    height: 6px;
    border-radius: 3px;
    background: rgba(138, 75, 50, 0.3);
    transition: width 0.2s ease, background-color 0.2s ease;
}

.table-dot.is-active {
    width: 18px;
    background: #8A4B32;
}

/* ============================================================
   Swipe-columns layout — the Table card's primary view (the swipe
   strip above is now only the fallback for content with no parallel
   "Attribute: Value" structure). Built by buildCompareHTML().

   One grid for the whole table. The attribute-name column is sticky
   (pinned left) while the item columns swipe under it, so a student
   never loses which question an answer belongs to. Each item column
   keeps a readable minimum width; the next one peeks in at the edge
   as the swipe cue. If every column fits (wide screens) nothing
   scrolls and it reads as a plain clean table.

   Deliberately minimal — hairlines only, no boxes / bars / chips —
   so the reader's attention stays on the text. Pure CSS, no JS.
   ============================================================ */
.def-card--table {
    max-width: 680px;
}

.cmp-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* The scroller bleeds to the card edges (cancels the card's 22px side
   padding) so columns slide off the paper edge instead of a padded box. */
.cmp-scroll {
    margin: 4px -22px 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: rgba(75, 66, 48, 0.28) transparent;
}

.cmp-scroll::-webkit-scrollbar {
    height: 4px;
}

.cmp-scroll::-webkit-scrollbar-thumb {
    background: rgba(75, 66, 48, 0.25);
    border-radius: 99px;
}

/* Touch screens: no visible scrollbar — the peeking column is the cue */
@media (hover: none) {
    .cmp-scroll {
        scrollbar-width: none;
    }

    .cmp-scroll::-webkit-scrollbar {
        display: none;
    }
}

.cmp-scroll:focus-visible {
    outline: 2px solid #4B4230;
    outline-offset: -2px;
}

.cmp-grid {
    display: grid;
    grid-template-columns: 116px repeat(var(--n), minmax(160px, 1fr));
    min-width: calc(116px + var(--n) * 160px + 22px);
    padding-right: 22px;
    box-sizing: border-box;
}

.cmp-row {
    display: contents;
}

/* Pinned attribute column (22px of its width is the card's left gutter) */
.cmp-corner,
.cmp-label {
    position: sticky;
    left: 0;
    z-index: 1;
    background: #F4EAD3;
    box-sizing: border-box;
}

.cmp-label {
    padding: 14px 6px 13px 22px;
    border-top: 1px solid rgba(75, 66, 48, 0.16);
    font-family: "Lexend Deca", sans-serif;
    font-weight: 600;
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.5;
    color: #8A4B32;
    overflow-wrap: break-word;
}

.cmp-head {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0 14px 10px 0;
    min-width: 0;
    font-family: "Lexend Deca", sans-serif;
    font-weight: 600;
    font-size: 0.88rem;
    line-height: 1.3;
    color: var(--ent);
    overflow-wrap: anywhere;
}

.cmp-cell {
    min-width: 0;
    padding: 12px 14px 13px 0;
    border-top: 1px solid rgba(75, 66, 48, 0.16);
    font-family: "Lexend Deca", sans-serif;
    font-size: 0.91rem;
    line-height: 1.55;
    overflow-wrap: break-word;
    word-break: break-word;
}

.cmp-val,
.cmp-miss {
    margin: 0;
}

.cmp-val+.cmp-val {
    margin-top: 6px;
}

.cmp-miss {
    color: rgba(75, 66, 48, 0.5);
}

.cmp-cell .def-body,
.cmp-cell .def-bullets li {
    font-size: 0.91rem;
}

.cmp-cell .def-body,
.cmp-cell .def-bullets {
    margin: 0;
}

/* Column header marker: colour + shape (never colour alone, so it works
   for colour-blind students and greyscale). Six variants, then cycles. */
.cmp-mark {
    flex: none;
    width: 9px;
    height: 9px;
    background: var(--ent);
}

.cmp-head[data-ent="0"] {
    --ent: #3F5D4E;
}

.cmp-head[data-ent="1"] {
    --ent: #A8493A;
}

.cmp-head[data-ent="2"] {
    --ent: #3E5C7A;
}

.cmp-head[data-ent="3"] {
    --ent: #8A6414;
}

.cmp-head[data-ent="4"] {
    --ent: #6B4A6B;
}

.cmp-head[data-ent="5"] {
    --ent: #4B4230;
}

.cmp-head[data-ent="0"] .cmp-mark {
    border-radius: 50%;
}

.cmp-head[data-ent="1"] .cmp-mark {
    border-radius: 2px;
}

.cmp-head[data-ent="2"] .cmp-mark {
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.cmp-head[data-ent="3"] .cmp-mark {
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

.cmp-head[data-ent="4"] .cmp-mark {
    clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}

.cmp-head[data-ent="5"] .cmp-mark {
    clip-path: polygon(35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65%, 0 35%, 35% 35%);
}

/* ============================================================
   Pros & cons panel — pairs an "Advantages"/"Disadvantages"-style
   subheading pair (see js/pros-cons.js) into two paper-toned
   columns instead of stacked bullet lists. Color still encodes
   pro/con, but the +/- mark carries the meaning too, so it isn't
   color-only.
   ============================================================ */
.pc-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin: 10px 0 18px;
}

.pc-grid.pc-grid-single,
.pc-grid:has(> .pc-panel:only-child) {
    grid-template-columns: 1fr;
}

@media (max-width: 420px) {
    .pc-grid {
        grid-template-columns: 1fr;
    }
}

.pc-panel {
    padding: 16px 14px 14px;
    border-radius: 3px 12px 3px 12px / 12px 3px 12px 3px;
}

.pc-pro {
    background: #E4EEDE;
    box-shadow: inset 0 0 0 1px rgba(59, 109, 17, 0.15);
}

.pc-con {
    background: #F5E4DE;
    box-shadow: inset 0 0 0 1px rgba(160, 60, 30, 0.15);
}

.pc-label {
    font-family: "Kalam", "Poppins", cursive, sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 10px;
}

.pc-pro .pc-label {
    color: #3B6D11;
}

.pc-con .pc-label {
    color: #A03C1E;
}

.pc-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 0.75rem;
    font-weight: 700;
    flex-shrink: 0;
}

.pc-pro .pc-mark {
    background: #3B6D11;
    color: #E4EEDE;
}

.pc-con .pc-mark {
    background: #A03C1E;
    color: #F5E4DE;
}

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

.pc-list li {
    font-family: "Lexend Deca", sans-serif;
    font-weight: 400;
    font-size: 0.9rem;
    line-height: 1.55;
    margin-bottom: 8px;
    padding-left: 14px;
    position: relative;
}

.pc-pro .pc-list li {
    color: #33511a;
}

.pc-con .pc-list li {
    color: #6b2c17;
}

.pc-list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
}

.pc-pro .pc-list li::before {
    background: #6a9a3c;
}

.pc-con .pc-list li::before {
    background: #c06a45;
}

.inline-code {
    background-color: #f0e6ce;
    color: #4B4230;
    padding: 0.1em 0.45em;
    border-radius: 5px;
    font-family: "Google Sans Code", monospace;
    font-size: 0.88em;
    font-weight: 500;
    border: 1px solid rgba(141, 141, 141, 0.11);
    white-space: normal;
    word-break: break-word;
}

/* ============================================================
   Code card — a block-level code snippet inside a topic's content
   (item.type === "code", see renderBulletsOrParagraphs() /
   buildCodeBlockHTML() in js/renderer.js). Deliberately flush and
   level rather than tilted/taped like the kraft cards around it —
   a macOS-style window, dark and level, because code reads better
   on a dark flat surface than on paper. The language pill is
   neutral grey (metadata, not a decoration) and the token colors
   are pulled back on purpose so nothing competes with the traffic
   lights for attention. Colors live in CSS custom properties on
   .code-card so the palette can be retuned in one place later.
   ============================================================ */
.code-card {
    --code-bg: #222428;
    --code-header-bg: #191a1c;
    --code-text: #f7f7f7;
    --code-gutter: #606570;
    --code-kw: #fc618d;
    /* Monokai Spectrum Pink (Keywords) */
    --code-type: #5ad4e6;
    /* Monokai Spectrum Cyan (Types/Classes) */
    --code-func: #fce566;
    /* Monokai Spectrum Yellow (Functions/Methods) */
    --code-str: #7bd88f;
    /* Monokai Spectrum Mint/Green (Strings) */
    --code-com: #696d77;
    /* Monokai Spectrum Slate Grey (Comments) */
    --code-num: #948ae3;
    /* Monokai Spectrum Purple (Numbers/Booleans) */
    --code-var: #fd9353;
    /* Monokai Spectrum Orange (Variables/Params) */
    position: relative;
    background-color: var(--code-bg);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    overflow: hidden;
    margin: 14px 0;

}

.code-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 12px;
    background-color: var(--code-header-bg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.code-dots {
    display: flex;
    gap: 7px;
}

.code-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: block;
    border: none;
}

.code-dot-red {
    background-color: #c99aa7;
}

.code-dot-yellow {
    background-color: #beb78f;
}

.code-dot-green {
    background-color: #92be9b;
}

.code-header-right {
    display: flex;
    align-items: center;
    gap: 10px;
}

.code-lang-pill {
    font-family: "Google Sans Code", "Google Code", Consolas, Monaco, monospace;
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    color: #9499a5a2;
    background-color: transparent;
    padding: 3px 10px;
    border-radius: 5px;
    font-weight: 500;
    text-transform: lowercase;
}

.code-copy-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    color: #727786;
    transition: color 0.15s ease;
}

.code-copy-btn:hover {
    color: #f7f7f7;
}

.code-copy-icon,
.code-check-icon {
    width: 15px;
    height: 15px;
    fill: currentColor;
}

.code-check-icon {
    display: none;
}

.code-copy-btn.is-copied .code-copy-icon {
    display: none;
}

.code-copy-btn.is-copied .code-check-icon {
    display: block;
}

.code-copy-btn.is-copied {
    color: #7bd88f;
}

/* Single 2D scroll surface for the whole code body (gutter + code
   scroll together, in both directions, as ONE element) instead of two
   nested independent scrollers. Two nested scrollers is what used to
   cause the mobile glitch: a vertical swipe and a horizontal swipe
   compete for the same touch gesture, and the horizontal scrollbar
   only existed at the very end of the code-pre's own content — so if
   you were scrolled partway down a long file, that horizontal bar (and
   the rest of a long line) was out of reach, i.e. the code visually
   got cut off mid-line.
   Fix: overflow: auto (both axes) lives on .code-card-body alone, so
   its scrollbars always track the visible viewport, not the content's
   edge. .code-gutter is pinned with position: sticky so it stays put
   horizontally while still scrolling normally with the vertical axis.
   max-height uses clamp() so short snippets hug their own content
   (never "too small" padding) while long ones cap out at a comfortable
   mobile-screen height (never "too tall") instead of a flat 420px. */
.code-card-body {
    display: flex;
    align-items: flex-start;
    max-height: clamp(140px, 45vh, 420px);
    overflow: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    overscroll-behavior-y: auto;
    touch-action: pan-y pan-x;
}

/* Thin, sleek, professional high-end scrollbar for the code card */
.code-card-body {
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
}

.code-card-body::-webkit-scrollbar {
    width: 4px;
    height: 4px;
}

.code-card-body::-webkit-scrollbar-track {
    background: transparent;
}

.code-card-body::-webkit-scrollbar-thumb {
    background-color: rgba(255, 255, 255, 0.14);
    border-radius: 99px;
    transition: background-color 0.2s ease;
}

.code-card-body::-webkit-scrollbar-thumb:hover {
    background-color: rgba(255, 255, 255, 0.32);
}

.code-card-body::-webkit-scrollbar-button {
    display: none;
    width: 0;
    height: 0;
}

.code-card-body::-webkit-scrollbar-corner {
    background: transparent;
}

.code-gutter {
    position: sticky;
    left: 0;
    z-index: 1;
    flex-shrink: 0;
    padding: 16px 0 20px 16px;
    text-align: right;
    font-family: "Google Sans Code", "Google Code", Consolas, Monaco, "Andale Mono", monospace;
    font-size: 0.8rem;
    line-height: 1.7;
    color: var(--code-gutter);
    background-color: var(--code-bg);
    user-select: none;
    box-sizing: border-box;
}

.code-pre {
    margin: 0;
    padding: 16px 18px 20px 12px;
    flex: 1;
    min-width: 0;
    font-family: "Google Sans Code", "Google Code", Consolas, Monaco, "Andale Mono", monospace;
    font-size: 0.8rem;
    line-height: 1.7;
    color: var(--code-text);
    white-space: pre;
    box-sizing: border-box;
}

.code-pre code {
    font-family: inherit;
}

.tok-kw {
    color: var(--code-kw);
    font-weight: 500;
}

.tok-type {
    color: var(--code-type);
}

.tok-func {
    color: var(--code-func);
}

.tok-str {
    color: var(--code-str);
}

.tok-com {
    color: var(--code-com);
    font-style: italic;
}

.tok-num {
    color: var(--code-num);
}

.tok-var {
    color: var(--code-var);
}

/* Allow normal text selection inside cards while keeping empty space non-selectable */
.def-card,
.pro-con-card,
.tbl-card,
.compare-table,
.code-block-card,
.math-block-card,
.timeline-card,
.mech-list-card {
    -webkit-user-select: text;
    user-select: text;
    -webkit-touch-callout: default;
}

/* ── DOWNLOAD JSON MODAL ── */
.json-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.58);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: json-fade-in 0.2s cubic-bezier(0.2, 0, 0, 1) forwards;
}

.json-modal-popup {
    background: #18171b;
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 22px 24px;
    width: min(380px, 90vw);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.65);
    display: flex;
    flex-direction: column;
    gap: 12px;
    font-family: "Poppins", sans-serif;
    animation: json-slide-up 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
    box-sizing: border-box;
}

.json-modal-popup h3 {
    font-size: clamp(0.95rem, 3.5vw, 1.05rem);
    font-weight: 600;
    color: var(--text-dark);
    margin: 0;
    font-family: "Lexend Deca", sans-serif;
}

.json-modal-popup p {
    font-size: clamp(0.78rem, 2.6vw, 0.85rem);
    color: var(--text-soft);
    margin: 0;
    line-height: 1.5;
}

.json-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 8px;
}

.json-modal-btn {
    padding: 8px 16px;
    border-radius: 10px;
    font-family: "Poppins", sans-serif;
    font-size: clamp(0.78rem, 2.5vw, 0.86rem);
    font-weight: 500;
    cursor: pointer;
    transition: transform 0.1s ease, opacity 0.15s ease, background 0.15s ease;
}

.json-modal-btn:active {
    transform: scale(0.94);
}

.json-modal-btn-cancel {
    background: #232228;
    border: 1px solid var(--border);
    color: var(--text-mid);
}

.json-modal-btn-cancel:hover {
    background: #2b2a32;
}

.json-modal-btn-confirm {
    background: var(--blue);
    border: 1px solid var(--blue);
    color: #ffffff;
    font-weight: 600;
}

.json-modal-btn-confirm:hover {
    background: var(--blue-dark);
}

@keyframes json-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes json-slide-up {
    from {
        opacity: 0;
        transform: translateY(16px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}


/* ─────────────────────────────────────────────────────────────────────────────
   Inline topic map ("peek map") — js/topic-map.js
   Always-visible, fits the card width, tap a branch to expand it.
   Dark inset panel so it reads as a separate study aid on the kraft paper.
   ───────────────────────────────────────────────────────────────────────────── */
.tmap {
    margin-top: 16px;
    padding: 10px 10px 10px;
    background: #1c1b1b;
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: 12px;
    color: #a0a0ab;
}

.tmap-cap {
    margin: 0 2px 8px;
    font-size: 12px;
    line-height: 1.3;
    color: #a0a0ab;
}

.tm-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 460px;
    margin: 0 auto;
    overflow: visible;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.tm-svg text {
    font-family: inherit;
    pointer-events: none;
}

.tm-link {
    fill: none;
    stroke: #4a4a55;
    stroke-width: 1.5;
}

.tm-node {
    cursor: pointer;
    outline: none;
}

.tm-node rect {
    stroke: transparent;
    stroke-width: 1;
    transition: stroke 0.15s ease;
}

.tm-root rect { fill: #f4ead3; }
.tm-group rect,
.tm-step rect { fill: var(--tm-fill, #e6d9b0); }
.tm-leaf rect { fill: #26262c; stroke: #3a3a44; }

.tm-node.is-sel rect {
    stroke: var(--blue, #5364fd);
    stroke-width: 2.5;
}

.tm-node:focus-visible rect {
    stroke: #ffffff;
    stroke-width: 2;
}

.tm-label { font-size: 12px; fill: #4b4230; }
.tm-leaf .tm-label { fill: #e2e2e9; }

.tm-num-bg { fill: #4b4230; }
.tm-num { font-size: 12px; fill: #f4ead3; }
.tm-flow-label { font-size: 13.5px; fill: #4b4230; }
.tm-flow-tag { font-size: 11.5px; fill: #6b5f48; }

.tm-badge-bg { fill: var(--blue, #5364fd); }
.tm-badge { font-size: 11.5px; fill: #ffffff; }

.tmap-note {
    min-height: 38px;
    margin: 10px 2px 0;
    padding-top: 8px;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 12.5px;
    line-height: 1.5;
    color: #a0a0ab;
}

.tmap-note strong {
    color: #ffffff;
    font-weight: 500;
}

/* Repeating-process ring / racetrack (topic-map.js, `lp: true`) */
.tm-orbit {
    fill: none;
    stroke: #4a4a55;
    stroke-width: 1.5;
    stroke-dasharray: 3 5;
}

.tm-loop {
    fill: none;
    stroke: #8f9bff;
    stroke-width: 1.5;
    stroke-dasharray: 3 5;
}

.tm-arrow { fill: #8f9bff; }
.tm-center { font-size: 12px; fill: #a0a0ab; }
.tm-loop-badge { fill: #26262c; stroke: #3a3a44; }
.tm-loop-icon { font-size: 14px; fill: #9aa5ff; }

.tmap-next {
    display: block;
    margin-top: 2px;
    color: #9aa5ff;
}

.tmap[data-kind="flow"] .tmap-note {
    min-height: 58px; /* room for note + "Next:" so the card doesn't jump between taps */
}
