<template>
  <div class="doc-detail-view">
    <a-spin :spinning="loading">
      <template v-if="document">
        <div class="doc-header">

          <h1>{{ document.title }}</h1>

          <div class="doc-meta-cards">
            <a-descriptions :column="4" bordered size="small">
              <a-descriptions-item label="文号">{{ document.doc_number || '-' }}</a-descriptions-item>
              <a-descriptions-item label="发文机关">{{ document.issuing_org || '-' }}</a-descriptions-item>
              <a-descriptions-item label="签发人">{{ document.signer || '-' }}</a-descriptions-item>
              <a-descriptions-item label="发文日期">{{ document.publish_date || '-' }}</a-descriptions-item>
              <a-descriptions-item label="文种">
                <a-tag color="blue">{{ document.doc_type || '-' }}</a-tag>
              </a-descriptions-item>
              <a-descriptions-item label="知识分类">
                <a-tag v-if="document.knowledge_category" color="green">{{ document.knowledge_category }}</a-tag>
                <span v-else>-</span>
              </a-descriptions-item>
              <a-descriptions-item label="主题词" :span="2">
                <a-tag v-for="kw in document.subject_words" :key="kw" color="blue">{{ kw }}</a-tag>
              </a-descriptions-item>
            </a-descriptions>
          </div>
        </div>

        <a-row :gutter="24" class="doc-main-layout">
          <a-col :span="17">
            <a-tabs v-model:activeKey="activeTab" class="doc-tabs">
              <a-tab-pane key="original" tab="原文">
                <div :class="['file-viewer-container', { 'file-viewer-paper': isWordFile }]">
                  <a-spin :spinning="previewLoading" tip="加载预览…">
                    <div v-if="previewError" class="file-placeholder">
                      <FileTextOutlined style="font-size: 48px; color: #bfbfbf" />
                      <p>{{ previewError }}</p>
                      <a-button type="primary" @click="downloadFile">
                        <DownloadOutlined /> 下载原文
                      </a-button>
                    </div>
                    <!-- PDF or blob HTML (frameset): blob URL in iframe -->
                    <iframe
                      v-else-if="previewBlobUrl"
                      :src="previewBlobUrl"
                      :class="['file-preview-iframe', { 'iframe-paper': isWordFile }]"
                      frameborder="0"
                    />
                    <!-- HTML: srcdoc in iframe -->
                    <iframe
                      v-else-if="previewHtml"
                      :srcdoc="previewHtml"
                      :class="['file-preview-iframe', { 'iframe-paper': isWordFile }]"
                      frameborder="0"
                    />
                  </a-spin>
                </div>
              </a-tab-pane>

              <a-tab-pane key="summary" tab="摘要">
                <a-card>
                  <MarkdownRenderer v-if="document.summary" :content="document.summary" />
                  <a-empty v-else description="暂无摘要" />
                </a-card>
              </a-tab-pane>

              <a-tab-pane key="graph" tab="知识图谱">
                <a-card :body-style="{ padding: 0, position: 'relative' }">
                  <div class="graph-toolbar" v-if="graphData">
                    <a-space>
                      <a-button size="small" @click="fitGraphView">适应画布</a-button>
                      <a-divider type="vertical" />
                      <span class="stats-text">
                        节点 {{ graphData.nodes.length }} | 边 {{ graphData.edges.length }}
                      </span>
                    </a-space>
                  </div>

                  <div ref="graphContainerRef" class="doc-graph-canvas" />

                  <div v-if="graphLoading" class="graph-overlay">
                    <a-spin tip="加载图谱…" />
                  </div>
                  <div v-else-if="!graphData || !graphData.nodes.length" class="graph-overlay graph-empty">
                    <a-empty description="暂无图谱数据" />
                  </div>
                </a-card>
              </a-tab-pane>

              <a-tab-pane key="related" tab="关联文件">
                <a-card>
                  <a-table
                    v-if="relatedDocs.length"
                    :data-source="relatedDocs"
                    :columns="relatedColumns"
                    size="small"
                    :pagination="false"
                    row-key="doc_id"
                  >
                    <template #bodyCell="{ column, record }">
                      <template v-if="column.key === 'relation_type'">
                        <a-tag :color="record.relation_type === '正文' ? 'blue' : 'orange'">
                          {{ record.relation_type }}
                        </a-tag>
                      </template>
                      <template v-else-if="column.key === 'title'">
                        <a @click="goToDocument(record.doc_id)">{{ record.title || record.doc_id }}</a>
                      </template>
                    </template>
                  </a-table>
                  <a-empty v-else description="暂无关联文件" />
                </a-card>
              </a-tab-pane>

              <a-tab-pane key="circulation" tab="公文流转意见">
                <a-card>
                  <a-empty description="待开发" />
                </a-card>
              </a-tab-pane>
            </a-tabs>
          </a-col>

          <a-col :span="7">
            <div class="governance-sidebar">
              <a-card title="政策依据链" size="small" :loading="governanceLoading">
                <a-empty v-if="policyChain.chain.length === 0" description="暂无依据链数据" />
                <div v-else class="doc-link-list">
                  <div v-for="item in policyChain.chain.slice(0, 5)" :key="item.doc_id" class="doc-link-item">
                    <div class="doc-link-title-row">
                      <a class="doc-link-title" @click="goToDocument(item.doc_id)">{{ item.title || item.doc_code || item.doc_id }}</a>
                      <StatusTag v-if="item.status" :status="item.status" />
                    </div>
                    <div class="doc-link-meta">{{ item.doc_code || '无文号' }}{{ item.publish_date ? ` · ${item.publish_date}` : '' }}</div>
                  </div>
                </div>
              </a-card>

              <a-card title="修订史" size="small" :loading="governanceLoading">
                <a-empty v-if="revisionHistory.documents.length === 0" description="暂无修订史数据" />
                <div v-else class="doc-link-list">
                  <div v-for="item in revisionHistory.documents.slice(0, 5)" :key="item.doc_id" class="doc-link-item">
                    <div class="doc-link-title-row">
                      <a class="doc-link-title" @click="goToDocument(item.doc_id)">{{ item.title || item.doc_code || item.doc_id }}</a>
                      <StatusTag v-if="item.status" :status="item.status" />
                    </div>
                    <div class="doc-link-meta">{{ item.doc_code || '无文号' }}{{ item.publish_date ? ` · ${item.publish_date}` : '' }}</div>
                  </div>
                </div>
              </a-card>

              <a-card title="推荐与同主题" size="small" :loading="governanceLoading">
                <a-empty v-if="recommendationTotal === 0" description="暂无推荐数据" />
                <template v-else>
                  <div v-if="recommendations.same_org.length" class="recommendation-section">
                    <div class="section-title">同机构</div>
                    <div v-for="item in recommendations.same_org.slice(0, 3)" :key="item.doc_id" class="doc-link-item">
                      <a class="doc-link-title" @click="goToDocument(item.doc_id)">{{ item.title }}</a>
                      <div class="doc-link-meta">{{ item.shared_entity || '同机构' }}</div>
                    </div>
                  </div>

                  <div v-if="sameThemeDocs.length" class="recommendation-section">
                    <div class="section-title">同主题</div>
                    <div v-for="item in sameThemeDocs.slice(0, 3)" :key="item.doc_id" class="doc-link-item">
                      <a class="doc-link-title" @click="goToDocument(item.doc_id)">{{ item.title }}</a>
                      <div class="doc-link-meta">{{ item.theme_name || '同主题' }}</div>
                    </div>
                  </div>

                  <div v-if="recommendations.same_region.length" class="recommendation-section">
                    <div class="section-title">同地域</div>
                    <div v-for="item in recommendations.same_region.slice(0, 3)" :key="item.doc_id" class="doc-link-item">
                      <a class="doc-link-title" @click="goToDocument(item.doc_id)">{{ item.title }}</a>
                      <div class="doc-link-meta">{{ item.shared_entity || '同地域' }}</div>
                    </div>
                  </div>
                </template>
              </a-card>

              <a-card title="操作" size="small">
                <a-space direction="vertical" style="width: 100%">
                  <a-button block type="primary" @click="askAboutDocument">问这篇文档</a-button>
                  <a-button block @click="openGuideDetailByDoc">查看结构化指南</a-button>
                  <a-button block @click="openImportDialog">加入资料篮</a-button>
                  <a-button block @click="router.push('/graph')">前往图谱页</a-button>
                  <a-button block type="primary" ghost @click="downloadFile">下载原文</a-button>
                </a-space>
              </a-card>
            </div>
          </a-col>
        </a-row>

        <ImportToResearchDialog
          v-model:open="importDialogOpen"
          :items="importPreviewItems"
          title="将当前文档加入资料篮"
          :extra-options="importExtraOptions"
          @confirm="handleImportConfirm"
        />
      </template>

      <a-result v-else-if="!loading" status="404" title="文档未找到" sub-title="请检查文档ID是否正确">
        <template #extra>
          <a-button type="primary" @click="router.push('/search')">返回搜索</a-button>
        </template>
      </a-result>
    </a-spin>
  </div>
</template>

/**
 * 文档详情视图
 * 展示单篇公文的完整信息：元数据、原文预览/下载、摘要、知识图谱可视化。
 * 右侧边栏展示治理增强信息：政策依据链、修订史、推荐同主题文档。
 * 支持文档导入 Research、查看结构化指南、图谱跳转与原文下载等操作。
 */
<script setup lang="ts">
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { useRoute, useRouter } from 'vue-router'
import { DownloadOutlined, FileTextOutlined } from '@ant-design/icons-vue'
import { downloadDocumentFile, getDocumentDetail, getDocumentGraph } from '@/api/document'
import request from '@/api/request'
import { findServiceGuideByDoc } from '@/api/serviceGuide'
import {
  getDocumentRecommendations,
  getPolicyChain,
  getRevisionHistory,
  getSameThemeDocuments,
} from '@/api/graph'
import ImportToResearchDialog from '@/components/ImportToResearchDialog.vue'
import MarkdownRenderer from '@/components/MarkdownRenderer.vue'
import StatusTag from '@/components/StatusTag.vue'
import { useG6Graph } from '@/composables/useG6Graph'
import { useResearchImport } from '@/composables/useResearchImport'
import { useBasketStore } from '@/stores/basket'
import { useTabsStore } from '@/stores/tabs'
import type { BasketItem } from '@/types/basket'
import type { DocumentDetail } from '@/types/document'
import type {
  DocumentRecommendations,
  GraphData,
  PolicyChainResponse,
  RevisionHistoryResponse,
  SameThemeDocItem,
} from '@/types/graph'
import type {
  ImportDialogExtraOption,
  ResearchImportDialogPayload,
} from '@/types/research-import'
import { getNodeColor } from '@/utils/graphLabels'

function getLabelColor(label: string) {
  return getNodeColor(label)
}

// G6 图谱 composable（只读模式：无 tooltip、无 onNodeClick）
const { graphInstance, initGraph, renderGraph, fitView: fitGraphView, destroy: destroyGraph } = useG6Graph({
  layoutType: 'preset',
})

const route = useRoute()
const router = useRouter()
const basketStore = useBasketStore()
const { applyImport } = useResearchImport()
const tabsStore = useTabsStore()

const currentDocId = computed(() => String(route.params.id || ''))

const document = ref<DocumentDetail | null>(null)
const graphData = ref<GraphData | null>(null)
const recommendations = ref<DocumentRecommendations>({
  same_org: [],
  same_theme: [],
  same_region: [],
})
const policyChain = ref<PolicyChainResponse>({ chain: [], edges: [] })
const revisionHistory = ref<RevisionHistoryResponse>({ documents: [], edges: [] })
const sameThemeDocs = ref<SameThemeDocItem[]>([])
const loading = ref(true)
const graphLoading = ref(false)
const governanceLoading = ref(false)
const activeTab = ref('original')
const importDialogOpen = ref(false)

// ── Preview state ──
const previewLoading = ref(true)
const previewError = ref('')
const previewBlobUrl = ref('')
const previewHtml = ref('')
const isWordFile = computed(() => {
  const ft = (document.value?.file_type || '').toLowerCase()
  return ['doc', 'docx', 'wps'].includes(ft)
})

function syncDocumentPageTitle(title?: string) {
  const normalizedTitle = title?.trim()
  if (!normalizedTitle) return
  tabsStore.updateTabTitle(route.path, normalizedTitle)
  window.document.title = `${normalizedTitle} - 政务文档智能检索系统`
}

/** 通过 axios（带 JWT）获取预览内容，按 content-type 分别处理 PDF / HTML */
/**
 * 加载文档预览。
 * PDF 直接用本地文件路径生成 blob URL；
 * 其他格式直接调 converter 服务（不经过 Python 后端，避免阻塞其他 API 请求）。
 */
async function loadPreview(docId: string) {
  previewLoading.value = true
  previewError.value = ''
  previewHtml.value = ''
  if (previewBlobUrl.value) {
    URL.revokeObjectURL(previewBlobUrl.value)
    previewBlobUrl.value = ''
  }

  try {
    const doc = document.value
    if (!doc) throw new Error('Document not loaded')

    const contentHash = doc.content_hash
    const fileType = (doc.file_type || 'pdf').toLowerCase()

    if (!contentHash) throw new Error('No content hash')

    if (fileType === 'pdf') {
      // PDF: fetch from Python backend (fast, just serves the file)
      const res = await request.get(`/api/ai/v1/document/preview/${docId}`, {
        responseType: 'arraybuffer',
      })
      const blob = new Blob([res.data], { type: 'application/pdf' })
      previewBlobUrl.value = URL.createObjectURL(blob)
      return
    }

    // Other formats: call converter directly (bypasses Python backend)
    const dockerPath = `/data/files/${contentHash}.${fileType}`
    const res = await request.get('/api/converter/preview', {
      params: { filePath: dockerPath, ext: fileType, hash: contentHash },
      responseType: 'arraybuffer',
    })

    const decoder = new TextDecoder('utf-8')
    let html = decoder.decode(res.data)

    const isFrameset = /<frameset[\s>]/i.test(html)
    const isWord = ['doc', 'docx', 'wps'].includes(fileType)

    if (isFrameset) {
      // Frameset HTML (e.g. Excel): rewrite sub-resource paths to converter proxy
      // {hash}_files/xxx → /api/converter/preview/resource/{hash}/xxx
      html = html.replace(
        new RegExp(`${contentHash}_files/`, 'g'),
        `${window.location.origin}/api/converter/preview/resource/${contentHash}/`,
      )
      const blob = new Blob([html], { type: 'text/html;charset=utf-8' })
      previewBlobUrl.value = URL.createObjectURL(blob)
    } else {
      const baseTag = `<base href="${window.location.origin}/" />`
      const injectStyle = isWord
        ? `<style>
            html, body { margin: 0; padding: 0; background: #fff; }
            body { padding: 60px 72px; box-sizing: border-box; }
          </style>`
        : `<style>
            html, body { margin: 0; padding: 0; background: #fff; width: 100%; }
          </style>`
      if (html.includes('</head>')) {
        html = html.replace('</head>', baseTag + injectStyle + '</head>')
      } else {
        html = baseTag + injectStyle + html
      }
      previewHtml.value = html
    }
  } catch {
    previewError.value = '预览加载失败，请下载原文查看'
  } finally {
    previewLoading.value = false
  }
}

const graphContainerRef = ref<HTMLDivElement>()

const importExtraOptions: ImportDialogExtraOption[] = [
  {
    key: 'include-policy-chain',
    label: '同时加入依据链文件',
    description: '将当前文档的政策依据链文件一并导入本次 Research。',
  },
]

const importPreviewItems = computed<BasketItem[]>(() => {
  if (!document.value) return []
  return [
    {
      item_type: 'document',
      title: document.value.title,
      selected_from: 'detail',
      importance: 'reference',
      doc_id: document.value.doc_id,
      content_hash: document.value.content_hash,
      doc_code: document.value.doc_number,
      added_at: Date.now(),
    },
  ]
})

const relatedDocs = computed(() => document.value?.related_docs || [])
const relatedColumns = [
  { title: '类型', key: 'relation_type', dataIndex: 'relation_type', width: 80 },
  { title: '文档标题', key: 'title', dataIndex: 'title' },
]

const recommendationTotal = computed(() => {
  return (
    recommendations.value.same_org.length +
    recommendations.value.same_region.length +
    sameThemeDocs.value.length
  )
})

/** 初始化 G6 图谱实例并渲染图谱数据（延迟加载 G6 以减小首屏体积） */
async function initAndRender() {
  if (!graphContainerRef.value || !graphData.value?.nodes.length) return

  // 首次初始化 G6 实例
  if (!graphInstance.value) {
    await initGraph(
      graphContainerRef.value,
      graphContainerRef.value.clientWidth,
      graphContainerRef.value.clientHeight || 480,
    )
  }

  // 渲染数据
  const { nodes, edges } = graphData.value
  await renderGraph(nodes, edges)
}

async function maybeRender() {
  if (activeTab.value !== 'graph') return
  if (!graphData.value?.nodes.length) return
  await nextTick()
  await initAndRender()
}

watch(activeTab, maybeRender)
watch(graphData, maybeRender)

watch(
  () => route.query.tab,
  (tab) => {
    if (tab === 'graph' || tab === 'summary' || tab === 'original') {
      activeTab.value = tab
    }
  },
  { immediate: true },
)

/** 并行加载治理增强数据：推荐文档、依据链、修订史、同主题文档 */
async function loadGovernance(docId: string) {
  governanceLoading.value = true
  recommendations.value = { same_org: [], same_theme: [], same_region: [] }
  policyChain.value = { chain: [], edges: [] }
  revisionHistory.value = { documents: [], edges: [] }
  sameThemeDocs.value = []

  const results = await Promise.allSettled([
    getDocumentRecommendations(docId),
    getPolicyChain(docId),
    getRevisionHistory(docId),
    getSameThemeDocuments(docId),
  ])

  if (results[0].status === 'fulfilled') recommendations.value = results[0].value
  if (results[1].status === 'fulfilled') policyChain.value = results[1].value
  if (results[2].status === 'fulfilled') revisionHistory.value = results[2].value
  if (results[3].status === 'fulfilled') sameThemeDocs.value = results[3].value

  governanceLoading.value = false
}

async function loadDocument(docId: string) {
  loading.value = true
  document.value = null
  graphData.value = null

  try {
    document.value = await getDocumentDetail(docId)
    syncDocumentPageTitle(document.value.title)

    graphLoading.value = true
    getDocumentGraph(docId)
      .then((data) => {
        graphData.value = data
      })
      .catch(() => {
        graphData.value = null
      })
      .finally(() => {
        graphLoading.value = false
      })

    // 并行加载预览和治理增强数据（不阻塞主流程）
    loadPreview(docId)
    loadGovernance(docId).catch(() => {
      message.warning('治理增强信息加载失败，已保留正文查看能力')
    })
  } catch (error) {
    console.error('Failed to load document:', error)
  } finally {
    loading.value = false
  }
}

watch(
  currentDocId,
  (docId) => {
    if (docId) {
      loadDocument(docId)
    }
  },
  { immediate: true },
)

onUnmounted(() => {
  destroyGraph()
  if (previewBlobUrl.value) {
    URL.revokeObjectURL(previewBlobUrl.value)
  }
})

function openImportDialog() {
  if (!document.value || !importPreviewItems.value.length) return
  const added = basketStore.addItem(importPreviewItems.value[0])
  if (added) {
    message.success('已加入资料篮')
  } else {
    message.warning('该资料已在资料篮中')
  }
}

function goToDocument(docId: string) {
  if (!docId) return
  router.push(`/doc/${docId}`)
}

async function openGuideDetailByDoc() {
  if (!document.value?.doc_id) return

  try {
    const detail = await findServiceGuideByDoc(document.value.doc_id)
    if (!detail) {
      message.info('当前文档暂无办事指南结构化详情')
      return
    }
    router.push(`/guides/${detail.profile_id}`)
  } catch (error) {
    console.error('Guide detail not available for document:', error)
    message.error('办事指南入口打开失败，请稍后重试')
  }
}

function askAboutDocument() {
  if (!document.value) return
  router.push({
    path: '/qa',
    query: {
      launchKey: String(Date.now()),
      kind: 'document',
      docId: document.value.doc_id,
      title: document.value.title,
      docCode: document.value.doc_number || '',
      prompt: `请围绕《${document.value.title}》梳理其核心要求、适用对象、执行要点与关联依据。`,
    },
  })
}

/** 构建导入 Research 的资料列表；若用户勾选了"同时加入依据链"则附带依据链文档 */
function buildImportItems(payload: ResearchImportDialogPayload): BasketItem[] {
  const baseItems = [...importPreviewItems.value]
  if (!payload.selectedExtraKeys.includes('include-policy-chain')) {
    return baseItems
  }

  const chainItems = policyChain.value.chain
    .filter((item) => item.doc_id && item.doc_id !== document.value?.doc_id)
    .map<BasketItem>((item) => ({
      item_type: 'document',
      title: item.title || item.doc_code || item.doc_id,
      selected_from: 'detail',
      importance: 'reference',
      doc_id: item.doc_id,
      doc_code: item.doc_code,
      added_at: Date.now(),
    }))

  return [...baseItems, ...chainItems]
}

function handleImportConfirm(payload: ResearchImportDialogPayload) {
  const items = buildImportItems(payload)
  applyImport(items, payload)
}

async function downloadFile() {
  try {
    const doc = document.value
    if (!doc) return
    const title = doc.title || currentDocId.value
    const ext = doc.file_type || 'pdf'
    await downloadDocumentFile(doc.doc_id, `${title}.${ext}`)
  } catch (error) {
    console.error('File download failed:', error)
    message.error('原文下载失败')
  }
}
</script>

<style scoped lang="less">
.doc-detail-view {
  padding: 24px;
  max-width: 1400px;
  margin: 0 auto;

  .doc-header {
    margin-bottom: 24px;

    h1 {
      font-size: 22px;
      margin: 0 0 16px;
    }
  }

  .doc-main-layout {
    align-items: flex-start;
  }

  .doc-tabs {
    .file-viewer-container {
      min-height: calc(100vh - 280px);
      background: #f5f5f5;
      border-radius: 8px;
      position: relative;
      width: 100%;

      :deep(.ant-spin-nested-loading),
      :deep(.ant-spin-container) {
        width: 100%;
      }

      // Default: fill full width (PDF, Excel, PPT, etc.)
      .file-preview-iframe {
        display: block;
        width: 100%;
        height: calc(100vh - 280px);
        min-height: 1000px;
        border: none;
        background: #fff;
      }

      // Word documents: A4 paper style with shadow
      .file-preview-iframe.iframe-paper {
        width: 794px; // A4 width at 96dpi (210mm)
        max-width: 100%;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
      }

      // Paper container: centered with gray background
      &.file-viewer-paper {
        background: #d6d6d6;
        display: flex;
        justify-content: center;
        padding: 20px 0;

        :deep(.ant-spin-nested-loading),
        :deep(.ant-spin-container) {
          display: flex;
          justify-content: center;
        }
      }

      .file-placeholder {
        text-align: center;
        padding: 48px 24px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        min-height: calc(100vh - 280px);

        p {
          color: #8c8c8c;
          margin: 16px 0;
          font-size: 14px;
        }
      }
    }
  }

  .governance-sidebar {
    display: flex;
    flex-direction: column;
    gap: 16px;
    position: sticky;
    top: 16px;
  }

  .doc-link-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .doc-link-item {
    padding-bottom: 10px;
    border-bottom: 1px solid #f0f0f0;

    &:last-child {
      border-bottom: none;
      padding-bottom: 0;
    }
  }

  .doc-link-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
  }

  .doc-link-title {
    color: #1677ff;
    font-size: 13px;
  }

  .doc-link-meta {
    margin-top: 4px;
    color: #8c8c8c;
    font-size: 12px;
  }

  .recommendation-section + .recommendation-section {
    margin-top: 12px;
  }

  .section-title {
    font-size: 12px;
    color: #8c8c8c;
    margin-bottom: 8px;
    font-weight: 600;
  }
}

.graph-toolbar {
  padding: 8px 12px;
  border-bottom: 1px solid #f0f0f0;
  background: #fafafa;

  .stats-text {
    font-size: 12px;
    color: #8c8c8c;
  }
}

.doc-graph-canvas {
  width: 100%;
  height: 500px;
}

.graph-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.7);
  pointer-events: none;

  &.graph-empty {
    background: transparent;
  }
}
</style>
