openfree commited on
Commit
6766497
ยท
verified ยท
1 Parent(s): c2ecd2e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -29
app.py CHANGED
@@ -166,7 +166,7 @@ UNIFIED_BASE_PROMPT_KO = """
166
  "brands": [
167
  {{
168
  "core": {{
169
- "brand_name": "๋ธŒ๋žœ๋“œ๋ช…",
170
  "slogan": "์Šฌ๋กœ๊ฑด",
171
  "core_value": "ํ•ต์‹ฌ ๊ฐ€์น˜",
172
  "target_emotion": "๋ชฉํ‘œ ๊ฐ์ •",
@@ -179,9 +179,9 @@ UNIFIED_BASE_PROMPT_KO = """
179
  "typography_style": "ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šคํƒ€์ผ"
180
  }},
181
  "linguistic": {{
182
- "pronunciation": "๋ฐœ์Œ ๊ฐ€์ด๋“œ",
183
- "etymology": "์–ด์›/๊ตฌ์„ฑ",
184
- "global_adaptability": "๊ธ€๋กœ๋ฒŒ ์ ์‘์„ฑ",
185
  "memorable_factor": "๊ธฐ์–ต ์šฉ์ด์„ฑ ์š”์†Œ"
186
  }},
187
  "strategic": {{
@@ -203,9 +203,11 @@ UNIFIED_BASE_PROMPT_KO = """
203
  ]
204
  }}
205
 
206
- ๋ฐ˜๋“œ์‹œ ์œ ํšจํ•œ JSON ํ˜•์‹์œผ๋กœ ์‘๋‹ตํ•˜๊ณ , ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”.
207
- ๊ฐ ์ด๋ก ์˜ ํŠน์„ฑ์„ theory_specific ์„น์…˜์— ๋‹ด๋˜, ๋‚˜๋จธ์ง€๋Š” ํ†ต์ผ๋œ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•˜์„ธ์š”.
208
- ๋ชจ๋“  ๋‚ด์šฉ์€ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.
 
 
209
  """
210
 
211
  # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ํ•„๋“œ ์ •์˜ (์˜์–ด)
@@ -369,7 +371,7 @@ THEORY_SPECIFIC_FIELDS_KO = {
369
 
370
  "linguistic": """
371
  "korean_adaptation": "ํ•œ๊ตญ์–ด ์ ์‘",
372
- "english_meaning": "์˜์–ด ์˜๋ฏธ",
373
  "cultural_considerations": "๋ฌธํ™”์  ๊ณ ๋ ค์‚ฌํ•ญ",
374
  "avoid_meanings": "ํ”ผํ•ด์•ผ ํ•  ์˜๋ฏธ๋“ค",
375
  "localization_strategy": "ํ˜„์ง€ํ™” ์ „๋žต"
@@ -533,7 +535,8 @@ Each brand should have a unified structure, with theory-specific characteristics
533
  ํ‚ค์›Œ๋“œ: {keywords}
534
 
535
  ์œ„ ์ •๋ณด๋กœ {count}๊ฐœ์˜ ๋ธŒ๋žœ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.
536
- ๊ฐ ๋ธŒ๋žœ๋“œ๋Š” ํ†ต์ผ๋œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋˜, theory_specific ์„น์…˜์—๋Š” {theory} ์ด๋ก ์˜ ํŠน์„ฑ์„ ๋ฐ˜์˜ํ•˜์„ธ์š”."""
 
537
 
538
  try:
539
  # ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ํ‘œ์‹œ
@@ -659,7 +662,47 @@ def generate_unified_markdown(theory: str, results: List[Dict], industry: str, k
659
  brand_name = core.get('brand_name', 'N/A')
660
  slogan = core.get('slogan', 'N/A')
661
 
662
- markdown += f"\n## {idx}. {brand_name}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
 
664
  if language == "en":
665
  markdown += f"""**Slogan**: *"{slogan}"*
@@ -762,6 +805,46 @@ def generate_unified_visualization(theory: str, results: List[Dict], language: s
762
  slogan = core.get('slogan', '')
763
  primary_color = visual.get('primary_color', '#667eea')
764
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  # ์–ธ์–ด๋ณ„ ๋ผ๋ฒจ
766
  if language == "en":
767
  labels = {
@@ -784,7 +867,7 @@ def generate_unified_visualization(theory: str, results: List[Dict], language: s
784
  <div style="background: white; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); overflow: hidden;">
785
  <!-- ํ—ค๋” -->
786
  <div style="background: linear-gradient(135deg, {primary_color} 0%, #2c3e50 100%); padding: 40px; color: white;">
787
- <h2 style="margin: 0 0 10px 0; font-size: 2.5em;">{brand_name}</h2>
788
  <p style="margin: 0; font-style: italic; font-size: 1.2em; opacity: 0.9;">"{slogan}"</p>
789
  </div>
790
 
@@ -975,15 +1058,51 @@ with gr.Blocks(
975
  css="""
976
  .gradio-container {
977
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 
 
 
 
 
 
 
 
 
 
 
978
  }
979
  .tab-nav button {
980
- font-size: 0.85em !important;
981
- padding: 8px 12px !important;
982
- white-space: nowrap !important;
 
 
 
 
 
 
 
 
 
983
  }
984
- .tab-nav {
985
- flex-wrap: wrap !important;
986
- gap: 5px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
987
  }
988
  @keyframes pulse {
989
  0% { opacity: 0.6; }
@@ -1030,7 +1149,7 @@ with gr.Blocks(
1030
  """)
1031
 
1032
  with gr.Row():
1033
- with gr.Column(scale=1, min_width=300):
1034
  gr.Markdown("""
1035
  <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
1036
  <h3 style="margin-top: 0; color: #2c3e50;">๐Ÿ“ Brand Information</h3>
@@ -1067,28 +1186,28 @@ with gr.Blocks(
1067
 
1068
  gr.Markdown("""
1069
  <div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
1070
- <h4 style="margin-top: 0; color: #1976d2;">๐ŸŽฏ 15 Specialized Theories</h4>
1071
- <p style="margin: 10px 0; font-size: 0.9em;">Each theory offers a unique approach to brand naming:</p>
1072
- <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.85em;">
1073
- <li><strong>Cognitive</strong>: Square, Sound, Cognitive Load, Gestalt</li>
1074
  <li><strong>Creative</strong>: Blending, SCAMPER, Biomimicry</li>
1075
- <li><strong>Strategic</strong>: Jobs-to-be-Done, Design Thinking</li>
1076
  <li><strong>Cultural</strong>: Archetype, Linguistic, Memetics</li>
1077
  <li><strong>Distinctive</strong>: Von Restorff, Color, Network</li>
1078
  </ul>
1079
  </div>
1080
 
1081
  <div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-top: 15px;">
1082
- <h4 style="margin-top: 0; color: #856404;">๐Ÿ’ก Pro Tips</h4>
1083
- <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.85em;">
1084
- <li>Try multiple theories to find the perfect fit</li>
1085
- <li>Compare results across different approaches</li>
1086
- <li>Combine insights from various theories</li>
1087
  </ul>
1088
  </div>
1089
  """)
1090
 
1091
- with gr.Column(scale=3):
1092
  # 15๊ฐœ ํƒญ์„ 3๊ฐœ ํ–‰์œผ๋กœ ๊ตฌ์„ฑ
1093
  gr.Markdown("""
1094
  <div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 20px;">
 
166
  "brands": [
167
  {{
168
  "core": {{
169
+ "brand_name": "ํ•œ๊ธ€ ๋ธŒ๋žœ๋“œ๋ช…",
170
  "slogan": "์Šฌ๋กœ๊ฑด",
171
  "core_value": "ํ•ต์‹ฌ ๊ฐ€์น˜",
172
  "target_emotion": "๋ชฉํ‘œ ๊ฐ์ •",
 
179
  "typography_style": "ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šคํƒ€์ผ"
180
  }},
181
  "linguistic": {{
182
+ "pronunciation": "ํ•œ๊ธ€ ๋ฐœ์Œ ๊ฐ€์ด๋“œ",
183
+ "etymology": "์–ด์›/๊ตฌ์„ฑ (์˜์–ด๋ช… ํฌํ•จ)",
184
+ "global_adaptability": "์˜์–ด ๋ธŒ๋žœ๋“œ๋ช… (์˜ˆ: Mother's Garden)",
185
  "memorable_factor": "๊ธฐ์–ต ์šฉ์ด์„ฑ ์š”์†Œ"
186
  }},
187
  "strategic": {{
 
203
  ]
204
  }}
205
 
206
+ ์ค‘์š”:
207
+ 1. brand_name์€ ๋ฐ˜๋“œ์‹œ ํ•œ๊ธ€๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.
208
+ 2. linguistic > global_adaptability์—๋Š” ๋ฐ˜๋“œ์‹œ ์˜์–ด ๋ธŒ๋žœ๋“œ๋ช…์„ ํฌํ•จํ•˜์„ธ์š”.
209
+ 3. ์˜์–ด๋ช…์€ ํ•œ๊ธ€๋ช…์˜ ์˜๋ฏธ๋ฅผ ์ž˜ ์ „๋‹ฌํ•˜๋˜, ๊ธ€๋กœ๋ฒŒํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“œ์„ธ์š”.
210
+ 4. ๋ชจ๋“  ํ•„๋“œ๋ฅผ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜๋˜, ์˜์–ด ๋ธŒ๋žœ๋“œ๋ช…๋งŒ ์˜์–ด๋กœ ํ‘œ๊ธฐํ•˜์„ธ์š”.
211
  """
212
 
213
  # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ํ•„๋“œ ์ •์˜ (์˜์–ด)
 
371
 
372
  "linguistic": """
373
  "korean_adaptation": "ํ•œ๊ตญ์–ด ์ ์‘",
374
+ "english_meaning": "์˜์–ด ๋ธŒ๋žœ๋“œ๋ช…",
375
  "cultural_considerations": "๋ฌธํ™”์  ๊ณ ๋ ค์‚ฌํ•ญ",
376
  "avoid_meanings": "ํ”ผํ•ด์•ผ ํ•  ์˜๋ฏธ๋“ค",
377
  "localization_strategy": "ํ˜„์ง€ํ™” ์ „๋žต"
 
535
  ํ‚ค์›Œ๋“œ: {keywords}
536
 
537
  ์œ„ ์ •๋ณด๋กœ {count}๊ฐœ์˜ ๋ธŒ๋žœ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.
538
+ ๊ฐ ๋ธŒ๋žœ๋“œ๋Š” ํ†ต์ผ๋œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋˜, theory_specific ์„น์…˜์—๋Š” {theory} ์ด๋ก ์˜ ํŠน์„ฑ์„ ๋ฐ˜์˜ํ•˜์„ธ์š”.
539
+ ์ค‘์š”: linguistic > global_adaptability ํ•„๋“œ์— ๋ฐ˜๋“œ์‹œ ์˜์–ด ๋ธŒ๋žœ๋“œ๋ช…์„ ํฌํ•จํ•˜์„ธ์š”."""
540
 
541
  try:
542
  # ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ํ‘œ์‹œ
 
662
  brand_name = core.get('brand_name', 'N/A')
663
  slogan = core.get('slogan', 'N/A')
664
 
665
+ # ํ•œ๊ธ€์ผ ๊ฒฝ์šฐ ์˜์–ด ํ‘œํ˜„ ์ถ”๊ฐ€
666
+ if language == "ko":
667
+ # ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์˜์–ด๋ช… ์ฐพ๊ธฐ
668
+ english_name = None
669
+
670
+ # 1. linguistic theory์˜ ๊ฒฝ์šฐ theory_specific์—์„œ ์ฐพ๊ธฐ
671
+ if theory == "linguistic" and 'english_meaning' in theory_specific:
672
+ english_name = theory_specific.get('english_meaning', '')
673
+
674
+ # 2. global_adaptability์—์„œ ์ฐพ๊ธฐ
675
+ if not english_name or english_name == 'N/A':
676
+ english_name = linguistic.get('global_adaptability', '')
677
+
678
+ # 3. etymology์—์„œ ์˜์–ด ์ถ”์ถœ
679
+ if not english_name or english_name == 'N/A':
680
+ etymology = linguistic.get('etymology', '')
681
+ if etymology and '์˜์–ด' in etymology and ':' in etymology:
682
+ # "์˜์–ด: Brand Name" ํ˜•์‹์—์„œ ์ถ”์ถœ
683
+ parts = etymology.split(':')
684
+ for i, part in enumerate(parts):
685
+ if '์˜์–ด' in part and i + 1 < len(parts):
686
+ english_name = parts[i + 1].strip().split(',')[0].strip()
687
+ break
688
+
689
+ # ์˜์–ด๋ช…์ด ์œ ํšจํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ถ”๊ฐ€
690
+ if english_name and english_name != 'N/A' and english_name != brand_name:
691
+ # ๊ธธ์ด๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๊ฑฐ๋‚˜ ์„ค๋ช…์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ์ •๋ฆฌ
692
+ if len(english_name) > 50 or '(' in english_name or ',' in english_name:
693
+ english_name = english_name.split('(')[0].split(',')[0].strip()
694
+
695
+ # ์˜์–ด๋ช…์ด ์‹ค์ œ๋กœ ์˜์–ด์ธ์ง€ ๊ฐ„๋‹จํžˆ ํ™•์ธ (ํ•œ๊ธ€์ด ํฌํ•จ๋˜์ง€ ์•Š์•˜๋Š”์ง€)
696
+ if not any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in english_name):
697
+ brand_display = f"{brand_name} / {english_name}"
698
+ else:
699
+ brand_display = brand_name
700
+ else:
701
+ brand_display = brand_name
702
+ else:
703
+ brand_display = brand_name
704
+
705
+ markdown += f"\n## {idx}. {brand_display}\n"
706
 
707
  if language == "en":
708
  markdown += f"""**Slogan**: *"{slogan}"*
 
805
  slogan = core.get('slogan', '')
806
  primary_color = visual.get('primary_color', '#667eea')
807
 
808
+ # ํ•œ๊ธ€์ผ ๊ฒฝ์šฐ ์˜์–ด ํ‘œํ˜„ ์ถ”๊ฐ€
809
+ if language == "ko":
810
+ # ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์˜์–ด๋ช… ์ฐพ๊ธฐ
811
+ english_name = None
812
+
813
+ # 1. linguistic theory์˜ ๊ฒฝ์šฐ theory_specific์—์„œ ์ฐพ๊ธฐ
814
+ if theory == "linguistic" and 'english_meaning' in theory_specific:
815
+ english_name = theory_specific.get('english_meaning', '')
816
+
817
+ # 2. global_adaptability์—์„œ ์ฐพ๊ธฐ
818
+ if not english_name or english_name == 'N/A':
819
+ english_name = linguistic.get('global_adaptability', '')
820
+
821
+ # 3. etymology์—์„œ ์˜์–ด ์ถ”์ถœ
822
+ if not english_name or english_name == 'N/A':
823
+ etymology = linguistic.get('etymology', '')
824
+ if etymology and '์˜์–ด' in etymology and ':' in etymology:
825
+ # "์˜์–ด: Brand Name" ํ˜•์‹์—์„œ ์ถ”์ถœ
826
+ parts = etymology.split(':')
827
+ for i, part in enumerate(parts):
828
+ if '์˜์–ด' in part and i + 1 < len(parts):
829
+ english_name = parts[i + 1].strip().split(',')[0].strip()
830
+ break
831
+
832
+ # ์˜์–ด๋ช…์ด ์œ ํšจํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ถ”๊ฐ€
833
+ if english_name and english_name != 'N/A' and english_name != brand_name:
834
+ # ๊ธธ์ด๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๊ฑฐ๋‚˜ ์„ค๋ช…์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ์ •๋ฆฌ
835
+ if len(english_name) > 50 or '(' in english_name or ',' in english_name:
836
+ english_name = english_name.split('(')[0].split(',')[0].strip()
837
+
838
+ # ์˜์–ด๋ช…์ด ์‹ค์ œ๋กœ ์˜์–ด์ธ์ง€ ๊ฐ„๋‹จํžˆ ํ™•์ธ (ํ•œ๊ธ€์ด ํฌํ•จ๋˜์ง€ ์•Š์•˜๋Š”์ง€)
839
+ if not any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in english_name):
840
+ brand_display = f"{brand_name} / {english_name}"
841
+ else:
842
+ brand_display = brand_name
843
+ else:
844
+ brand_display = brand_name
845
+ else:
846
+ brand_display = brand_name
847
+
848
  # ์–ธ์–ด๋ณ„ ๋ผ๋ฒจ
849
  if language == "en":
850
  labels = {
 
867
  <div style="background: white; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); overflow: hidden;">
868
  <!-- ํ—ค๋” -->
869
  <div style="background: linear-gradient(135deg, {primary_color} 0%, #2c3e50 100%); padding: 40px; color: white;">
870
+ <h2 style="margin: 0 0 10px 0; font-size: 2.5em;">{brand_display}</h2>
871
  <p style="margin: 0; font-style: italic; font-size: 1.2em; opacity: 0.9;">"{slogan}"</p>
872
  </div>
873
 
 
1058
  css="""
1059
  .gradio-container {
1060
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1061
+ max-width: 1400px !important;
1062
+ }
1063
+ /* ํƒญ ๋„ค๋น„๊ฒŒ์ด์…˜ ์Šคํƒ€์ผ ๊ฐœ์„  */
1064
+ .tab-nav {
1065
+ display: grid !important;
1066
+ grid-template-columns: repeat(5, 1fr) !important;
1067
+ gap: 8px !important;
1068
+ padding: 15px !important;
1069
+ background: #f8f9fa !important;
1070
+ border-radius: 10px !important;
1071
+ margin-bottom: 20px !important;
1072
  }
1073
  .tab-nav button {
1074
+ font-size: 0.8em !important;
1075
+ padding: 10px 8px !important;
1076
+ white-space: normal !important;
1077
+ line-height: 1.3 !important;
1078
+ height: auto !important;
1079
+ min-height: 50px !important;
1080
+ display: flex !important;
1081
+ align-items: center !important;
1082
+ justify-content: center !important;
1083
+ text-align: center !important;
1084
+ border-radius: 8px !important;
1085
+ transition: all 0.3s ease !important;
1086
  }
1087
+ .tab-nav button:hover {
1088
+ transform: translateY(-2px) !important;
1089
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important;
1090
+ }
1091
+ .tab-nav button.selected {
1092
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
1093
+ color: white !important;
1094
+ font-weight: 600 !important;
1095
+ }
1096
+ /* ๋ชจ๋ฐ”์ผ ๋ฐ˜์‘ํ˜• */
1097
+ @media (max-width: 768px) {
1098
+ .tab-nav {
1099
+ grid-template-columns: repeat(3, 1fr) !important;
1100
+ }
1101
+ }
1102
+ @media (max-width: 480px) {
1103
+ .tab-nav {
1104
+ grid-template-columns: repeat(2, 1fr) !important;
1105
+ }
1106
  }
1107
  @keyframes pulse {
1108
  0% { opacity: 0.6; }
 
1149
  """)
1150
 
1151
  with gr.Row():
1152
+ with gr.Column(scale=1, min_width=250):
1153
  gr.Markdown("""
1154
  <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
1155
  <h3 style="margin-top: 0; color: #2c3e50;">๐Ÿ“ Brand Information</h3>
 
1186
 
1187
  gr.Markdown("""
1188
  <div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
1189
+ <h4 style="margin-top: 0; color: #1976d2;">๐ŸŽฏ 15 Theories</h4>
1190
+ <p style="margin: 10px 0; font-size: 0.9em;">Each theory offers unique approach:</p>
1191
+ <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.8em; line-height: 1.4;">
1192
+ <li><strong>Cognitive</strong>: Square, Sound, Cognitive, Gestalt</li>
1193
  <li><strong>Creative</strong>: Blending, SCAMPER, Biomimicry</li>
1194
+ <li><strong>Strategic</strong>: Jobs-to-be-Done, Design</li>
1195
  <li><strong>Cultural</strong>: Archetype, Linguistic, Memetics</li>
1196
  <li><strong>Distinctive</strong>: Von Restorff, Color, Network</li>
1197
  </ul>
1198
  </div>
1199
 
1200
  <div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-top: 15px;">
1201
+ <h4 style="margin-top: 0; color: #856404;">๐Ÿ’ก Tips</h4>
1202
+ <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.8em; line-height: 1.4;">
1203
+ <li>Try multiple theories</li>
1204
+ <li>Compare results</li>
1205
+ <li>Combine insights</li>
1206
  </ul>
1207
  </div>
1208
  """)
1209
 
1210
+ with gr.Column(scale=4):
1211
  # 15๊ฐœ ํƒญ์„ 3๊ฐœ ํ–‰์œผ๋กœ ๊ตฌ์„ฑ
1212
  gr.Markdown("""
1213
  <div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 20px;">