"""Six scientific illustrations for the home frontier cards, as inline SVG data URIs.

The old backgrounds were CSS gradient recipes — blue field, cyan lines, a glow — which is why
every card read as decoration. Each card now carries an actual diagram of its subject, drawn in
the site's palette and nothing else:

  1  metasurface unit-cell array: split-rings, crosses, patches — one cell picked out in gold
  2  photonic-crystal hole lattice with a line-defect waveguide and a gold cavity site
  3  bowtie nanoantenna: two gold tips, the hotspot in the gap, thin field lines around it
  4  integrated photonic circuit: a Mach–Zehnder with couplers, a gold ring resonator, photons
  5  anticrossing: dashed bare photon and exciton lines, solid polariton branches, Rabi gap
  6  auxetic re-entrant honeycomb — an architected mechanical lattice

Vector, ~2 KB apiece, embedded in meta27.css: no new HTTP requests, no stock imagery, no AI
texture. A dark vignette sits over each drawing where the caption lives, so the type stays as
readable as before.
"""

import re
from urllib.parse import quote

NAVY = '#0d2a3d'
CYAN = '#39c4de'
CYAN_S = '#7fdcee'
GOLD = '#d8b46a'
GOLD_S = '#e7cf9e'


def svg(body, w=600, h=400):
    doc = ('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d %d">'
           '<rect width="%d" height="%d" fill="%s"/>%s</svg>' % (w, h, w, h, NAVY, body))
    return 'url("data:image/svg+xml,%s")' % quote(doc, safe="~()*!.'/:,%=<>-")


# ---------------------------------------------------------------- 1 · metasurface array
def metasurface():
    """A periodic surface, not an alphabet: three unit-cell families (split-ring, cross, patch)
    repeated as a regular super-cell, secondary strokes at one opacity, one gold SRR framed."""
    cells = []
    kinds = ['ring', 'cross', 'patch']
    for r in range(4):
        for c in range(6):
            x, y = 55 + c * 100, 52 + r * 100
            kind = kinds[c % 3]
            hot = (r == 1 and c == 3)
            col = GOLD if hot else CYAN_S
            op = '0.92' if hot else '0.35'
            if kind == 'ring':
                cells.append('<circle cx="%d" cy="%d" r="21" fill="none" stroke="%s" stroke-opacity="%s" stroke-width="4" stroke-dasharray="116 16" transform="rotate(%d %d %d)"/>'
                             % (x, y, col, op, (r * 90 - 104) % 360, x, y))
            elif kind == 'cross':
                cells.append('<path d="M%d %dh34M%d %dv34" stroke="%s" stroke-opacity="%s" stroke-width="4"/>'
                             % (x - 17, y, x, y - 17, col, op))
            else:
                cells.append('<rect x="%d" y="%d" width="28" height="28" rx="3" fill="none" stroke="%s" stroke-opacity="%s" stroke-width="4"/>'
                             % (x - 14, y - 14, col, op))
            if hot:
                cells.append('<rect x="%d" y="%d" width="70" height="70" rx="6" fill="none" stroke="%s" stroke-opacity="0.55" stroke-width="2"/>'
                             % (x - 35, y - 35, GOLD))
    return svg(''.join(cells))


# ---------------------------------------------------------------- 2 · photonic crystal
def photonic_crystal():
    holes = []
    for r in range(7):
        y = 40 + r * 54
        off = 27 if r % 2 else 0
        for c in range(12):
            x = 30 + c * 52 + off
            if r == 3:              # line defect: the waveguide row
                continue
            if r == 2 and c == 6:   # cavity: one missing hole, glowing
                holes.append('<circle cx="%d" cy="%d" r="26" fill="%s" fill-opacity="0.14"/>' % (x, y, GOLD))
                holes.append('<circle cx="%d" cy="%d" r="12" fill="%s" fill-opacity="0.5"/>' % (x, y, GOLD_S))
                continue
            holes.append('<circle cx="%d" cy="%d" r="15" fill="none" stroke="%s" stroke-opacity="0.42" stroke-width="4"/>' % (x, y, CYAN_S))
    # guided mode in the defect row — a hint, not a decoration: faint cyan, the cavity keeps
    # the card's one gold accent
    holes.append('<path d="M0 202 q30 -13 60 0 t60 0 t60 0 t60 0 t60 0 t60 0 t60 0 t60 0 t60 0 t60 0" fill="none" stroke="%s" stroke-opacity="0.22" stroke-width="2.5"/>' % CYAN_S)
    return svg(''.join(holes))


# ---------------------------------------------------------------- 3 · plasmonic bowtie
def plasmonics():
    parts = []
    # field lines: nested ellipses through the gap
    for i, (rx, ry, o) in enumerate([(70, 40, .38), (115, 72, .28), (165, 108, .18), (215, 146, .10)]):
        parts.append('<ellipse cx="300" cy="200" rx="%d" ry="%d" fill="none" stroke="%s" stroke-opacity="%s" stroke-width="2.5"/>' % (rx, ry, CYAN, o))
    # bowtie: two gold triangles tip to tip, small gap
    parts.append('<path d="M120 120 L286 196 L120 280 Z" fill="%s" fill-opacity="0.66"/>' % GOLD)
    parts.append('<path d="M480 120 L314 196 L480 280 Z" fill="%s" fill-opacity="0.66"/>' % GOLD)
    # hotspot in the gap
    parts.append('<circle cx="300" cy="197" r="26" fill="%s" fill-opacity="0.22"/>' % CYAN_S)
    parts.append('<circle cx="300" cy="197" r="12" fill="%s" fill-opacity="0.7"/>' % CYAN_S)
    parts.append('<circle cx="300" cy="197" r="5" fill="#ffffff" fill-opacity="0.95"/>')
    return svg(''.join(parts))


# ---------------------------------------------------------------- 4 · quantum photonic circuit
def quantum():
    p = []
    wg = 'fill="none" stroke="%s" stroke-opacity="0.75" stroke-width="4"' % CYAN_S
    # two waveguides forming an MZI: couplers at x 140-200 and 400-460
    p.append('<path d="M0 150 H120 C150 150 150 178 180 178 H420 C450 178 450 150 480 150 H600" %s/>' % wg)
    p.append('<path d="M0 250 H120 C150 250 150 222 180 222 H420 C450 222 450 250 480 250 H600" %s/>' % wg)
    # phase shifter pad on upper arm — circuit element, cyan like the guides
    p.append('<rect x="270" y="160" width="60" height="10" rx="4" fill="none" stroke="%s" stroke-opacity="0.7" stroke-width="3"/>' % CYAN_S)
    # ring resonator tangent to the lower bus with a visible coupling gap: the card's gold element
    p.append('<circle cx="470" cy="286" r="26" fill="none" stroke="%s" stroke-opacity="0.9" stroke-width="4"/>' % GOLD)
    # single photons on the inputs/outputs, white so the ring keeps the only gold
    for x, y in [(48, 150), (92, 150), (540, 178), (566, 250)]:
        p.append('<circle cx="%d" cy="%d" r="6" fill="#ffffff" fill-opacity="0.85"/>' % (x, y))
    # faint second circuit layer for depth
    p.append('<path d="M0 70 H600" stroke="%s" stroke-opacity="0.12" stroke-width="3"/>' % CYAN)
    p.append('<path d="M0 345 H240 C270 345 270 334 300 334" fill="none" stroke="%s" stroke-opacity="0.18" stroke-width="3"/>' % CYAN)
    return svg(''.join(p))


# ---------------------------------------------------------------- 5 · anticrossing
def light_matter():
    p = []
    # bare modes, dashed: photon (diagonal) and exciton (horizontal)
    p.append('<path d="M60 340 L540 60" stroke="%s" stroke-opacity="0.4" stroke-width="3" stroke-dasharray="10 9"/>' % CYAN_S)
    p.append('<path d="M40 200 H560" stroke="%s" stroke-opacity="0.4" stroke-width="3" stroke-dasharray="10 9"/>' % CYAN_S)
    # polariton branches, solid gold, avoiding the crossing
    p.append('<path d="M60 348 C220 260 240 238 300 232 C420 222 480 216 552 208" fill="none" stroke="%s" stroke-opacity="0.95" stroke-width="5"/>' % GOLD)
    p.append('<path d="M48 192 C120 184 180 178 300 168 C360 160 380 140 540 52" fill="none" stroke="%s" stroke-opacity="0.95" stroke-width="5"/>' % GOLD_S)
    # Rabi splitting marker at the anticrossing
    p.append('<path d="M300 176 V224" stroke="#ffffff" stroke-opacity="0.85" stroke-width="3"/>')
    p.append('<path d="M294 184 L300 176 L306 184 M294 216 L300 224 L306 216" fill="none" stroke="#ffffff" stroke-opacity="0.85" stroke-width="3"/>')
    return svg(''.join(p))


# ---------------------------------------------------------------- 6 · auxetic lattice
def multiphysics():
    cell = ('M0 0 L46 18 L92 0 M0 0 L0 62 M92 0 L92 62 M0 62 L46 44 L92 62')
    p = []
    for r in range(5):
        for c in range(6):
            x, y = 18 + c * 96, 12 + r * 84
            hot = (r == 2 and c == 3)
            col, op, w = (GOLD, '0.9', '5') if hot else (CYAN_S, '0.3', '4')
            p.append('<path d="%s" transform="translate(%d %d)" fill="none" stroke="%s" stroke-opacity="%s" stroke-width="%s" stroke-linejoin="round"/>'
                     % (cell, x, y, col, op, w))
    return svg(''.join(p))


VIGNETTE = 'linear-gradient(180deg, rgba(6,18,28,.18) 0%, rgba(6,18,28,0) 32%, rgba(6,18,28,.08) 58%, rgba(6,18,28,.72) 100%)'

BGS = {
    1: metasurface(), 2: photonic_crystal(), 3: plasmonics(),
    4: quantum(), 5: light_matter(), 6: multiphysics(),
}

css = open('meta27.css', encoding='utf-8').read()
for n, bg in BGS.items():
    pat = re.compile(r'\.bg-%d\{[^}]*\}' % n)
    rule = '.bg-%d{background:%s, %s center/cover no-repeat, %s}' % (n, VIGNETTE, bg, NAVY)
    css, k = pat.subn(lambda m: rule, css, count=1)
    assert k, n
    print('bg-%d : %d octets de SVG' % (n, len(bg)))
open('meta27.css', 'w', encoding='utf-8').write(css)
print('meta27.css : %d octets' % len(css))
