/* =========================================================================
   Mind Map — NotebookLM-style branch map.

   Nodes are DOM elements, not canvas drawings, which is what makes the text
   always readable at any zoom, always complete, and selectable. Movement is a
   CSS transform transition: the compositor runs it, so it stays smooth even
   while the rest of the page is busy.
   ========================================================================= */

/* The modal's own box. It is here rather than inline in index.html so that
   the fullscreen rules below can simply override it. */
.mm-container {
    width: 96%;
    height: 92%;
    border-radius: 14px;
}

/* Two ways to fill the screen, because they are not equally available.
   :fullscreen is the real thing — the browser's own chrome goes away too —
   but requestFullscreen() is missing on iOS Safari for anything that is not a
   <video>, and it is refused outright inside an iframe without allowfullscreen.
   .is-fullscreen is what runs then: the modal already covers the viewport, so
   the container just stops leaving a margin around itself. */
.mm-container:fullscreen,
.mm-container.is-fullscreen {
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.mm-stage {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: #1b1c1e;
    cursor: grab;
    touch-action: none;
    user-select: none;
}

.mm-stage.is-panning {
    cursor: grabbing;
}

/* Everything is laid out in one un-scrolled plane and the plane is moved.
   `will-change` is deliberately NOT on by default: it pins the plane into a
   compositor layer rastered at the scale it had when the layer was made, so
   zooming in blew that bitmap up and the text went soft. The class is added
   only while something is actually moving; the moment it comes off the browser
   re-rasterises at the current scale and the text is sharp again. */
.mm-world {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
}

.mm-world.is-moving {
    will-change: transform;
}

.mm-links {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 1px;
    overflow: visible;
    pointer-events: none;
}

/* One colour per depth, so a branch stays the same colour all the way out. */
.mm-link {
    fill: none;
    stroke: rgba(154, 168, 189, 0.55);
    stroke-width: 1.6;
    stroke-linecap: round;
}

.mm-link.mm-depth-1 { stroke: rgba(147, 158, 214, 0.6); }
.mm-link.mm-depth-2 { stroke: rgba(129, 178, 214, 0.6); }
.mm-link.mm-depth-3 { stroke: rgba(214, 179, 129, 0.55); }
.mm-link.mm-depth-4 { stroke: rgba(197, 148, 197, 0.55); }
.mm-link.mm-depth-5 { stroke: rgba(140, 176, 152, 0.55); }

/* ------------------------------------------------------------------ node */

.mm-node {
    position: absolute;
    top: 0;
    left: 0;
    /* max-content, not shrink-to-fit: an absolutely positioned flex box sizes
       itself to its min-content width, and with wrapping enabled that is one
       character — the nodes came out 70px wide and 300px tall. */
    width: max-content;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px 9px 14px;
    border-radius: 9px;
    background: #3a4450;
    color: #f1f3f4;
    font-family: 'Google Sans', 'Segoe UI', system-ui, sans-serif;
    font-size: 13.5px;
    line-height: 1.35;
    letter-spacing: 0.1px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    /* The one line that makes the map move smoothly. */
    transition: transform 420ms cubic-bezier(.4, 0, .2, 1),
                opacity 260ms ease,
                background-color 160ms ease;
}

/* Hover only where a pointer can actually hover. On a touch screen the
   state latches after a tap, so the node you just opened stays lit and reads
   as selected while you tap the next one. :active below is the touch feedback
   instead. */
@media (hover: hover) {
    .mm-node:hover {
        background: #46525f;
    }
}

.mm-node:active {
    background: #46525f;
}

.mm-node-text {
    display: block;
    white-space: normal;
    /* break-word, never "anywhere": the latter also shrinks the box's
       intrinsic min-content width, which is what collapsed every node into a
       column of single letters. */
    overflow-wrap: break-word;
}

/* The chapter itself: bigger, and it reads as the trunk. */
.mm-node.is-root {
    background: #33404d;
    font-size: 15px;
    font-weight: 600;
    padding: 12px 14px 12px 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}

/* A leaf carries content rather than structure, so it gets the green. */
.mm-node.is-leaf {
    background: #2f4a3f;
}

@media (hover: hover) {
    .mm-node.is-leaf:hover {
        background: #37564a;
    }
}

.mm-node.is-leaf:active {
    background: #37564a;
}

/* NotebookLM puts the chevron in its own little square at the node's edge. */
.mm-toggle {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 2px;
    border: none;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.09);
    color: #e8eaed;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 160ms ease;
}

@media (hover: hover) {
    .mm-node:hover .mm-toggle {
        background: rgba(255, 255, 255, 0.16);
    }
}

/* A branch that has just appeared grows out of its parent. */
.mm-node.is-entering {
    opacity: 0;
    transform-origin: 0 50%;
}

.mm-node.is-leaving {
    opacity: 0;
    pointer-events: none;
}

/* --------------------------------------------------------------- controls */

.mm-controls {
    position: absolute;
    right: 18px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    gap: 8px;
    z-index: 3;
}

.mm-controls button {
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    background: rgba(40, 44, 50, 0.92);
    color: #e8eaed;
    font-size: 15px;
    cursor: pointer;
    backdrop-filter: blur(6px);
    transition: background-color 160ms ease, border-color 160ms ease;
}

.mm-controls button:hover {
    background: rgba(58, 68, 80, 0.96);
    border-color: rgba(255, 255, 255, 0.22);
}

.mm-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    text-align: center;
    color: #9aa0a6;
    font-size: 0.95rem;
}

@media (prefers-reduced-motion: reduce) {
    .mm-node,
    .mm-world {
        transition: none !important;
    }
}

@media (max-width: 720px) {
    .mm-node {
        font-size: 12.5px;
        padding: 8px 10px 8px 12px;
    }

    .mm-controls {
        right: 10px;
    }

    .mm-controls button {
        width: 34px;
        height: 34px;
    }
}

/* The header carries a title and, now, six controls. Flex resolves a row that
   cannot fit by crushing the item that is allowed to shrink — which is the
   title, so on a narrow screen the chapter name disappeared entirely rather
   than the row wrapping. Wrapping is the honest answer, and the title keeps a
   floor and an ellipsis so it always reads as a name that has been cut short. */
.mm-header {
    flex-wrap: wrap;
    gap: 8px;
}

.mm-header > div:last-child {
    flex-wrap: wrap;
    justify-content: flex-end;
}

#mm-title {
    flex: 1 1 auto;
    min-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Header buttons in the modal chrome. */
.mm-head-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 13px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.05);
    color: #cfd4da;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}

.mm-head-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.24);
    color: #f1f3f4;
}

/* Only fullscreen holds a state, and it says so the same way the segmented
   switches beside it do. */
.mm-head-btn.is-active {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(255, 255, 255, 0.28);
    color: #f1f3f4;
}

/* The header is a single row that already carries three buttons and two
   switches; on a narrow screen the fullscreen label is the first thing that
   can go, because its icon says the same thing. */
@media (max-width: 720px) {
    #mm-fullscreen-btn span {
        display: none;
    }

    .mm-head-btn {
        padding: 7px 10px;
    }

    #mm-title {
        min-width: 100px;
        font-size: 1rem;
    }
}

/* Two-way segmented switches in the header: direction and language. */
.mm-seg {
    display: inline-flex;
    padding: 2px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
}

.mm-seg button {
    min-width: 36px;
    padding: 5px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: #9aa0a6;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 160ms ease, color 160ms ease;
}

.mm-seg button:hover {
    color: #e8eaed;
}

.mm-seg button.is-active {
    background: rgba(255, 255, 255, 0.14);
    color: #f1f3f4;
}

/* ------------------------------------------------------------- galaxy mode

   The canvas covers the stage and takes the pointer itself: dragging orbits
   the cloud rather than panning the tidy map underneath, which is still in the
   DOM (hidden) so its expanded branches survive the trip. */

.mm-stage.is-galaxy .mm-world,
.mm-stage.is-galaxy .mm-links {
    display: none;
}

.mm-stage.is-galaxy {
    cursor: default;
    background: #0a0d14;
}

.mm-galaxy {
    position: absolute;
    inset: 0;
    display: block;
    cursor: grab;
    touch-action: none;
}

.mm-galaxy:active {
    cursor: grabbing;
}


/* ------------------------------------------------------------------ touch */

/* A finger is about 9mm wide and has no hover to aim with, so every target
   here is sized up rather than down. This block sits last in the file so it
   wins over the `max-width: 720px` rules above, which shrink the node for a
   narrow screen — narrow and touch are not the same thing, and a phone is
   both. `pointer: coarse` is the touch screen itself, not the window size, so
   a desktop browser resized to phone width keeps the compact map. */
@media (pointer: coarse) {
    .mm-node {
        font-size: 13.5px;
        padding: 11px 13px 11px 15px;
        gap: 10px;
    }

    .mm-node.is-root {
        font-size: 15px;
        padding: 13px 15px 13px 17px;
    }

    .mm-toggle {
        width: 26px;
        height: 26px;
        font-size: 16px;
    }

    .mm-controls {
        gap: 10px;
    }

    .mm-controls button {
        width: 42px;
        height: 42px;
        font-size: 17px;
    }
}
