Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -601,7 +601,38 @@ def generate(prompt, control_image, seed, random_seed, progress=gr.Progress(trac
|
|
| 601 |
|
| 602 |
|
| 603 |
# =============================================================================
|
| 604 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 605 |
# =============================================================================
|
| 606 |
THEME = gr.themes.Base(
|
| 607 |
primary_hue=gr.themes.colors.red,
|
|
@@ -662,22 +693,22 @@ CSS = """
|
|
| 662 |
}
|
| 663 |
|
| 664 |
/* Hero */
|
| 665 |
-
#hero { padding:
|
| 666 |
#hero .kicker {
|
| 667 |
font-family: 'JetBrains Mono', monospace;
|
| 668 |
text-transform: uppercase; letter-spacing: 0.34em;
|
| 669 |
-
font-size: 10px; color: #FF5128; margin: 0 0
|
| 670 |
}
|
| 671 |
#hero h1 {
|
| 672 |
-
font-family:
|
| 673 |
-
font-weight: 900; font-size: clamp(
|
| 674 |
-
line-height: 0.
|
| 675 |
}
|
| 676 |
#hero h1 em { font-style: italic; color: #FF5128; }
|
| 677 |
#hero .tag {
|
| 678 |
font-family: 'JetBrains Mono', monospace;
|
| 679 |
-
font-size:
|
| 680 |
-
color: #6E6A60; margin-top:
|
| 681 |
}
|
| 682 |
#hero .tag b { color: #1A1815; font-weight: 600; }
|
| 683 |
|
|
@@ -701,14 +732,19 @@ CSS = """
|
|
| 701 |
letter-spacing: 0.16em !important;
|
| 702 |
font-family: 'JetBrains Mono', monospace !important;
|
| 703 |
font-weight: 600 !important;
|
| 704 |
-
font-size:
|
| 705 |
border-radius: 3px !important;
|
| 706 |
-
min-height:
|
| 707 |
-
box-shadow: 0
|
| 708 |
transition: transform .12s ease, box-shadow .2s ease !important;
|
| 709 |
}
|
| 710 |
.go-btn:hover { transform: translateY(-1px); }
|
| 711 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 712 |
/* Status line */
|
| 713 |
.status-line { min-height: 22px; }
|
| 714 |
.status-line p {
|
|
@@ -725,6 +761,9 @@ CSS = """
|
|
| 725 |
footer { display: none !important; }
|
| 726 |
"""
|
| 727 |
|
|
|
|
|
|
|
|
|
|
| 728 |
with gr.Blocks(title="Typotopia", theme=THEME, css=CSS) as demo:
|
| 729 |
gr.HTML(
|
| 730 |
"""
|
|
@@ -745,9 +784,9 @@ with gr.Blocks(title="Typotopia", theme=THEME, css=CSS) as demo:
|
|
| 745 |
prompt = gr.Textbox(
|
| 746 |
label="Prompt",
|
| 747 |
placeholder="e.g. a bold geometric sans inspired by brutalist concrete signage",
|
| 748 |
-
lines=
|
| 749 |
)
|
| 750 |
-
control_image = gr.Image(label="Control image (optional)", type="pil")
|
| 751 |
with gr.Row():
|
| 752 |
seed = gr.Number(label="Seed", value=0, precision=0)
|
| 753 |
random_seed = gr.Checkbox(label="Random seed", value=True)
|
|
@@ -755,9 +794,9 @@ with gr.Blocks(title="Typotopia", theme=THEME, css=CSS) as demo:
|
|
| 755 |
with gr.Column(scale=1):
|
| 756 |
gr.HTML("<p class='eyebrow'>02 β Specimen</p>")
|
| 757 |
status = gr.HTML(elem_classes=["status-line"])
|
| 758 |
-
otf_file = gr.File(label="Download .otf")
|
| 759 |
-
preview = gr.Image(label="Preview", type="pil")
|
| 760 |
-
gallery = gr.Gallery(label="Generated grids", columns=3, height="
|
| 761 |
|
| 762 |
btn.click(
|
| 763 |
generate,
|
|
|
|
| 601 |
|
| 602 |
|
| 603 |
# =============================================================================
|
| 604 |
+
# OPTIONAL CUSTOM TITLE FONT
|
| 605 |
+
# Drop your own font in the repo as one of these names and the hero title will
|
| 606 |
+
# use it (otherwise it falls back to Fraunces):
|
| 607 |
+
# title.otf / title.ttf / title.woff2 / title.woff (or under assets/)
|
| 608 |
+
# =============================================================================
|
| 609 |
+
def _load_title_font():
|
| 610 |
+
import base64
|
| 611 |
+
fmt = {"otf": "opentype", "ttf": "truetype", "woff": "woff", "woff2": "woff2"}
|
| 612 |
+
mime = {"otf": "font/otf", "ttf": "font/ttf", "woff": "font/woff", "woff2": "font/woff2"}
|
| 613 |
+
candidates = [
|
| 614 |
+
"title.otf", "title.ttf", "title.woff2", "title.woff",
|
| 615 |
+
"assets/title.otf", "assets/title.ttf", "assets/title.woff2", "assets/title.woff",
|
| 616 |
+
]
|
| 617 |
+
for path in candidates:
|
| 618 |
+
if os.path.exists(path):
|
| 619 |
+
ext = path.rsplit(".", 1)[-1].lower()
|
| 620 |
+
with open(path, "rb") as fh:
|
| 621 |
+
b64 = base64.b64encode(fh.read()).decode()
|
| 622 |
+
print(f"π€ Title font: {path}")
|
| 623 |
+
face = (
|
| 624 |
+
"@font-face {"
|
| 625 |
+
"font-family: 'TitleFont';"
|
| 626 |
+
f"src: url(data:{mime[ext]};base64,{b64}) format('{fmt[ext]}');"
|
| 627 |
+
"font-weight: 100 900; font-style: normal; font-display: swap;}"
|
| 628 |
+
)
|
| 629 |
+
return face, "'TitleFont', 'Fraunces', Georgia, serif"
|
| 630 |
+
return "", "'Fraunces', Georgia, serif"
|
| 631 |
+
|
| 632 |
+
TITLE_FONT_FACE, TITLE_FAMILY = _load_title_font()
|
| 633 |
+
|
| 634 |
+
# =============================================================================
|
| 635 |
+
# THEME β type-foundry / specimen-sheet look (paper + ink + vermillion)
|
| 636 |
# =============================================================================
|
| 637 |
THEME = gr.themes.Base(
|
| 638 |
primary_hue=gr.themes.colors.red,
|
|
|
|
| 693 |
}
|
| 694 |
|
| 695 |
/* Hero */
|
| 696 |
+
#hero { padding: 10px 0 14px; border-bottom: 1px solid #DAD3C4; margin-bottom: 14px; }
|
| 697 |
#hero .kicker {
|
| 698 |
font-family: 'JetBrains Mono', monospace;
|
| 699 |
text-transform: uppercase; letter-spacing: 0.34em;
|
| 700 |
+
font-size: 10px; color: #FF5128; margin: 0 0 8px;
|
| 701 |
}
|
| 702 |
#hero h1 {
|
| 703 |
+
font-family: __TITLE_FAMILY__;
|
| 704 |
+
font-weight: 900; font-size: clamp(34px, 6vw, 64px);
|
| 705 |
+
line-height: 0.9; letter-spacing: -0.03em; margin: 0; color: #1A1815;
|
| 706 |
}
|
| 707 |
#hero h1 em { font-style: italic; color: #FF5128; }
|
| 708 |
#hero .tag {
|
| 709 |
font-family: 'JetBrains Mono', monospace;
|
| 710 |
+
font-size: 11px; line-height: 1.6; letter-spacing: 0.02em;
|
| 711 |
+
color: #6E6A60; margin-top: 10px; max-width: 680px;
|
| 712 |
}
|
| 713 |
#hero .tag b { color: #1A1815; font-weight: 600; }
|
| 714 |
|
|
|
|
| 732 |
letter-spacing: 0.16em !important;
|
| 733 |
font-family: 'JetBrains Mono', monospace !important;
|
| 734 |
font-weight: 600 !important;
|
| 735 |
+
font-size: 12px !important;
|
| 736 |
border-radius: 3px !important;
|
| 737 |
+
min-height: 44px !important;
|
| 738 |
+
box-shadow: 0 8px 22px -12px rgba(255,81,40,0.7) !important;
|
| 739 |
transition: transform .12s ease, box-shadow .2s ease !important;
|
| 740 |
}
|
| 741 |
.go-btn:hover { transform: translateY(-1px); }
|
| 742 |
|
| 743 |
+
/* Compaction β keep everything on one screen */
|
| 744 |
+
#hero ~ .row, .gradio-container .gap { gap: 10px !important; }
|
| 745 |
+
.gradio-container .padded, .gradio-container .block { padding: 10px !important; }
|
| 746 |
+
.eyebrow { margin: 0 0 0 !important; }
|
| 747 |
+
|
| 748 |
/* Status line */
|
| 749 |
.status-line { min-height: 22px; }
|
| 750 |
.status-line p {
|
|
|
|
| 761 |
footer { display: none !important; }
|
| 762 |
"""
|
| 763 |
|
| 764 |
+
# Inject the chosen title font-family + (optional) embedded @font-face.
|
| 765 |
+
CSS = CSS.replace("__TITLE_FAMILY__", TITLE_FAMILY) + TITLE_FONT_FACE
|
| 766 |
+
|
| 767 |
with gr.Blocks(title="Typotopia", theme=THEME, css=CSS) as demo:
|
| 768 |
gr.HTML(
|
| 769 |
"""
|
|
|
|
| 784 |
prompt = gr.Textbox(
|
| 785 |
label="Prompt",
|
| 786 |
placeholder="e.g. a bold geometric sans inspired by brutalist concrete signage",
|
| 787 |
+
lines=2,
|
| 788 |
)
|
| 789 |
+
control_image = gr.Image(label="Control image (optional)", type="pil", height=140)
|
| 790 |
with gr.Row():
|
| 791 |
seed = gr.Number(label="Seed", value=0, precision=0)
|
| 792 |
random_seed = gr.Checkbox(label="Random seed", value=True)
|
|
|
|
| 794 |
with gr.Column(scale=1):
|
| 795 |
gr.HTML("<p class='eyebrow'>02 β Specimen</p>")
|
| 796 |
status = gr.HTML(elem_classes=["status-line"])
|
| 797 |
+
otf_file = gr.File(label="Download .otf", height=80)
|
| 798 |
+
preview = gr.Image(label="Preview", type="pil", height=160)
|
| 799 |
+
gallery = gr.Gallery(label="Generated grids", columns=3, height=150, object_fit="contain")
|
| 800 |
|
| 801 |
btn.click(
|
| 802 |
generate,
|