Compare commits

...

4 Commits

Author SHA1 Message Date
Cal Corum
20697585de docs: update diamond tier colors — green/blue/red/purple progression
T1 dark green (#1a6b1a), T2 light blue (#2070b0), T3 red (#a82020),
T4 regal purple (#6b2d8e). Cal approved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:19:17 -05:00
Cal Corum
07e8da1935 docs: restore original diamond with bloom/metallic/shadow effects
Recovered the diamondEffect feature (bloom, metallic, border, shadow,
escalation) from session logs and applied to the original quad-based
diamond design. All 12 edits from the effects subagent applied cleanly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:13:13 -05:00
Cal Corum
9990743357 docs: baseball diamond with CSS-based bases preserving bloom/shine effects
Replaces SVG polygon approach with CSS divs so inset box-shadows,
gradient fills, and glow animations are preserved from the original
implementation. Outer container rotated 45deg = diamond outline,
4 child divs positioned at cardinal points = base diamonds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:07:03 -05:00
Cal Corum
251eb1b05a docs: replace diamond indicator with baseball-diamond SVG design
Replaces the rotated 2x2 CSS grid diamond with an SVG baseball diamond
containing 4 small diamond-shaped bases at 1B/2B/3B/Home positions.
Fill order: east(1B) → north(2B) → west(3B) → south(Home).
Keeps all existing controls and tier preset properties intact.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:00:19 -05:00
2 changed files with 832 additions and 24 deletions

View File

@ -0,0 +1,810 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paper Dynasty — Card Cosmetics Explorer</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;700&family=Source+Sans+3:wght@400;700&display=swap');
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: #0e0e12;
color: #ccc;
display: flex;
height: 100vh;
overflow: hidden;
}
/* ── Controls Panel ── */
#controls {
width: 340px;
min-width: 340px;
background: #16161e;
border-right: 1px solid #2a2a3a;
overflow-y: auto;
padding: 16px;
}
#controls h1 {
font-size: 16px;
color: #fff;
margin-bottom: 4px;
letter-spacing: 0.5px;
}
#controls .subtitle {
font-size: 11px;
color: #666;
margin-bottom: 16px;
}
.control-group {
margin-bottom: 18px;
}
.control-group h3 {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1px;
color: #888;
margin-bottom: 8px;
border-bottom: 1px solid #2a2a3a;
padding-bottom: 4px;
}
.control-group label {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
transition: background 0.15s;
}
.control-group label:hover {
background: #1e1e2e;
}
.control-group label.active-option {
background: #1e1e2e;
color: #fff;
}
input[type="radio"] {
accent-color: #6c8aff;
}
input[type="color"] {
width: 28px;
height: 22px;
border: 1px solid #444;
border-radius: 3px;
background: none;
cursor: pointer;
padding: 0;
}
.color-row {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
font-size: 13px;
}
.presets {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 16px;
}
.preset-btn {
padding: 5px 10px;
font-size: 11px;
background: #1e1e2e;
color: #aaa;
border: 1px solid #333;
border-radius: 4px;
cursor: pointer;
transition: all 0.15s;
}
.preset-btn:hover {
background: #2a2a3e;
color: #fff;
border-color: #555;
}
/* ── Preview Area ── */
#preview-area {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 24px;
background: #111118;
overflow: hidden;
}
#card-wrapper {
width: 100%;
max-width: 900px;
aspect-ratio: 2 / 1;
position: relative;
}
/* ── The Card ── */
#fullCard {
width: 1200px;
height: 600px;
transform-origin: top left;
position: absolute;
top: 0;
left: 0;
font-family: "Open Sans", sans-serif;
font-weight: 400;
overflow: hidden;
background: #fff;
transition: box-shadow 0.3s, border 0.3s, outline 0.3s;
}
/* Card internals — matching the real template */
.row-wrapper {
width: 100%;
flex-grow: 1;
display: flex;
flex-direction: row;
}
.vline { border-left: 3px solid black; height: 100%; }
.header-text { font-size: 25px; text-align: left; }
.column-num {
display: flex;
height: 100%;
justify-content: center;
align-items: center;
font-weight: 700;
font-size: 20px;
color: #fff;
}
.border-bot { border-bottom: 3px solid black; }
.border-right-thick { border-right: 5px solid black; }
.border-right-thin { border-right: 3px solid black; }
.blue-gradient {
background-image: linear-gradient(to right, rgba(0,156,224,1), rgba(0,156,224,0.5), rgba(0,156,224,1));
}
.red-gradient {
background-image: linear-gradient(to right, rgba(211,49,21,1), rgba(211,49,21,0.5), rgba(211,49,21,1));
}
.result {
font-family: 'Source Sans 3', sans-serif;
font-size: 26px;
line-height: 1.3;
}
.result-row {
display: flex;
width: 200px;
padding: 0 4px;
}
.result-2d6 { width: 35px; text-align: right; font-weight: 700; }
.result-col { flex: 1; padding-left: 4px; }
.result-d20 { width: 65px; text-align: right; }
.center { display: block; margin-left: auto; margin-right: auto; }
#header {
transition: background 0.3s;
}
/* Rarity badge SVG area */
.rarity-badge {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
height: 100%;
}
.rarity-badge-img {
height: 50px;
padding: 4px 12px;
border-radius: 6px;
font-size: 18px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 1px;
text-transform: uppercase;
}
.evo-badge {
font-size: 24px;
display: none;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
font-weight: 700;
transition: all 0.3s;
}
/* Gradient bar overrides */
.gold-gradient {
background-image: linear-gradient(to right, rgba(218,165,32,1), rgba(218,165,32,0.5), rgba(218,165,32,1)) !important;
}
.dark-gradient {
background-image: linear-gradient(to right, rgba(40,40,50,1), rgba(40,40,50,0.6), rgba(40,40,50,1)) !important;
color: #ccc;
}
/* Holographic frame animation */
@keyframes holoShift {
0% { border-color: #ff0000; box-shadow: 0 0 12px #ff000066; }
16% { border-color: #ff8800; box-shadow: 0 0 12px #ff880066; }
33% { border-color: #ffff00; box-shadow: 0 0 12px #ffff0066; }
50% { border-color: #00ff44; box-shadow: 0 0 12px #00ff4466; }
66% { border-color: #0088ff; box-shadow: 0 0 12px #0088ff66; }
83% { border-color: #aa00ff; box-shadow: 0 0 12px #aa00ff66; }
100% { border-color: #ff0000; box-shadow: 0 0 12px #ff000066; }
}
@keyframes subtlePulse {
0%, 100% { box-shadow: 0 0 8px 2px var(--glow-color); }
50% { box-shadow: 0 0 16px 6px var(--glow-color); }
}
@keyframes strongPulse {
0%, 100% { box-shadow: 0 0 12px 4px var(--glow-color); }
50% { box-shadow: 0 0 28px 12px var(--glow-color); }
}
/* ── Prompt Output ── */
#prompt-area {
width: 100%;
max-width: 900px;
margin-top: 16px;
}
#prompt-output {
background: #1a1a24;
border: 1px solid #2a2a3a;
border-radius: 6px;
padding: 12px 16px;
font-size: 13px;
font-family: 'SF Mono', 'Fira Code', monospace;
color: #aaa;
line-height: 1.5;
min-height: 48px;
position: relative;
}
#copy-btn {
position: absolute;
top: 8px;
right: 8px;
padding: 4px 10px;
font-size: 11px;
background: #2a2a3e;
color: #888;
border: 1px solid #444;
border-radius: 3px;
cursor: pointer;
}
#copy-btn:hover { background: #3a3a4e; color: #ccc; }
#prompt-area { position: relative; }
</style>
</head>
<body>
<!-- ══════════ CONTROLS ══════════ -->
<div id="controls">
<h1>Card Cosmetics Explorer</h1>
<p class="subtitle">Paper Dynasty — Evolution Visual System</p>
<div class="presets">
<button class="preset-btn" onclick="applyPreset('default')">Default</button>
<button class="preset-btn" onclick="applyPreset('prestige')">Prestige Gold</button>
<button class="preset-btn" onclick="applyPreset('dark')">Dark Mode</button>
<button class="preset-btn" onclick="applyPreset('midnight')">Midnight</button>
<button class="preset-btn" onclick="applyPreset('holo')">Holographic</button>
<button class="preset-btn" onclick="applyPreset('evolved')">Fully Evolved</button>
</div>
<div class="control-group">
<h3>Frame</h3>
<label><input type="radio" name="frame" value="none" checked onchange="update()"> None</label>
<label><input type="radio" name="frame" value="gold" onchange="update()"> Gold Frame</label>
<label><input type="radio" name="frame" value="diamond" onchange="update()"> Diamond Frame</label>
<label><input type="radio" name="frame" value="team" onchange="update()"> Team Color Frame</label>
<label><input type="radio" name="frame" value="holo" onchange="update()"> Holographic Frame</label>
</div>
<div class="control-group">
<h3>Header Background</h3>
<label><input type="radio" name="headerBg" value="default" checked onchange="update()"> Default (white)</label>
<label><input type="radio" name="headerBg" value="dark" onchange="update()"> Dark Mode</label>
<label><input type="radio" name="headerBg" value="gold" onchange="update()"> Metallic Gold</label>
<label><input type="radio" name="headerBg" value="team" onchange="update()"> Team Color</label>
</div>
<div class="control-group">
<h3>Column Backgrounds</h3>
<label><input type="radio" name="colBg" value="default" checked onchange="update()"> Default (blue / salmon)</label>
<label><input type="radio" name="colBg" value="dark" onchange="update()"> Dark Mode</label>
<label><input type="radio" name="colBg" value="midnight" onchange="update()"> Midnight</label>
<label><input type="radio" name="colBg" value="cream" onchange="update()"> Cream</label>
<label><input type="radio" name="colBg" value="team" onchange="update()"> Team Themed</label>
</div>
<div class="control-group">
<h3>Gradient Bars</h3>
<label><input type="radio" name="gradBars" value="default" checked onchange="update()"> Default (blue / red)</label>
<label><input type="radio" name="gradBars" value="gold" onchange="update()"> Gold / Gold</label>
<label><input type="radio" name="gradBars" value="dark" onchange="update()"> Dark</label>
<label><input type="radio" name="gradBars" value="match" onchange="update()"> Match Column Bg</label>
</div>
<div class="control-group">
<h3>Evolution Badge</h3>
<label><input type="radio" name="evoBadge" value="none" checked onchange="update()"> None</label>
<label><input type="radio" name="evoBadge" value="t1" onchange="update()"> T1 — Initiate</label>
<label><input type="radio" name="evoBadge" value="t2" onchange="update()"> T2 — Rising</label>
<label><input type="radio" name="evoBadge" value="t3" onchange="update()"> T3 — Ascendant</label>
<label><input type="radio" name="evoBadge" value="t4" onchange="update()"> T4 — Evolved</label>
</div>
<div class="control-group">
<h3>Rarity Glow</h3>
<label><input type="radio" name="rarityGlow" value="none" checked onchange="update()"> None</label>
<label><input type="radio" name="rarityGlow" value="subtle" onchange="update()"> Subtle Pulse</label>
<label><input type="radio" name="rarityGlow" value="strong" onchange="update()"> Strong Pulse</label>
</div>
<div class="control-group">
<h3>Team Color</h3>
<div class="color-row">
<input type="color" id="teamColor" value="#003831" onchange="update()">
<span style="font-size: 13px;">Team primary color</span>
</div>
<div style="display: flex; gap: 4px; padding: 4px 8px; flex-wrap: wrap; margin-top: 4px;">
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#003831')">OAK</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#C41E3A')">STL</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#003278')">LAD</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#132448')">NYY</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#BD3039')">LAA</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#002D62')">HOU</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#E81828')">CIN</button>
<button class="preset-btn" style="font-size:10px;padding:3px 6px" onclick="setTeamColor('#0E3386')">NYM</button>
</div>
</div>
</div>
<!-- ══════════ PREVIEW ══════════ -->
<div id="preview-area">
<div id="card-wrapper">
<div id="fullCard">
<!-- HEADER -->
<div id="header" class="row-wrapper header-text border-bot" style="height: 65px;">
<div id="headerLeft" style="width: 477px; height: auto;">
<div class="row-wrapper" style="height: 100%;">
<div style="width: 29px; height: auto; font-size: 30px; margin-left: 6px; display:flex; align-items:center;">
<b>R</b>
</div>
<div class="vline"></div>
<div class="header-text" style="padding-left: 5px; width: 442px;">
<div style="height: 50%; font-variant: small-caps; font-size: 27px; padding-top: 4px;"><b>Mike Trout</b></div>
<div style="height: 50%; padding-left: 18px; font-size: 18px;">CF &nbsp; LF &nbsp; RF</div>
</div>
</div>
</div>
<div id="headerMiddle" style="width: 246px; height: auto; display: flex; align-items: center; justify-content: center;">
<div class="rarity-badge">
<div class="rarity-badge-img" id="rarityBadge" style="background: linear-gradient(135deg, #1a5276, #2e86c1); color: #fff;">
ALL-STAR
</div>
<div class="evo-badge" id="evoBadge"></div>
</div>
</div>
<div id="headerRight" style="width: 477px; height: auto; text-align: right; position: relative;">
<div style="position: absolute; left: 228px; width: 320px; top: 8px;">stealing <b>A-12</b></div>
<div style="position: absolute; left: 563px; width: 150px; top: 8px;">running <b>14</b></div>
<div style="position: absolute; left: 443px; top: 35px; width: 120px;">bunting <b>B</b></div>
<div style="position: absolute; left: 583px; top: 35px; width: 130px;">hit &amp; run <b>A</b></div>
<div style="position: absolute; left: 283px; top: 42px; width: 140px; font-size: 14px;">2025 Live</div>
</div>
</div>
<!-- RESULT HEADERS -->
<div id="allResults" class="result">
<div id="resultHeader" class="row-wrapper border-bot" style="height: 30px;">
<div class="row-wrapper border-right-thick" style="width: 600px;">
<div id="gradL1" class="column-num border-right-thin blue-gradient" style="width: 200px;"><b>1</b></div>
<div id="gradL2" class="column-num border-right-thin blue-gradient" style="width: 200px;"><b>2</b></div>
<div id="gradL3" class="column-num blue-gradient" style="width: 200px;"><b>3</b></div>
</div>
<div class="row-wrapper" style="width: 600px;">
<div id="gradR1" class="column-num border-right-thin red-gradient" style="width: 200px;"><b>1</b></div>
<div id="gradR2" class="column-num border-right-thin red-gradient" style="width: 200px;"><b>2</b></div>
<div id="gradR3" class="column-num red-gradient" style="width: 200px;"><b>3</b></div>
</div>
</div>
<!-- RESULT BODY -->
<div id="resultWrapper" class="row-wrapper" style="height: 505px;">
<div id="vlSide" class="row-wrapper border-right-thick" style="width: 600px; background-color: #ACE6FF;">
<div class="border-right-thin" style="width: 200px;" id="vlCol1"></div>
<div class="border-right-thin" style="width: 200px;" id="vlCol2"></div>
<div style="width: 200px;" id="vlCol3"></div>
</div>
<div id="vrSide" class="row-wrapper" style="width: 600px; background-color: #EAA49C;">
<div class="border-right-thin" style="width: 200px;" id="vrCol1"></div>
<div class="border-right-thin" style="width: 200px;" id="vrCol2"></div>
<div style="width: 200px;" id="vrCol3"></div>
</div>
</div>
</div>
</div>
</div>
<div id="prompt-area">
<div id="prompt-output">
<span id="prompt-text">Default card — no cosmetics applied.</span>
<button id="copy-btn" onclick="copyPrompt()">Copy</button>
</div>
</div>
</div>
<script>
// ── Fake card data ──
const vlData = [
// col1, col2, col3
[
{d:'2',res:'HR',r:'1-2'},{d:'3',res:'3B',r:'3'},{d:'4',res:'DO**',r:'4-5'},
{d:'5',res:'DO*',r:'6'},{d:'6',res:'DO',r:'7-8'},{d:'7',res:'SI**',r:'9'},
{d:'8',res:'SI*',r:'10-11'},{d:'9',res:'SI',r:'12'},{d:'10',res:'W',r:'13-14'},
{d:'11',res:'HBP',r:'15'},{d:'12',res:'K',r:'16-20'},
],
[
{d:'2',res:'HR',r:'1'},{d:'3',res:'DO**',r:'2-3'},{d:'4',res:'DO*',r:'4-5'},
{d:'5',res:'DO',r:'6-7'},{d:'6',res:'SI**',r:'8-9'},{d:'7',res:'SI*',r:'10'},
{d:'8',res:'SI',r:'11-12'},{d:'9',res:'W',r:'13-14'},{d:'10',res:'W',r:'15'},
{d:'11',res:'K',r:'16-18'},{d:'12',res:'K',r:'19-20'},
],
[
{d:'2',res:'HR',r:'1'},{d:'3',res:'3B',r:'2'},{d:'4',res:'DO*',r:'3-4'},
{d:'5',res:'SI**',r:'5-7'},{d:'6',res:'SI*',r:'8-9'},{d:'7',res:'SI',r:'10-11'},
{d:'8',res:'W',r:'12-13'},{d:'9',res:'K',r:'14-15'},{d:'10',res:'LO',r:'16'},
{d:'11',res:'FO(a)',r:'17-18'},{d:'12',res:'GO(b)',r:'19-20'},
]
];
const vrData = [
[
{d:'2',res:'HR',r:'1'},{d:'3',res:'DO**',r:'2-3'},{d:'4',res:'DO*',r:'4'},
{d:'5',res:'DO',r:'5-6'},{d:'6',res:'SI*',r:'7-8'},{d:'7',res:'SI',r:'9-10'},
{d:'8',res:'W',r:'11-12'},{d:'9',res:'K',r:'13-15'},{d:'10',res:'K',r:'16-17'},
{d:'11',res:'FO(b)',r:'18-19'},{d:'12',res:'GO(a)',r:'20'},
],
[
{d:'2',res:'HR',r:'1'},{d:'3',res:'3B',r:'2'},{d:'4',res:'DO**',r:'3-4'},
{d:'5',res:'DO',r:'5-6'},{d:'6',res:'SI**',r:'7'},{d:'7',res:'SI*',r:'8-9'},
{d:'8',res:'SI',r:'10-11'},{d:'9',res:'W',r:'12-13'},{d:'10',res:'K',r:'14-16'},
{d:'11',res:'PO',r:'17-18'},{d:'12',res:'GO(c)',r:'19-20'},
],
[
{d:'2',res:'HR',r:'1-2'},{d:'3',res:'DO*',r:'3-4'},{d:'4',res:'DO',r:'5-6'},
{d:'5',res:'SI**',r:'7'},{d:'6',res:'SI*',r:'8-9'},{d:'7',res:'SI',r:'10-11'},
{d:'8',res:'W',r:'12'},{d:'9',res:'HBP',r:'13'},{d:'10',res:'K',r:'14-16'},
{d:'11',res:'FO(a)',r:'17-18'},{d:'12',res:'GO(b)',r:'19-20'},
]
];
function renderColumn(el, data, textColor) {
el.innerHTML = data.map(r =>
`<div style="display:flex;width:200px;padding:0 4px;color:${textColor}">
<div style="width:35px;text-align:right;font-weight:700">${r.d}</div>
<div style="flex:1;padding-left:6px">${r.res}</div>
<div style="width:65px;text-align:right">${r.r}</div>
</div>`
).join('');
}
function initColumns() {
renderColumn(document.getElementById('vlCol1'), vlData[0], '#000');
renderColumn(document.getElementById('vlCol2'), vlData[1], '#000');
renderColumn(document.getElementById('vlCol3'), vlData[2], '#000');
renderColumn(document.getElementById('vrCol1'), vrData[0], '#000');
renderColumn(document.getElementById('vrCol2'), vrData[1], '#000');
renderColumn(document.getElementById('vrCol3'), vrData[2], '#000');
}
// ── State ──
const DEFAULTS = {
frame: 'none', headerBg: 'default', colBg: 'default',
gradBars: 'default', evoBadge: 'none', rarityGlow: 'none',
teamColor: '#003831'
};
function getState() {
return {
frame: document.querySelector('input[name="frame"]:checked').value,
headerBg: document.querySelector('input[name="headerBg"]:checked').value,
colBg: document.querySelector('input[name="colBg"]:checked').value,
gradBars: document.querySelector('input[name="gradBars"]:checked').value,
evoBadge: document.querySelector('input[name="evoBadge"]:checked').value,
rarityGlow: document.querySelector('input[name="rarityGlow"]:checked').value,
teamColor: document.getElementById('teamColor').value,
};
}
function setTeamColor(c) {
document.getElementById('teamColor').value = c;
update();
}
// ── Rarity color for glow ──
const RARITY_COLOR = '#2e86c1'; // All-Star blue
// ── Update ──
function update() {
const s = getState();
const card = document.getElementById('fullCard');
const header = document.getElementById('header');
const vlSide = document.getElementById('vlSide');
const vrSide = document.getElementById('vrSide');
const badge = document.getElementById('evoBadge');
const gradLs = [document.getElementById('gradL1'), document.getElementById('gradL2'), document.getElementById('gradL3')];
const gradRs = [document.getElementById('gradR1'), document.getElementById('gradR2'), document.getElementById('gradR3')];
// Reset
card.style.border = 'none';
card.style.outline = 'none';
card.style.boxShadow = 'none';
card.style.animation = 'none';
card.style.setProperty('--glow-color', 'transparent');
// ── Frame ──
if (s.frame === 'gold') {
card.style.border = '6px solid #d4a017';
card.style.boxShadow = '0 0 18px 4px rgba(212,160,23,0.4)';
} else if (s.frame === 'diamond') {
card.style.border = '4px solid transparent';
card.style.backgroundClip = 'padding-box';
card.style.outline = '4px solid';
card.style.outlineColor = '#b8d4e3';
card.style.boxShadow = '0 0 12px 3px rgba(184,212,227,0.5), inset 0 0 8px rgba(184,212,227,0.2)';
} else if (s.frame === 'team') {
card.style.border = `6px solid ${s.teamColor}`;
card.style.boxShadow = `0 0 14px 3px ${s.teamColor}66`;
} else if (s.frame === 'holo') {
card.style.border = '5px solid #ff0000';
card.style.animation = 'holoShift 3s linear infinite';
}
// ── Rarity Glow (layered on top of frame) ──
if (s.rarityGlow !== 'none') {
card.style.setProperty('--glow-color', RARITY_COLOR + '88');
if (s.frame === 'none') {
// Glow is the only border effect
if (s.rarityGlow === 'subtle') {
card.style.animation = 'subtlePulse 2.5s ease-in-out infinite';
} else {
card.style.animation = 'strongPulse 2s ease-in-out infinite';
}
} else if (s.frame !== 'holo') {
// Combine glow with existing frame shadow
const existingShadow = card.style.boxShadow || '';
const glowShadow = s.rarityGlow === 'subtle'
? `0 0 16px 6px ${RARITY_COLOR}44`
: `0 0 28px 12px ${RARITY_COLOR}66`;
card.style.boxShadow = existingShadow ? `${existingShadow}, ${glowShadow}` : glowShadow;
}
}
// ── Header Bg ──
const headerTextEls = header.querySelectorAll('b, div');
let headerTextColor = '#000';
if (s.headerBg === 'default') {
header.style.background = '#fff';
} else if (s.headerBg === 'dark') {
header.style.background = '#1a1a2e';
headerTextColor = '#e0e0e0';
} else if (s.headerBg === 'gold') {
header.style.background = 'linear-gradient(135deg, #d4a017, #f0d060, #d4a017)';
headerTextColor = '#1a1000';
} else if (s.headerBg === 'team') {
header.style.background = s.teamColor;
headerTextColor = isLightColor(s.teamColor) ? '#111' : '#f0f0f0';
}
header.style.color = headerTextColor;
document.getElementById('headerRight').style.color = headerTextColor;
// ── Column Backgrounds ──
let vlBg, vrBg, colTextColor = '#000';
if (s.colBg === 'default') { vlBg = '#ACE6FF'; vrBg = '#EAA49C'; }
else if (s.colBg === 'dark') { vlBg = '#1a1a2e'; vrBg = '#2d1b1b'; colTextColor = '#d0d0d0'; }
else if (s.colBg === 'midnight') { vlBg = '#0d1b2a'; vrBg = '#1b0d0d'; colTextColor = '#c8c8c8'; }
else if (s.colBg === 'cream') { vlBg = '#FFF8DC'; vrBg = '#FFE4C4'; }
else if (s.colBg === 'team') {
vlBg = s.teamColor + '30';
vrBg = s.teamColor + '50';
colTextColor = '#111';
}
vlSide.style.backgroundColor = vlBg;
vrSide.style.backgroundColor = vrBg;
// Re-render columns with correct text color
renderColumn(document.getElementById('vlCol1'), vlData[0], colTextColor);
renderColumn(document.getElementById('vlCol2'), vlData[1], colTextColor);
renderColumn(document.getElementById('vlCol3'), vlData[2], colTextColor);
renderColumn(document.getElementById('vrCol1'), vrData[0], colTextColor);
renderColumn(document.getElementById('vrCol2'), vrData[1], colTextColor);
renderColumn(document.getElementById('vrCol3'), vrData[2], colTextColor);
// ── Gradient Bars ──
const gradClasses = { default: ['blue-gradient','red-gradient'], gold: ['gold-gradient','gold-gradient'], dark: ['dark-gradient','dark-gradient'] };
let lClass, rClass;
if (s.gradBars === 'match') {
// Generate inline gradient from column bg
gradLs.forEach(el => {
el.className = 'column-num border-right-thin';
el.style.backgroundImage = `linear-gradient(to right, ${vlBg}, ${adjustAlpha(vlBg, 0.5)}, ${vlBg})`;
el.style.color = colTextColor;
});
gradRs.forEach(el => {
el.className = 'column-num border-right-thin';
el.style.backgroundImage = `linear-gradient(to right, ${vrBg}, ${adjustAlpha(vrBg, 0.5)}, ${vrBg})`;
el.style.color = colTextColor;
});
// Fix last in each group (no right border)
gradLs[2].className = 'column-num';
gradRs[2].className = 'column-num';
} else {
[lClass, rClass] = gradClasses[s.gradBars] || gradClasses.default;
gradLs.forEach((el, i) => {
el.className = `column-num ${lClass}` + (i < 2 ? ' border-right-thin' : '');
el.style.backgroundImage = '';
el.style.color = s.gradBars === 'dark' ? '#ccc' : '#fff';
});
gradRs.forEach((el, i) => {
el.className = `column-num ${rClass}` + (i < 2 ? ' border-right-thin' : '');
el.style.backgroundImage = '';
el.style.color = s.gradBars === 'dark' ? '#ccc' : '#fff';
});
}
// ── Evolution Badge ──
const evoBadges = {
none: { display: 'none' },
t1: { display: 'flex', text: '🌱', bg: '#1a6b1a', color: '#90ee90', shadow: 'none' },
t2: { display: 'flex', text: '⭐', bg: '#8b6914', color: '#ffd700', shadow: 'none' },
t3: { display: 'flex', text: '💎', bg: '#4a1a6b', color: '#c084fc', shadow: '0 0 10px #c084fc66' },
t4: { display: 'flex', text: '👑', bg: '#0a5a5a', color: '#2dd4bf', shadow: '0 0 14px #2dd4bf88' },
};
const eb = evoBadges[s.evoBadge];
badge.style.display = eb.display;
if (eb.display !== 'none') {
badge.textContent = eb.text;
badge.style.background = eb.bg;
badge.style.color = eb.color;
badge.style.boxShadow = eb.shadow;
}
// ── Scale card ──
scaleCard();
// ── Prompt ──
updatePrompt(s);
}
function adjustAlpha(color, alpha) {
// For hex colors with alpha suffix, just return with adjusted alpha
if (color.startsWith('#') && color.length <= 7) {
const r = parseInt(color.slice(1,3), 16);
const g = parseInt(color.slice(3,5), 16);
const b = parseInt(color.slice(5,7), 16);
return `rgba(${r},${g},${b},${alpha})`;
}
return color;
}
function isLightColor(hex) {
const r = parseInt(hex.slice(1,3), 16);
const g = parseInt(hex.slice(3,5), 16);
const b = parseInt(hex.slice(5,7), 16);
return (r * 299 + g * 587 + b * 114) / 1000 > 128;
}
function scaleCard() {
const wrapper = document.getElementById('card-wrapper');
const card = document.getElementById('fullCard');
const ww = wrapper.clientWidth;
const scale = ww / 1200;
card.style.transform = `scale(${scale})`;
wrapper.style.height = `${600 * scale}px`;
}
// ── Presets ──
function applyPreset(name) {
const presets = {
default: { frame:'none', headerBg:'default', colBg:'default', gradBars:'default', evoBadge:'none', rarityGlow:'none' },
prestige: { frame:'gold', headerBg:'gold', colBg:'cream', gradBars:'gold', evoBadge:'t4', rarityGlow:'subtle' },
dark: { frame:'none', headerBg:'dark', colBg:'dark', gradBars:'dark', evoBadge:'none', rarityGlow:'none' },
midnight: { frame:'diamond', headerBg:'dark', colBg:'midnight', gradBars:'dark', evoBadge:'t3', rarityGlow:'subtle' },
holo: { frame:'holo', headerBg:'default', colBg:'default', gradBars:'default', evoBadge:'t2', rarityGlow:'strong' },
evolved: { frame:'gold', headerBg:'dark', colBg:'midnight', gradBars:'gold', evoBadge:'t4', rarityGlow:'strong' },
};
const p = presets[name];
if (!p) return;
Object.entries(p).forEach(([k, v]) => {
const radio = document.querySelector(`input[name="${k}"][value="${v}"]`);
if (radio) radio.checked = true;
});
update();
}
// ── Prompt ──
function updatePrompt(s) {
const parts = [];
const labels = {
frame: { gold: 'Gold Frame (6px gold border + glow)', diamond: 'Diamond Frame (shimmer border)', team: 'Team Color Frame', holo: 'Holographic Frame (animated rainbow)' },
headerBg: { dark: 'Dark Mode header (#1a1a2e)', gold: 'Metallic Gold header gradient', team: 'Team-colored header' },
colBg: { dark: 'Dark Mode columns (#1a1a2e / #2d1b1b, light text)', midnight: 'Midnight columns (#0d1b2a / #1b0d0d, light text)', cream: 'Cream columns (#FFF8DC / #FFE4C4)', team: 'Team-themed columns (team color at 20%/30% opacity)' },
gradBars: { gold: 'Gold gradient bars', dark: 'Dark charcoal gradient bars', match: 'Gradient bars matching column backgrounds' },
evoBadge: { t1: 'T1 Initiate badge (🌱 green)', t2: 'T2 Rising badge (⭐ gold)', t3: 'T3 Ascendant badge (💎 purple, glow)', t4: 'T4 Evolved badge (👑 teal, strong glow)' },
rarityGlow: { subtle: 'Subtle rarity pulse glow', strong: 'Strong rarity pulse glow' },
};
for (const [key, map] of Object.entries(labels)) {
if (s[key] !== 'none' && s[key] !== 'default' && map[s[key]]) {
parts.push(map[s[key]]);
}
}
if ((s.frame === 'team' || s.headerBg === 'team' || s.colBg === 'team') && s.teamColor !== DEFAULTS.teamColor) {
parts.push(`Team color: ${s.teamColor}`);
}
const text = parts.length > 0
? `Apply these cosmetics to the card template: ${parts.join('; ')}.`
: 'Default card — no cosmetics applied.';
document.getElementById('prompt-text').textContent = text;
}
function copyPrompt() {
const text = document.getElementById('prompt-text').textContent;
navigator.clipboard.writeText(text).then(() => {
const btn = document.getElementById('copy-btn');
btn.textContent = 'Copied!';
setTimeout(() => btn.textContent = 'Copy', 1500);
});
}
// ── Init ──
window.addEventListener('resize', scaleCard);
initColumns();
update();
</script>
</body>
</html>

View File

@ -920,23 +920,23 @@ body {
inset 1px 0 2px rgba(255,255,255,0.15);
}
/* Diamond glow pulse animation — applied to whole container */
/* Diamond glow pulse animation — applied to whole container for T4 */
@keyframes diamond-glow-pulse {
0% { box-shadow:
0 0 0 1.5px rgba(0,0,0,0.7),
0 2px 5px rgba(0,0,0,0.5),
0 0 5px 1px var(--diamond-glow-color, rgba(201,169,78,0.6));
0 0 8px 2px var(--diamond-glow-color, rgba(201,169,78,0.6));
}
50% { box-shadow:
0 0 0 1.5px rgba(0,0,0,0.5),
0 2px 4px rgba(0,0,0,0.3),
0 0 8px 3px var(--diamond-glow-color, rgba(201,169,78,0.8)),
0 0 14px 5px var(--diamond-glow-color, rgba(201,169,78,0.25));
0 0 14px 5px var(--diamond-glow-color, rgba(201,169,78,0.8)),
0 0 24px 8px var(--diamond-glow-color, rgba(201,169,78,0.3));
}
100% { box-shadow:
0 0 0 1.5px rgba(0,0,0,0.7),
0 2px 5px rgba(0,0,0,0.5),
0 0 5px 1px var(--diamond-glow-color, rgba(201,169,78,0.6));
0 0 8px 2px var(--diamond-glow-color, rgba(201,169,78,0.6));
}
}
@ -1365,11 +1365,11 @@ const TIER_PRESETS = {
cornerSize: 30,
cornerThick: 3,
diamondFill: 1,
diamondColor: '#d46a1a',
diamondHighlight: '#f0a050',
diamondColor: '#1a6b1a',
diamondHighlight: '#40b040',
diamondSize: 19,
diamondGlow: 'off',
diamondGlowColor: '#d46a1a',
diamondGlowColor: '#1a6b1a',
diamondEffect: 'none',
},
t2: {
@ -1393,11 +1393,11 @@ const TIER_PRESETS = {
cornerSize: 30,
cornerThick: 3,
diamondFill: 2,
diamondColor: '#b82020',
diamondHighlight: '#e85050',
diamondColor: '#2070b0',
diamondHighlight: '#50a0e8',
diamondSize: 19,
diamondGlow: 'off',
diamondGlowColor: '#b82020',
diamondGlowColor: '#2070b0',
diamondEffect: 'none',
},
t3: {
@ -1421,11 +1421,11 @@ const TIER_PRESETS = {
cornerSize: 30,
cornerThick: 3,
diamondFill: 3,
diamondColor: '#7b2d8e',
diamondHighlight: '#b860d0',
diamondColor: '#a82020',
diamondHighlight: '#e85050',
diamondSize: 19,
diamondGlow: 'off',
diamondGlowColor: '#7b2d8e',
diamondGlowColor: '#a82020',
diamondEffect: 'none',
},
t4: {
@ -1449,11 +1449,11 @@ const TIER_PRESETS = {
cornerSize: 35,
cornerThick: 3,
diamondFill: 4,
diamondColor: '#1a6af0',
diamondHighlight: '#60b0ff',
diamondColor: '#6b2d8e',
diamondHighlight: '#a060d0',
diamondSize: 19,
diamondGlow: 'on',
diamondGlowColor: '#1a6af0',
diamondGlowColor: '#6b2d8e',
diamondEffect: 'none',
},
t4b: {
@ -1477,11 +1477,11 @@ const TIER_PRESETS = {
cornerSize: 35,
cornerThick: 3,
diamondFill: 4,
diamondColor: '#1a6af0',
diamondHighlight: '#60b0ff',
diamondColor: '#6b2d8e',
diamondHighlight: '#a060d0',
diamondSize: 19,
diamondGlow: 'on',
diamondGlowColor: '#1a6af0',
diamondGlowColor: '#6b2d8e',
diamondEffect: 'none',
},
};
@ -1563,10 +1563,8 @@ function renderCardHTML(tierKey) {
diamondBG = `linear-gradient(135deg, rgba(255,255,255,0.9) 0%, ${t.diamondHighlight} 20%, ${t.diamondColor} 50%, ${darkenHex(t.diamondColor, 0.6)} 80%, ${t.diamondHighlight} 100%)`;
}
// Metallic effect automatically includes glow pulse
const wantsGlow = t.diamondGlow === 'on' || effect === 'metallic';
const glowClass = wantsGlow ? ' diamond-glow' : '';
const glowVar = wantsGlow ? ` --diamond-glow-color: ${t.diamondGlowColor || t.diamondColor};` : '';
const glowClass = t.diamondGlow === 'on' ? ' diamond-glow' : '';
const glowVar = t.diamondGlow === 'on' ? ` --diamond-glow-color: ${t.diamondGlowColor};` : '';
// Build container inline style — effects stack on top of the base box-shadow
let containerStyle = `width:${ds}px;height:${ds}px;${glowVar}`;