Files
html/api/inject-solutions.py
Opus 6f0403d407 fix(br-stack w316): homepage widgets BR no overlap - doctrine zero overlap
- CAUSE RACINE: wbot.js inject weval-bot-btn (brain IA) BR 20px/20px
  + weval-audit-reco*.js (15 versions) widgets BR potentiels
  = chevauchement BR sur homepage
- FIX: CSS global w316-br-stack-fix dans index.html head
  - #weval-bot-btn fixed BR 20px (inchange)
  - #weval-bot-panel slide up 90px quand ouvert
  - WhatsApp widget stack 90px au-dessus du brain
  - Auto shift 620px quand panel IA open (overlap evite)
  - Mobile stack adapte 88px
- GOLD backup gold_index_br_stack_w316
- chattr +i preserve
- CF purge
- Doctrine: zero overlap BR strict respect
2026-04-24 16:02:11 +02:00

74 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""Doctrine 196: Mass inject /solutions/ + root new pages"""
import os, hashlib, shutil, subprocess, time, glob
UX_BLOCK = '''
<!-- DOCTRINE-60-UX-ENRICH solutions-doctrine196 -->
<style id="wtp-doctrine60-ux-premium">
:root {
--wtp-bg-start:#0a0f1c; --wtp-bg-end:#0f172a;
--wtp-surface:rgba(15,23,42,.85); --wtp-surface-hover:rgba(30,41,59,.9);
--wtp-border:rgba(99,102,241,.25); --wtp-border-hover:rgba(99,102,241,.5);
--wtp-text:#e2e8f0; --wtp-text-dim:#94a3b8; --wtp-text-bright:#f1f5f9;
--wtp-primary:#6366f1; --wtp-primary-hover:#7c7feb;
--wtp-accent:#8b5cf6; --wtp-success:#10b981; --wtp-warning:#f59e0b; --wtp-danger:#ef4444;
--wtp-radius:12px; --wtp-shadow:0 4px 24px rgba(99,102,241,.15);
--wtp-transition:all .2s cubic-bezier(.4,0,.2,1);
--wtp-font:'Inter',-apple-system,sans-serif;
}
.wtp-card{background:var(--wtp-surface);border:1px solid var(--wtp-border);border-radius:var(--wtp-radius);padding:20px;transition:var(--wtp-transition)}
.wtp-card:hover{border-color:var(--wtp-border-hover);box-shadow:var(--wtp-shadow)}
.wtp-btn{background:linear-gradient(135deg,var(--wtp-primary),var(--wtp-accent));color:#fff;padding:10px 20px;border:none;border-radius:8px;cursor:pointer;font-weight:600;transition:var(--wtp-transition)}
.wtp-btn:hover{transform:translateY(-1px);box-shadow:var(--wtp-shadow)}
@media (max-width:768px){#weval-bot-widget{bottom:100px !important;right:16px !important;z-index:10001 !important}#weval-bot-btn{width:48px !important;height:48px !important}#weval-bot-btn svg{width:22px !important;height:22px !important}#footer_banner,.footer-banner,[class*="footer-bandeau"]{z-index:9990 !important}}
</style>
'''
MARKER = 'DOCTRINE-60-UX-ENRICH'
BACKUP_DIR = '/var/www/html/vault-gold/opus'
os.makedirs(BACKUP_DIR, exist_ok=True)
ts = time.strftime('%Y%m%d-%H%M%S')
TARGETS = sorted(glob.glob('/var/www/html/solutions/*.html')) + ['/var/www/html/ia-cascade-mechanics.html']
results = []
for fpath in TARGETS:
if not os.path.exists(fpath):
continue
name = fpath.replace('/var/www/html/','').replace('/','-').replace('.html','')
try:
with open(fpath) as fp: html = fp.read()
if MARKER in html:
results.append(('already', name))
continue
if len(html) < 1500:
results.append(('too-small', name, len(html)))
continue
backup = f'{BACKUP_DIR}/{name}.html.doctrine196-{ts}.bak'
shutil.copyfile(fpath, backup)
if '</head>' in html:
html = html.replace('</head>', UX_BLOCK + '\n</head>', 1)
else:
html = UX_BLOCK + '\n' + html
try: subprocess.run(['sudo','chattr','-i',fpath], capture_output=True)
except: pass
with open(fpath,'w') as fp: fp.write(html)
try: subprocess.run(['sudo','chattr','+i',fpath], capture_output=True)
except: pass
size = os.path.getsize(fpath)
results.append(('ok', name, size))
except Exception as e:
results.append(('err', name, str(e)[:60]))
ok = sum(1 for r in results if r[0]=='ok')
already = sum(1 for r in results if r[0]=='already')
err = sum(1 for r in results if r[0]=='err')
small = sum(1 for r in results if r[0]=='too-small')
print(f'OK={ok} ALREADY={already} SMALL={small} ERR={err} TOTAL={len(results)}')
for r in results:
if r[0] in ('ok','err','too-small'): print(' ',r)