SJLee-0525
[TEST] test45
ab1ab06
"""
헀더 μ»΄ν¬λ„ŒνŠΈ - Voice Sementle μŠ€νƒ€μΌ
μ• λ‹ˆλ©”μ΄μ…˜ν’ κ·€μ—¬μš΄ 둜고 λ””μžμΈ
πŸ‘¨β€πŸ’» λ‹΄λ‹Ή: 개발자 A
"""
import gradio as gr
class HeaderComponent:
"""Voice Sementle μŠ€νƒ€μΌ 헀더 μ»΄ν¬λ„ŒνŠΈ"""
# Voice Sementle μŠ€νƒ€μΌ 헀더 HTML ν…œν”Œλ¦Ώ
HEADER_HTML_TEMPLATE = """
<link href="https://fonts.googleapis.com/css2?family=Lilita+One&family=Bangers&display=swap" rel="stylesheet">
<div class="vs-header">
<div class="header-center">
<h1 class="game-title">
<span class="title-line">
<span class="title-voice">VOICE</span>
</span>
<span class="title-line">
<span class="title-sementle">SEMENTLE</span>
</span>
</h1>
</div>
</div>
"""
# CSS ν…œν”Œλ¦Ώ - 이미지와 μœ μ‚¬ν•œ 3D 카툰 μŠ€νƒ€μΌ
HEADER_CSS_TEMPLATE = """
.vs-header {
display: flex;
justify-content: center;
align-items: center;
padding: 24px 16px 16px 16px;
background: transparent;
width: 100%;
box-sizing: border-box;
}
.header-center {
display: flex;
justify-content: center;
align-items: center;
}
.game-title {
font-family: 'Lilita One', 'Bangers', Impact, sans-serif;
text-align: center;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
line-height: 0.85;
}
.title-line {
display: block;
}
.title-voice {
font-size: 100px;
font-weight: 500;
color: #5ac8fa;
letter-spacing: 6px;
-webkit-text-stroke: 4px #1a6b8a;
text-shadow:
6px 6px 0 #1a6b8a,
7px 7px 0 #0d4a5f,
8px 8px 0 #0d4a5f,
0 0 20px rgba(90, 200, 250, 0.5);
paint-order: stroke fill;
}
.title-sementle {
font-size: 90px;
font-weight: 500;
color: #e8a054;
letter-spacing: 5px;
-webkit-text-stroke: 4px #8b5a2b;
text-shadow:
6px 6px 0 #8b5a2b,
7px 7px 0 #5c3d1e,
8px 8px 0 #5c3d1e,
0 0 20px rgba(232, 160, 84, 0.5);
paint-order: stroke fill;
}
/* 닀크λͺ¨λ“œ */
.dark .vs-header {
background: transparent;
}
.dark .title-voice {
color: #5ac8fa;
-webkit-text-stroke: 4px #0d4a5f;
text-shadow:
6px 6px 0 #0d4a5f,
7px 7px 0 #082a35,
8px 8px 0 #082a35,
0 0 25px rgba(90, 200, 250, 0.6);
}
.dark .title-sementle {
color: #e8a054;
-webkit-text-stroke: 4px #5c3d1e;
text-shadow:
6px 6px 0 #5c3d1e,
7px 7px 0 #3a2510,
8px 8px 0 #3a2510,
0 0 25px rgba(232, 160, 84, 0.6);
}
/* λ°˜μ‘ν˜• - 800px μ΄ν•˜ */
@media (max-width: 800px) {
.title-voice {
font-size: 80px;
letter-spacing: 6px;
-webkit-text-stroke: 4px #1a6b8a;
text-shadow:
5px 5px 0 #1a6b8a,
6px 6px 0 #0d4a5f,
7px 7px 0 #0d4a5f,
0 0 20px rgba(90, 200, 250, 0.5);
}
.title-sementle {
font-size: 72px;
letter-spacing: 4px;
-webkit-text-stroke: 4px #8b5a2b;
text-shadow:
5px 5px 0 #8b5a2b,
6px 6px 0 #5c3d1e,
7px 7px 0 #5c3d1e,
0 0 20px rgba(232, 160, 84, 0.5);
}
.dark .title-voice {
-webkit-text-stroke: 4px #1a6b8a;
text-shadow:
5px 5px 0 #1a6b8a,
6px 6px 0 #0d4a5f,
7px 7px 0 #0d4a5f,
0 0 20px rgba(90, 200, 250, 0.5);
}
.dark .title-sementle {
-webkit-text-stroke: 4px #8b5a2b;
text-shadow:
5px 5px 0 #8b5a2b,
6px 6px 0 #5c3d1e,
7px 7px 0 #5c3d1e,
0 0 20px rgba(232, 160, 84, 0.5);
}
}
/* λ°˜μ‘ν˜• - 600px μ΄ν•˜ */
@media (max-width: 600px) {
.title-voice {
font-size: 60px;
letter-spacing: 4px;
-webkit-text-stroke: 3px #1a6b8a;
text-shadow:
4px 4px 0 #1a6b8a,
5px 5px 0 #0d4a5f,
0 0 15px rgba(90, 200, 250, 0.5);
}
.title-sementle {
font-size: 52px;
letter-spacing: 3px;
-webkit-text-stroke: 3px #8b5a2b;
text-shadow:
4px 4px 0 #8b5a2b,
5px 5px 0 #5c3d1e,
0 0 15px rgba(232, 160, 84, 0.5);
}
.dark .title-voice {
-webkit-text-stroke: 3px #0d4a5f;
text-shadow:
4px 4px 0 #0d4a5f,
5px 5px 0 #082a35,
0 0 20px rgba(90, 200, 250, 0.6);
}
.dark .title-sementle {
-webkit-text-stroke: 3px #5c3d1e;
text-shadow:
4px 4px 0 #5c3d1e,
5px 5px 0 #3a2510,
0 0 20px rgba(232, 160, 84, 0.6);
}
}
"""
def __init__(self, validator):
"""
Args:
validator: AudioValidator μΈμŠ€ν„΄μŠ€
"""
self.validator = validator
self.header_html = None
def render(self):
"""
Wordle μŠ€νƒ€μΌ 헀더 UI λ Œλ”λ§
"""
# Wordle μŠ€νƒ€μΌ 헀더 (gr.HTML with Gradio 6 ν…œν”Œλ¦Ώ)
self.header_html = gr.HTML(
value=self.HEADER_HTML_TEMPLATE,
css_template=self.HEADER_CSS_TEMPLATE,
elem_id="wordle-header-container",
padding=False
)