<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Noobismatics Collection Entry</title>
<style>
:root {
/* High-contrast palette: Crisp off-white canvas with a touch of cash-green */
--bg-dark: #f2f7f4;
--panel-dark: #ffffff;
--border-color: #000000;
--accent-blue: #1e3a1f;
--text-light: #000000;
--text-muted: #4b5563;
--accent-green: #15803d;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background-color: var(--bg-dark);
color: var(--text-light);
padding: 2rem;
line-height: 1.5;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
header {
margin-bottom: 2rem;
border-bottom: 2px solid var(--border-color);
padding-bottom: 1.5rem;
text-align: center;
}
/* Macro Button Header Logo Link */
.logo-link {
display: inline-block;
cursor: pointer;
text-decoration: none;
transition: transform 0.1s ease, filter 0.1s ease;
}
.logo-link:hover {
transform: scale(1.02);
filter: drop-shadow(0px 4px 6px rgba(0,0,0,0.15));
}
.logo-link:active {
transform: scale(0.98);
}
.logo-img {
max-width: 100%;
height: auto;
max-height: 160px;
display: block;
}
/* Dynamic Catalog ID Banner */
.id-banner {
background-color: rgba(21, 128, 61, 0.08);
border: 2px solid var(--border-color);
padding: 1rem;
border-radius: 0.25rem;
margin-bottom: 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.id-label {
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
font-weight: bold;
}
.id-output {
font-family: monospace;
font-size: 1.6rem;
font-weight: bold;
color: var(--border-color);
}
/* Dashboard Grid Layout (STRICTLY handles form input panel boxes side-by-side) */
.dashboard-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
}
@media (max-width: 1024px) {
.dashboard-grid {
grid-template-columns: 1fr;
}
}
.panel {
background-color: var(--panel-dark);
border: 2px solid var(--border-color);
border-radius: 0.25rem;
padding: 2rem;
}
.panel-title {
font-size: 1.3rem;
font-weight: bold;
margin-bottom: 1.5rem;
color: var(--text-light);
border-bottom: 2px solid var(--border-color);
padding-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 0.02em;
}
/* Form Controls */
.form-group {
margin-bottom: 1.25rem;
}
label {
display: block;
font-size: 0.875rem;
font-weight: bold;
margin-bottom: 0.5rem;
color: var(--text-light);
text-transform: uppercase;
}
select, input[type="text"], input[type="number"] {
width: 100%;
padding: 0.75rem;
background-color: var(--panel-dark);
border: 2px solid var(--border-color);
border-radius: 0.25rem;
color: var(--text-light);
font-size: 1rem;
font-weight: 500;
}
select:focus, input:focus {
outline: none;
background-color: #ffffff;
}
/* Image Studio Grid */
.image-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-bottom: 1.5rem;
}
.image-uploader {
border: 2px dashed var(--border-color);
border-radius: 0.25rem;
padding: 1.5rem;
text-align: center;
background-color: #ffffff;
cursor: pointer;
position: relative;
min-height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.image-uploader:hover {
background-color: rgba(0, 0, 0, 0.02);
}
.image-uploader span {
display: block;
font-size: 0.875rem;
color: var(--text-muted);
margin-top: 0.5rem;
}
.slot-title {
font-weight: bold;
color: var(--text-light);
font-size: 0.9rem;
}
/* Dynamic Conditional Sections */
.dynamic-section {
background-color: rgba(0, 0, 0, 0.02);
border: 2px dashed var(--border-color);
padding: 1.25rem;
border-radius: 0.25rem;
margin-top: 1rem;
margin-bottom: 1rem;
display: none;
}
/* Errors Toggles Grid */
.toggle-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
gap: 0.75rem;
}
.toggle-btn {
display: block;
text-align: center;
background-color: var(--panel-dark);
border: 2px solid var(--border-color);
padding: 0.5rem;
border-radius: 0.25rem;
font-size: 0.875rem;
font-weight: bold;
cursor: pointer;
user-select: none;
}
.toggle-btn input {
display: none;
}
.toggle-btn:has(input:checked) {
background-color: rgba(21, 128, 61, 0.15);
color: var(--accent-green);
}
/* Custom Visual Divider Centering Component */
.divider-wrapper {
width: 100%;
text-align: center;
margin-top: 3rem;
margin-bottom: 2rem;
padding-top: 1rem;
clear: both;
}
/* Interactive Portal Link Styles for your "N" Logo */
.divider-link {
display: inline-block;
cursor: pointer;
text-decoration: none;
transition: transform 0.1s ease, filter 0.1s ease;
}
.divider-link:hover {
transform: scale(1.04);
filter: drop-shadow(0px 6px 8px rgba(0,0,0,0.2));
}
.divider-link:active {
transform: scale(0.96);
}
.divider-emblem {
max-width: 100%;
height: auto;
max-height: 180px;
display: block;
}
.submit-btn {
grid-column: span 2;
background-color: var(--border-color);
color: #ffffff;
border: none;
padding: 1rem;
border-radius: 0.25rem;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
width: 100%;
margin-top: 2rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.submit-btn:hover {
background-color: #222222;
}
@media (max-width: 1024px) {
.submit-btn {
grid-column: span 1;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<!-- Clickable Logo Macro -->
<a href="#" class="logo-link" onclick="event.preventDefault(); triggerFormSave();" title="Click to Save Entry & Start New">
<img src="/logo.png" alt="Noobismatics Logo" class="logo-img">
</a>
</header>
<!-- Dynamic ID Output Banner -->
<div class="id-banner">
<div>
<div class="id-label">Generated Catalog Inventory ID</div>
<div class="id-output" id="catalogIdOutput">US-XXXX-XXXX-XXXX-X-001</div>
</div>
</div>
<!-- The core input form columns -->
<form id="coinForm" class="dashboard-grid">
<!-- LEFT PANEL: Identification & Photo Studio -->
<div class="panel">
<div class="panel-title">1. Visual & Identification Hub</div>
<!-- Category -->
<div class="form-group">
<label for="category">Category</label>
<select id="category" required onchange="updateSubTypes(); updateCatalogID();">
<option value="COIN" selected>COIN</option>
<option value="CURRENCY">CURRENCY</option>
<option value="SILVER">SILVER</option>
<option value="INTERNATIONAL">INTERNATIONAL</option>
<option value="COMMEMORATIVE">COMMEMORATIVE</option>
<option value="OTHER">OTHER</option>
</select>
</div>
<!-- Parent Type -->
<div class="form-group">
<label for="parentType">Type (U.S. Denominations)</label>
<select id="parentType" required onchange="updateSubTypes(); updateCatalogID();">
<option value="">-- Select Type --</option>
<option value="1C">1 CENT</option>
<option value="5C">5 CENT</option>
<option value="10C">10 CENT</option>
<option value="25C">25 CENT</option>
<option value="50C">50 CENT</option>
<option value="1D">DOLLAR</option>
</select>
</div>
<!-- Sub-Type Layout Block -->
<div class="form-group">
<label for="subType">Sub-Type (Era / Design Series)</label>
<select id="subType" required onchange="handleSpecialFields(); updateCatalogID();">
<option value="">-- Choose Parent Type First --</option>
</select>
</div>
<!-- Photo Studio 4x Grid -->
<label style="margin-top: 1.5rem; display: block;">Coin Photo Studio (4x Views)</label>
<div class="image-grid">
<div class="image-uploader" data-slot="obverse">
<div class="slot-title">Obverse</div>
<span>[ Front Side ]</span>
</div>
<div class="image-uploader" data-slot="reverse">
<div class="slot-title">Reverse</div>
<span>[ Back Side ]</span>
</div>
<div class="image-uploader" data-slot="edge">
<div class="slot-title">Edge</div>
<span>[ Rim Profile ]</span>
</div>
<div class="image-uploader" data-slot="slab">
<div class="slot-title">Slab / Detail</div>
<span>[ Close-up / Tag ]</span>
</div>
</div>
<!-- Standard Varieties Block -->
<div class="form-group">
<label for="strikeType">Strike / Finish Type</label>
<select id="strikeType" onchange="updateCatalogID();">
<option value="BS">Business Strike (Circulating)</option>
<option value="PR">Proof (PR / PF)</option>
<option value="SMS">Special Mint Set (SMS)</option>
</select>
</div>
<div class="form-group">
<label for="toning">Toning / Eye Appeal Finish</label>
<select id="toning">
<option value="untoned">Untoned (Blazing / Brilliant)</option>
<option value="light">Lightly Toned</option>
<option value="monster">Beautifully Toned (Monster Toned)</option>
<option value="questionable">Artificial / Questionable</option>
</select>
</div>
</div>
<!-- RIGHT PANEL: Specs, Grades, and Errors -->
<div class="panel">
<div class="panel-title">2. Collection Specs & Error Desk</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div class="form-group">
<label for="coinYear">Year</label>
<input type="text" id="coinYear" placeholder="e.g., 1938" oninput="updateCatalogID();">
</div>
<div class="form-group">
<label for="mintMark">Mint Office</label>
<select id="mintMark" onchange="updateCatalogID();">
<option value="P">P (Philadelphia)</option>
<option value="D">D (Denver)</option>
<option value="S">S (San Francisco)</option>
<option value="W">W (West Point)</option>
<option value="O">O (New Orleans)</option>
<option value="CC">CC (Carson City)</option>
<option value="Plain">No Mint Mark (Plain)</option>
</select>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div class="form-group">
<label for="gradingCompany">Grading Service</label>
<select id="gradingCompany">
<option value="RAW">Raw / Uncertified</option>
<option value="PCGS">PCGS</option>
<option value="NGC">NGC</option>
<option value="ANACS">ANACS</option>
<option value="ICG">ICG</option>
</select>
</div>
<div class="form-group">
<label for="numericGrade">Sheldon Grade (1-70)</label>
<input type="number" id="numericGrade" min="1" max="70" placeholder="e.g., 65">
</div>
</div>
<!-- Hidden Nickel Block -->
<div class="dynamic-section" id="nickelSection">
<label for="fullSteps">Jefferson Strike Designation</label>
<select id="fullSteps">
<option value="standard">Standard / No Steps</option>
<option value="5FS">5 Full Steps (5FS)</option>
<option value="6FS">6 Full Steps (6FS)</option>
</select>
</div>
<!-- Hidden Dime Block -->
<div class="dynamic-section" id="dimeSection">
<label for="fullBands">Dime Split-Band Designation</label>
<select id="fullBands">
<option value="standard">Standard Strike</option>
<option value="FB">Full Bands (FB)</option>
</select>
</div>
<!-- Hidden Quarter Block -->
<div class="dynamic-section" id="quarterSection">
<label for="quarterType">Quarter Design Modification</label>
<select id="quarterType">
<option value="standard">Standard / Not Applicable</option>
<option value="T1">Type 1</option>
<option value="T2">Type 2</option>
</select>
</div>
<!-- Hidden Memorial Penny Block -->
<div class="dynamic-section" id="pennySection">
<label>Lincoln Memorial Specific Varieties</label>
<div class="toggle-grid" style="margin-top: 0.5rem;">
<label class="toggle-btn">
<input type="checkbox" id="floatingRoof"> Floating Roof
</label>
<label class="toggle-btn">
<input type="checkbox" id="noFG"> No FG Error
</label>
</div>
</div>
<!-- Shared General Errors Section -->
<div class="form-group">
<label style="margin-top: 1.5rem; display: block;">Errors & Planchet Oddities</label>
<div class="toggle-grid" style="margin-top: 0.5rem;">
<label class="toggle-btn">
<input type="checkbox" id="errDoubleDie"> Double Die
</label>
<label class="toggle-btn">
<input type="checkbox" id="errOffset"> Offset Striking
</label>
<label class="toggle-btn">
<input type="checkbox" id="errStrikethrough"> Strikethrough
</label>
<label class="toggle-btn">
<input type="checkbox" id="errLimited"> Limited Issue
</label>
</div>
</div>
</div>
<button type="submit" class="submit-btn">Process and Catalog New Entry</button>
</form> <!-- INPUT BLOCK RECTANGLE CLOSES PERMANENTLY HERE -->
<!-- VISUAL DIVIDER SECTION: Houses your interactive link to the search ledger -->
<div class="divider-wrapper">
<a href="/ledger.html" target="_blank" class="divider-link" title="Open Advanced Search Ledger Database in New Tab">
<img src="/divider.png" alt="Noobismatics Emblem" class="divider-emblem">
</a>
</div>
</div>
<script>
const subTypeData = {
"1C": [
{ code: "IND", name: "Indian Head Cent" },
{ code: "WHT", name: "Lincoln Wheat Cent" },
{ code: "MEM", name: "Lincoln Memorial Cent" },
{ code: "BIC", name: "Lincoln Bicentennial Cent" },
{ code: "SHL", name: "Lincoln Shield Cent" }
],
"5C": [
{ code: "VNK", name: "Liberty Head V Nickel" },
{ code: "BUF", name: "Buffalo Nickel" },
{ code: "JEF", name: "Jefferson Nickel (Base)" },
{ code: "WAR", name: "Jefferson Wartime Silver" },
{ code: "WJR", name: "Jefferson Westward Journey" },
{ code: "FWD", name: "Jefferson Forward Facing" }
],
"10C": [
{ code: "BAR", name: "Liberty Head Barber Dime" },
{ code: "MERC", name: "Mercury Dime" },
{ code: "SLV", name: "Roosevelt Dime (Silver)" },
{ code: "CLD", name: "Roosevelt Dime (Clad)" }
],
"25C": [
{ code: "BAR", name: "Liberty Head Barber Quarter" },
{ code: "STLB", name: "Standing Liberty Quarter" },
{ code: "WASH", name: "Washington Quarter (Silver)" },
{ code: "WCLD", name: "Washington Quarter (Clad)" },
{ code: "STAT", name: "50 State Quarters" },
{ code: "TERR", name: "DC & US Territories" },
{ code: "ATB", name: "America the Beautiful" },
{ code: "DEL", name: "Washington Crossing Delaware" },
{ code: "AMW", name: "American Women Quarters" },
{ code: "SEMI", name: "Semiquincentennial Series" }
],
"50C": [
{ code: "BAR", name: "Liberty Head Barber Half" },
{ code: "WALK", name: "Walking Liberty Half" },
{ code: "FRNK", name: "Franklin Half Dollar" },
{ code: "K90", name: "Kennedy Half (90% Silver)" },
{ code: "K40", name: "Kennedy Half (40% Silver)" },
{ code: "KCLD", name: "Kennedy Half (Clad)" }
],
"1D": [
{ code: "MORG", name: "Morgan Dollar" },
{ code: "PEAC", name: "Peace Dollar" },
{ code: "IKE", name: "Eisenhower Dollar" },
{ code: "SBA", name: "Susan B. Anthony Dollar" },
{ code: "SACA", name: "Sacagawea / Native American" },
{ code: "PRES", name: "Presidential Dollar" },
{ code: "INNO", name: "American Innovation Dollar" }
]
};
// Temporary session buffers to retain base64 image strings until submission
let currentUploadedImages = {
obverse: "",
reverse: "",
edge: "",
slab: ""
};
let savedInventory = JSON.parse(localStorage.getItem("noobismatics_db")) || [];
let activeCounter = savedInventory.length + 1;
function updateSubTypes() {
const parentType = document.getElementById("parentType").value;
const subTypeSelect = document.getElementById("subType");
subTypeSelect.innerHTML = "";
if (!parentType || !subTypeData[parentType]) {
const opt = document.createElement("option");
opt.textContent = "-- Choose Parent Type First --";
opt.value = "";
subTypeSelect.appendChild(opt);
handleSpecialFields();
return;
}
subTypeData[parentType].forEach(item => {
const opt = document.createElement("option");
opt.value = item.code;
opt.textContent = item.name;
subTypeSelect.appendChild(opt);
});
handleSpecialFields();
}
function handleSpecialFields() {
const parentType = document.getElementById("parentType").value;
const subType = document.getElementById("subType").value;
document.getElementById("nickelSection").style.display = "none";
document.getElementById("dimeSection").style.display = "none";
document.getElementById("quarterSection").style.display = "none";
document.getElementById("pennySection").style.display = "none";
if (parentType === "5C") {
document.getElementById("nickelSection").style.display = "block";
} else if (parentType === "10C") {
document.getElementById("dimeSection").style.display = "block";
} else if (parentType === "25C") {
document.getElementById("quarterSection").style.display = "block";
} else if (parentType === "1C" && subType === "MEM") {
document.getElementById("pennySection").style.display = "block";
}
}
function updateCatalogID() {
const category = document.getElementById("category").value.substring(0, 2);
const type = document.getElementById("parentType").value || "XX";
const subType = document.getElementById("subType").value || "XXXX";
const year = document.getElementById("coinYear").value || "XXXX";
const mint = document.getElementById("mintMark").value || "X";
const strike = document.getElementById("strikeType").value || "BS";
const padCounter = String(activeCounter).padStart(3, '0');
const compiledID = `${category}-${type}-${subType}-${year}-${mint}-${strike}-${padCounter}`;
document.getElementById("catalogIdOutput").textContent = compiledID.toUpperCase();
return compiledID.toUpperCase();
}
function triggerFormSave() {
const form = document.getElementById("coinForm");
if (form.reportValidity()) {
form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
}
}
// Functional Image File Upload Logic Engine mapped to object buffer states
document.querySelectorAll('.image-uploader').forEach(uploader => {
const slotType = uploader.getAttribute('data-slot');
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.style.display = 'none';
uploader.appendChild(fileInput);
uploader.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', function() {
if (this.files && this.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
uploader.style.backgroundImage = `url('${e.target.result}')`;
uploader.style.backgroundSize = 'cover';
uploader.style.backgroundPosition = 'center';
uploader.querySelectorAll('span, div.slot-title').forEach(s => s.style.visibility = 'hidden');
// Buffer base64 data for form submission payload mapping
currentUploadedImages[slotType] = e.target.result;
}
reader.readAsDataURL(this.files[0]);
}
});
});
document.getElementById("coinForm").addEventListener("submit", function(event) {
event.preventDefault();
const finalId = updateCatalogID();
const cat = document.getElementById("category").value;
const pType = document.getElementById("parentType").options[document.getElementById("parentType").selectedIndex].text;
const sType = document.getElementById("subType").options[document.getElementById("subType").selectedIndex].text;
const gradCo = document.getElementById("gradingCompany").value;
const numGrad = document.getElementById("numericGrade").value || "Raw";
const fullGradeSpec = `${gradCo}-${numGrad}`;
let specialTraits = [];
if(document.getElementById("parentType").value === "5C") {
const fs = document.getElementById("fullSteps").value;
if(fs !== "standard") specialTraits.push(fs);
}
if(document.getElementById("parentType").value === "10C") {
const fb = document.getElementById("fullBands").value;
if(fb !== "standard") specialTraits.push(fb);
}
if(document.getElementById("parentType").value === "25C") {
const qt = document.getElementById("quarterType").value;
if(qt !== "standard") specialTraits.push(qt);
}
if(document.getElementById("parentType").value === "1C" && document.getElementById("subType").value === "MEM") {
if(document.getElementById("floatingRoof").checked) specialTraits.push("Floating Roof");
if(document.getElementById("noFG").checked) specialTraits.push("No FG");
}
if(document.getElementById("errDoubleDie").checked) specialTraits.push("DDO/DDR");
if(document.getElementById("errOffset").checked) specialTraits.push("Offset");
if(document.getElementById("errStrikethrough").checked) specialTraits.push("Strikethrough");
if(document.getElementById("errLimited").checked) specialTraits.push("Limited");
const traitString = specialTraits.length > 0 ? specialTraits.join(", ") : "None/Standard";
const coinEntry = {
id: finalId,
category: cat,
parentType: pType,
subType: sType,
grade: fullGradeSpec,
traits: traitString,
images: { ...currentUploadedImages } // Commit current view states to storage entry
};
savedInventory.push(coinEntry);
localStorage.setItem("noobismatics_db", JSON.stringify(savedInventory));
activeCounter++;
document.getElementById("coinForm").reset();
// Clean slate image resets
document.querySelectorAll('.image-uploader').forEach(up => {
up.style.backgroundImage = 'none';
up.querySelectorAll('span, div.slot-title').forEach(s => s.style.visibility = 'visible');
});
currentUploadedImages = { obverse: "", reverse: "", edge: "", slab: "" };
updateCatalogID();
handleSpecialFields();
alert("Entry with Photo Assets Saved Permanently to Cache Database Ledger!");
});
updateCatalogID();
</script>
</body>
</html>