ITNovaML/PCAgentinAI
0
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="UTF-8">5<meta name="viewport" content="width=device-width, initial-scale=1.0">6<title>PolicyBridge — P&C Intelligence Platform</title>7<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=IBM+Plex+Sans:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">8<style>9:root {10 --bg: #0a0d12;11 --bg2: #0f141c;12 --bg3: #151c27;13 --bg4: #1c2535;14 --border: #1e2d42;15 --border2: #2a3a52;16 --muted: #4a6080;17 --muted2: #6a80a0;18 --text: #c8d8e8;19 --text2: #e8f2ff;20 --white: #f0f6ff;21 --accent: #00a8ff;22 --accent2: #0070cc;23 --amber: #ffb020;24 --amber2: #cc8800;25 --green: #00cc6a;26 --green2: #008844;27 --red: #ff4444;28 --red2: #cc1111;29 --purple: #8860ff;30 --bronze-c: #cd7f32;31 --silver-c: #8ab4c8;32 --gold-c: #ffd700;33 --font-head: 'Syne', sans-serif;34 --font-body: 'IBM Plex Sans', sans-serif;35 --font-mono: 'IBM Plex Mono', monospace;36 --r: 8px;37 --r2: 12px;38}39 40*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }41html { scroll-behavior: smooth; }42body { font-family: var(--font-body); background: var(--bg); color: var(--text); min-height: 100vh; font-size: 13px; line-height: 1.6; overflow-x: hidden; }43 44/* ── HEADER ── */45.app-header {46 background: var(--bg2);47 border-bottom: 1px solid var(--border);48 display: flex; align-items: center;49 padding: 0 20px;50 height: 54px;51 position: sticky; top: 0; z-index: 200;52 gap: 24px;53}54.logo { display: flex; align-items: center; gap: 10px; margin-right: 8px; }55.logo-mark {56 width: 30px; height: 30px; border-radius: 7px;57 background: linear-gradient(135deg, var(--accent), var(--purple));58 display: flex; align-items: center; justify-content: center;59 font-family: var(--font-head); font-size: 15px; font-weight: 800; color: white;60}61.logo-name { font-family: var(--font-head); font-size: 17px; font-weight: 700; color: var(--white); }62.logo-sub { font-size: 10px; color: var(--muted2); letter-spacing: 1.5px; text-transform: uppercase; }63 64/* ── TABS ── */65.main-tabs {66 display: flex; gap: 2px; flex: 1;67 overflow-x: auto;68}69.tab-btn {70 padding: 6px 16px;71 border-radius: 7px;72 border: none;73 background: transparent;74 color: var(--muted2);75 font-family: var(--font-body);76 font-size: 12px; font-weight: 500;77 cursor: pointer;78 display: flex; align-items: center; gap: 7px;79 transition: all 0.2s;80 white-space: nowrap;81 letter-spacing: 0.2px;82}83.tab-btn:hover { background: var(--bg3); color: var(--text2); }84.tab-btn.active { background: var(--bg4); color: var(--accent); border: 1px solid var(--border2); }85.tab-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.6; }86 87.hdr-right { display: flex; gap: 10px; align-items: center; margin-left: auto; }88.pill {89 padding: 3px 10px; border-radius: 20px;90 font-size: 10px; font-weight: 600; letter-spacing: 0.5px; text-transform: uppercase;91}92.pill-accent { background: rgba(0,168,255,0.15); color: var(--accent); border: 1px solid rgba(0,168,255,0.3); }93.pill-amber { background: rgba(255,176,32,0.15); color: var(--amber); border: 1px solid rgba(255,176,32,0.3); }94.pill-green { background: rgba(0,204,106,0.15); color: var(--green); border: 1px solid rgba(0,204,106,0.3); }95.pill-muted { background: var(--bg4); color: var(--muted2); border: 1px solid var(--border); }96 97/* ── TAB PAGES ── */98.tab-page { display: none; min-height: calc(100vh - 54px); }99.tab-page.active { display: block; }100 101/* ══════════════════════════════════════════102 TAB 1 — SUBMISSION FORM103══════════════════════════════════════════ */104.sub-layout {105 display: grid;106 grid-template-columns: 220px 1fr 260px;107 min-height: calc(100vh - 54px);108}109 110/* Left nav */111.sub-nav {112 background: var(--bg2);113 border-right: 1px solid var(--border);114 padding: 20px 14px;115 position: sticky; top: 54px;116 height: calc(100vh - 54px); overflow-y: auto;117}118.snav-title { font-size: 10px; text-transform: uppercase; letter-spacing: 1.5px; color: var(--muted); font-weight: 600; margin-bottom: 10px; padding: 0 8px; }119.snav-item {120 display: flex; align-items: center; gap: 9px;121 padding: 8px 10px; border-radius: var(--r);122 cursor: pointer; color: var(--muted2); font-size: 12px; font-weight: 500;123 transition: all 0.2s; margin-bottom: 2px;124}125.snav-item:hover { background: var(--bg3); color: var(--text); }126.snav-item.active { background: rgba(0,168,255,0.1); color: var(--accent); border: 1px solid rgba(0,168,255,0.2); }127.snav-item.done { color: var(--green); }128.snav-num {129 width: 20px; height: 20px; border-radius: 50%;130 background: var(--bg4); border: 1px solid var(--border2);131 display: flex; align-items: center; justify-content: center;132 font-size: 10px; font-weight: 600; flex-shrink: 0;133 transition: all 0.2s;134}135.snav-item.active .snav-num { background: var(--accent); border-color: var(--accent); color: white; }136.snav-item.done .snav-num { background: var(--green); border-color: var(--green); color: white; }137 138.submitter-type-box { margin-top: 20px; padding: 12px; background: var(--bg3); border-radius: var(--r); border: 1px solid var(--border); }139.stype-title { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 8px; }140.stype-opt { display: flex; flex-direction: column; gap: 4px; }141.stype-opt label {142 display: flex; align-items: center; gap: 7px;143 font-size: 11px; color: var(--muted2); cursor: pointer;144 padding: 5px 7px; border-radius: 6px; transition: background 0.15s;145}146.stype-opt label:hover { background: var(--bg4); }147.stype-opt input[type="radio"] { accent-color: var(--accent); }148 149.db-info-box { margin-top: 16px; padding: 10px 12px; background: var(--bg3); border-radius: var(--r); border: 1px solid var(--border); }150.db-info-title { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 8px; }151.db-row { display: flex; justify-content: space-between; font-size: 11px; margin-bottom: 4px; }152.db-row .dk { color: var(--muted); }153.db-row .dv { color: var(--text); font-family: var(--font-mono); }154 155/* Form main */156.sub-form-main { padding: 24px 28px; overflow-y: auto; }157.form-section { display: none; animation: fadeIn 0.25s ease; }158.form-section.active { display: block; }159@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }160 161.fsec-hdr { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }162.fsec-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--bg4); display: flex; align-items: center; justify-content: center; font-size: 20px; border: 1px solid var(--border2); }163.fsec-title { font-family: var(--font-head); font-size: 19px; font-weight: 700; color: var(--white); }164.fsec-desc { font-size: 12px; color: var(--muted2); }165 166/* Cards */167.fcard { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2); padding: 18px 20px; margin-bottom: 16px; }168.fcard-title {169 font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px;170 color: var(--muted2); margin-bottom: 14px;171 display: flex; align-items: center; gap: 8px;172}173.fcard-title::before { content: ''; width: 3px; height: 14px; background: var(--accent); border-radius: 2px; display: inline-block; }174 175/* Grid */176.fg { display: grid; gap: 14px; }177.fg2 { grid-template-columns: 1fr 1fr; }178.fg3 { grid-template-columns: 1fr 1fr 1fr; }179.fg4 { grid-template-columns: 1fr 1fr 1fr 1fr; }180.cs2 { grid-column: span 2; }181.cs3 { grid-column: span 3; }182 183/* Fields */184.fld { display: flex; flex-direction: column; gap: 4px; }185.flabel { font-size: 11px; font-weight: 600; color: var(--text); letter-spacing: 0.2px; display: flex; align-items: center; gap: 4px; }186.flabel .req { color: var(--red); }187.flabel .ftip { font-weight: 400; color: var(--muted); font-size: 10px; margin-left: auto; }188 189input[type="text"], input[type="email"], input[type="tel"], input[type="date"],190input[type="number"], select, textarea {191 width: 100%; padding: 8px 11px;192 background: var(--bg3); border: 1px solid var(--border2);193 border-radius: var(--r); color: var(--text2);194 font-family: var(--font-body); font-size: 12px;195 transition: border-color 0.2s, box-shadow 0.2s;196 outline: none; appearance: none;197}198input:focus, select:focus, textarea:focus {199 border-color: var(--accent);200 box-shadow: 0 0 0 3px rgba(0,168,255,0.12);201}202input.err, select.err { border-color: var(--red); background: rgba(255,68,68,0.06); }203input.ok, select.ok { border-color: var(--green); }204select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6' fill='none' stroke='%234a6080' stroke-width='1.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; padding-right: 28px; }205select option { background: var(--bg3); }206textarea { resize: vertical; min-height: 72px; }207.ferr { font-size: 10px; color: var(--red); display: none; }208.ferr.show { display: block; }209.fhint { font-size: 10px; color: var(--muted); }210 211/* Coverage cards */212.cov-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 16px; }213.cov-card {214 border: 1.5px solid var(--border2); border-radius: 10px; padding: 12px;215 cursor: pointer; transition: all 0.2s; background: var(--bg3); position: relative;216}217.cov-card:hover { border-color: var(--accent); transform: translateY(-1px); }218.cov-card.sel { border-color: var(--accent); background: rgba(0,168,255,0.06); }219.cov-card input { position: absolute; opacity: 0; }220.cov-code { font-family: var(--font-mono); font-size: 14px; font-weight: 500; color: var(--accent); margin-bottom: 3px; }221.cov-name { font-size: 10px; color: var(--text); font-weight: 600; }222.cov-desc { font-size: 9px; color: var(--muted); margin-top: 3px; }223 224/* Checkboxes */225.chk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }226.chk-item {227 display: flex; align-items: center; gap: 8px; padding: 7px 10px;228 border: 1px solid var(--border2); border-radius: var(--r); cursor: pointer;229 font-size: 11px; color: var(--muted2); transition: all 0.2s; background: var(--bg3);230}231.chk-item:hover { border-color: var(--accent); color: var(--accent); }232.chk-item.on { border-color: var(--accent); background: rgba(0,168,255,0.08); color: var(--accent); font-weight: 600; }233.chk-item input { accent-color: var(--accent); }234 235/* Buttons */236.btn-row { display: flex; gap: 10px; align-items: center; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }237.btn {238 padding: 8px 20px; border-radius: var(--r);239 font-family: var(--font-body); font-size: 12px; font-weight: 600;240 cursor: pointer; border: none; transition: all 0.2s;241 display: flex; align-items: center; gap: 6px;242}243.btn-accent { background: var(--accent); color: white; }244.btn-accent:hover { background: var(--accent2); box-shadow: 0 4px 16px rgba(0,168,255,0.3); }245.btn-ghost { background: transparent; color: var(--muted2); border: 1px solid var(--border2); }246.btn-ghost:hover { border-color: var(--text); color: var(--text); }247.btn-green { background: var(--green); color: white; }248.btn-green:hover { background: var(--green2); }249.btn-amber { background: var(--amber); color: var(--bg); }250.btn-amber:hover { background: var(--amber2); }251.ml { margin-left: auto; }252.step-hint { font-size: 11px; color: var(--muted); }253 254/* Alert */255.alert {256 display: flex; align-items: flex-start; gap: 10px;257 padding: 10px 14px; border-radius: var(--r);258 font-size: 12px; margin-bottom: 14px; border-left: 3px solid;259}260.alert-info { background: rgba(0,168,255,0.06); border-color: var(--accent); color: var(--accent); }261.alert-warn { background: rgba(255,176,32,0.06); border-color: var(--amber); color: var(--amber); }262.alert-green { background: rgba(0,204,106,0.06); border-color: var(--green); color: var(--green); }263.alert-red { background: rgba(255,68,68,0.06); border-color: var(--red); color: var(--red); }264 265/* Right summary panel */266.sub-panel {267 background: var(--bg2); border-left: 1px solid var(--border);268 padding: 18px 16px; position: sticky; top: 54px;269 height: calc(100vh - 54px); overflow-y: auto;270}271.panel-sub-id {272 background: var(--bg3); border: 1px solid var(--border2);273 border-radius: 8px; padding: 10px 12px; margin-bottom: 14px;274}275.ps-label { font-size: 9px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--muted); margin-bottom: 4px; }276.ps-val { font-family: var(--font-mono); font-size: 12px; color: var(--amber); }277.pcard { background: var(--bg3); border: 1px solid var(--border); border-radius: 8px; padding: 12px; margin-bottom: 10px; }278.pcard-title { font-size: 9px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--muted); margin-bottom: 8px; font-weight: 600; }279.prow { display: flex; justify-content: space-between; gap: 6px; font-size: 11px; margin-bottom: 4px; }280.pk { color: var(--muted2); flex-shrink: 0; }281.pv { color: var(--text2); font-weight: 500; text-align: right; word-break: break-word; }282.pv.mono { font-family: var(--font-mono); font-size: 10px; }283 284.val-list { display: flex; flex-direction: column; gap: 4px; }285.val-row { display: flex; align-items: center; gap: 7px; font-size: 11px; padding: 5px 8px; border-radius: 5px; }286.val-row.ok { background: rgba(0,204,106,0.08); color: var(--green); }287.val-row.idle { background: var(--bg4); color: var(--muted); }288.val-row.err { background: rgba(255,68,68,0.08); color: var(--red); }289 290/* Review tables */291.rtable { width: 100%; border-collapse: collapse; margin-bottom: 16px; }292.rtable th { background: var(--bg4); color: var(--muted2); padding: 8px 12px; text-align: left; font-size: 10px; font-weight: 600; letter-spacing: 0.5px; text-transform: uppercase; }293.rtable td { padding: 7px 12px; border-bottom: 1px solid var(--border); font-size: 12px; vertical-align: top; }294.rtable tr:nth-child(even) td { background: rgba(255,255,255,0.01); }295.rtable td:first-child { color: var(--muted2); width: 35%; font-size: 11px; }296.rtable td:last-child { color: var(--text2); font-weight: 500; }297 298/* JSON box */299.json-box {300 background: var(--bg); border: 1px solid var(--border2); border-radius: 10px; padding: 14px;301 font-family: var(--font-mono); font-size: 10.5px; line-height: 1.7;302 max-height: 380px; overflow-y: auto; white-space: pre-wrap; word-break: break-all;303}304.jk { color: #79b8ff; }305.jstr{ color: #9ec8a0; }306.jnum{ color: #f08d49; }307.jbol{ color: #d19a66; }308 309/* Success */310.success-wrap { text-align: center; padding: 50px 30px; }311.suc-icon { width: 72px; height: 72px; border-radius: 50%; background: rgba(0,204,106,0.1); border: 2px solid var(--green); display: flex; align-items: center; justify-content: center; font-size: 34px; margin: 0 auto 20px; animation: popIn 0.5s cubic-bezier(.175,.885,.32,1.275); }312@keyframes popIn { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }313.suc-title { font-family: var(--font-head); font-size: 24px; font-weight: 800; color: var(--white); margin-bottom: 6px; }314.suc-sub { color: var(--muted2); margin-bottom: 28px; font-size: 13px; }315.suc-detail { background: var(--bg2); border: 1px solid var(--border2); border-radius: 12px; padding: 20px 24px; display: inline-block; text-align: left; min-width: 360px; margin-bottom: 20px; }316.path-box { background: var(--bg); border: 1px solid var(--border2); border-radius: 8px; padding: 12px 16px; display: inline-block; text-align: left; min-width: 360px; margin-bottom: 24px; }317.path-label { font-size: 9px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--muted); margin-bottom: 5px; }318.path-val { font-family: var(--font-mono); font-size: 12px; color: var(--amber); }319 320/* ══════════════════════════════════════════321 TAB 2 — MYSQL INTEGRATION322══════════════════════════════════════════ */323.int-layout { display: grid; grid-template-columns: 260px 1fr; min-height: calc(100vh - 54px); }324.int-sidebar { background: var(--bg2); border-right: 1px solid var(--border); padding: 20px 14px; }325.int-main { padding: 24px 28px; overflow-y: auto; }326 327.int-section { display: none; }328.int-section.active { display: block; animation: fadeIn 0.25s ease; }329 330.config-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2); padding: 20px 22px; margin-bottom: 16px; }331.cc-title { font-family: var(--font-head); font-size: 15px; font-weight: 700; color: var(--white); margin-bottom: 4px; }332.cc-desc { font-size: 12px; color: var(--muted2); margin-bottom: 18px; }333 334.conn-status {335 display: flex; align-items: center; gap: 10px;336 padding: 10px 14px; border-radius: var(--r); background: var(--bg3);337 border: 1px solid var(--border2); font-size: 12px;338}339.status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }340.status-dot.green { background: var(--green); animation: pulse 2s infinite; }341.status-dot.red { background: var(--red); }342.status-dot.amber { background: var(--amber); animation: pulse 1s infinite; }343@keyframes pulse { 0%,100%{opacity:1}50%{opacity:0.4} }344 345.sql-area {346 background: var(--bg); border: 1px solid var(--border2); border-radius: 8px;347 padding: 14px; font-family: var(--font-mono); font-size: 11px; line-height: 1.7;348 color: #9ec8a0; min-height: 120px; max-height: 400px; overflow-y: auto;349 white-space: pre-wrap; word-break: break-all;350}351.sql-kw { color: #79b8ff; font-weight: 600; }352.sql-str { color: #f0c060; }353.sql-cmt { color: #4a6080; font-style: italic; }354.sql-fn { color: #f08d49; }355 356.log-console {357 background: var(--bg); border: 1px solid var(--border2); border-radius: 8px;358 padding: 12px 14px; font-family: var(--font-mono); font-size: 11px;359 min-height: 180px; max-height: 350px; overflow-y: auto; line-height: 1.8;360}361.log-line { display: flex; gap: 10px; }362.log-ts { color: var(--muted); flex-shrink: 0; font-size: 10px; }363.log-ok { color: var(--green); }364.log-err { color: var(--red); }365.log-info { color: var(--accent); }366.log-warn { color: var(--amber); }367 368/* Table mapping */369.tmap { width: 100%; border-collapse: collapse; }370.tmap th { background: var(--bg4); color: var(--muted2); padding: 7px 12px; text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; }371.tmap td { padding: 6px 12px; border-bottom: 1px solid var(--border); font-size: 11px; vertical-align: top; }372.tmap tr:hover td { background: rgba(255,255,255,0.02); }373.tmap .schema-badge { font-family: var(--font-mono); font-size: 10px; padding: 1px 6px; border-radius: 4px; background: rgba(205,127,50,0.15); color: var(--bronze-c); }374.tmap .status-cell { display: flex; align-items: center; gap: 5px; }375.tmap .s-ok { color: var(--green); }376.tmap .s-pend { color: var(--amber); }377 378/* Progress bars */379.prog-wrap { margin-bottom: 16px; }380.prog-label { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted2); margin-bottom: 5px; }381.prog-bar { height: 6px; background: var(--bg4); border-radius: 10px; overflow: hidden; }382.prog-fill { height: 100%; border-radius: 10px; transition: width 0.8s ease; }383.fill-accent { background: linear-gradient(90deg, var(--accent2), var(--accent)); }384.fill-green { background: linear-gradient(90deg, var(--green2), var(--green)); }385.fill-amber { background: linear-gradient(90deg, var(--amber2), var(--amber)); }386 387/* ══════════════════════════════════════════388 TAB 3 — CONNECTORS389══════════════════════════════════════════ */390.conn-page { padding: 28px; }391.conn-page-title { font-family: var(--font-head); font-size: 24px; font-weight: 800; color: var(--white); margin-bottom: 6px; }392.conn-page-sub { font-size: 13px; color: var(--muted2); margin-bottom: 28px; }393 394.conn-cats { display: flex; gap: 8px; margin-bottom: 24px; flex-wrap: wrap; }395.cat-btn { padding: 5px 14px; border-radius: 20px; border: 1px solid var(--border2); background: var(--bg2); color: var(--muted2); font-size: 11px; cursor: pointer; transition: all 0.2s; font-family: var(--font-body); }396.cat-btn.active, .cat-btn:hover { background: var(--accent); color: white; border-color: var(--accent); }397 398.conn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }399.conn-card {400 background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2);401 padding: 18px; transition: all 0.2s; cursor: pointer; position: relative;402}403.conn-card:hover { border-color: var(--border2); transform: translateY(-2px); box-shadow: 0 8px 30px rgba(0,0,0,0.3); }404.conn-card.connected { border-color: rgba(0,204,106,0.3); }405.conn-top { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }406.conn-logo { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0; }407.conn-name { font-size: 14px; font-weight: 600; color: var(--text2); }408.conn-cat { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }409.conn-desc { font-size: 11px; color: var(--muted2); line-height: 1.5; margin-bottom: 12px; }410.conn-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 12px; }411.conn-tag { padding: 2px 7px; border-radius: 4px; font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }412.tag-db { background: rgba(0,168,255,0.12); color: var(--accent); }413.tag-api { background: rgba(136,96,255,0.12); color: var(--purple); }414.tag-file { background: rgba(255,176,32,0.12); color: var(--amber); }415.tag-cloud { background: rgba(0,204,106,0.12); color: var(--green); }416.tag-stream{ background: rgba(255,68,68,0.12); color: var(--red); }417.conn-status-row { display: flex; align-items: center; justify-content: space-between; }418.conn-badge-on { padding: 3px 9px; border-radius: 20px; font-size: 10px; font-weight: 600; background: rgba(0,204,106,0.12); color: var(--green); border: 1px solid rgba(0,204,106,0.25); }419.conn-badge-off { padding: 3px 9px; border-radius: 20px; font-size: 10px; font-weight: 600; background: var(--bg4); color: var(--muted); border: 1px solid var(--border); }420.conn-action { padding: 4px 12px; border-radius: 6px; font-size: 11px; font-weight: 600; cursor: pointer; border: none; font-family: var(--font-body); transition: all 0.2s; }421.ca-connect { background: var(--accent); color: white; }422.ca-connect:hover { background: var(--accent2); }423.ca-manage { background: var(--bg4); color: var(--text2); border: 1px solid var(--border2); }424.ca-manage:hover { background: var(--bg3); }425 426/* ══════════════════════════════════════════427 TAB 4 — AGENT PIPELINE428══════════════════════════════════════════ */429.agents-page { padding: 28px; }430.agents-title { font-family: var(--font-head); font-size: 24px; font-weight: 800; color: var(--white); margin-bottom: 6px; }431.agents-sub { font-size: 13px; color: var(--muted2); margin-bottom: 28px; }432 433.pipeline-flow { display: flex; align-items: flex-start; gap: 0; margin-bottom: 32px; overflow-x: auto; padding-bottom: 8px; }434.pf-agent { flex: 0 0 180px; }435.pf-connector { display: flex; align-items: center; flex: 1; min-width: 30px; max-width: 60px; padding-top: 35px; }436.pf-line { flex: 1; height: 2px; background: var(--border2); position: relative; }437.pf-line::after { content: '▶'; position: absolute; right: -6px; top: -7px; font-size: 10px; color: var(--border2); }438.pf-line.active { background: var(--accent); }439.pf-line.active::after { color: var(--accent); }440.pf-line.done { background: var(--green); }441.pf-line.done::after { color: var(--green); }442 443.agent-box {444 background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2);445 padding: 14px; text-align: center; cursor: pointer;446 transition: all 0.2s; position: relative;447}448.agent-box:hover { border-color: var(--border2); transform: translateY(-2px); }449.agent-box.phase2 { border-style: dashed; opacity: 0.6; }450.agent-box.active { border-color: var(--accent); box-shadow: 0 0 20px rgba(0,168,255,0.15); }451.agent-box.done { border-color: var(--green); }452.agent-icon-wrap { width: 50px; height: 50px; border-radius: 12px; margin: 0 auto 8px; display: flex; align-items: center; justify-content: center; font-size: 26px; }453.agent-step { font-size: 9px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 4px; }454.agent-name { font-size: 12px; font-weight: 600; color: var(--text2); margin-bottom: 3px; }455.agent-code { font-family: var(--font-mono); font-size: 9px; color: var(--muted2); }456.agent-badge { position: absolute; top: -7px; right: -7px; padding: 2px 7px; border-radius: 10px; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; }457.ab-p1 { background: var(--amber); color: var(--bg); }458.ab-p2 { background: var(--bg4); color: var(--muted2); border: 1px solid var(--border2); }459 460.agent-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }461.agent-detail-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2); padding: 18px 20px; }462.adc-header { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }463.adc-icon { width: 36px; height: 36px; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-size: 18px; }464.adc-name { font-size: 14px; font-weight: 600; color: var(--white); }465.adc-step { font-size: 10px; color: var(--muted2); }466.adc-prop { display: flex; justify-content: space-between; font-size: 11px; margin-bottom: 6px; }467.adc-pk { color: var(--muted2); }468.adc-pv { color: var(--text2); font-family: var(--font-mono); font-size: 10px; }469 470.python-snippet {471 background: var(--bg); border: 1px solid var(--border2); border-radius: 8px;472 padding: 14px; font-family: var(--font-mono); font-size: 11px; line-height: 1.7;473 overflow-x: auto; white-space: pre; margin-top: 14px;474}475.py-kw { color: #cc99ff; }476.py-str { color: #9ec8a0; }477.py-fn { color: #79b8ff; }478.py-cmt { color: #4a6080; font-style: italic; }479.py-cls { color: #f08d49; }480.py-num { color: #f08d49; }481.py-dec { color: #ffcc66; }482 483/* ══════════════════════════════════════════484 SHARED / MISC485══════════════════════════════════════════ */486.page-header { margin-bottom: 24px; }487.ph-title { font-family: var(--font-head); font-size: 22px; font-weight: 800; color: var(--white); }488.ph-sub { font-size: 12px; color: var(--muted2); margin-top: 3px; }489 490.section-divider { height: 1px; background: var(--border); margin: 22px 0; }491.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }492.three-col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }493 494.stat-box { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2); padding: 16px 18px; }495.stat-val { font-family: var(--font-head); font-size: 28px; font-weight: 800; margin-bottom: 2px; }496.stat-label { font-size: 11px; color: var(--muted2); }497 498::-webkit-scrollbar { width: 4px; height: 4px; }499::-webkit-scrollbar-track { background: var(--bg); }500::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }501 502/* Step progress bar */503.step-bar {504 display: flex; gap: 0; align-items: center;505 margin-bottom: 24px; padding: 14px 20px;506 background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r2);507}508.sb-step { display: flex; align-items: center; gap: 0; flex: 1; }509.sb-wrap { display: flex; flex-direction: column; align-items: center; gap: 3px; }510.sb-bubble {511 width: 28px; height: 28px; border-radius: 50%;512 background: var(--bg4); border: 1.5px solid var(--border2);513 display: flex; align-items: center; justify-content: center;514 font-size: 11px; font-weight: 600; color: var(--muted);515 transition: all 0.25s; flex-shrink: 0;516}517.sb-bubble.active { background: var(--accent); border-color: var(--accent); color: white; }518.sb-bubble.done { background: var(--green); border-color: var(--green); color: white; }519.sb-name { font-size: 9px; color: var(--muted); white-space: nowrap; }520.sb-wrap.active .sb-name { color: var(--accent); font-weight: 600; }521.sb-wrap.done .sb-name { color: var(--green); }522.sb-line { flex: 1; height: 1.5px; background: var(--border2); margin: 0 4px; }523.sb-line.done { background: var(--green); }524 525/* Bottom status */526.status-bar {527 position: fixed; bottom: 0; left: 0; right: 0;528 background: var(--bg2); border-top: 1px solid var(--border);529 padding: 5px 20px; display: flex; gap: 18px; align-items: center;530 font-family: var(--font-mono); font-size: 10px; color: var(--muted);531 z-index: 100;532}533.sb-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green); animation: pulse 2s infinite; }534.sb-sep { color: var(--border2); }535/* Document upload styles */536.doc-slot { background: var(--bg3); border: 1px solid var(--border); border-radius: 8px; padding: 14px; }537.doc-slot-hdr { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }538.doc-slot-label { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; min-width: 90px; }539.doc-type-sel { flex: 1; background: var(--bg2); border: 1px solid var(--border); color: var(--text); padding: 6px 10px; border-radius: 5px; font-size: 12px; }540.doc-dropzone { border: 2px dashed var(--border); border-radius: 6px; padding: 22px; text-align: center; cursor: pointer; transition: all .2s; background: var(--bg2); }541.doc-dropzone:hover, .doc-dropzone.drag-over { border-color: var(--accent); background: rgba(99,102,241,.06); }542.doc-dropzone.uploaded { border-color: var(--green); background: rgba(34,197,94,.05); border-style: solid; }543.doc-dropzone.rejected { border-color: var(--red); background: rgba(239,68,68,.05); border-style: solid; }544.dz-icon { font-size: 28px; margin-bottom: 6px; }545.dz-text { font-size: 13px; color: var(--text); font-weight: 500; }546.dz-hint { font-size: 11px; color: var(--muted); margin-top: 3px; }547.doc-status { margin-top: 8px; font-size: 12px; min-height: 18px; }548.doc-status.ok { color: var(--green); }549.doc-status.err { color: var(--red); }550.doc-status.checking { color: var(--amber); }551</style>552</head>553<body>554 555<!-- ═══ APP HEADER ═══ -->556<header class="app-header">557 <div class="logo">558 <div class="logo-mark">P</div>559 <div>560 <div class="logo-name">PolicyBridge</div>561 <div class="logo-sub">P&C Intelligence Platform</div>562 </div>563 </div>564 565 <nav class="main-tabs">566 <button class="tab-btn active" onclick="switchTab('submission')">567 <span class="tab-dot"></span> Submission Form568 </button>569 <button class="tab-btn" onclick="switchTab('integration')">570 <span class="tab-dot"></span> MySQL Integration571 </button>572 <button class="tab-btn" onclick="switchTab('connectors')">573 <span class="tab-dot"></span> Connectors Hub574 </button>575 <button class="tab-btn" onclick="switchTab('agents')">576 <span class="tab-dot"></span> Agent Pipeline577 </button>578 </nav>579 580 <div class="hdr-right">581 <span class="pill pill-accent">Phase 1</span>582 <span class="pill pill-amber" id="db-conn-pill">DB: Connecting…</span>583 </div>584</header>585 586<!-- ═══════════════════════════════════════════587 TAB 1 — SUBMISSION FORM588═══════════════════════════════════════════ -->589<div class="tab-page active" id="tab-submission">590 <div class="sub-layout">591 592 <!-- Left nav -->593 <aside class="sub-nav">594 <div class="snav-title">Form Steps</div>595 <div class="snav-item active" id="snav-1" onclick="goStep(1)"><div class="snav-num" id="sn-1">1</div> Submitter</div>596 <div class="snav-item" id="snav-2" onclick="goStep(2)"><div class="snav-num" id="sn-2">2</div> Insured</div>597 <div class="snav-item" id="snav-3" onclick="goStep(3)"><div class="snav-num" id="sn-3">3</div> Property</div>598 <div class="snav-item" id="snav-4" onclick="goStep(4)"><div class="snav-num" id="sn-4">4</div> Coverage</div>599 <div class="snav-item" id="snav-5" onclick="goStep(5)"><div class="snav-num" id="sn-5">5</div> Documents</div>600 <div class="snav-item" id="snav-6" onclick="goStep(6)"><div class="snav-num" id="sn-6">6</div> Review</div>601 <div class="snav-item" id="snav-7" onclick="goStep(7)"><div class="snav-num" id="sn-7">7</div> Submit</div>602 603 <div class="submitter-type-box">604 <div class="stype-title">Submitter Role</div>605 <div class="stype-opt">606 <label><input type="radio" name="sub_type" value="broker" checked onchange="APP.subType=this.value"> 🏢 Broker/Agent</label>607 <label><input type="radio" name="sub_type" value="mga" onchange="APP.subType=this.value"> 🏦 MGA</label>608 <label><input type="radio" name="sub_type" value="direct" onchange="APP.subType=this.value"> 👤 Direct</label>609 </div>610 </div>611 612 <div class="db-info-box">613 <div class="db-info-title">Target Database</div>614 <div class="db-row"><span class="dk">Host</span><span class="dv">localhost</span></div>615 <div class="db-row"><span class="dk">Schema</span><span class="dv">bronze</span></div>616 <div class="db-row"><span class="dk">User</span><span class="dv">root</span></div>617 <div class="db-row"><span class="dk">Layer</span><span class="dv">BRONZE</span></div>618 </div>619 </aside>620 621 <!-- Main form -->622 <main class="sub-form-main">623 624 <!-- Progress bar -->625 <div class="step-bar" id="step-bar">626 <div class="sb-step"><div class="sb-wrap active" id="sbw-1"><div class="sb-bubble active" id="sbb-1">1</div><div class="sb-name">Submitter</div></div></div>627 <div class="sb-line" id="sbl-1"></div>628 <div class="sb-step"><div class="sb-wrap" id="sbw-2"><div class="sb-bubble" id="sbb-2">2</div><div class="sb-name">Insured</div></div></div>629 <div class="sb-line" id="sbl-2"></div>630 <div class="sb-step"><div class="sb-wrap" id="sbw-3"><div class="sb-bubble" id="sbb-3">3</div><div class="sb-name">Property</div></div></div>631 <div class="sb-line" id="sbl-3"></div>632 <div class="sb-step"><div class="sb-wrap" id="sbw-4"><div class="sb-bubble" id="sbb-4">4</div><div class="sb-name">Coverage</div></div></div>633 <div class="sb-line" id="sbl-4"></div>634 <div class="sb-step"><div class="sb-wrap" id="sbw-5"><div class="sb-bubble" id="sbb-5">5</div><div class="sb-name">Documents</div></div></div>635 <div class="sb-line" id="sbl-5"></div>636 <div class="sb-step"><div class="sb-wrap" id="sbw-6"><div class="sb-bubble" id="sbb-6">6</div><div class="sb-name">Review</div></div></div>637 <div class="sb-line" id="sbl-6"></div>638 <div class="sb-step"><div class="sb-wrap" id="sbw-7"><div class="sb-bubble" id="sbb-7">7</div><div class="sb-name">Submit</div></div></div>639 </div>640 641 <!-- STEP 1: SUBMITTER -->642 <div class="form-section active" id="sec-1">643 <div class="fsec-hdr">644 <div class="fsec-icon">🏢</div>645 <div><div class="fsec-title">Submitter Information</div><div class="fsec-desc">Broker, MGA, or direct customer details → bronze_brokers</div></div>646 </div>647 <div class="fcard">648 <div class="fcard-title">Organization Details</div>649 <div class="fg fg2">650 <div class="fld cs2">651 <label class="flabel">Organization / Broker Name <span class="req">*</span></label>652 <input type="text" id="broker_name" placeholder="Acme Insurance Brokers LLC" oninput="V.field('broker_name')">653 <span class="ferr" id="e-broker_name">Organization name is required</span>654 </div>655 <div class="fld">656 <label class="flabel">Broker Code <span class="req">*</span> <span class="ftip">Format: ACM-TX-0041</span></label>657 <input type="text" id="broker_code" placeholder="ACM-TX-0041" oninput="V.brokerCode()" maxlength="15">658 <span class="ferr" id="e-broker_code">Format: AAA-ST-0000 (letters-state-4digits)</span>659 </div>660 <div class="fld">661 <label class="flabel">Contact Email <span class="req">*</span></label>662 <input type="email" id="broker_email" placeholder="submissions@broker.com" oninput="V.email('broker_email')">663 <span class="ferr" id="e-broker_email">Valid email required</span>664 </div>665 <div class="fld">666 <label class="flabel">Licensed State <span class="req">*</span></label>667 <select id="broker_state" onchange="V.req('broker_state')"><option value="">— State —</option></select>668 <span class="ferr" id="e-broker_state">Select state</span>669 </div>670 <div class="fld">671 <label class="flabel">Phone</label>672 <input type="tel" id="broker_phone" placeholder="(512) 555-0192" oninput="V.phone(this,'broker_phone')">673 <span class="ferr" id="e-broker_phone">Valid US phone required</span>674 </div>675 </div>676 </div>677 <div class="fcard">678 <div class="fcard-title">Submission Metadata</div>679 <div class="fg fg3">680 <div class="fld">681 <label class="flabel">Line of Business <span class="req">*</span></label>682 <select id="line_of_business" onchange="V.req('line_of_business')">683 <option value="">— Select —</option>684 <option value="Personal Lines">Personal Lines</option>685 <option value="Commercial Lines">Commercial Lines</option>686 <option value="Farm & Ranch">Farm & Ranch</option>687 </select>688 <span class="ferr" id="e-line_of_business">Required</span>689 </div>690 <div class="fld">691 <label class="flabel">Market Type</label>692 <select id="market_type">693 <option value="Admitted">Admitted</option>694 <option value="E&S">E&S (Excess & Surplus)</option>695 <option value="Surplus Lines">Surplus Lines</option>696 </select>697 </div>698 <div class="fld">699 <label class="flabel">Submission Date <span class="req">*</span></label>700 <input type="date" id="submitted_at" onchange="V.req('submitted_at')">701 <span class="ferr" id="e-submitted_at">Required</span>702 </div>703 </div>704 </div>705 <div class="btn-row">706 <span class="step-hint">Step 1 of 6</span>707 <button class="btn btn-accent ml" onclick="nextStep(1)">Next: Insured →</button>708 </div>709 </div>710 711 <!-- STEP 2: INSURED -->712 <div class="form-section" id="sec-2">713 <div class="fsec-hdr">714 <div class="fsec-icon">👤</div>715 <div><div class="fsec-title">Insured Information</div><div class="fsec-desc">Applicant PII → bronze_insureds (SSN stored as SHA-256 hash)</div></div>716 </div>717 <div class="alert alert-info">🔒 SSN is hashed client-side using SHA-256. The raw SSN never leaves the browser or gets stored in the database.</div>718 <div class="fcard">719 <div class="fcard-title">Personal Identity</div>720 <div class="fg fg2">721 <div class="fld"><label class="flabel">First Name <span class="req">*</span></label>722 <input type="text" id="insured_first" placeholder="Sarah" oninput="V.field('insured_first')">723 <span class="ferr" id="e-insured_first">Required</span></div>724 <div class="fld"><label class="flabel">Last Name <span class="req">*</span></label>725 <input type="text" id="insured_last" placeholder="Mitchell" oninput="V.field('insured_last')">726 <span class="ferr" id="e-insured_last">Required</span></div>727 <div class="fld"><label class="flabel">Date of Birth <span class="req">*</span></label>728 <input type="date" id="insured_dob" onchange="V.dob()">729 <span class="ferr" id="e-insured_dob">Must be 18+ years old</span></div>730 <div class="fld"><label class="flabel">SSN <span class="req">*</span> <span class="ftip">Hashed before storage</span></label>731 <input type="text" id="insured_ssn" placeholder="•••-••-####" maxlength="11" oninput="V.ssn(this)">732 <span class="ferr" id="e-insured_ssn">Enter full SSN (###-##-####)</span>733 <span class="fhint" id="ssn-hint"></span></div>734 <div class="fld"><label class="flabel">Email <span class="req">*</span></label>735 <input type="email" id="insured_email" placeholder="sarah@email.com" oninput="V.email('insured_email')">736 <span class="ferr" id="e-insured_email">Valid email required</span></div>737 <div class="fld"><label class="flabel">Phone <span class="req">*</span></label>738 <input type="tel" id="insured_phone" placeholder="(512) 555-0192" oninput="V.phone(this,'insured_phone')">739 <span class="ferr" id="e-insured_phone">Valid US phone required</span></div>740 </div>741 </div>742 <div class="fcard">743 <div class="fcard-title">Mailing Address</div>744 <div class="fg fg2">745 <div class="fld cs2"><label class="flabel">Street <span class="req">*</span></label>746 <input type="text" id="ins_street" placeholder="4821 Oakwood Drive" oninput="V.field('ins_street')">747 <span class="ferr" id="e-ins_street">Required</span></div>748 <div class="fld"><label class="flabel">City <span class="req">*</span></label>749 <input type="text" id="ins_city" placeholder="Austin" oninput="V.field('ins_city')">750 <span class="ferr" id="e-ins_city">Required</span></div>751 <div class="fld"><label class="flabel">State <span class="req">*</span></label>752 <select id="ins_state" onchange="V.req('ins_state')"><option value="">— State —</option></select>753 <span class="ferr" id="e-ins_state">Required</span></div>754 <div class="fld"><label class="flabel">ZIP <span class="req">*</span></label>755 <input type="text" id="ins_zip" placeholder="78701" maxlength="10" oninput="V.zip(this,'ins_zip')">756 <span class="ferr" id="e-ins_zip">5 or 9-digit ZIP</span></div>757 <div class="fld"><label class="flabel">Country</label>758 <select id="ins_country"><option value="US">🇺🇸 United States</option></select></div>759 </div>760 </div>761 <div class="btn-row">762 <button class="btn btn-ghost" onclick="prevStep(2)">← Back</button>763 <span class="step-hint" style="margin:0 auto;">Step 2 of 6</span>764 <button class="btn btn-accent" onclick="nextStep(2)">Next: Property →</button>765 </div>766 </div>767 768 <!-- STEP 3: PROPERTY -->769 <div class="form-section" id="sec-3">770 <div class="fsec-hdr">771 <div class="fsec-icon">🏠</div>772 <div><div class="fsec-title">Property Information</div><div class="fsec-desc">Risk location details → bronze_properties</div></div>773 </div>774 <div class="alert alert-warn">📍 If property address differs from mailing address, enter it below.</div>775 <div class="fcard">776 <div class="fcard-title">Risk Location Address</div>777 <div style="margin-bottom:10px;">778 <label class="chk-item" id="same-addr-lbl" style="display:inline-flex;max-width:260px;" onclick="toggleSameAddr()">779 <input type="checkbox" id="same_addr"> Same as mailing address780 </label>781 </div>782 <div class="fg fg2" id="prop-addr-fields">783 <div class="fld cs2"><label class="flabel">Street <span class="req">*</span></label>784 <input type="text" id="prop_street" placeholder="4821 Oakwood Drive" oninput="V.field('prop_street')">785 <span class="ferr" id="e-prop_street">Required</span></div>786 <div class="fld"><label class="flabel">City <span class="req">*</span></label>787 <input type="text" id="prop_city" placeholder="Austin" oninput="V.field('prop_city')">788 <span class="ferr" id="e-prop_city">Required</span></div>789 <div class="fld"><label class="flabel">State <span class="req">*</span></label>790 <select id="prop_state" onchange="V.req('prop_state')"><option value="">— State —</option></select>791 <span class="ferr" id="e-prop_state">Required</span></div>792 <div class="fld"><label class="flabel">ZIP <span class="req">*</span></label>793 <input type="text" id="prop_zip" placeholder="78701" maxlength="10" oninput="V.zip(this,'prop_zip')">794 <span class="ferr" id="e-prop_zip">5 or 9-digit ZIP</span></div>795 </div>796 </div>797 <div class="fcard">798 <div class="fcard-title">Physical Characteristics</div>799 <div class="fg fg3">800 <div class="fld"><label class="flabel">Property Type <span class="req">*</span></label>801 <select id="property_type" onchange="V.req('property_type')">802 <option value="">— Select —</option>803 <option>Single Family Residential</option><option>Condo / Townhouse</option>804 <option>Multi-Family (2-4 units)</option><option>Mobile Home</option>805 <option>Manufactured Home</option><option>Vacation / Seasonal</option>806 <option>Commercial Building</option><option>Mixed Use</option>807 </select><span class="ferr" id="e-property_type">Required</span></div>808 <div class="fld"><label class="flabel">Occupancy <span class="req">*</span></label>809 <select id="occupancy" onchange="V.req('occupancy')">810 <option value="">— Select —</option>811 <option>Owner Occupied</option><option>Tenant Occupied</option>812 <option>Seasonal / Vacant</option><option>Rented to Others</option><option>Under Construction</option>813 </select><span class="ferr" id="e-occupancy">Required</span></div>814 <div class="fld"><label class="flabel">Year Built <span class="req">*</span></label>815 <input type="number" id="year_built" placeholder="2004" min="1800" oninput="V.yearBuilt()">816 <span class="ferr" id="e-year_built">1800–present</span></div>817 <div class="fld"><label class="flabel">Square Footage <span class="req">*</span></label>818 <input type="number" id="sq_footage" placeholder="2340" min="100" max="50000" oninput="V.field('sq_footage')">819 <span class="ferr" id="e-sq_footage">100–50,000 sq ft</span></div>820 <div class="fld"><label class="flabel">Stories</label>821 <select id="num_stories">822 <option value="">—</option><option value="1">1</option><option value="2">2</option>823 <option value="3">3</option><option value="4+">4+</option><option value="Split Level">Split Level</option>824 </select></div>825 <div class="fld"><label class="flabel">Units</label>826 <input type="number" id="num_units" value="1" min="1" max="100"></div>827 </div>828 </div>829 <div class="fcard">830 <div class="fcard-title">Construction Details</div>831 <div class="fg fg3">832 <div class="fld"><label class="flabel">Construction Type <span class="req">*</span></label>833 <select id="construction_type" onchange="V.req('construction_type')">834 <option value="">— Select —</option>835 <option>Frame</option><option>Masonry</option><option>Masonry Veneer</option>836 <option>Fire Resistive</option><option>Non-Combustible</option><option>Log</option><option>Stucco</option>837 </select><span class="ferr" id="e-construction_type">Required</span></div>838 <div class="fld"><label class="flabel">Roof Type <span class="req">*</span></label>839 <select id="roof_type" onchange="V.req('roof_type')">840 <option value="">— Select —</option>841 <option>Composition Shingle</option><option>Metal</option><option>Tile</option>842 <option>Flat / Built-Up</option><option>Wood Shake</option><option>Slate</option>843 </select><span class="ferr" id="e-roof_type">Required</span></div>844 <div class="fld"><label class="flabel">Roof Year <span class="req">*</span></label>845 <input type="number" id="roof_year" placeholder="2019" min="1950" oninput="V.roofYear()">846 <span class="ferr" id="e-roof_year">Must be ≥ year built</span></div>847 <div class="fld"><label class="flabel">Foundation</label>848 <select id="foundation"><option value="">—</option><option>Slab</option><option>Crawl Space</option><option>Basement</option><option>Pier and Beam</option></select></div>849 <div class="fld"><label class="flabel">Heating</label>850 <select id="heating"><option value="">—</option><option>Central Gas</option><option>Central Electric</option><option>Heat Pump</option><option>Oil</option></select></div>851 <div class="fld"><label class="flabel">Electrical</label>852 <select id="electrical"><option value="">—</option><option>Circuit Breaker</option><option>Fuse Box</option><option>Updated (2000+)</option><option>Knob and Tube</option><option>Aluminum Wiring</option></select></div>853 </div>854 </div>855 <div class="fcard">856 <div class="fcard-title">Liability Indicators</div>857 <div class="chk-grid">858 <label class="chk-item" onclick="toggleChk(this,'chk_pool')"><input type="checkbox" id="chk_pool"> 🏊 Swimming Pool</label>859 <label class="chk-item" onclick="toggleChk(this,'chk_tramp')"><input type="checkbox" id="chk_tramp"> 🤸 Trampoline</label>860 <label class="chk-item" onclick="toggleChk(this,'chk_dog')"><input type="checkbox" id="chk_dog"> 🐕 Aggressive Dog Breed</label>861 <label class="chk-item" onclick="toggleChk(this,'chk_biz')"><input type="checkbox" id="chk_biz"> 💼 Home Business</label>862 <label class="chk-item" onclick="toggleChk(this,'chk_rental')"><input type="checkbox" id="chk_rental"> 🏘 Rental Units</label>863 <label class="chk-item" onclick="toggleChk(this,'chk_solar')"><input type="checkbox" id="chk_solar"> ☀️ Solar Panels</label>864 </div>865 </div>866 <div class="btn-row">867 <button class="btn btn-ghost" onclick="prevStep(3)">← Back</button>868 <span class="step-hint" style="margin:0 auto;">Step 3 of 6</span>869 <button class="btn btn-accent" onclick="nextStep(3)">Next: Coverage →</button>870 </div>871 </div>872 873 <!-- STEP 4: COVERAGE -->874 <div class="form-section" id="sec-4">875 <div class="fsec-hdr">876 <div class="fsec-icon">🛡️</div>877 <div><div class="fsec-title">Coverage Request</div><div class="fsec-desc">Coverage type and limits → bronze_submissions</div></div>878 </div>879 <div class="fcard">880 <div class="fcard-title">Coverage Type</div>881 <div class="cov-grid">882 <div class="cov-card sel" data-code="HO-3" onclick="selCov(this)"><input type="radio" name="cov" value="HO-3" checked><div class="cov-code">HO-3</div><div class="cov-name">Special Form</div><div class="cov-desc">Most common homeowners</div></div>883 <div class="cov-card" data-code="HO-4" onclick="selCov(this)"><input type="radio" name="cov" value="HO-4"><div class="cov-code">HO-4</div><div class="cov-name">Renters</div><div class="cov-desc">Contents & liability only</div></div>884 <div class="cov-card" data-code="HO-5" onclick="selCov(this)"><input type="radio" name="cov" value="HO-5"><div class="cov-code">HO-5</div><div class="cov-name">Comprehensive</div><div class="cov-desc">Open perils on all</div></div>885 <div class="cov-card" data-code="HO-6" onclick="selCov(this)"><input type="radio" name="cov" value="HO-6"><div class="cov-code">HO-6</div><div class="cov-name">Condo Owner</div><div class="cov-desc">Walls-in condo coverage</div></div>886 <div class="cov-card" data-code="DP-1" onclick="selCov(this)"><input type="radio" name="cov" value="DP-1"><div class="cov-code">DP-1</div><div class="cov-name">Dwelling Basic</div><div class="cov-desc">Named perils only</div></div>887 <div class="cov-card" data-code="DP-3" onclick="selCov(this)"><input type="radio" name="cov" value="DP-3"><div class="cov-code">DP-3</div><div class="cov-name">Dwelling Special</div><div class="cov-desc">Landlord open perils</div></div>888 <div class="cov-card" data-code="BOP" onclick="selCov(this)"><input type="radio" name="cov" value="BOP"><div class="cov-code">BOP</div><div class="cov-name">Business Owners</div><div class="cov-desc">Property + liability</div></div>889 <div class="cov-card" data-code="CPP" onclick="selCov(this)"><input type="radio" name="cov" value="CPP"><div class="cov-code">CPP</div><div class="cov-name">Comm. Package</div><div class="cov-desc">Multi-line commercial</div></div>890 <div class="cov-card" data-code="FARM" onclick="selCov(this)"><input type="radio" name="cov" value="FARM"><div class="cov-code">FARM</div><div class="cov-name">Farm & Ranch</div><div class="cov-desc">Dwelling + equipment</div></div>891 </div>892 </div>893 <div class="fcard">894 <div class="fcard-title">Limits & Deductibles</div>895 <div class="fg fg2">896 <div class="fld"><label class="flabel">Coverage Limit ($) <span class="req">*</span></label>897 <input type="number" id="cov_limit" placeholder="450000" min="50000" max="10000000" oninput="V.covLimit()">898 <span class="ferr" id="e-cov_limit">$50,000–$10,000,000</span>899 <span class="fhint">~$165/sq ft avg construction cost</span></div>900 <div class="fld"><label class="flabel">Deductible <span class="req">*</span></label>901 <select id="deductible" onchange="V.req('deductible')">902 <option value="">— Select —</option>903 <option value="500">$500</option><option value="1000">$1,000</option>904 <option value="1500">$1,500</option><option value="2500">$2,500</option>905 <option value="5000">$5,000</option><option value="10000">$10,000</option>906 <option value="25000">$25,000</option><option value="50000">$50,000</option>907 </select><span class="ferr" id="e-deductible">Select deductible</span></div>908 <div class="fld"><label class="flabel">Liability Limit</label>909 <select id="liab_limit"><option value="100000">$100,000</option><option value="300000" selected>$300,000</option><option value="500000">$500,000</option><option value="1000000">$1,000,000</option></select></div>910 <div class="fld"><label class="flabel">Medical Payments</label>911 <select id="med_pay"><option value="1000">$1,000</option><option value="2000">$2,000</option><option value="5000" selected>$5,000</option><option value="10000">$10,000</option></select></div>912 <div class="fld"><label class="flabel">Effective Date <span class="req">*</span></label>913 <input type="date" id="effective_date" onchange="V.effDate()">914 <span class="ferr" id="e-effective_date">Today–60 days out</span></div>915 <div class="fld"><label class="flabel">Payment Schedule</label>916 <select id="pay_schedule"><option>Annual</option><option>Semi-Annual</option><option>Quarterly</option><option value="Monthly EFT">Monthly (EFT)</option></select></div>917 </div>918 </div>919 <div class="fcard">920 <div class="fcard-title">Endorsements Requested</div>921 <div class="chk-grid">922 <label class="chk-item" onclick="toggleChk(this,'end_identity')"><input type="checkbox" id="end_identity"> 🔐 Identity Theft</label>923 <label class="chk-item" onclick="toggleChk(this,'end_equip')"><input type="checkbox" id="end_equip"> 🖥️ Equipment Breakdown</label>924 <label class="chk-item" onclick="toggleChk(this,'end_water')"><input type="checkbox" id="end_water"> 💧 Water Backup</label>925 <label class="chk-item" onclick="toggleChk(this,'end_quake')"><input type="checkbox" id="end_quake"> 🌋 Earthquake</label>926 <label class="chk-item" onclick="toggleChk(this,'end_flood')"><input type="checkbox" id="end_flood"> 🌊 Flood (NFIP)</label>927 <label class="chk-item" onclick="toggleChk(this,'end_umbrella')"><input type="checkbox" id="end_umbrella"> ☂️ Umbrella</label>928 </div>929 </div>930 <div class="fcard">931 <div class="fcard-title">Notes</div>932 <div class="fld">933 <label class="flabel">Submission Notes</label>934 <textarea id="notes" placeholder="Special circumstances, prior losses, renovation details..." maxlength="1000"></textarea>935 <span class="fhint"><span id="nc">0</span>/1000</span>936 </div>937 </div>938 <div class="btn-row">939 <button class="btn btn-ghost" onclick="prevStep(4)">← Back</button>940 <span class="step-hint" style="margin:0 auto;">Step 4 of 6</span>941 <button class="btn btn-accent" onclick="nextStep(4)">Documents →</button>942 </div>943 </div>944 945 <!-- STEP 5: DOCUMENTS -->946 <div class="form-section" id="sec-5">947 <div class="fsec-hdr">948 <div class="fsec-icon">📎</div>949 <div><div class="fsec-title">Supporting Documents</div><div class="fsec-desc">Upload property inspection report, deed, or photos — validated before submission → bronze_submission_attachments</div></div>950 </div>951 952 <div class="fcard">953 <div class="fcard-title">Document Upload <span style="font-size:11px;font-weight:400;color:var(--muted);">— At least one property document required</span></div>954 <div style="display:grid;gap:14px;">955 956 <!-- Upload slot 1 -->957 <div class="doc-slot" id="slot-0">958 <div class="doc-slot-hdr">959 <span class="doc-slot-label">Document 1 <span style="color:var(--red);">*</span></span>960 <select class="doc-type-sel" id="doc-type-0" onchange="docTypeChanged(0)">961 <option value="">— Select document type —</option>962 <option value="PROPERTY_INSPECTION">Property Inspection Report</option>963 <option value="PROPERTY_DEED">Property Deed / Title</option>964 <option value="PROPERTY_PHOTO">Property Photograph</option>965 <option value="APPRAISAL">Property Appraisal</option>966 <option value="PRIOR_POLICY">Prior Insurance Policy</option>967 <option value="OTHER">Other Supporting Document</option>968 </select>969 </div>970 <div class="doc-dropzone" id="dz-0" onclick="triggerUpload(0)" ondragover="dzDragOver(event,0)" ondragleave="dzDragLeave(0)" ondrop="dzDrop(event,0)">971 <div class="dz-icon">📄</div>972 <div class="dz-text">Click to upload or drag & drop</div>973 <div class="dz-hint">PDF or JPG/PNG · Max 10MB</div>974 <input type="file" id="file-input-0" accept=".pdf,.jpg,.jpeg,.png" style="display:none" onchange="handleFileSelect(0,this)">975 </div>976 <div class="doc-status" id="doc-status-0"></div>977 </div>978 979 <!-- Upload slot 2 -->980 <div class="doc-slot" id="slot-1">981 <div class="doc-slot-hdr">982 <span class="doc-slot-label">Document 2 <span style="color:var(--muted);font-size:11px;">(optional)</span></span>983 <select class="doc-type-sel" id="doc-type-1" onchange="docTypeChanged(1)">984 <option value="">— Select document type —</option>985 <option value="PROPERTY_INSPECTION">Property Inspection Report</option>986 <option value="PROPERTY_DEED">Property Deed / Title</option>987 <option value="PROPERTY_PHOTO">Property Photograph</option>988 <option value="APPRAISAL">Property Appraisal</option>989 <option value="PRIOR_POLICY">Prior Insurance Policy</option>990 <option value="OTHER">Other Supporting Document</option>991 </select>992 </div>993 <div class="doc-dropzone" id="dz-1" onclick="triggerUpload(1)" ondragover="dzDragOver(event,1)" ondragleave="dzDragLeave(1)" ondrop="dzDrop(event,1)">994 <div class="dz-icon">📄</div>995 <div class="dz-text">Click to upload or drag & drop</div>996 <div class="dz-hint">PDF or JPG/PNG · Max 10MB</div>997 <input type="file" id="file-input-1" accept=".pdf,.jpg,.jpeg,.png" style="display:none" onchange="handleFileSelect(1,this)">998 </div>999 <div class="doc-status" id="doc-status-1"></div>1000 </div>1001 </div>1002 1003 <!-- Validation rules info -->1004 <div style="margin-top:18px;padding:12px 14px;background:var(--bg3);border-radius:6px;border:1px solid var(--border);font-size:12px;color:var(--muted);">1005 <strong style="color:var(--text);">✓ Validation Rules Applied:</strong>1006 PDF files are checked for property-related keywords (address, inspection, property, coverage, insured, roof, construction).1007 JPG/PNG files are verified as valid images. Generic invoices or unrelated documents are rejected.1008 </div>1009 </div>1010 1011 <div class="btn-row">1012 <button class="btn btn-ghost" onclick="prevStep(5)">← Back</button>1013 <span class="step-hint" style="margin:0 auto;">Step 5 of 6</span>1014 <button class="btn btn-accent" onclick="nextStep(5)">Review →</button>1015 </div>1016 </div>1017 1018 <!-- STEP 6: REVIEW -->1019 <div class="form-section" id="sec-6">1020 <div class="fsec-hdr">1021 <div class="fsec-icon">📋</div>1022 <div><div class="fsec-title">Review & Confirm</div><div class="fsec-desc">Verify all fields before Bronze layer commit</div></div>1023 </div>1024 <div id="review-content"></div>1025 <div class="fcard" style="background:var(--bg);">1026 <div class="fcard-title" style="color:var(--amber);">Generated JSON Payload</div>1027 <div class="json-box" id="json-preview">—</div>1028 <button class="btn btn-ghost" style="margin-top:10px;font-size:11px;" onclick="copyJSON()">📋 Copy JSON</button>1029 </div>1030 <div class="btn-row">1031 <button class="btn btn-ghost" onclick="prevStep(6)">← Back</button>1032 <button class="btn btn-green ml" onclick="doSubmit()">✅ Submit to MySQL + Save JSON</button>1033 </div>1034 </div>1035 1036 <!-- STEP 7: SUCCESS -->1037 <div class="form-section" id="sec-7">1038 <div class="success-wrap">1039 <div class="suc-icon">✓</div>1040 <div class="suc-title">Submission Accepted!</div>1041 <div class="suc-sub">Policy request committed to Bronze layer · JSON saved to disk</div>1042 <div class="suc-detail" id="suc-detail"></div>1043 <div class="path-box">1044 <div class="path-label">JSON File Path</div>1045 <div class="path-val" id="json-path">D:\Personal\Usecase\Jsons\SUB-XXXX.json</div>1046 </div>1047 <div>1048 <button class="btn btn-accent" onclick="location.reload()">+ New Submission</button>1049 <button class="btn btn-ghost" style="margin-left:8px;" onclick="downloadJSON()">⬇ Download JSON</button>1050 <button class="btn btn-ghost" style="margin-left:8px;" onclick="switchTab('integration');showIntSection('inserts')">View SQL Inserts →</button>1051 </div>1052 </div>1053 </div>1054 1055 </main>1056 1057 <!-- Right panel -->1058 <aside class="sub-panel">1059 <div class="panel-sub-id"><div class="ps-label">Submission ID</div><div class="ps-val" id="live-subid">SUB-2025-—</div></div>1060 <div class="pcard">1061 <div class="pcard-title">Submitter</div>1062 <div class="prow"><span class="pk">Name</span><span class="pv" id="lv-bname">—</span></div>1063 <div class="prow"><span class="pk">Code</span><span class="pv mono" id="lv-bcode">—</span></div>1064 <div class="prow"><span class="pk">State</span><span class="pv" id="lv-bstate">—</span></div>1065 </div>1066 <div class="pcard">1067 <div class="pcard-title">Insured</div>1068 <div class="prow"><span class="pk">Name</span><span class="pv" id="lv-iname">—</span></div>1069 <div class="prow"><span class="pk">DOB</span><span class="pv" id="lv-idob">—</span></div>1070 <div class="prow"><span class="pk">State</span><span class="pv" id="lv-istate">—</span></div>1071 </div>1072 <div class="pcard">1073 <div class="pcard-title">Property</div>1074 <div class="prow"><span class="pk">City/State</span><span class="pv" id="lv-paddr">—</span></div>1075 <div class="prow"><span class="pk">Type</span><span class="pv" id="lv-ptype">—</span></div>1076 <div class="prow"><span class="pk">Built</span><span class="pv" id="lv-pbuilt">—</span></div>1077 <div class="prow"><span class="pk">Sq Ft</span><span class="pv" id="lv-psqft">—</span></div>1078 </div>1079 <div class="pcard">1080 <div class="pcard-title">Coverage</div>1081 <div class="prow"><span class="pk">Type</span><span class="pv mono" id="lv-ctype">HO-3</span></div>1082 <div class="prow"><span class="pk">Limit</span><span class="pv" id="lv-climit">—</span></div>1083 <div class="prow"><span class="pk">Ded.</span><span class="pv" id="lv-cded">—</span></div>1084 <div class="prow"><span class="pk">Eff.</span><span class="pv" id="lv-ceff">—</span></div>1085 </div>1086 <div class="pcard">1087 <div class="pcard-title">Step Validation</div>1088 <div class="val-list">1089 <div class="val-row idle" id="vl-1">○ Submitter</div>1090 <div class="val-row idle" id="vl-2">○ Insured</div>1091 <div class="val-row idle" id="vl-3">○ Property</div>1092 <div class="val-row idle" id="vl-4">○ Coverage</div>1093 <div class="val-row idle" id="vl-5">○ Documents</div>1094 </div>1095 </div>1096 <div class="pcard">1097 <div class="pcard-title">Bronze Tables</div>1098 <div style="font-size:10px;color:var(--muted2);line-height:1.8;">1099 ↳ bronze_brokers<br>1100 ↳ bronze_insureds<br>1101 ↳ bronze_properties<br>1102 ↳ bronze_submissions<br>1103 ↳ bronze_submission_attachments<br>1104 ↳ bronze_pipeline_agent_log1105 </div>1106 </div>1107 </aside>1108 </div>1109</div>1110 1111<!-- ═══════════════════════════════════════════1112 TAB 2 — MYSQL INTEGRATION1113═══════════════════════════════════════════ -->1114<div class="tab-page" id="tab-integration">1115 <div class="int-layout">1116 <aside class="int-sidebar">1117 <div class="snav-title">Integration Sections</div>1118 <div class="snav-item active" id="inav-conn" onclick="showIntSection('conn')"><div class="snav-num">⚙</div> DB Connection</div>1119 <div class="snav-item" id="inav-schema" onclick="showIntSection('schema')"><div class="snav-num">📊</div> Schema Map</div>1120 <div class="snav-item" id="inav-inserts" onclick="showIntSection('inserts')"><div class="snav-num">📝</div> SQL Inserts</div>1121 <div class="snav-item" id="inav-log" onclick="showIntSection('log')"><div class="snav-num">📋</div> Activity Log</div>1122 <div class="snav-item" id="inav-python" onclick="showIntSection('python')"><div class="snav-num">🐍</div> Python Connector</div>1123 1124 <div style="margin-top:20px;padding:12px;background:var(--bg3);border-radius:var(--r);border:1px solid var(--border);">1125 <div class="snav-title">DB Config</div>1126 <div class="db-row" style="margin-bottom:5px;"><span class="dk">Host</span><span class="dv" style="font-size:11px;">localhost:3306</span></div>1127 <div class="db-row" style="margin-bottom:5px;"><span class="dk">User</span><span class="dv" style="font-size:11px;">root</span></div>1128 <div class="db-row" style="margin-bottom:5px;"><span class="dk">Pass</span><span class="dv" style="font-size:11px;">root@123</span></div>1129 <div class="db-row" style="margin-bottom:5px;"><span class="dk">DB</span><span class="dv" style="font-size:11px;">bronze</span></div>1130 <div class="conn-status" style="margin-top:8px;padding:7px 10px;">1131 <div class="status-dot amber" id="conn-dot"></div>1132 <span id="conn-txt" style="font-size:11px;">Not tested</span>1133 </div>1134 <button class="btn btn-accent" style="width:100%;margin-top:8px;font-size:11px;justify-content:center;" onclick="testConnection()">Test Connection</button>1135 </div>1136 </aside>1137 1138 <main class="int-main">1139 1140 <!-- DB Connection -->1141 <div class="int-section active" id="int-conn">1142 <div class="page-header">1143 <div class="ph-title">MySQL Bronze Layer Connection</div>1144 <div class="ph-sub">Configure and verify · Local: localhost/bronze · HF: Clever Cloud (single schema, prefixed tables)</div>1145 </div>1146 1147 <div class="alert alert-info" style="margin-bottom:20px;">1148 💡 This is a browser-based app. Direct MySQL TCP connections require a backend proxy. The SQL Inserts tab generates ready-to-run statements for MySQL Workbench or CLI. The Python Connector tab provides a production-ready script for direct DB writes.1149 </div>1150 1151 <div class="two-col" style="margin-bottom:16px;">1152 <div class="config-card">1153 <div class="cc-title">Connection Details</div>1154 <div class="cc-desc">Pre-configured · localhost (local) or Clever Cloud (HuggingFace)</div>1155 <div class="fg fg2" style="gap:10px;">1156 <div class="fld"><label class="flabel">Host</label><input type="text" value="localhost" id="db_host"></div>1157 <div class="fld"><label class="flabel">Port</label><input type="number" value="3306" id="db_port"></div>1158 <div class="fld"><label class="flabel">Username</label><input type="text" value="root" id="db_user"></div>1159 <div class="fld"><label class="flabel">Password</label><input type="text" value="root@123" id="db_pass"></div>1160 <div class="fld"><label class="flabel">Database</label><input type="text" value="bronze" id="db_name"></div>1161 <div class="fld"><label class="flabel">Charset</label><input type="text" value="utf8mb4"></div>1162 </div>1163 <button class="btn btn-accent" style="margin-top:14px;" onclick="testConnection()">⚡ Test Connection</button>1164 </div>1165 <div class="config-card">1166 <div class="cc-title">Connection Status</div>1167 <div class="cc-desc">Live diagnostics and health check</div>1168 <div class="log-console" id="conn-log" style="min-height:140px;">1169<div class="log-line"><span class="log-ts">00:00:00</span><span class="log-info">PolicyBridge MySQL Integration v1.0</span></div>1170<div class="log-line"><span class="log-ts">00:00:00</span><span class="log-info">Target: localhost:3306 / bronze</span></div>1171<div class="log-line"><span class="log-ts">00:00:00</span><span class="log-warn">Click "Test Connection" to verify connectivity</span></div>1172 </div>1173 </div>1174 </div>1175 1176 <div class="config-card">1177 <div class="cc-title">Bronze Layer Tables — Write Targets</div>1178 <div class="cc-desc">All tables that receive data on each submission</div>1179 <table class="tmap">1180 <thead><tr><th>Schema</th><th>Table</th><th>Write Trigger</th><th>Key Fields</th><th>Status</th></tr></thead>1181 <tbody id="tmap-body">1182 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_brokers</td><td>Every new broker</td><td>broker_code, broker_name, contact_email</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1183 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_insureds</td><td>Every submission</td><td>full_name, dob, ssn_hash, email, phone</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1184 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_properties</td><td>Every submission</td><td>insured_id, street, city, state_code, zip</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1185 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_submissions</td><td>Every submission</td><td>submission_id, broker_id, insured_id, property_id</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1186 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_submission_attachments</td><td>Static S3 URIs (Phase 1)</td><td>submission_id, attachment_type, s3_uri</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1187 <tr><td><span class="schema-badge">bronze</span></td><td>bronze_pipeline_agent_log</td><td>On submission</td><td>submission_id, agent_code, status=QUEUED</td><td class="status-cell"><span class="s-pend">● Pending</span></td></tr>1188 </tbody>1189 </table>1190 </div>1191 </div>1192 1193 <!-- Schema Map -->1194 <div class="int-section" id="int-schema">1195 <div class="page-header">1196 <div class="ph-title">Bronze Schema → Form Field Mapping</div>1197 <div class="ph-sub">Complete field-to-column mapping for all Bronze tables</div>1198 </div>1199 <div id="schema-map-content"></div>1200 </div>