This commit is contained in:
aaron 2025-05-15 00:58:54 +08:00
parent 35448085c5
commit 398ec0306e
5 changed files with 377 additions and 254 deletions

View File

@ -5,7 +5,7 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
image: tradus-web:1.11 image: tradus-web:1.12
container_name: tradus-web container_name: tradus-web
ports: ports:
- '6000:80' - '6000:80'

View File

@ -1159,7 +1159,6 @@ body {
.chat-container { .chat-container {
margin-left: 0; margin-left: 0;
padding-top: 4.5rem;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
} }

View File

@ -96,3 +96,22 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
/* 全局滚动条样式 */
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background-color: rgba(125, 125, 125, 0.2);
border-radius: 3px;
}
*::-webkit-scrollbar-thumb:hover {
background-color: rgba(125, 125, 125, 0.3);
}

View File

@ -9,6 +9,7 @@ const analysisContent = ref('')
const analysisContainer = ref<HTMLElement | null>(null) const analysisContainer = ref<HTMLElement | null>(null)
const currentThought = ref('') const currentThought = ref('')
const showInitialView = ref(true) const showInitialView = ref(true)
const copySuccess = ref(false)
// APIURL // APIURL
const apiBaseUrl = const apiBaseUrl =
@ -138,6 +139,24 @@ const clearInput = () => {
analysisContent.value = '' analysisContent.value = ''
currentThought.value = '' currentThought.value = ''
} }
const copyAnalysis = async () => {
if (!analysisContent.value) return
try {
const tempDiv = document.createElement('div')
tempDiv.innerHTML = analysisContent.value
const textContent = tempDiv.textContent || tempDiv.innerText || ''
await navigator.clipboard.writeText(textContent)
copySuccess.value = true
setTimeout(() => {
copySuccess.value = false
}, 2000)
} catch {
console.error('复制失败')
}
}
</script> </script>
<template> <template>
@ -201,7 +220,7 @@ const clearInput = () => {
<div v-else class="analysis-view"> <div v-else class="analysis-view">
<div class="analysis-header"> <div class="analysis-header">
<div class="target-info"> <div class="target-info">
<span class="label">正在分析</span> <span class="label">正在分析股票</span>
<span class="value">{{ stockCode }}</span> <span class="value">{{ stockCode }}</span>
</div> </div>
<button class="new-analysis-button" @click="resetView" :disabled="isAnalyzing"> <button class="new-analysis-button" @click="resetView" :disabled="isAnalyzing">
@ -231,8 +250,8 @@ const clearInput = () => {
<span></span> <span></span>
</div> </div>
<div class="status-text"> <div class="status-text">
<div class="status-label">AI分析进行中</div> <div class="status-label">AI 正在分析</div>
<div v-if="currentThought" class="thought-text">{{ currentThought }}</div> <!-- <div v-if="currentThought" class="thought-text">{{ currentThought }}</div> -->
</div> </div>
</div> </div>
@ -242,6 +261,12 @@ const clearInput = () => {
:class="{ 'fade-in': analysisContent }" :class="{ 'fade-in': analysisContent }"
> >
<div class="analysis-content" v-html="analysisContent"></div> <div class="analysis-content" v-html="analysisContent"></div>
<div v-if="analysisContent && !isAnalyzing" class="copy-button-container">
<button class="copy-button" @click="copyAnalysis" :class="{ success: copySuccess }">
<span v-if="!copySuccess">复制分析结果</span>
<span v-else>复制成功</span>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -266,14 +291,15 @@ const clearInput = () => {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; min-height: 0;
justify-content: center;
} }
.initial-content { .initial-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-top: 15vh; margin-bottom: 15vh;
gap: 2rem; gap: 2rem;
transition: all 0.5s ease; transition: all 0.5s ease;
} }
@ -284,7 +310,7 @@ const clearInput = () => {
} }
.title { .title {
font-size: 2.5rem; font-size: 2rem;
font-weight: 700; font-weight: 700;
color: var(--color-text-primary); color: var(--color-text-primary);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
@ -292,7 +318,7 @@ const clearInput = () => {
} }
.description { .description {
font-size: 1rem; font-size: 0.95rem;
color: var(--color-text-secondary); color: var(--color-text-secondary);
transition: all 0.5s ease; transition: all 0.5s ease;
} }
@ -338,7 +364,7 @@ const clearInput = () => {
border: none; border: none;
background: none; background: none;
padding: 0.5rem; padding: 0.5rem;
font-size: 1.1rem; font-size: 0.95rem;
color: var(--color-text-primary); color: var(--color-text-primary);
outline: none; outline: none;
height: 2.5rem; height: 2.5rem;
@ -370,7 +396,7 @@ const clearInput = () => {
.analyze-button { .analyze-button {
width: 100%; width: 100%;
padding: 0.75rem; padding: 0.75rem;
font-size: 1rem; font-size: 0.9rem;
font-weight: 500; font-weight: 500;
color: white; color: white;
background-color: var(--color-accent); background-color: var(--color-accent);
@ -391,21 +417,20 @@ const clearInput = () => {
.analysis-status { .analysis-status {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 2rem 1rem; padding: 1rem;
text-align: center; text-align: center;
background-color: var(--color-bg-secondary); gap: 1rem;
border-radius: var(--border-radius); margin-top: 1rem;
} }
.progress-dots { .progress-dots {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 8px; gap: 6px;
margin-bottom: 1rem;
} }
.progress-dots span { .progress-dots span {
@ -427,7 +452,7 @@ const clearInput = () => {
.status-text { .status-text {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
} }
@ -435,35 +460,39 @@ const clearInput = () => {
.status-label { .status-label {
font-weight: 500; font-weight: 500;
color: var(--color-accent); color: var(--color-accent);
font-size: 1.1rem; font-size: 0.85rem;
} }
.thought-text { .thought-text {
font-size: 0.95rem; font-size: 0.9rem;
color: var(--color-text-secondary); color: var(--color-text-secondary);
max-width: 600px;
text-align: center;
line-height: 1.5;
} }
.analysis-container { .analysis-container {
flex: 1; flex: 1;
min-height: 0;
overflow-y: auto; overflow-y: auto;
padding: 1rem 1.5rem; border-radius: var(--border-radius);
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.analysis-container.fade-in {
background-color: var(--color-bg-secondary);
}
.analysis-content { .analysis-content {
color: var(--color-text-primary); color: var(--color-text-primary);
line-height: 1.8; line-height: 1.6;
font-size: 1.1rem; font-size: 0.95rem;
white-space: pre-wrap; white-space: pre-wrap;
padding-bottom: 2rem; padding: 1.5rem 2rem;
flex: 1; overflow-y: auto;
padding: 1rem 1.5rem 4.5rem 1.5rem; }
.analysis-content::-webkit-scrollbar {
display: none;
} }
:deep(.error-message) { :deep(.error-message) {
@ -505,7 +534,7 @@ const clearInput = () => {
@media (max-width: 768px) { @media (max-width: 768px) {
.initial-content { .initial-content {
padding-top: 12vh; margin-bottom: 12vh;
gap: 1.5rem; gap: 1.5rem;
} }
@ -518,23 +547,49 @@ const clearInput = () => {
} }
.search-input { .search-input {
font-size: 1rem; font-size: 0.9rem;
}
.analysis-container {
padding: 0.75rem 1rem;
margin-bottom: 0.75rem;
} }
.analysis-content { .analysis-content {
font-size: 1rem; padding: 1.25rem 1.5rem;
padding: 1rem 1rem 4.5rem 1rem; font-size: 0.9rem;
}
.analysis-view {
padding: 0.5rem;
margin-top: 4.5rem;
}
.analysis-header {
padding: 0.75rem;
flex-direction: column;
gap: 0.75rem;
align-items: flex-start;
}
.new-analysis-button {
width: 100%;
justify-content: center;
}
.analysis-container {
margin-top: 1rem;
}
.analysis-content {
padding: 1.25rem 1.5rem;
font-size: 0.9rem;
}
.copy-button-container {
bottom: 1.5rem;
right: 1.5rem;
} }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.initial-content { .initial-content {
padding-top: 10vh; margin-bottom: 10vh;
gap: 1rem; gap: 1rem;
} }
@ -543,33 +598,78 @@ const clearInput = () => {
} }
.description { .description {
font-size: 0.9rem; font-size: 0.85rem;
} }
.search-input { .search-input {
font-size: 0.95rem; font-size: 0.85rem;
} }
.analyze-button { .analyze-button {
font-size: 0.95rem; font-size: 0.85rem;
padding: 0.6rem; padding: 0.6rem;
} }
.analysis-content {
padding: 1rem;
font-size: 0.85rem;
line-height: 1.5;
}
.target-info .label {
font-size: 0.8rem;
}
.target-info .value {
font-size: 0.85rem;
}
.stock-analysis-view {
padding: 0.5rem;
}
.analysis-view {
padding: 0.5rem;
height: calc(100% - 1rem);
}
.analysis-header {
padding: 0.75rem;
}
.analysis-container { .analysis-container {
margin-bottom: 0.5rem; margin-top: 1rem;
} }
.analysis-content { .analysis-content {
padding: 0.75rem 0.75rem 4.5rem 0.75rem; padding: 1rem;
font-size: 0.85rem;
line-height: 1.5;
}
.analysis-status {
margin-top: 0.5rem;
padding: 0.75rem;
}
.copy-button-container {
bottom: 1rem;
right: 1rem;
}
.copy-button {
padding: 0.6rem 1.2rem;
font-size: 0.85rem;
} }
} }
.analysis-view { .analysis-view {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100%;
padding: 1rem; padding: 0.5rem;
animation: fadeIn 0.3s ease-out; animation: fadeIn 0.3s ease-out;
min-height: 0;
} }
.analysis-header { .analysis-header {
@ -579,7 +679,6 @@ const clearInput = () => {
padding: 1rem; padding: 1rem;
background-color: var(--color-bg-secondary); background-color: var(--color-bg-secondary);
border-radius: var(--border-radius); border-radius: var(--border-radius);
margin-bottom: 1rem;
} }
.target-info { .target-info {
@ -590,13 +689,13 @@ const clearInput = () => {
.target-info .label { .target-info .label {
color: var(--color-text-secondary); color: var(--color-text-secondary);
font-size: 0.95rem; font-size: 0.85rem;
} }
.target-info .value { .target-info .value {
color: var(--color-accent); color: var(--color-accent);
font-weight: 500; font-weight: 500;
font-size: 1.1rem; font-size: 0.9rem;
} }
.new-analysis-button { .new-analysis-button {
@ -627,43 +726,53 @@ const clearInput = () => {
height: 16px; height: 16px;
} }
.analysis-container { :deep(*::-webkit-scrollbar) {
flex: 1; width: 6px;
overflow-y: auto; height: 6px;
background-color: var(--color-bg-primary); }
:deep(*::-webkit-scrollbar-track) {
background: transparent;
}
:deep(*::-webkit-scrollbar-thumb) {
background-color: rgba(125, 125, 125, 0.2);
border-radius: 3px;
}
:deep(*::-webkit-scrollbar-thumb:hover) {
background-color: rgba(125, 125, 125, 0.3);
}
.copy-button-container {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 10;
}
.copy-button {
display: flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1.5rem;
border: none;
border-radius: var(--border-radius); border-radius: var(--border-radius);
margin-top: 1rem; background-color: var(--color-accent);
color: white;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
} }
@media (max-width: 768px) { .copy-button:hover {
.analysis-view { transform: translateY(-1px);
padding: 0.5rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.analysis-header {
padding: 0.75rem;
flex-direction: column;
gap: 0.75rem;
align-items: flex-start;
}
.new-analysis-button {
width: 100%;
justify-content: center;
}
} }
@media (max-width: 480px) { .copy-button.success {
.analysis-header { background-color: #4caf50;
padding: 0.5rem;
}
.target-info .label {
font-size: 0.9rem;
}
.target-info .value {
font-size: 1rem;
}
} }
</style> </style>

View File

@ -13,11 +13,11 @@ const isAnalyzing = ref(false)
const analysisContent = ref('') const analysisContent = ref('')
const analysisContainer = ref<HTMLElement | null>(null) const analysisContainer = ref<HTMLElement | null>(null)
const currentThought = ref('') const currentThought = ref('')
const selectedTimeframe = ref('all') const selectedTimeframe = ref('15m')
const showInitialView = ref(true) const showInitialView = ref(true)
const copySuccess = ref(false)
const timeframes = [ const timeframes = [
{ label: '全部', value: 'all' },
{ label: '15分钟', value: '15m' }, { label: '15分钟', value: '15m' },
{ label: '1小时', value: '1h' }, { label: '1小时', value: '1h' },
{ label: '4小时', value: '4h' }, { label: '4小时', value: '4h' },
@ -61,11 +61,7 @@ const handleAnalysis = async () => {
const requestData: AnalysisRequest = { const requestData: AnalysisRequest = {
symbol: cryptoCode.value.trim().toUpperCase(), symbol: cryptoCode.value.trim().toUpperCase(),
} timeframe: selectedTimeframe.value,
// 'all' timeframe
if (selectedTimeframe.value !== 'all') {
requestData.timeframe = selectedTimeframe.value
} }
const response = await fetch(`${apiBaseUrl}/crypto/crypto/analysis`, { const response = await fetch(`${apiBaseUrl}/crypto/crypto/analysis`, {
@ -124,15 +120,13 @@ const handleAnalysis = async () => {
await scrollToBottom() await scrollToBottom()
break break
} }
} catch (e) { } catch {
console.error('解析响应数据出错:', e)
analysisContent.value = '<div class="error-message">解析响应数据时出错,请稍后重试</div>' analysisContent.value = '<div class="error-message">解析响应数据时出错,请稍后重试</div>'
currentThought.value = '数据解析出错' currentThought.value = '数据解析出错'
} }
} }
} }
} catch (error) { } catch {
console.error('分析请求失败:', error)
analysisContent.value = '<div class="error-message">抱歉,分析请求失败,请稍后重试</div>' analysisContent.value = '<div class="error-message">抱歉,分析请求失败,请稍后重试</div>'
currentThought.value = '请求失败' currentThought.value = '请求失败'
} finally { } finally {
@ -155,6 +149,24 @@ const clearInput = () => {
analysisContent.value = '' analysisContent.value = ''
currentThought.value = '' currentThought.value = ''
} }
const copyAnalysis = async () => {
if (!analysisContent.value) return
try {
const tempDiv = document.createElement('div')
tempDiv.innerHTML = analysisContent.value
const textContent = tempDiv.textContent || tempDiv.innerText || ''
await navigator.clipboard.writeText(textContent)
copySuccess.value = true
setTimeout(() => {
copySuccess.value = false
}, 2000)
} catch {
console.error('复制失败')
}
}
</script> </script>
<template> <template>
@ -261,8 +273,7 @@ const clearInput = () => {
<span></span> <span></span>
</div> </div>
<div class="status-text"> <div class="status-text">
<div class="status-label">AI分析进行中</div> <div class="status-label">AI 正在分析</div>
<div v-if="currentThought" class="thought-text">{{ currentThought }}</div>
</div> </div>
</div> </div>
@ -272,6 +283,12 @@ const clearInput = () => {
:class="{ 'fade-in': analysisContent }" :class="{ 'fade-in': analysisContent }"
> >
<div class="analysis-content" v-html="analysisContent"></div> <div class="analysis-content" v-html="analysisContent"></div>
<div v-if="analysisContent && !isAnalyzing" class="copy-button-container">
<button class="copy-button" @click="copyAnalysis" :class="{ success: copySuccess }">
<span v-if="!copySuccess">复制分析结果</span>
<span v-else>复制成功</span>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -302,13 +319,14 @@ const clearInput = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
justify-content: center;
} }
.initial-content { .initial-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-top: 15vh; margin-bottom: 15vh;
gap: 2rem; gap: 2rem;
transition: all 0.5s ease; transition: all 0.5s ease;
} }
@ -319,7 +337,7 @@ const clearInput = () => {
} }
.title { .title {
font-size: 2.5rem; font-size: 2rem;
font-weight: 700; font-weight: 700;
color: var(--color-text-primary); color: var(--color-text-primary);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
@ -327,7 +345,7 @@ const clearInput = () => {
} }
.description { .description {
font-size: 1rem; font-size: 0.95rem;
color: var(--color-text-secondary); color: var(--color-text-secondary);
transition: all 0.5s ease; transition: all 0.5s ease;
} }
@ -445,7 +463,7 @@ const clearInput = () => {
border: none; border: none;
background: none; background: none;
padding: 0; padding: 0;
font-size: 1.1rem; font-size: 0.95rem;
color: var(--color-text-primary); color: var(--color-text-primary);
outline: none; outline: none;
height: 2.5rem; height: 2.5rem;
@ -489,7 +507,7 @@ const clearInput = () => {
.analyze-button { .analyze-button {
width: 100%; width: 100%;
padding: 0.75rem; padding: 0.75rem;
font-size: 1rem; font-size: 0.9rem;
font-weight: 500; font-weight: 500;
color: white; color: white;
background-color: var(--color-accent); background-color: var(--color-accent);
@ -553,21 +571,20 @@ const clearInput = () => {
.analysis-status { .analysis-status {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 2rem 1rem; padding: 1rem;
text-align: center; text-align: center;
background-color: var(--color-bg-secondary); gap: 1rem;
border-radius: var(--border-radius); margin-top: 1rem;
} }
.progress-dots { .progress-dots {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 8px; gap: 6px;
margin-bottom: 1rem;
} }
.progress-dots span { .progress-dots span {
@ -589,7 +606,7 @@ const clearInput = () => {
.status-text { .status-text {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
} }
@ -597,15 +614,12 @@ const clearInput = () => {
.status-label { .status-label {
font-weight: 500; font-weight: 500;
color: var(--color-accent); color: var(--color-accent);
font-size: 1.1rem; font-size: 0.85rem;
} }
.thought-text { .thought-text {
font-size: 0.95rem; font-size: 0.9rem;
color: var(--color-text-secondary); color: var(--color-text-secondary);
max-width: 600px;
text-align: center;
line-height: 1.5;
} }
.no-results { .no-results {
@ -620,20 +634,25 @@ const clearInput = () => {
.analysis-container { .analysis-container {
flex: 1; flex: 1;
min-height: 0;
overflow-y: auto;
border-radius: var(--border-radius);
margin-top: 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 0; }
overflow: hidden;
.analysis-container.fade-in {
background-color: var(--color-bg-secondary);
} }
.analysis-content { .analysis-content {
flex: 1;
overflow-y: auto;
color: var(--color-text-primary); color: var(--color-text-primary);
line-height: 1.8; line-height: 1.6;
font-size: 1.1rem; font-size: 0.9rem;
white-space: pre-wrap; white-space: pre-wrap;
padding: 1rem 1.5rem 4.5rem 1.5rem; padding: 1.5rem 2rem;
overflow-y: auto;
} }
.analysis-content :deep(h1), .analysis-content :deep(h1),
@ -744,29 +763,38 @@ const clearInput = () => {
} }
.analysis-content::-webkit-scrollbar { .analysis-content::-webkit-scrollbar {
width: 6px; display: none;
}
.analysis-content::-webkit-scrollbar-track {
background: transparent;
}
.analysis-content::-webkit-scrollbar-thumb {
background-color: var(--color-border);
border-radius: 3px;
}
.analysis-content::-webkit-scrollbar-thumb:hover {
background-color: var(--color-accent);
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.crypto-analysis-view { .crypto-analysis-view {
padding: 0.75rem;
}
.analysis-view {
padding: 0.5rem; padding: 0.5rem;
margin-top: 4.5rem;
}
.analysis-header {
padding: 1rem;
flex-direction: column;
gap: 0.75rem;
align-items: flex-start;
}
.new-analysis-button {
width: 100%;
justify-content: center;
}
.analysis-content {
padding: 1.25rem 1.5rem;
font-size: 0.85rem;
} }
.initial-content { .initial-content {
padding-top: 12vh; margin-bottom: 12vh;
gap: 1.5rem; gap: 1.5rem;
} }
@ -774,76 +802,60 @@ const clearInput = () => {
font-size: 1.75rem; font-size: 1.75rem;
} }
.search-container { .description {
padding: 1rem; font-size: 0.9rem;
margin: 0 -0.5rem;
} }
.search-input { .search-input {
height: 3rem;
font-size: 1rem;
padding: 0.75rem 2rem 0.75rem 1rem;
border-radius: 0;
}
.analysis-container {
margin: 0.5rem -0.5rem 0;
border-left: none;
border-right: none;
border-radius: 0;
padding: 1rem;
}
.analysis-content {
font-size: 1rem;
padding: 1rem 1rem 4.5rem 1rem;
}
.crypto-card {
margin: 0;
}
.status-text {
font-size: 0.95rem;
gap: 0.75rem;
}
.status-label {
font-size: 1rem;
}
.thought-text {
font-size: 0.9rem; font-size: 0.9rem;
max-width: 95%;
}
.selected-tag {
padding: 0.4rem 0.6rem;
font-size: 0.95rem;
}
.tag-remove {
padding: 0.12rem;
}
.tag-remove svg {
width: 12px;
height: 12px;
}
.timeframe-selector {
gap: 0.35rem;
} }
.timeframe-selector .timeframe-label { .timeframe-selector .timeframe-label {
padding: 0.2rem 0.5rem; font-size: 0.85rem;
}
.analyze-button {
font-size: 0.85rem; font-size: 0.85rem;
} }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.crypto-analysis-view {
padding: 0.5rem;
}
.analysis-view {
padding: 0.5rem;
}
.analysis-header {
padding: 1rem;
}
.target-info {
flex-wrap: wrap;
}
.target-info .label {
font-size: 0.8rem;
}
.target-info .value {
font-size: 0.85rem;
}
.target-info .timeframe {
font-size: 0.75rem;
}
.analysis-content {
padding: 1rem;
font-size: 0.8rem;
line-height: 1.5;
}
.initial-content { .initial-content {
padding-top: 10vh; margin-bottom: 10vh;
gap: 1rem; gap: 1rem;
} }
@ -852,34 +864,22 @@ const clearInput = () => {
} }
.description { .description {
font-size: 0.9rem; font-size: 0.85rem;
} }
.crypto-option { .search-input {
padding: 0.5rem 0.75rem; font-size: 0.85rem;
}
.analysis-container {
padding: 1rem;
}
.timeframe-selector {
gap: 0.25rem;
} }
.timeframe-selector .timeframe-label { .timeframe-selector .timeframe-label {
padding: 0.15rem 0.4rem;
font-size: 0.8rem; font-size: 0.8rem;
padding: 0.2rem 0.6rem;
} }
.analyze-button { .analyze-button {
font-size: 0.95rem; font-size: 0.85rem;
padding: 0.6rem; padding: 0.6rem;
} }
.analysis-content {
padding: 0.75rem 0.75rem 4.5rem 0.75rem;
}
} }
.search-container.is-analyzing { .search-container.is-analyzing {
@ -1132,8 +1132,8 @@ const clearInput = () => {
.analysis-view { .analysis-view {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: calc(100vh - 2rem);
padding: 1rem; padding: 0.5rem;
animation: fadeIn 0.3s ease-out; animation: fadeIn 0.3s ease-out;
} }
@ -1144,7 +1144,21 @@ const clearInput = () => {
padding: 1rem; padding: 1rem;
background-color: var(--color-bg-secondary); background-color: var(--color-bg-secondary);
border-radius: var(--border-radius); border-radius: var(--border-radius);
margin-bottom: 1rem; flex-shrink: 0;
}
.analysis-status {
flex-shrink: 0;
}
.analysis-container {
flex: 1;
min-height: 0;
overflow-y: auto;
border-radius: var(--border-radius);
margin-top: 1rem;
display: flex;
flex-direction: column;
} }
.target-info { .target-info {
@ -1155,18 +1169,18 @@ const clearInput = () => {
.target-info .label { .target-info .label {
color: var(--color-text-secondary); color: var(--color-text-secondary);
font-size: 0.95rem; font-size: 0.85rem;
} }
.target-info .value { .target-info .value {
color: var(--color-accent); color: var(--color-accent);
font-weight: 500; font-weight: 500;
font-size: 1.1rem; font-size: 0.9rem;
} }
.target-info .timeframe { .target-info .timeframe {
color: var(--color-text-secondary); color: var(--color-text-secondary);
font-size: 0.9rem; font-size: 0.8rem;
padding: 0.15rem 0.5rem; padding: 0.15rem 0.5rem;
background-color: var(--color-bg-primary); background-color: var(--color-bg-primary);
border-radius: var(--border-radius); border-radius: var(--border-radius);
@ -1200,51 +1214,33 @@ const clearInput = () => {
height: 16px; height: 16px;
} }
.analysis-container {
flex: 1;
overflow-y: auto;
background-color: var(--color-bg-primary);
border-radius: var(--border-radius);
margin-top: 1rem;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.analysis-view { .analysis-view {
padding: 0.5rem; height: calc(100vh - 1.5rem);
}
.analysis-header {
padding: 0.75rem;
flex-direction: column;
gap: 0.75rem;
align-items: flex-start;
}
.new-analysis-button {
width: 100%;
justify-content: center;
} }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.analysis-header { .analysis-view {
padding: 0.5rem; height: calc(100vh - 1rem);
}
.target-info {
flex-wrap: wrap;
}
.target-info .label {
font-size: 0.9rem;
}
.target-info .value {
font-size: 1rem;
}
.target-info .timeframe {
font-size: 0.85rem;
} }
} }
:deep(*::-webkit-scrollbar) {
width: 6px;
height: 6px;
}
:deep(*::-webkit-scrollbar-track) {
background: transparent;
}
:deep(*::-webkit-scrollbar-thumb) {
background-color: rgba(125, 125, 125, 0.2);
border-radius: 3px;
}
:deep(*::-webkit-scrollbar-thumb:hover) {
background-color: rgba(125, 125, 125, 0.3);
}
</style> </style>