Update app.py
Browse files
app.py
CHANGED
|
@@ -704,6 +704,7 @@ FRONTEND_HTML = r"""<!DOCTYPE html>
|
|
| 704 |
--grotesk:'Helvetica Neue',Helvetica,'Archivo',Arial,sans-serif;
|
| 705 |
--mono:'JetBrains Mono',ui-monospace,monospace;
|
| 706 |
--title:__TITLE_FAMILY__;
|
|
|
|
| 707 |
}
|
| 708 |
*{box-sizing:border-box;margin:0;padding:0;}
|
| 709 |
html,body{background:var(--bg);color:var(--ink);font-family:var(--grotesk);-webkit-font-smoothing:antialiased;}
|
|
@@ -713,7 +714,7 @@ a{color:inherit;}
|
|
| 713 |
|
| 714 |
/* ---- masthead ---- */
|
| 715 |
.masthead{display:flex;justify-content:space-between;align-items:flex-end;gap:32px;flex-wrap:wrap;
|
| 716 |
-
padding-bottom:
|
| 717 |
.wordmark{font-family:var(--title);font-weight:800;line-height:.8;letter-spacing:-.05em;
|
| 718 |
font-size:clamp(48px,9vw,124px);}
|
| 719 |
.wordmark .stop{color:var(--accent);}
|
|
@@ -725,7 +726,8 @@ a{color:inherit;}
|
|
| 725 |
.meta .v{text-align:right;}
|
| 726 |
|
| 727 |
/* ---- working grid ---- */
|
| 728 |
-
.work{display:grid;grid-template-columns:0.92fr 1.18fr;gap:0;margin-top:28px;border:1px solid var(--ink);
|
|
|
|
| 729 |
.col{padding:clamp(18px,2.4vw,34px);}
|
| 730 |
.col.left{border-right:1px solid var(--ink);background:var(--paper);}
|
| 731 |
.col.right{background:var(--paper);}
|
|
@@ -736,24 +738,26 @@ a{color:inherit;}
|
|
| 736 |
.sub{color:var(--grey);}
|
| 737 |
|
| 738 |
textarea{width:100%;min-height:120px;resize:vertical;border:1px solid var(--ink);background:var(--paper);
|
| 739 |
-
font-family:var(--grotesk);font-size:15px;line-height:1.45;padding:14px;outline:none;color:var(--ink);
|
|
|
|
| 740 |
textarea:focus{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);}
|
| 741 |
textarea::placeholder{color:var(--grey);}
|
| 742 |
|
| 743 |
.dz{margin-top:22px;border:1px dashed var(--ink);background:var(--paper);min-height:120px;
|
| 744 |
display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;
|
|
|
|
| 745 |
transition:border-color .12s,background .12s;}
|
| 746 |
.dz:hover,.dz.over{border-color:var(--accent);background:#FAF8FF;}
|
| 747 |
.dz .dzhint{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--grey);}
|
| 748 |
.dz img{max-width:100%;max-height:200px;display:block;}
|
| 749 |
.dz .clear{position:absolute;top:6px;right:6px;width:26px;height:26px;border:1px solid var(--ink);
|
| 750 |
-
background:var(--paper);font-family:var(--mono);font-size:13px;line-height:1;cursor:pointer;
|
| 751 |
display:flex;align-items:center;justify-content:center;}
|
| 752 |
.dz .clear:hover{background:var(--ink);color:var(--paper);}
|
| 753 |
|
| 754 |
.go{margin-top:24px;width:100%;min-height:54px;border:none;background:var(--accent);color:#fff;
|
| 755 |
font-family:var(--grotesk);font-weight:700;font-size:13px;text-transform:uppercase;letter-spacing:.22em;
|
| 756 |
-
cursor:pointer;transition:background .12s;}
|
| 757 |
.go:hover{background:var(--ink);}
|
| 758 |
.go:disabled{background:var(--grey);cursor:not-allowed;}
|
| 759 |
|
|
@@ -763,7 +767,7 @@ textarea::placeholder{color:var(--grey);}
|
|
| 763 |
.placeholder{height:100%;min-height:280px;display:flex;align-items:center;justify-content:center;
|
| 764 |
font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--hairline);}
|
| 765 |
|
| 766 |
-
.specimen{border:1px solid var(--ink);background:var(--paper);overflow:hidden;}
|
| 767 |
.specimen .bar{display:flex;justify-content:space-between;align-items:baseline;
|
| 768 |
padding:10px 14px;border-bottom:1px solid var(--ink);}
|
| 769 |
.specimen .name{font-family:var(--title);font-weight:800;font-size:22px;letter-spacing:-.02em;}
|
|
@@ -771,7 +775,8 @@ textarea::placeholder{color:var(--grey);}
|
|
| 771 |
.specimen .canvas{padding:18px 14px;display:flex;align-items:center;justify-content:center;background:var(--paper);}
|
| 772 |
.specimen .canvas img{width:100%;height:auto;display:block;}
|
| 773 |
|
| 774 |
-
.dl{margin-top:18px;display:flex;align-items:stretch;border:1px solid var(--ink);background:var(--paper);
|
|
|
|
| 775 |
.dl .info{flex:1;padding:12px 16px;}
|
| 776 |
.dl .info .fn{font-family:var(--mono);font-size:14px;font-weight:600;letter-spacing:.02em;}
|
| 777 |
.dl .info .ft{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--grey);margin-top:3px;}
|
|
@@ -781,7 +786,7 @@ textarea::placeholder{color:var(--grey);}
|
|
| 781 |
.dl a.btn:hover{background:var(--accent);}
|
| 782 |
|
| 783 |
.grids{margin-top:18px;display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
|
| 784 |
-
.gridcard{border:1px solid var(--ink);background:var(--paper);}
|
| 785 |
.gridcard .gl{font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;
|
| 786 |
padding:7px 9px;border-bottom:1px solid var(--ink);color:var(--grey);}
|
| 787 |
.gridcard img{width:100%;height:auto;display:block;}
|
|
@@ -789,7 +794,7 @@ textarea::placeholder{color:var(--grey);}
|
|
| 789 |
|
| 790 |
/* ---- loading ---- */
|
| 791 |
.loading{height:100%;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;}
|
| 792 |
-
.scan{width:64px;height:64px;border:2px solid var(--ink);position:relative;overflow:hidden;}
|
| 793 |
.scan::after{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--accent);
|
| 794 |
animation:scan 1.1s ease-in-out infinite;}
|
| 795 |
@keyframes scan{0%{top:0}50%{top:calc(100% - 2px)}100%{top:0}}
|
|
|
|
| 704 |
--grotesk:'Helvetica Neue',Helvetica,'Archivo',Arial,sans-serif;
|
| 705 |
--mono:'JetBrains Mono',ui-monospace,monospace;
|
| 706 |
--title:__TITLE_FAMILY__;
|
| 707 |
+
--r:14px; --r-sm:9px;
|
| 708 |
}
|
| 709 |
*{box-sizing:border-box;margin:0;padding:0;}
|
| 710 |
html,body{background:var(--bg);color:var(--ink);font-family:var(--grotesk);-webkit-font-smoothing:antialiased;}
|
|
|
|
| 714 |
|
| 715 |
/* ---- masthead ---- */
|
| 716 |
.masthead{display:flex;justify-content:space-between;align-items:flex-end;gap:32px;flex-wrap:wrap;
|
| 717 |
+
padding-bottom:2px;}
|
| 718 |
.wordmark{font-family:var(--title);font-weight:800;line-height:.8;letter-spacing:-.05em;
|
| 719 |
font-size:clamp(48px,9vw,124px);}
|
| 720 |
.wordmark .stop{color:var(--accent);}
|
|
|
|
| 726 |
.meta .v{text-align:right;}
|
| 727 |
|
| 728 |
/* ---- working grid ---- */
|
| 729 |
+
.work{display:grid;grid-template-columns:0.92fr 1.18fr;gap:0;margin-top:28px;border:1px solid var(--ink);
|
| 730 |
+
border-radius:var(--r);overflow:hidden;}
|
| 731 |
.col{padding:clamp(18px,2.4vw,34px);}
|
| 732 |
.col.left{border-right:1px solid var(--ink);background:var(--paper);}
|
| 733 |
.col.right{background:var(--paper);}
|
|
|
|
| 738 |
.sub{color:var(--grey);}
|
| 739 |
|
| 740 |
textarea{width:100%;min-height:120px;resize:vertical;border:1px solid var(--ink);background:var(--paper);
|
| 741 |
+
font-family:var(--grotesk);font-size:15px;line-height:1.45;padding:14px;outline:none;color:var(--ink);
|
| 742 |
+
border-radius:var(--r-sm);}
|
| 743 |
textarea:focus{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);}
|
| 744 |
textarea::placeholder{color:var(--grey);}
|
| 745 |
|
| 746 |
.dz{margin-top:22px;border:1px dashed var(--ink);background:var(--paper);min-height:120px;
|
| 747 |
display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;
|
| 748 |
+
border-radius:var(--r-sm);overflow:hidden;
|
| 749 |
transition:border-color .12s,background .12s;}
|
| 750 |
.dz:hover,.dz.over{border-color:var(--accent);background:#FAF8FF;}
|
| 751 |
.dz .dzhint{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--grey);}
|
| 752 |
.dz img{max-width:100%;max-height:200px;display:block;}
|
| 753 |
.dz .clear{position:absolute;top:6px;right:6px;width:26px;height:26px;border:1px solid var(--ink);
|
| 754 |
+
background:var(--paper);font-family:var(--mono);font-size:13px;line-height:1;cursor:pointer;border-radius:6px;
|
| 755 |
display:flex;align-items:center;justify-content:center;}
|
| 756 |
.dz .clear:hover{background:var(--ink);color:var(--paper);}
|
| 757 |
|
| 758 |
.go{margin-top:24px;width:100%;min-height:54px;border:none;background:var(--accent);color:#fff;
|
| 759 |
font-family:var(--grotesk);font-weight:700;font-size:13px;text-transform:uppercase;letter-spacing:.22em;
|
| 760 |
+
cursor:pointer;border-radius:var(--r-sm);transition:background .12s;}
|
| 761 |
.go:hover{background:var(--ink);}
|
| 762 |
.go:disabled{background:var(--grey);cursor:not-allowed;}
|
| 763 |
|
|
|
|
| 767 |
.placeholder{height:100%;min-height:280px;display:flex;align-items:center;justify-content:center;
|
| 768 |
font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--hairline);}
|
| 769 |
|
| 770 |
+
.specimen{border:1px solid var(--ink);background:var(--paper);overflow:hidden;border-radius:var(--r);}
|
| 771 |
.specimen .bar{display:flex;justify-content:space-between;align-items:baseline;
|
| 772 |
padding:10px 14px;border-bottom:1px solid var(--ink);}
|
| 773 |
.specimen .name{font-family:var(--title);font-weight:800;font-size:22px;letter-spacing:-.02em;}
|
|
|
|
| 775 |
.specimen .canvas{padding:18px 14px;display:flex;align-items:center;justify-content:center;background:var(--paper);}
|
| 776 |
.specimen .canvas img{width:100%;height:auto;display:block;}
|
| 777 |
|
| 778 |
+
.dl{margin-top:18px;display:flex;align-items:stretch;border:1px solid var(--ink);background:var(--paper);
|
| 779 |
+
border-radius:var(--r-sm);overflow:hidden;}
|
| 780 |
.dl .info{flex:1;padding:12px 16px;}
|
| 781 |
.dl .info .fn{font-family:var(--mono);font-size:14px;font-weight:600;letter-spacing:.02em;}
|
| 782 |
.dl .info .ft{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--grey);margin-top:3px;}
|
|
|
|
| 786 |
.dl a.btn:hover{background:var(--accent);}
|
| 787 |
|
| 788 |
.grids{margin-top:18px;display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
|
| 789 |
+
.gridcard{border:1px solid var(--ink);background:var(--paper);border-radius:var(--r-sm);overflow:hidden;}
|
| 790 |
.gridcard .gl{font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;
|
| 791 |
padding:7px 9px;border-bottom:1px solid var(--ink);color:var(--grey);}
|
| 792 |
.gridcard img{width:100%;height:auto;display:block;}
|
|
|
|
| 794 |
|
| 795 |
/* ---- loading ---- */
|
| 796 |
.loading{height:100%;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;}
|
| 797 |
+
.scan{width:64px;height:64px;border:2px solid var(--ink);position:relative;overflow:hidden;border-radius:var(--r-sm);}
|
| 798 |
.scan::after{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--accent);
|
| 799 |
animation:scan 1.1s ease-in-out infinite;}
|
| 800 |
@keyframes scan{0%{top:0}50%{top:calc(100% - 2px)}100%{top:0}}
|