CoolFace
Apppublic

zhshuvo/HuggingClaw

sourceHugging Facemitupdated 4mo agoView on Hugging Face
0likes
env-builder.html957 linesDownload Raw Back to root
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>HuggingClaw · ENV Builder</title>7<link rel="preconnect" href="https://fonts.googleapis.com">8<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>9<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Syne:wght@400;500;600;700;800&display=swap" rel="stylesheet">10 11<style>12/* ── Reset & Tokens ── */13*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }14 15:root {16  --bg:        #0b0c0f;17  --bg2:       #111318;18  --bg3:       #181c23;19  --bg4:       #1e2330;20  --border:    #252b38;21  --border2:   #2e3648;22  --amber:     #f5a623;23  --amber2:    #ffbe55;24  --amber-dim: rgba(245,166,35,.12);25  --amber-glow:rgba(245,166,35,.22);26  --green:     #3dd68c;27  --red:       #f05f5f;28  --blue:      #5b8af5;29  --text:      #e4e8f0;30  --text2:     #8d97ad;31  --text3:     #535f76;32  --mono:      'JetBrains Mono', monospace;33  --sans:      'Syne', sans-serif;34  --r:         8px;35  --r2:        12px;36  --sidebar-w: 220px;37  --panel-w:   340px;38}39 40html { scroll-behavior: smooth; height: 100%; }41 42body {43  font-family: var(--sans);44  background: var(--bg);45  color: var(--text);46  height: 100vh;47  overflow: hidden;48  display: flex;49  flex-direction: column;50}51 52/* ── Topbar ── */53.topbar {54  position: sticky;55  top: 0;56  z-index: 100;57  height: 52px;58  background: rgba(11,12,15,.9);59  backdrop-filter: blur(14px);60  border-bottom: 1px solid var(--border);61  display: flex;62  align-items: center;63  padding: 0 20px;64  gap: 16px;65  flex-shrink: 0;66}67 68.topbar-logo {69  display: flex;70  align-items: center;71  gap: 10px;72  flex-shrink: 0;73}74 75.topbar-logo svg { width: 26px; height: 26px; }76 77.topbar-wordmark {78  font-weight: 800;79  font-size: 14px;80  letter-spacing: -.2px;81  color: var(--text);82  white-space: nowrap;83}84 85.topbar-wordmark em {86  color: var(--amber);87  font-style: normal;88}89 90.topbar-divider {91  width: 1px;92  height: 22px;93  background: var(--border2);94}95 96.topbar-title {97  font-size: 12px;98  font-weight: 600;99  color: var(--text2);100  letter-spacing: .5px;101  text-transform: uppercase;102}103 104.topbar-spacer { flex: 1; }105 106.topbar-pill {107  font-family: var(--mono);108  font-size: 10px;109  color: var(--amber);110  background: var(--amber-dim);111  border: 1px solid var(--amber-glow);112  border-radius: 20px;113  padding: 3px 10px;114  letter-spacing: .5px;115}116 117/* ── Layout ── */118.layout {119  display: flex;120  flex: 1;121  min-height: 0;122  height: calc(100vh - 52px);123}124 125/* ── Sidebar ── */126.sidebar-wrap {127  width: var(--sidebar-w);128  flex-shrink: 0;129  border-right: 1px solid var(--border);130  background: var(--bg2);131  display: flex;132  flex-direction: column;133  min-height: 0;134  overflow: hidden;135}136 137.sidebar-scroll {138  flex: 1;139  overflow-y: auto;140  padding: 14px 10px;141}142 143.sidebar-scroll::-webkit-scrollbar { width: 4px; }144.sidebar-scroll::-webkit-scrollbar-track { background: transparent; }145.sidebar-scroll::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }146 147/* sb-label rendered by JS */148.sb-label {149  font-size: 9px;150  font-weight: 700;151  text-transform: uppercase;152  letter-spacing: 1.2px;153  color: var(--text3);154  padding: 0 8px 10px;155}156 157.nav-btn {158  width: 100%;159  display: flex;160  align-items: center;161  gap: 8px;162  padding: 8px 10px;163  border: none;164  background: transparent;165  cursor: pointer;166  border-radius: var(--r);167  text-align: left;168  color: var(--text2);169  font-family: var(--sans);170  font-size: 12.5px;171  font-weight: 500;172  transition: background .15s, color .15s;173  margin-bottom: 2px;174}175 176.nav-btn:hover { background: var(--bg3); color: var(--text); }177.nav-btn.active {178  background: var(--amber-dim);179  color: var(--amber);180  border: 1px solid var(--amber-glow);181}182 183.nav-icon { font-size: 13px; flex-shrink: 0; }184.nav-label { flex: 1; }185.nav-count {186  font-family: var(--mono);187  font-size: 10px;188  font-weight: 600;189  color: var(--text3);190  background: var(--bg3);191  border-radius: 10px;192  padding: 1px 6px;193  min-width: 20px;194  text-align: center;195  transition: background .2s, color .2s;196}197.nav-btn.active .nav-count {198  background: var(--amber-glow);199  color: var(--amber2);200}201 202/* ── Main ── */203.main {204  flex: 1;205  display: flex;206  flex-direction: column;207  min-width: 0;208  overflow: hidden;209}210 211/* ── Toolbar ── */212.toolbar {213  display: flex;214  align-items: center;215  gap: 10px;216  padding: 12px 20px;217  border-bottom: 1px solid var(--border);218  background: var(--bg2);219  flex-shrink: 0;220  flex-wrap: wrap;221}222 223.search-wrap {224  position: relative;225  flex: 1;226  min-width: 160px;227  max-width: 340px;228}229 230.search-icon {231  position: absolute;232  left: 10px;233  top: 50%;234  transform: translateY(-50%);235  color: var(--text3);236  pointer-events: none;237  font-size: 12px;238}239 240#search {241  width: 100%;242  background: var(--bg3);243  border: 1px solid var(--border2);244  border-radius: var(--r);245  padding: 7px 10px 7px 30px;246  font-family: var(--mono);247  font-size: 12px;248  color: var(--text);249  outline: none;250  transition: border-color .15s;251}252 253#search:focus { border-color: var(--amber); }254#search::placeholder { color: var(--text3); }255 256.tb-sep {257  width: 1px;258  height: 24px;259  background: var(--border2);260}261 262.btn {263  display: inline-flex;264  align-items: center;265  gap: 5px;266  padding: 6px 13px;267  border-radius: var(--r);268  border: 1px solid var(--border2);269  background: var(--bg3);270  color: var(--text2);271  font-family: var(--sans);272  font-size: 11.5px;273  font-weight: 600;274  cursor: pointer;275  transition: all .15s;276  white-space: nowrap;277}278 279.btn:hover { background: var(--bg4); color: var(--text); border-color: var(--border2); }280 281.btn-amber {282  background: var(--amber);283  color: #0b0c0f;284  border-color: var(--amber);285}286.btn-amber:hover { background: var(--amber2); border-color: var(--amber2); }287 288.btn-ghost {289  background: transparent;290  border-color: transparent;291  color: var(--text3);292}293.btn-ghost:hover { background: var(--bg3); color: var(--text2); border-color: var(--border2); }294 295/* ── Content area ── */296.content-wrap {297  flex: 1;298  display: flex;299  min-height: 0;300  overflow: hidden;301}302 303/* ── Sections scroll ── */304.sections-scroll {305  flex: 1;306  overflow-y: auto;307  padding: 16px 20px 80px;308  min-width: 0;309}310 311.sections-scroll::-webkit-scrollbar { width: 5px; }312.sections-scroll::-webkit-scrollbar-track { background: transparent; }313.sections-scroll::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }314 315/* ── Section ── */316.sec { margin-bottom: 28px; }317.sec.sec-hidden { display: none !important; }318 319.sec-header {320  display: flex;321  align-items: center;322  gap: 8px;323  margin-bottom: 12px;324}325 326.sec-icon { font-size: 14px; }327.sec-title {328  font-size: 11px;329  font-weight: 700;330  text-transform: uppercase;331  letter-spacing: 1.2px;332  color: var(--text3);333}334.sec-count {335  font-family: var(--mono);336  font-size: 10px;337  color: var(--text3);338  background: var(--bg3);339  border: 1px solid var(--border);340  border-radius: 10px;341  padding: 1px 7px;342}343 344.sec-line {345  flex: 1;346  height: 1px;347  background: var(--border);348}349 350.cards {351  display: grid;352  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));353  gap: 9px;354}355 356/* ── ENV Card ── */357.env-card {358  background: var(--bg2);359  border: 1px solid var(--border);360  border-radius: var(--r2);361  padding: 12px;362  transition: border-color .2s, background .2s;363}364 365.env-card:hover { border-color: var(--border2); }366.env-card.hidden { display: none; }367 368.env-card.selected {369  border-color: var(--amber-glow);370  background: linear-gradient(135deg, var(--bg2) 80%, rgba(245,166,35,.04));371}372 373/* Critical cards get a red left-border accent */374.env-card:has(.badge-critical) {375  border-left: 3px solid rgba(240,80,80,.4);376}377.env-card:has(.badge-critical):hover {378  border-left-color: rgba(240,80,80,.7);379}380.env-card:has(.badge-critical).selected {381  border-left-color: #f05f5f;382}383 384/* Credential cards get an amber left-border accent */385.env-card:has(.badge-credential) {386  border-left: 3px solid rgba(220,140,60,.3);387}388 389.card-top {390  display: flex;391  align-items: flex-start;392  gap: 9px;393  margin-bottom: 9px;394}395 396.card-check {397  width: 15px;398  height: 15px;399  accent-color: var(--amber);400  flex-shrink: 0;401  margin-top: 2px;402  cursor: pointer;403}404 405.card-info { flex: 1; min-width: 0; }406 407.card-key {408  font-family: var(--mono);409  font-size: 11.5px;410  font-weight: 600;411  color: var(--text);412  letter-spacing: .3px;413  white-space: nowrap;414  overflow: hidden;415  text-overflow: ellipsis;416}417 418.card-lbl {419  font-size: 11px;420  color: var(--text3);421  margin-top: 2px;422  line-height: 1.35;423}424 425.badge {426  flex-shrink: 0;427  font-family: var(--mono);428  font-size: 9px;429  font-weight: 700;430  text-transform: uppercase;431  letter-spacing: .6px;432  padding: 2px 7px;433  border-radius: 20px;434}435 436/* critical — space breaks without this */437.badge-critical {438  background: rgba(240,80,80,.14);439  color: #f05f5f;440  border: 1px solid rgba(240,80,80,.3);441}442 443/* credential — sensitive key / token */444.badge-credential {445  background: rgba(220,140,60,.13);446  color: #e09040;447  border: 1px solid rgba(220,140,60,.28);448}449 450/* feature — enables an optional feature */451.badge-feature {452  background: rgba(70,140,250,.12);453  color: #5a9eff;454  border: 1px solid rgba(70,140,250,.25);455}456 457/* optional — safe to change freely */458.badge-optional {459  background: rgba(61,214,140,.10);460  color: #3dd68c;461  border: 1px solid rgba(61,214,140,.22);462}463 464/* advanced — power-user, risky if wrong */465.badge-advanced {466  background: rgba(160,100,230,.12);467  color: #b07ae0;468  border: 1px solid rgba(160,100,230,.25);469}470 471/* build-time — needs HF Space rebuild */472.badge-build {473  background: rgba(240,185,60,.12);474  color: #e0b030;475  border: 1px solid rgba(240,185,60,.28);476}477 478/* ── Card inputs ── */479.card-input { position: relative; }480 481.card-input input[type="text"],482.card-input input[type="password"],483.card-input input[type="number"],484.card-input textarea,485.card-input select {486  width: 100%;487  background: var(--bg3);488  border: 1px solid var(--border);489  border-radius: var(--r);490  padding: 7px 10px;491  font-family: var(--mono);492  font-size: 11.5px;493  color: var(--text);494  outline: none;495  transition: border-color .15s;496  resize: vertical;497}498 499.card-input input[type="text"]:focus,500.card-input input[type="password"]:focus,501.card-input input[type="number"]:focus,502.card-input textarea:focus,503.card-input select:focus {504  border-color: var(--amber);505}506 507.card-input textarea { min-height: 64px; }508.card-input select {509  cursor: pointer;510  appearance: none;511  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238d97ad' d='M6 8L1 3h10z'/%3E%3C/svg%3E");512  background-repeat: no-repeat;513  background-position: right 10px center;514  padding-right: 28px;515}516 517.card-input optgroup { color: var(--text2); font-weight: 600; }518.card-input option { color: var(--text); background: var(--bg3); }519 520/* ── Toggle ── */521.toggle-shell { display: flex; align-items: center; gap: 8px; }522.tog {523  padding: 5px 14px;524  border-radius: 20px;525  border: 1px solid var(--border2);526  background: var(--bg3);527  color: var(--text3);528  font-family: var(--mono);529  font-size: 11px;530  font-weight: 700;531  cursor: pointer;532  transition: all .18s;533  letter-spacing: .5px;534}535.tog.on {536  background: rgba(61,214,140,.15);537  border-color: rgba(61,214,140,.4);538  color: var(--green);539}540 541/* ── Picker shell ── */542.picker-shell { display: flex; flex-direction: column; gap: 6px; }543.picker-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }544 545.picker-select {546  flex: 1;547  min-width: 0;548  padding: 6px 28px 6px 8px !important;549  font-size: 11px !important;550}551 552.mini-btn {553  padding: 5px 9px;554  border-radius: var(--r);555  border: 1px solid var(--border2);556  background: var(--bg3);557  color: var(--text2);558  font-family: var(--mono);559  font-size: 10px;560  font-weight: 600;561  cursor: pointer;562  transition: all .15s;563  white-space: nowrap;564}565.mini-btn:hover { background: var(--bg4); color: var(--text); }566 567/* ── Right panel ── */568.right-panel {569  width: var(--panel-w);570  flex-shrink: 0;571  border-left: 1px solid var(--border);572  background: var(--bg2);573  display: flex;574  flex-direction: column;575  overflow: hidden;576}577 578.panel-scroll {579  flex: 1;580  overflow-y: auto;581  min-height: 0;582  padding: 16px;583  display: flex;584  flex-direction: column;585  gap: 16px;586}587 588.panel-scroll::-webkit-scrollbar { width: 4px; }589.panel-scroll::-webkit-scrollbar-track { background: transparent; }590.panel-scroll::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }591 592/* ── Panel block ── */593.pblock {594  background: var(--bg3);595  border: 1px solid var(--border);596  border-radius: var(--r2);597  overflow: hidden;598}599 600.pblock-head {601  display: flex;602  align-items: center;603  justify-content: space-between;604  padding: 10px 14px;605  border-bottom: 1px solid var(--border);606}607 608.pblock-title {609  font-size: 10.5px;610  font-weight: 700;611  text-transform: uppercase;612  letter-spacing: 1px;613  color: var(--text3);614  display: flex;615  align-items: center;616  gap: 6px;617}618 619.pblock-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }620 621.pblock-body textarea,622.pblock-body input[type="text"] {623  width: 100%;624  background: var(--bg);625  border: 1px solid var(--border);626  border-radius: var(--r);627  padding: 8px 10px;628  font-family: var(--mono);629  font-size: 10.5px;630  color: var(--text2);631  outline: none;632  resize: vertical;633  transition: border-color .15s;634}635 636.pblock-body textarea:focus,637.pblock-body input[type="text"]:focus {638  border-color: var(--amber);639  color: var(--text);640}641 642#importText { min-height: 80px; }643#bundleOut { min-height: 60px; color: var(--amber2); }644#envLineOut { font-size: 10px; }645 646.row-btns { display: flex; gap: 6px; flex-wrap: wrap; }647 648/* ── Summary ── */649#summary {650  font-size: 11.5px;651  color: var(--text2);652  line-height: 1.6;653}654 655#summary strong {656  font-size: 15px;657  color: var(--amber);658  font-family: var(--mono);659}660 661.sum-keys {662  margin-top: 8px;663  display: flex;664  flex-wrap: wrap;665  gap: 4px;666}667 668.sum-key {669  font-family: var(--mono);670  font-size: 9.5px;671  color: var(--text2);672  background: var(--bg4);673  border: 1px solid var(--border2);674  border-radius: 4px;675  padding: 2px 6px;676}677 678/* ── Custom Env section ── */679#customSec {680  margin-top: 8px;681}682 683.custom-row {684  display: flex;685  gap: 8px;686  align-items: center;687  margin-bottom: 8px;688}689 690.custom-row input {691  flex: 1;692  background: var(--bg3);693  border: 1px solid var(--border);694  border-radius: var(--r);695  padding: 7px 10px;696  font-family: var(--mono);697  font-size: 11px;698  color: var(--text);699  outline: none;700  transition: border-color .15s;701  min-width: 0;702}703 704.custom-row input:focus { border-color: var(--amber); }705.custom-row input:first-child { flex: 0 0 40%; }706 707/* ── Toast ── */708#toast {709  position: fixed;710  bottom: 24px;711  left: 50%;712  transform: translateX(-50%) translateY(20px);713  background: var(--bg4);714  border: 1px solid var(--border2);715  color: var(--amber);716  font-family: var(--mono);717  font-size: 12px;718  font-weight: 600;719  padding: 9px 20px;720  border-radius: 30px;721  z-index: 9999;722  opacity: 0;723  transition: opacity .2s, transform .2s;724  pointer-events: none;725  box-shadow: 0 8px 32px rgba(0,0,0,.5);726}727 728#toast.show {729  opacity: 1;730  transform: translateX(-50%) translateY(0);731}732 733/* ── Scrollbar global ── */734::-webkit-scrollbar { width: 6px; height: 6px; }735::-webkit-scrollbar-track { background: transparent; }736::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }737 738/* ── Responsive ── */739 740@media (max-width: 1100px) {741  .toolbar-hint { display: none; }742}743@media (max-width: 900px) {744  :root { --panel-w: 280px; --sidebar-w: 180px; }745}746 747@media (max-width: 700px) {748  .right-panel { display: none; }749  :root { --sidebar-w: 160px; }750}751 752@media (max-width: 520px) {753  .sidebar-wrap { display: none; }754  .topbar-divider, .topbar-title { display: none; }755}756 757/* ── Tag Legend (collapsible) ── */758.tag-legend {759  margin-bottom: 14px;760  background: var(--bg2);761  border: 1px solid var(--border);762  border-radius: var(--r);763  overflow: hidden;764}765.legend-summary {766  display: flex;767  align-items: center;768  gap: 10px;769  padding: 7px 12px;770  cursor: pointer;771  list-style: none;772  user-select: none;773  outline: none;774}775.legend-summary::-webkit-details-marker { display: none; }776.legend-chips { display: flex; gap: 5px; flex-wrap: wrap; flex: 1; }777.legend-hint {778  font-size: 10px;779  color: var(--text3);780  white-space: nowrap;781  flex-shrink: 0;782}783.tag-legend[open] .legend-hint { opacity: 0; }784.toolbar-hint { color: var(--muted); font-size: 12px; margin-right: 10px; white-space: nowrap; }785.legend-body {786  padding: 8px 12px 10px;787  border-top: 1px solid var(--border);788  display: flex;789  flex-direction: column;790  gap: 6px;791}792.legend-row {793  display: flex;794  align-items: center;795  gap: 10px;796  font-size: 11px;797  color: var(--text2);798}799.legend-row .badge { flex-shrink: 0; width: 74px; text-align: center; }800.legend-tip {801  font-size: 9.5px;802  color: var(--text3);803  margin-top: 4px;804  padding-top: 6px;805  border-top: 1px solid var(--border);806}807</style>808</head>809 810<body>811 812<!-- ── Topbar ── -->813<header class="topbar">814  <div class="topbar-logo">815    <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">816      <rect width="64" height="64" rx="14" fill="#1a1f2e"/>817      <text x="10" y="46" font-size="40" font-family="monospace">🤗</text>818      <circle cx="46" cy="20" r="10" fill="#f5a623"/>819      <text x="40" y="25" font-size="14" font-family="monospace" fill="#0b0c0f">⚡</text>820    </svg>821    <span class="topbar-wordmark">Hugging<em>Claw</em></span>822  </div>823  <div class="topbar-divider"></div>824  <span class="topbar-title">ENV Builder</span>825  <div class="topbar-spacer"></div>826  <span class="topbar-pill">v2025</span>827</header>828 829<!-- ── Layout ── -->830<div class="layout">831 832  <!-- ── Sidebar ── -->833  <aside class="sidebar-wrap">834    <div class="sidebar-scroll">835      <div id="sidebar"></div>836    </div>837  </aside>838 839  <!-- ── Main ── -->840  <main class="main">841 842    <!-- toolbar -->843    <div class="toolbar">844      <div class="toolbar-hint">Tip: Start with <strong>⚡ Required</strong>, then fill keys and click <strong># Generate Bundle</strong>.</div>845      <div class="search-wrap">846        <span class="search-icon">⌕</span>847        <input id="search" type="text" placeholder="Search variables…" autocomplete="off" spellcheck="false">848      </div>849 850      <div class="tb-sep"></div>851 852      <button id="selectRequired" class="btn" title="Select all critical variables first">⚡ Required</button>853      <button id="selectCommon" class="btn">★ Common</button>854      <button id="selectVisible" class="btn">☑ Visible</button>855      <button id="clearAll" class="btn btn-ghost">✕ Clear</button>856    </div>857 858    <!-- content row -->859    <div class="content-wrap">860 861      <!-- sections -->862      <div class="sections-scroll">863        <!-- Tag Legend (compact collapsible) -->864        <details class="tag-legend" id="tagLegend">865          <summary class="legend-summary">866            <span class="legend-chips">867              <span class="badge badge-critical">critical</span>868              <span class="badge badge-credential">credential</span>869              <span class="badge badge-feature">feature</span>870              <span class="badge badge-optional">optional</span>871              <span class="badge badge-advanced">advanced</span>872              <span class="badge badge-build">build-time</span>873            </span>874            <span class="legend-hint">what do these mean?</span>875          </summary>876          <div class="legend-body">877            <div class="legend-row"><span class="badge badge-critical">critical</span><span>Space won't work without this</span></div>878            <div class="legend-row"><span class="badge badge-credential">credential</span><span>Sensitive key or token — never share</span></div>879            <div class="legend-row"><span class="badge badge-feature">feature</span><span>Enables a specific optional feature</span></div>880            <div class="legend-row"><span class="badge badge-optional">optional</span><span>Safe to change — nothing breaks</span></div>881            <div class="legend-row"><span class="badge badge-advanced">advanced</span><span>Power-user setting — wrong value causes issues</span></div>882            <div class="legend-row"><span class="badge badge-build">build-time</span><span>Needs HF Space rebuild to fully take effect</span></div>883            <div class="legend-tip">💡 Type a tag name in search to filter by it</div>884          </div>885        </details>886        <div id="sections"></div>887 888        <!-- Custom Env section -->889        <div id="customSec" class="sec" data-section="Custom Env">890          <div class="sec-header">891            <span class="sec-icon">🔧</span>892            <span class="sec-title">Custom Env</span>893            <div class="sec-line"></div>894          </div>895          <div id="customRows"></div>896          <button id="addCustom" class="btn" style="margin-top:6px;">+ Add variable</button>897        </div>898      </div>899 900      <!-- right panel -->901      <aside class="right-panel">902        <div class="panel-scroll">903 904          <div class="pblock">905            <div class="pblock-head">906              <span class="pblock-title">📊 Summary</span>907            </div>908            <div class="pblock-body">909              <div id="summary">No variables selected yet.</div>910            </div>911          </div>912 913          <!-- Output -->914          <div class="pblock">915            <div class="pblock-head">916              <span class="pblock-title">📦 Bundle Output</span>917            </div>918            <div class="pblock-body">919              <button id="generateBundle" class="btn btn-amber" style="width:100%;font-size:12.5px;"># Generate Bundle</button>920              <textarea id="bundleOut" placeholder="Click # Generate to build your bundle…" readonly spellcheck="false"></textarea>921              <input type="text" id="envLineOut" placeholder="HUGGINGCLAW_ENV_BUNDLE=…" readonly spellcheck="false">922              <div class="row-btns">923                <button id="copyBundle" class="btn btn-amber">⎘ Bundle</button>924                <button id="copyEnvLine" class="btn">⎘ Env Line</button>925                <button id="copyJson" class="btn">⎘ JSON</button>926                <button id="applyBundle" class="btn btn-ghost">↺ Apply</button>927              </div>928            </div>929          </div>930 931          <!-- Import -->932          <div class="pblock">933            <div class="pblock-head">934              <span class="pblock-title">📥 Import</span>935            </div>936            <div class="pblock-body">937              <textarea id="importText" placeholder="Paste .env, JSON, or HUGGINGCLAW_ENV_BUNDLE=… here" spellcheck="false"></textarea>938              <button id="applyImport" class="btn btn-amber" style="width:100%;">↓ Import & Apply</button>939            </div>940          </div>941 942        </div>943      </aside>944 945    </div><!-- /content-wrap -->946  </main>947</div><!-- /layout -->948 949<!-- Toast -->950<div id="toast">Copied ✓</div>951 952<!-- env-builder.js provides MODEL_CATALOGS, FIELDS, ICONS and all logic -->953<script src="env-builder.js"></script>954 955</body>956</html>957