luxury-authenticator / scripts /_patch_css.py
Princess24's picture
ui enhanced
3b01ec8
Raw
History Blame Contribute Delete
15.8 kB
"""Patch app.py CSS block only — no imports, pure file I/O."""
import re, sys, pathlib
TARGET = pathlib.Path(__file__).parent.parent / 'app.py'
NEW_CSS = (
"\n"
" @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700"
"&family=Plus+Jakarta+Sans:wght@500;700;800&display=swap');\n"
"\n"
" :root {\n"
" --bg: #0f1117;\n"
" --bg-card: #181c27;\n"
" --bg-inset: #11141d;\n"
" --fg: #e8eaf0;\n"
" --fg-soft: #9ea3b5;\n"
" --muted: #636880;\n"
" --accent: #7c6fff;\n"
" --accent-light: #a89eff;\n"
" --accent-glow: rgba(124, 111, 255, 0.28);\n"
" --border: rgba(255, 255, 255, 0.07);\n"
" --border-accent: rgba(124, 111, 255, 0.35);\n"
" --shadow-card: 0 4px 32px rgba(0, 0, 0, 0.45), 0 1px 0 rgba(255,255,255,0.05) inset;\n"
" --shadow-inset: inset 0 2px 8px rgba(0, 0, 0, 0.55);\n"
" --shadow-btn: 0 4px 20px rgba(124, 111, 255, 0.28);\n"
" --radius-card: 20px;\n"
" --radius-base: 12px;\n"
" --radius-sm: 8px;\n"
" }\n"
"\n"
" html { scroll-behavior: smooth; }\n"
"\n"
" *, *::before, *::after { box-sizing: border-box; }\n"
"\n"
" body,\n"
" .gradio-container,\n"
" .gradio-container > .main,\n"
" .gradio-container > .main > .wrap,\n"
" footer {\n"
" background: var(--bg) !important;\n"
" color: var(--fg) !important;\n"
" font-family: 'DM Sans', sans-serif !important;\n"
" border: none !important;\n"
" }\n"
"\n"
" .gradio-container {\n"
" max-width: 1300px !important;\n"
" padding: 28px 20px 56px !important;\n"
" }\n"
"\n"
" h1, h2, h3, h4 {\n"
" font-family: 'Plus Jakarta Sans', sans-serif !important;\n"
" color: var(--fg) !important;\n"
" letter-spacing: -0.025em;\n"
" }\n"
"\n"
" /* === Hero === */\n"
" .hero-shell {\n"
" position: relative;\n"
" overflow: hidden;\n"
" padding: 40px 44px 36px;\n"
" margin-bottom: 20px;\n"
" background: var(--bg-card);\n"
" border: 1px solid var(--border);\n"
" border-radius: var(--radius-card);\n"
" box-shadow: var(--shadow-card);\n"
" }\n"
"\n"
" .hero-shell::before {\n"
" content: '';\n"
" position: absolute;\n"
" right: -80px;\n"
" top: -80px;\n"
" width: 300px;\n"
" height: 300px;\n"
" border-radius: 9999px;\n"
" background: radial-gradient(circle, rgba(124,111,255,0.25) 0%, transparent 70%);\n"
" animation: orb-drift 6s ease-in-out infinite;\n"
" pointer-events: none;\n"
" }\n"
"\n"
" .hero-shell::after {\n"
" content: '';\n"
" position: absolute;\n"
" left: 50%;\n"
" bottom: -60px;\n"
" width: 200px;\n"
" height: 200px;\n"
" border-radius: 9999px;\n"
" background: radial-gradient(circle, rgba(99,200,200,0.12) 0%, transparent 70%);\n"
" animation: orb-drift 8s ease-in-out infinite reverse;\n"
" pointer-events: none;\n"
" }\n"
"\n"
" .hero-kicker {\n"
" display: inline-block;\n"
" text-transform: uppercase;\n"
" letter-spacing: 0.18em;\n"
" font-size: 11px;\n"
" color: var(--accent-light);\n"
" font-weight: 700;\n"
" background: rgba(124,111,255,0.12);\n"
" border: 1px solid var(--border-accent);\n"
" padding: 4px 12px;\n"
" border-radius: 99px;\n"
" margin-bottom: 16px;\n"
" }\n"
"\n"
" .hero-title {\n"
" margin: 0 0 14px;\n"
" font-size: clamp(2.4rem, 4.5vw, 3.8rem);\n"
" line-height: 1.0;\n"
" font-weight: 800;\n"
" background: linear-gradient(135deg, #ffffff 30%, var(--accent-light));\n"
" -webkit-background-clip: text;\n"
" -webkit-text-fill-color: transparent;\n"
" background-clip: text;\n"
" }\n"
"\n"
" .hero-copy {\n"
" max-width: 680px;\n"
" color: var(--fg-soft);\n"
" font-size: 0.97rem;\n"
" line-height: 1.75;\n"
" margin: 0;\n"
" }\n"
"\n"
" .hero-grid {\n"
" display: grid;\n"
" grid-template-columns: repeat(3, minmax(0, 1fr));\n"
" gap: 12px;\n"
" margin-top: 28px;\n"
" }\n"
"\n"
" .hero-pill {\n"
" border-radius: var(--radius-base);\n"
" padding: 14px 16px;\n"
" background: var(--bg-inset);\n"
" border: 1px solid var(--border);\n"
" min-height: 82px;\n"
" transition: border-color 0.2s;\n"
" }\n"
" .hero-pill:hover { border-color: var(--border-accent); }\n"
"\n"
" .hero-pill-label {\n"
" display: block;\n"
" text-transform: uppercase;\n"
" letter-spacing: 0.14em;\n"
" color: var(--accent-light);\n"
" font-size: 10px;\n"
" margin-bottom: 6px;\n"
" font-weight: 700;\n"
" }\n"
"\n"
" /* === Status bar === */\n"
" .soft-status {\n"
" border-radius: var(--radius-base);\n"
" padding: 10px 18px;\n"
" margin-bottom: 18px;\n"
" background: var(--bg-card) !important;\n"
" border: 1px solid var(--border) !important;\n"
" box-shadow: none !important;\n"
" font-size: 0.88rem;\n"
" color: var(--fg-soft) !important;\n"
" }\n"
"\n"
" /* === Cards === */\n"
" .soft-card {\n"
" padding: 24px;\n"
" background: var(--bg-card) !important;\n"
" border: 1px solid var(--border) !important;\n"
" border-radius: var(--radius-card) !important;\n"
" box-shadow: var(--shadow-card) !important;\n"
" }\n"
"\n"
" .section-title {\n"
" margin: 0 0 6px;\n"
" font-size: 1.35rem;\n"
" font-weight: 800;\n"
" color: var(--fg) !important;\n"
" }\n"
"\n"
" .section-copy {\n"
" margin: 0 0 18px;\n"
" color: var(--muted);\n"
" line-height: 1.6;\n"
" font-size: 0.9rem;\n"
" }\n"
"\n"
" /* === Image well === */\n"
" .well {\n"
" border-radius: var(--radius-base);\n"
" box-shadow: var(--shadow-inset);\n"
" padding: 10px;\n"
" background: var(--bg-inset) !important;\n"
" border: 1px solid var(--border) !important;\n"
" }\n"
"\n"
" /* === Output boxes === */\n"
" .summary-box {\n"
" margin-top: 14px;\n"
" border-radius: var(--radius-base);\n"
" padding: 16px;\n"
" background: var(--bg-inset) !important;\n"
" border: 1px solid var(--border-accent) !important;\n"
" box-shadow: 0 0 20px rgba(124,111,255,0.18) !important;\n"
" }\n"
"\n"
" .detail-box {\n"
" margin-top: 10px;\n"
" border-radius: var(--radius-base);\n"
" padding: 4px;\n"
" background: var(--bg-inset) !important;\n"
" border: 1px solid var(--border) !important;\n"
" box-shadow: none !important;\n"
" transition: border-color 0.2s;\n"
" }\n"
" .detail-box:hover { border-color: var(--border-accent) !important; }\n"
"\n"
" .download-box {\n"
" margin-top: 12px;\n"
" border-radius: var(--radius-base);\n"
" padding: 8px;\n"
" background: var(--bg-inset) !important;\n"
" border: 1px dashed var(--border) !important;\n"
" box-shadow: none !important;\n"
" }\n"
"\n"
" .soft-footer {\n"
" padding: 16px 20px;\n"
" margin-top: 16px;\n"
" background: transparent !important;\n"
" border: none !important;\n"
" box-shadow: none !important;\n"
" }\n"
"\n"
" /* === Analyse button === */\n"
" #analyze-btn {\n"
" min-height: 52px;\n"
" border: none !important;\n"
" border-radius: var(--radius-base) !important;\n"
" background: linear-gradient(135deg, var(--accent-light), var(--accent)) !important;\n"
" color: white !important;\n"
" font-weight: 700 !important;\n"
" font-size: 1rem !important;\n"
" letter-spacing: 0.02em !important;\n"
" box-shadow: var(--shadow-btn) !important;\n"
" transition: transform 260ms ease, box-shadow 260ms ease !important;\n"
" }\n"
" #analyze-btn:hover {\n"
" transform: translateY(-2px) !important;\n"
" box-shadow: 0 8px 30px rgba(124,111,255,0.4) !important;\n"
" }\n"
" #analyze-btn:active {\n"
" transform: translateY(0) !important;\n"
" box-shadow: none !important;\n"
" }\n"
"\n"
" /* === Gradio structural overrides: kill conflicting defaults === */\n"
" .gradio-container .block,\n"
" .gradio-container .gr-box,\n"
" .gradio-container .gr-group,\n"
" .gradio-container .gr-form,\n"
" .gradio-container .gr-panel,\n"
" .gradio-container .gap-4,\n"
" .gradio-container .row,\n"
" .gradio-container [data-testid='block'] {\n"
" background: transparent !important;\n"
" border: none !important;\n"
" box-shadow: none !important;\n"
" color: var(--fg) !important;\n"
" }\n"
"\n"
" /* Accordions */\n"
" .gradio-container .gr-accordion {\n"
" background: var(--bg-inset) !important;\n"
" border: 1px solid var(--border) !important;\n"
" border-radius: var(--radius-base) !important;\n"
" box-shadow: none !important;\n"
" overflow: hidden;\n"
" }\n"
" .gradio-container .gr-accordion > button {\n"
" background: var(--bg-inset) !important;\n"
" color: var(--fg) !important;\n"
" font-weight: 600 !important;\n"
" min-height: 46px;\n"
" padding: 0 16px !important;\n"
" border: none !important;\n"
" }\n"
"\n"
" /* Text inputs */\n"
" .gradio-container textarea,\n"
" .gradio-container input[type='text'],\n"
" .gradio-container input[type='number'] {\n"
" background: var(--bg-inset) !important;\n"
" border: 1px solid var(--border) !important;\n"
" border-radius: var(--radius-sm) !important;\n"
" color: var(--fg) !important;\n"
" box-shadow: var(--shadow-inset) !important;\n"
" }\n"
"\n"
" /* Image/file uploader zones */\n"
" .gradio-container .wrap,\n"
" .gradio-container .image-container,\n"
" .gradio-container .upload-container,\n"
" .gradio-container .empty,\n"
" .gradio-container .file-preview,\n"
" .gradio-container .file-wrap,\n"
" .gradio-container [data-testid='image'],\n"
" .gradio-container .gr-image,\n"
" .gradio-container .gr-file {\n"
" background: var(--bg-inset) !important;\n"
" border: 1px dashed rgba(124,111,255,0.25) !important;\n"
" border-radius: var(--radius-base) !important;\n"
" box-shadow: none !important;\n"
" color: var(--fg-soft) !important;\n"
" }\n"
"\n"
" /* Markdown */\n"
" .gradio-container .gradio-markdown,\n"
" .gradio-container .prose {\n"
" color: var(--fg) !important;\n"
" background: transparent !important;\n"
" }\n"
" .gradio-container .gradio-markdown p,\n"
" .gradio-container .gradio-markdown li,\n"
" .gradio-container .gradio-markdown strong {\n"
" color: var(--fg) !important;\n"
" }\n"
" .gradio-container .gradio-markdown h1,\n"
" .gradio-container .gradio-markdown h2,\n"
" .gradio-container .gradio-markdown h3 {\n"
" color: var(--fg) !important;\n"
" font-family: 'Plus Jakarta Sans', sans-serif !important;\n"
" }\n"
" .gradio-container .gradio-markdown blockquote {\n"
" border-left: 3px solid var(--accent);\n"
" padding-left: 12px;\n"
" color: var(--fg-soft) !important;\n"
" }\n"
" .gradio-container .gradio-markdown code {\n"
" background: rgba(124,111,255,0.12) !important;\n"
" color: var(--accent-light) !important;\n"
" border-radius: 4px;\n"
" padding: 1px 5px;\n"
" }\n"
"\n"
" /* Component labels */\n"
" .gradio-container label > span,\n"
" .gradio-container .label-wrap > span {\n"
" color: var(--muted) !important;\n"
" font-size: 0.75rem !important;\n"
" font-weight: 700 !important;\n"
" text-transform: uppercase !important;\n"
" letter-spacing: 0.1em !important;\n"
" }\n"
"\n"
" /* SVG icons */\n"
" .gradio-container svg {\n"
" color: var(--muted) !important;\n"
" stroke: var(--muted) !important;\n"
" }\n"
"\n"
" /* Secondary buttons */\n"
" .gradio-container button:not(#analyze-btn) {\n"
" background: var(--bg-card) !important;\n"
" color: var(--fg) !important;\n"
" border: 1px solid var(--border) !important;\n"
" border-radius: var(--radius-sm) !important;\n"
" }\n"
"\n"
" /* Focus rings */\n"
" .gradio-container button:focus-visible,\n"
" .gradio-container input:focus-visible,\n"
" .gradio-container textarea:focus-visible {\n"
" outline: none !important;\n"
" box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent) !important;\n"
" }\n"
"\n"
" /* Custom scrollbar */\n"
" ::-webkit-scrollbar { width: 6px; height: 6px; }\n"
" ::-webkit-scrollbar-track { background: var(--bg); }\n"
" ::-webkit-scrollbar-thumb { background: var(--muted); border-radius: 99px; }\n"
"\n"
" @keyframes orb-drift {\n"
" 0%, 100% { transform: translate(0, 0) scale(1); }\n"
" 50% { transform: translate(-20px, 14px) scale(1.08); }\n"
" }\n"
"\n"
" @media (max-width: 900px) {\n"
" .hero-grid { grid-template-columns: 1fr; }\n"
" .hero-title { font-size: 2.6rem; }\n"
" .hero-shell { padding: 28px 24px; }\n"
" }\n"
" "
)
# Read and normalise to LF so markers work regardless of CRLF
raw = TARGET.read_bytes()
src = raw.decode('utf-8').replace('\r\n', '\n')
# Find the css = """...""" block
start_marker = ' css = """\n'
end_marker = '\n """\n'
s = src.find(start_marker)
if s == -1:
print('ERROR: start marker not found')
sys.exit(1)
e = src.find(end_marker, s + len(start_marker))
if e == -1:
print('ERROR: end marker not found')
sys.exit(1)
new_src = src[:s] + start_marker + NEW_CSS + src[e:]
# Write back with LF endings
TARGET.write_bytes(new_src.encode('utf-8'))
print(f'OK - patched {TARGET} ({len(src)} -> {len(new_src)} bytes)')