Usages:
  conventions: .goga/usages/conventions.md
  frontend_styling: .goga/usages/frontend_styling.md
  js_rendering: |
    Требования к JS-функциям.

    Структура данных graph (получена из API /api/graph):
    - graph.cells[] — массив объектов: {name, description, types[], usages[], children[],
      dependencies[{from_cell, to_cell, types[], usages[]}]}
    - graph.edges[] — массив объектов: {from_cell, to_cell, types[], usages[]}

    Параметры:
    - graph_json_url — URL API для загрузки данных графа
    - Иконки — data URI для SVG-иконок секций, узлов дерева и действий

    Глобальное состояние:
    - selectedCells — набор имён выделенных cells. Используется для
      мультивыделения в sidebar. Toggle по клику: повторный клик снимает выделение.

    Функции:
    - render_graph(container_id, graph) — отображает ориентированный граф зависимостей.
      Узлы — cells с именем и описанием, рёбра — зависимости между cells.
      Использовать иерархический layout (dagre).
    - highlight_cell(cell_name, cy_instance) — подсвечивает cell и все её связи,
      остальные узлы затемняются. Используется при hover на node в графе.
    - apply_filter(cy_instance) — фильтрует граф по текущему набору выделенных cells
      (selectedCells). Для каждой cell из набора — показать её и все связанные элементы.
      Показывает union всех связанных элементов, скрывает остальные.
      Подсвечивает выделенные cells и их рёбра.
      Если selectedCells пуст — показывает весь граф.
    - reset_filter(cy_instance) — сбрасывает фильтрацию: очищает выделение,
      показывает все элементы, снимает все визуальные эффекты подсветки/затемнения,
      снимает выделение с узлов дерева.
    - show_cell_info(cell_name, graph) — показывает панель с информацией о cell.
      При показе скролл сбрасывается в начало.
      Секции: Name, Description, Types, Usages (если есть), Consumers (если есть), Dependencies (если есть).
      В секции Types каждый элемент является кликабельной ссылкой — при клике
      открывается/переиспользуется панель CODEMANIFEST, находится строка с объявлением типа,
      строка подсвечивается. Ссылки стилистически равнозначны usage-ссылкам.
      В секции Usages каждый элемент является кликабельной ссылкой — при клике
      открывается модальное окно с содержимым соответствующего usage-файла.
      Ссылка «CODEMANIFEST» в фиксированном footer внизу панели — всегда видима,
      не скроллируется. Аналогично кнопке «Reset» в sidebar.
    - show_codemanifest(cell_name, graph, highlightType) — открывает панель с содержимым CODEMANIFEST.
      Содержимое загружается без кеширования — каждый клик инициирует новый запрос.
      Если передан highlightType — после загрузки панели строка с объявлением
      указанного типа подсвечивается.
      YAML-контент подсвечивается синтаксически: ключи (включая ключи
      в кавычках и внутри элементов списка), комментарии, разделители,
      операторы многострочности, логические значения, числа и inline-код
      в обратных кавычках. Содержимое многострочных блоков (|, >)
      не подсвечивается — символ # внутри считается текстом, а не комментарием.
      Панель заполняет всё пространство между sidebar и info panel.
      При 404 показывает «CODEMANIFEST not found».
      При сетевой ошибке показывает сообщение об ошибке.
      Панель закрывается крестиком.
    - render_tree(container_id, graph, cy_instance) — строит дерево вложенности cells
      в sidebar. Дерево полностью раскрыто, в скроллируемом контейнере.
      Корневые cells — те, чьё имя отсутствует в children других cells.
      Каждый узел показывает иконку, короткое имя cell (последний сегмент пути),
      бейдж с количеством зависимостей.
      Клик по узлу дерева toggle'ит выделение:
      повторный клик по выделенной cell снимает выделение, клик по невыделенной — добавляет.
      После каждого клика обновляется фильтрация графа.
      Кнопка «Reset» сбрасывает выделение и показывает весь граф.
    - _init_custom_scroll(wrapper) — инициализирует кастомный скроллбар для
      скроллируемого контейнера. Поддерживает drag для прокрутки перетаскиванием.
      Если контент не переполняется — скроллбар скрывается.
    - _highlight_yaml(text) — YAML-подсветка синтаксиса.
      Дополнительно распознаёт пути к .md файлам в значениях секции Usages
      и делает их кликабельными ссылками.
    - _highlight_type_line(typeName) — подсвечивает строку с объявлением типа
      в панели CODEMANIFEST. Строка определяется как содержащая имя типа,
      за которым следует символ, не являющийся буквой, цифрой или подчёркиванием.
      Каждое новое нажатие снимает предыдущую подсветку.
      Скролл автоматически позиционирует подсвеченную строку в видимую область.
    - _navigate_to_type(typeName, cellName, graph) — обеспечивает навигацию к типу:
      открывает CODEMANIFEST с подсветкой типа, если панель не была открыта;
      подсвечивает строку типа, если панель уже открыта.
    - _open_usage(mdPath) — загружает содержимое usage .md файла и показывает
      в модальном окне. При 404 — «File not found». При сетевой ошибке — сообщение об ошибке.
    - _show_usage_modal(title, markdownContent) — показывает модальное окно
      с рендеренным Markdown. Закрытие: клик на overlay, кнопка ×, клавиша Escape.
      Заголовок — имя файла (последний сегмент пути).
      Модальное окно центрировано.

Annotations: |
  Использовать `conventions` для правил написания кода и тестов.

  SPA-приложение для отображения графа зависимостей cells.
  HTML, CSS и JS разделены на отдельные ресурсы.
  Тёмная тема в стиле qarium.ru/goga с фирменными цветами.

  Используй `frontend_styling` для требований к визуальному оформлению:
  - дизайн-токены
  - layout
  - стили графа, sidebar и информационной панели

  Используй `js_rendering` для требований к JS-функциям.

---

"index_page(graph_json_url: str) -> html:str":
  location: pages.py
  annotations: |
    Генерирует HTML-страницу SPA с тёмной темой qarium.ru/goga.
    HTML, CSS и JS разделены на отдельные ресурсы.
    Включает: хедер с логотипом и backdrop-blur,
    футер с копирайтом, sidebar фиксированной ширины (260px) слева с деревом
    вложенности cells, стилизованный граф справа от sidebar,
    информационную панель как карточку справа.

    Sidebar и info panel должны иметь кастомный скроллбар: тонкий стилизованный thumb,
    поддержка drag для прокрутки перетаскиванием, скрытие thumb при отсутствии переполнения.
    Должен работать fallback для браузеров без нативной поддержки стилизации scrollbar.

    В info panel внизу — ссылка «CODEMANIFEST» (аналог «Reset» в sidebar).
    При клике открывается центральная панель между sidebar и info panel.
    Центральная панель показывает содержимое CODEMANIFEST как yaml-код (<pre><code>).
    Содержимое загружается без кеширования — каждый клик инициирует новый запрос.
    Панель закрывается крестиком. При переполнении — скроллинг.
    При 404 — «CODEMANIFEST not found». При сетевой ошибке — сообщение об ошибке.

    Sidebar содержит полностью раскрытое дерево вложенности cells.
    Дерево строится рекурсивно из children[] в graph.cells.
    Клик по узлу дерева toggle'ит выделение cell — повторный клик снимает выделение.
    Видны все выделенные cells и их связи (union).
    Кнопка «Reset» сбрасывает выделение — все узлы видимы.
    Активный узел дерева подсвечивается бордером слева teal.

    `graph_json_url`: URL API-эндпоинта для загрузки данных графа

    `html`: полная HTML-страница как строка

    Используй `js_rendering` для требований к JS-функциям.

    Favicon подключается через <link>.

---

Author: Goga
CreatedAt: 09/05/26
Description: |
  SPA-приложение — HTML-файл со внешними CSS и JS для графа зависимостей cells.
  Тёмная тема в стиле qarium.ru/goga.
