Image Rich Data

The Image Rich Data demo demonstrates how to use IImageRichData to set image values in cells and display rich product data in a spreadsheet.

SpreadJS supports Image Rich Data as cell values. You can use the setValue API with IImageRichData objects to embed images directly in cells. The IImageRichData structure includes: richDataType: Must be "Image" value.src: The location of the image on the web or base64 string value.altText: A text description for the image This demo shows a product inventory list with embedded product images.
// Product image base64 data (64x64 PNG icons) var productImages = { laptop: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAFiUlEQVR4nO3dwU8cZRjH8WdgobQU2bailBobbROsgt2aeC1bjXrw4HLx0JhI48H4B3jwJJ49eDSexMT04KUbjfGE3e3VaBdBK4nV1LQUJW0XgRaEZXxeyuyyy7LLvMvO+848v0+yk3cghIT32/dd3jSMQyAaAhAOAQiHAIRDAMIhAOEQgHAIQDgEIBwCEA4BCIcAhEMAwiEA4RCAcAhAOAQgHAIQbk8CeD45/Pa66444LiVcojh/CJqEJyzvOpRrcZyxnzOXvuAPNcThl7ZEMhVfc+kSuZQkCJ5DmZhDw7lMOs93WhoKYGAodRmTbxhHMJVNn+ORFodfWgaTqRF3nT7nIRjmtNCFyUx6jDRoBzBwNpUhoiF+bWh94jmKDb5KzqE+voNmcZfu0tqPX1Ph5i98V5SdupJOkgbtAAbPpu65W97w7XvjA3I6D/MIms29N0Mr333Co4d4EvOTV9KHeOgbf60eXgF4/ks6zn/MVwjK8sX3+VrCK4DWXGp9kYIAzEIAwiEA4UITQGebQ0e72qitVftbibRacOn2wiotrZb9mItCE8DJw+2YfE0qgt/v/sej7UITwKmefXwFXdfmVvi6HQIQAgEIhwCEQwDCIQDhEIBwCEC4yAdw5EArne7dTwfaWvjOHvdX12li9gHduV/gO3MiH8BLTx+0bvI9KoLv/1jkkTmRD+C1k13WHhU/4ADGEUB1exWA2gISvAXst2wVUJOfwxaws70KAGpDAMIhAOEQgHAIQDgEIFzkA1C/BgZxEqgOdWw42fMr8gEEeRKoIjB9sudX5AMI8iRQHe6YPtnzK/IBqC0giJNANfk2nOz5FfkAoDYEIBwCEA4BCIcAhEMAwkU+APVrYBAngfWoQyIbTwojH0CQJ4H1qAhsOymMfABBngTWow6LbDspjHwAagsI4iSwHjX5Np4URj4AqA0BCIcAhEMAwiEA4RCAcAhAOAQgXOgD6H+0nVoc7W8jWiT+UCT+VKweNfmR+FOx0BwIQDgEIBwCEM54AINDqbzrUjcPN+ChUcHZ9tAoh+Yns+niA7z80A6AV4AMlT02boBig6/gsXFN9vCxcd9Q4eYU3xUZeGwcHhxpDSMPjlQqVwEwQvtfv9JQABsPj16nNA+NRXCs7zE6l3yRuro6+S44CwtLdDnzA92a+YfvjMnGWihl7OHRns3tYITfjCS2vjEMwlvnXw988j0qgi8vfsuj4PDPeJ5/xjle9sd0l/2tqgbAE5riCT3NQ+u99+6bo2TQp599NUohwMFMcDBpHpapGgAv7Qle2q/y0HocAF/N4QD4aj/eKs7wVpHjYZmqASj8Bm+UiD7kl9XeuTBM7e1tPAqeiS1A00f8RnGUqtgxAGVgKJUjt7QVPNv/JF/tEo8/Qv3PnKCOjmD/38Hy8gpN/3ad8vl/+c4uv07/xddNDk1MZdMJHlVVM4DKrUAFcKr/OI/AVtemb5QFsNPS76kZgFK5Fbw89ALFu82864ba8vNLNJ79iUdFOy79nroBKFu3gnj3QY7gDI/sFmuN0eM9PTwi+ntujtYKazwqafTzNhrPXuUIFnnE6iz9nl0FEMat4FjvUTpx/CkeEV2/8Sfdmr3No5JGP28bv0u/x+HXroRtK6g3gY1+3iY6S7/H4deuhWkrqLeEN/p5m+gs/R5fAYRxK4g63aXf4ysAJWxbQZQ1svR7fAegVG4Ffb1HeARBm5m9wxEs8oj5XPo9WgFUbgVgnt+l36MVgFK5FYBRvpd+j3YAymYEYJju5CsNBQDhhwCEQwDCIQDhEIBwCEA4BCAcAhAOAQiHAIRDAMIhAOEQgHAIQDgEIBwCEA4BCIcAhEMAwiEA4RCAcAhAOAQgHAIQDgEIhwCEQwDCIQDhEIBwCEC4/wHuWNqug6X4qQAAAABJRU5ErkJggg==", phone: "data:image/png;base64,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", headphones: "data:image/png;base64,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", watch: "data:image/png;base64,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", camera: "data:image/png;base64,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" }; // Default product data var defaultProducts = [ { name: "Laptop Pro", imageBase64: productImages.laptop, price: 1299, stock: 45, area: "North America" }, { name: "SmartPhone X", imageBase64: productImages.phone, price: 899, stock: 120, area: "Asia-Pacific" }, { name: "Studio Phones", imageBase64: productImages.headphones, price: 349, stock: 200, area: "Europe" }, { name: "Sport Watch", imageBase64: productImages.watch, price: 499, stock: 75, area: "Asia-Pacific" }, { name: "DSLR Camera", imageBase64: productImages.camera, price: 1599, stock: 30, area: "North America" } ]; // Map of product name (lowercase) → base64 for existing-name detection var productNameImageMap = {}; var spread, sheet, currentRowCount; var allProducts = []; // persistent store of all product data var DATA_START_ROW = 1; // row 0 is header var DATA_COL_NAME = 0; var DATA_COL_IMAGE = 1; var DATA_COL_AREA = 2; var DATA_COL_PRICE = 3; var DATA_COL_STOCK = 4; var TABLE_NAME = "ProductTable"; window.onload = function () { spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 }); initSpread(spread); bindEvents(); initPanelToggle(); }; function initPanelToggle() { var panel = document.querySelector('.options-container'); var toggleBtn = document.getElementById('panelToggleBtn'); var collapseBtn = document.getElementById('panelCollapseBtn'); function collapsePanel() { panel.classList.add('collapsed'); toggleBtn.classList.add('visible'); setTimeout(function () { spread.refresh(); }, 320); } function expandPanel() { panel.classList.remove('collapsed'); toggleBtn.classList.remove('visible'); setTimeout(function () { spread.refresh(); }, 320); } collapseBtn.addEventListener('click', collapsePanel); toggleBtn.addEventListener('click', expandPanel); } function initSpread(spread) { spread.suspendPaint(); sheet = spread.getSheet(0); sheet.name("Product Inventory"); sheet.setRowCount(200); sheet.setColumnCount(15); // Set up headers sheet.setValue(0, DATA_COL_NAME, "Product Name"); sheet.setValue(0, DATA_COL_IMAGE, "Product Image"); sheet.setValue(0, DATA_COL_AREA, "Area"); sheet.setValue(0, DATA_COL_PRICE, "Price ($)"); sheet.setValue(0, DATA_COL_STOCK, "Stock"); // Set column widths sheet.setColumnWidth(DATA_COL_NAME, 140); sheet.setColumnWidth(DATA_COL_IMAGE, 100); sheet.setColumnWidth(DATA_COL_AREA, 120); sheet.setColumnWidth(DATA_COL_PRICE, 100); sheet.setColumnWidth(DATA_COL_STOCK, 80); // Set uniform row height for all data rows (row 1 to 199) to accommodate images var DATA_ROW_HEIGHT = 50; for (var r = DATA_START_ROW; r < 200; r++) { sheet.setRowHeight(r, DATA_ROW_HEIGHT); } // Style headers var headerStyle = new GC.Spread.Sheets.Style(); headerStyle.font = "bold 13px Calibri"; headerStyle.backColor = "#4a7a00"; headerStyle.foreColor = "#ffffff"; headerStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center; headerStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; for (var c = 0; c <= 4; c++) { sheet.setStyle(0, c, headerStyle); } // Populate default product data currentRowCount = 0; for (var i = 0; i < defaultProducts.length; i++) { addProductRow(defaultProducts[i]); } // Create table from data createDataTable(); spread.resumePaint(); } function createImageRichData(imageBase64, altText) { return { richDataType: "Image", value: { src: imageBase64, altText: altText || "" } }; } function addProductRow(product) { var row = DATA_START_ROW + currentRowCount; sheet.setValue(row, DATA_COL_NAME, product.name); // Set image using IImageRichData var imageData = createImageRichData(product.imageBase64, product.name); sheet.setValue(row, DATA_COL_IMAGE, imageData); sheet.setValue(row, DATA_COL_PRICE, product.price); sheet.setValue(row, DATA_COL_STOCK, product.stock); sheet.setValue(row, DATA_COL_AREA, product.area); // Center-align cells var cellStyle = new GC.Spread.Sheets.Style(); cellStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; cellStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center; sheet.setStyle(row, DATA_COL_IMAGE, cellStyle); sheet.setStyle(row, DATA_COL_PRICE, cellStyle); sheet.setStyle(row, DATA_COL_STOCK, cellStyle); sheet.setStyle(row, DATA_COL_AREA, cellStyle); var nameStyle = new GC.Spread.Sheets.Style(); nameStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; sheet.setStyle(row, DATA_COL_NAME, nameStyle); currentRowCount++; // Register in name→image map productNameImageMap[product.name.toLowerCase()] = product.imageBase64; // Persist in allProducts array allProducts.push({ name: product.name, imageBase64: product.imageBase64, price: product.price, stock: product.stock, area: product.area }); } function createDataTable() { // Remove existing table if present (this may clear cell data in some SpreadJS builds) try { sheet.tables.remove(TABLE_NAME); } catch (e) { /* ignore if not exists */ } // Always re-write header row (also cleared by tables.remove) sheet.setValue(0, DATA_COL_NAME, "Product Name"); sheet.setValue(0, DATA_COL_IMAGE, "Product Image"); sheet.setValue(0, DATA_COL_AREA, "Area"); sheet.setValue(0, DATA_COL_PRICE, "Price ($)"); sheet.setValue(0, DATA_COL_STOCK, "Stock"); var headerStyle = new GC.Spread.Sheets.Style(); headerStyle.font = "bold 13px Calibri"; headerStyle.backColor = "#4a7a00"; headerStyle.foreColor = "#ffffff"; headerStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center; headerStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; for (var h = 0; h <= 4; h++) { sheet.setStyle(0, h, headerStyle); } // Always re-write all product rows from the in-memory array so data is never lost var centerStyle = new GC.Spread.Sheets.Style(); centerStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; centerStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center; var nameStyle = new GC.Spread.Sheets.Style(); nameStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center; for (var i = 0; i < allProducts.length; i++) { var p = allProducts[i]; var row = DATA_START_ROW + i; sheet.setValue(row, DATA_COL_NAME, p.name); sheet.setValue(row, DATA_COL_IMAGE, createImageRichData(p.imageBase64, p.name)); sheet.setValue(row, DATA_COL_PRICE, p.price); sheet.setValue(row, DATA_COL_STOCK, p.stock); sheet.setValue(row, DATA_COL_AREA, p.area); sheet.setStyle(row, DATA_COL_NAME, nameStyle); sheet.setStyle(row, DATA_COL_IMAGE, centerStyle); sheet.setStyle(row, DATA_COL_PRICE, centerStyle); sheet.setStyle(row, DATA_COL_STOCK, centerStyle); sheet.setStyle(row, DATA_COL_AREA, centerStyle); } var table = sheet.tables.add( TABLE_NAME, 0, // start row 0, // start col allProducts.length + 1, // header + data rows 5 // col count ); table.style(GC.Spread.Sheets.Tables.TableThemes.light6); } function bindEvents() { var nameInput = document.getElementById("productName"); var fileInput = document.getElementById("productImageFile"); var uploadLabel = document.getElementById("imageUploadLabel"); var uploadText = document.getElementById("imageUploadText"); var previewWrap = document.getElementById("imagePreviewWrap"); var previewImg = document.getElementById("imagePreview"); var clearBtn = document.getElementById("imageClearBtn"); var base64Input = document.getElementById("productImageBase64"); var uploadGroup = document.getElementById("imageUploadGroup"); function setPreview(base64) { base64Input.value = base64; previewImg.src = base64; previewWrap.style.display = "inline-block"; uploadLabel.style.display = "none"; } function clearPreview() { base64Input.value = ""; previewImg.src = ""; previewWrap.style.display = "none"; fileInput.value = ""; uploadLabel.style.display = ""; uploadLabel.classList.remove("locked"); uploadText.textContent = "Click to upload image"; // Remove locked notice if present var notice = uploadGroup.querySelector(".image-locked-notice"); if (notice) notice.remove(); } // Product name input: check if name matches an existing product nameInput.addEventListener("input", function () { var key = nameInput.value.trim().toLowerCase(); var existing = productNameImageMap[key]; if (existing) { // Lock image to the existing product's image setPreview(existing); uploadLabel.classList.add("locked"); uploadText.textContent = "Image locked (existing product)"; clearBtn.style.display = "none"; if (!uploadGroup.querySelector(".image-locked-notice")) { var notice = document.createElement("p"); notice.className = "image-locked-notice"; notice.textContent = "Image is auto-filled from existing product."; uploadGroup.appendChild(notice); } } else { // Not an existing product — allow normal upload uploadLabel.classList.remove("locked"); clearBtn.style.display = ""; var notice = uploadGroup.querySelector(".image-locked-notice"); if (notice) notice.remove(); // If the current preview came from a lock, clear it if (uploadLabel.style.display === "none" && base64Input.value) { // keep user's uploaded image if they already uploaded } } }); // File upload: read as base64 and preview fileInput.addEventListener("change", function () { var file = fileInput.files[0]; if (!file) return; var reader = new FileReader(); reader.onload = function (e) { setPreview(e.target.result); }; reader.readAsDataURL(file); }); // Clear image button clearBtn.addEventListener("click", function (e) { e.stopPropagation(); clearPreview(); }); // Add product button document.getElementById("btnAddProduct").addEventListener("click", function () { var name = nameInput.value.trim(); var imageBase64 = base64Input.value; var price = parseFloat(document.getElementById("productPrice").value); var stock = parseInt(document.getElementById("productStock").value, 10); var area = document.getElementById("productArea").value; if (!name) { alert("Please enter a product name."); return; } if (!imageBase64) { alert("Please upload a product image."); return; } if (isNaN(price) || price <= 0) { alert("Please enter a valid price."); return; } if (isNaN(stock) || stock < 0) { alert("Please enter a valid stock quantity."); return; } spread.suspendPaint(); addProductRow({ name: name, imageBase64: imageBase64, price: price, stock: stock, area: area }); createDataTable(); spread.resumePaint(); // Clear inputs nameInput.value = ""; document.getElementById("productPrice").value = ""; document.getElementById("productStock").value = ""; clearPreview(); }); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> <div id="panelToggleBtn" class="panel-toggle-btn" title="Toggle Panel"> <span class="panel-toggle-icon"><span></span></span> </div> <div class="options-container"> <div class="panel-header"> <span class="panel-title">Image Rich Data</span> <span id="panelCollapseBtn" class="panel-collapse-btn" title="Collapse">&times;</span> </div> <div class="panel-section"> <div class="panel-section-title"> <span>Add Product</span> </div> <div class="panel-card"> <div class="form-group"> <label class="form-label" for="productName">Product Name</label> <input id="productName" class="form-input" type="text" placeholder="e.g. Tablet" /> </div> <div class="form-group" id="imageUploadGroup"> <label class="form-label">Product Image</label> <label id="imageUploadLabel" class="image-upload-label" for="productImageFile"> <span id="imageUploadText">Click to upload image</span> <input id="productImageFile" type="file" accept="image/*" style="display:none;" /> </label> <div id="imagePreviewWrap" class="image-preview-wrap" style="display:none;"> <img id="imagePreview" class="image-preview" src="" alt="preview" /> <button id="imageClearBtn" class="image-clear-btn" type="button" title="Remove image">&times;</button> </div> <input id="productImageBase64" type="hidden" value="" /> </div> <div class="form-group"> <label class="form-label" for="productPrice">Product Price ($)</label> <input id="productPrice" class="form-input" type="number" placeholder="e.g. 999" /> </div> <div class="form-group"> <label class="form-label" for="productStock">Product Stock</label> <input id="productStock" class="form-input" type="number" placeholder="e.g. 50" /> </div> <div class="form-group"> <label class="form-label" for="productArea">Product Area</label> <select id="productArea" class="form-select"> <option value="Asia-Pacific">Asia-Pacific</option> <option value="Europe">Europe</option> <option value="North America">North America</option> <option value="Middle East">Middle East</option> <option value="Latin America">Latin America</option> </select> </div> <div class="panel-actions"> <button id="btnAddProduct" class="btn btn-primary">Add Product</button> </div> </div> </div> <div class="panel-section"> <div class="panel-section-title"> <span>Info</span> </div> <div class="panel-info"> <p>This demo uses <code>IImageRichData</code> to set image cell values via <code>setValue</code>.</p> <p>Click <strong>Add Product</strong> to append a new product row to the table.</p> </div> </div> </div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; } .options-container { position: absolute; top: 0; right: 0; width: 400px; height: 100%; box-sizing: border-box; background: #fff; overflow-y: auto; overflow-x: hidden; z-index: 1000; box-shadow: -2px 0 12px rgba(0, 0, 0, 0.10); transition: transform 0.3s ease; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 13px; color: #333; } .options-container.collapsed { transform: translateX(100%); } .panel-toggle-btn { position: absolute; top: 8px; right: 8px; z-index: 999; width: 36px; height: 36px; background: #4a7a00; border-radius: 8px; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(74, 122, 0, 0.3); transition: background 0.2s; } .panel-toggle-btn:hover { background: #3d6b00; } .panel-toggle-btn.visible { display: flex; } .panel-toggle-icon { width: 18px; height: 14px; display: flex; flex-direction: column; justify-content: space-between; } .panel-toggle-icon::before, .panel-toggle-icon::after, .panel-toggle-icon span { content: ''; display: block; height: 2px; background: #fff; border-radius: 1px; } .options-container .panel-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid #e8e8e8; background: #fff; position: sticky; top: 0; z-index: 2; } .options-container .panel-title { font-weight: 600; font-size: 15px; color: #1a1a1a; } .options-container .panel-collapse-btn { cursor: pointer; font-size: 20px; color: #999; width: 28px; height: 28px; line-height: 28px; text-align: center; border-radius: 6px; user-select: none; transition: all 0.15s; } .options-container .panel-collapse-btn:hover { background: #f0f0f0; color: #333; } .options-container .panel-section { padding: 12px 16px; border-bottom: 1px solid #f0f0f0; } .options-container .panel-section:last-child { border-bottom: none; } .options-container .panel-section-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; font-weight: 600; font-size: 13px; color: #555; text-transform: uppercase; letter-spacing: 0.3px; } .options-container .panel-card { background: #fafafa; border: 1px solid #e8e8e8; border-radius: 8px; padding: 14px; } .options-container .form-group { margin-bottom: 12px; } .options-container .form-group:last-of-type { margin-bottom: 0; } .options-container .form-group-inline { display: flex; align-items: center; } .options-container .form-group-inline .form-label { display: inline-block; width: 100px; min-width: 100px; margin-bottom: 0; padding: 0 4px; box-sizing: border-box; } .options-container .form-group-inline .form-select { flex: 1; margin-left: 8px; } .options-container .form-label { display: block; font-size: 12px; font-weight: 500; color: #666; margin-bottom: 4px; } .options-container .form-select { width: 100%; height: 32px; padding: 0 8px; border: 1px solid #d0d0d0; border-radius: 6px; background: #fff; font-size: 13px; color: #333; outline: none; box-sizing: border-box; transition: border-color 0.15s; cursor: pointer; } .options-container .form-select:focus { border-color: #4a7a00; box-shadow: 0 0 0 2px rgba(74, 122, 0, 0.15); } .options-container .form-input { width: 100%; height: 32px; padding: 0 8px; border: 1px solid #d0d0d0; border-radius: 6px; background: #fff; font-size: 13px; color: #333; outline: none; box-sizing: border-box; transition: border-color 0.15s; } .options-container .form-input:focus { border-color: #4a7a00; box-shadow: 0 0 0 2px rgba(74, 122, 0, 0.15); } .options-container .image-upload-label { display: flex; align-items: center; justify-content: center; width: 100%; height: 64px; border: 2px dashed #d0d0d0; border-radius: 6px; background: #fafafa; cursor: pointer; transition: border-color 0.15s, background 0.15s; box-sizing: border-box; font-size: 12px; color: #999; } .options-container .image-upload-label:hover { border-color: #4a7a00; background: #f0f7e6; color: #4a7a00; } .options-container .image-upload-label.locked { cursor: not-allowed; opacity: 0.6; pointer-events: none; } .options-container .image-preview-wrap { position: relative; display: inline-block; margin-top: 6px; width: 100%; } .options-container .image-preview { display: block; width: 64px; height: 64px; object-fit: contain; border: 1px solid #e8e8e8; border-radius: 6px; background: #f5f5f5; } .options-container .image-clear-btn { position: absolute; top: -6px; left: 52px; width: 18px; height: 18px; border-radius: 50%; border: none; background: #e74c3c; color: #fff; font-size: 13px; line-height: 18px; text-align: center; cursor: pointer; padding: 0; } .options-container .image-clear-btn:hover { background: #c0392b; } .options-container .image-locked-notice { font-size: 11px; color: #888; margin-top: 4px; font-style: italic; } .options-container .panel-actions { margin-top: 14px; display: flex; gap: 8px; } .options-container .btn { height: 34px; padding: 0 16px; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.15s; white-space: nowrap; } .options-container .btn-primary { background: #4a7a00; color: #fff; flex: 1; } .options-container .btn-primary:hover { background: #3d6b00; } .options-container .btn-secondary { background: #f0f0f0; color: #333; border: 1px solid #d0d0d0; flex: 1; } .options-container .btn-secondary:hover { background: #e5e5e5; } .options-container .panel-info { font-size: 12px; color: #666; line-height: 1.5; } .options-container .panel-info p { margin: 0 0 8px 0; } .options-container .panel-info p:last-child { margin-bottom: 0; } .options-container .panel-info code { background: #f0f0f0; padding: 1px 4px; border-radius: 3px; font-size: 11px; color: #c7254e; }