|
|
""" |
|
|
ν€λ μ»΄ν¬λνΈ - Voice Sementle μ€νμΌ |
|
|
μ λλ©μ΄μ
ν κ·μ¬μ΄ λ‘κ³ λμμΈ |
|
|
|
|
|
π¨βπ» λ΄λΉ: κ°λ°μ A |
|
|
""" |
|
|
|
|
|
import gradio as gr |
|
|
|
|
|
|
|
|
class HeaderComponent: |
|
|
"""Voice Sementle μ€νμΌ ν€λ μ»΄ν¬λνΈ""" |
|
|
|
|
|
|
|
|
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> |
|
|
""" |
|
|
|
|
|
|
|
|
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 λ λλ§ |
|
|
""" |
|
|
|
|
|
self.header_html = gr.HTML( |
|
|
value=self.HEADER_HTML_TEMPLATE, |
|
|
css_template=self.HEADER_CSS_TEMPLATE, |
|
|
elem_id="wordle-header-container", |
|
|
padding=False |
|
|
) |
|
|
|