โœ“ ใ‚ณใƒ”ใƒผใ—ใพใ—ใŸ
๐ŸŽจ ใ‚ซใƒฉใƒผใƒ‘ใƒฌใƒƒใƒˆ
ๆทกใ„ใƒŸใƒณใƒˆใ‚ฐใƒชใƒผใƒณใ‚’ๅŸบ่ชฟใจใ—ใŸ9่‰ฒใฎใ‚ทใ‚นใƒ†ใƒ ใ‚ซใƒฉใƒผใ€‚CSSๅค‰ๆ•ฐใจใ—ใฆๅฎš็พฉใ—ใ€ไธ€่ฒซใ—ใŸใƒ†ใƒผใƒžใ‚’็ถญๆŒใ—ใพใ™ใ€‚ใ‚นใ‚ฆใ‚ฉใƒƒใƒใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ™ใ‚‹ใจใ‚ซใƒฉใƒผใ‚ณใƒผใƒ‰ใ‚’ใ‚ณใƒ”ใƒผใงใใพใ™ใ€‚
ใ‚ทใ‚นใƒ†ใƒ ใ‚ซใƒฉใƒผ
่ฃœๅŠฉใ‚ซใƒฉใƒผ๏ผˆ็›ดๆŽฅๆŒ‡ๅฎš๏ผ‰
CSSๅค‰ๆ•ฐๅฎš็พฉ
css
:root {
  --base-bg:     #e8f5f1;  /* ใƒ™ใƒผใ‚น่ƒŒๆ™ฏ๏ผˆๆทกใ„ใƒŸใƒณใƒˆ๏ผ‰*/
  --accent:      #a8d5ba;  /* ใ‚ขใ‚ฏใ‚ปใƒณใƒˆ๏ผˆ่‹ฅ่‘‰ใƒŸใƒณใƒˆ๏ผ‰*/
  --accent-deep: #4a8c6f;  /* ใ‚ขใ‚ฏใ‚ปใƒณใƒˆๆทฑ๏ผˆๆทฑใฟใƒŸใƒณใƒˆ๏ผ‰*/
  --text-main:   #44504c;  /* ใƒกใ‚คใƒณๆ–‡ๅญ—๏ผˆใƒใƒฃใ‚ณใƒผใƒซใ‚ฐใƒฌใƒผ๏ผ‰*/
  --text-sub:    #ccd6d1;  /* ใ‚ตใƒ–ๆ–‡ๅญ—๏ผˆๆฅต่–„ใ‚ฐใƒฌใƒผ๏ผ‰*/
  --card-bg:     #ffffff;  /* ใ‚ซใƒผใƒ‰่ƒŒๆ™ฏ๏ผˆ็ด”็™ฝ๏ผ‰*/
  --mint-light:  #d4ede3;  /* ใƒœใƒผใƒ€ใƒผใƒปใƒใƒผ่ƒŒๆ™ฏ */
  --mint-pale:   #f0faf5;  /* ๅ…ฅๅŠ›ใƒปใ‚ซใƒผใƒ‰่ƒŒๆ™ฏ */
  --shadow:      rgba(74,140,111,0.12); /* ใ‚ฐใƒชใƒผใƒณ็ณปใ‚ทใƒฃใƒ‰ใ‚ฆ */
}
๐Ÿ”ค ใ‚ฟใ‚คใƒใ‚ฐใƒฉใƒ•ใ‚ฃ
ๆ—ฅๆœฌ่ชžใฏใƒ’ใƒฉใ‚ฎใƒŽ่ง’ใ‚ด๏ผˆใ‚ทใ‚นใƒ†ใƒ ใƒ•ใ‚ฉใƒณใƒˆ๏ผ‰ใ€ๆ•ฐๅญ—ใƒป่‹ฑๅญ—ใฏRoboto๏ผˆGoogle Fonts๏ผ‰ใ€‚ๆ•ฐๅญ—ใ‚’Light๏ผˆ300๏ผ‰ใง็ดฐใ่กจ็คบใ™ใ‚‹ใ“ใจใงใ€ๆ•ฐๅญ—ใŒ่‹ฆๆ‰‹ใชใƒฆใƒผใ‚ถใƒผใธใฎๅœง่ฟซๆ„Ÿใ‚’ๆธ›ใ‚‰ใ—ใพใ™ใ€‚
ใƒ•ใ‚ฉใƒณใƒˆ่ชญใฟ่พผใฟ
html
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">

/* CSS: ๆ—ฅๆœฌ่ชžใƒ™ใƒผใ‚น */
body {
  font-family: 'Hiragino Kaku Gothic ProN', 'ใƒ’ใƒฉใ‚ฎใƒŽ่ง’ใ‚ด ProN W3',
               'Hiragino Sans', sans-serif;
}
/* ๆ•ฐๅญ—ใƒป่‹ฑๅญ—่ฆ็ด ใซๅ€‹ๅˆฅๆŒ‡ๅฎš */
.number, input { font-family: 'Roboto', sans-serif; }
ใ‚ฟใ‚คใƒ—ใ‚นใ‚ฑใƒผใƒซ
LIVE PREVIEW
็”จ้€”ใ‚ตใ‚คใ‚บWeightใƒ•ใ‚ฉใƒณใƒˆใƒ—ใƒฌใƒ“ใƒฅใƒผ
๐Ÿ“ ใ‚นใƒšใƒผใ‚ทใƒณใ‚ฐ & ่ง’ไธธ
8ใฎๅ€ๆ•ฐใƒ™ใƒผใ‚นใฎใ‚นใƒšใƒผใ‚ทใƒณใ‚ฐใ‚ทใ‚นใƒ†ใƒ ใ€‚่ง’ไธธใฏ่ฆ็ด ใฎ้‡่ฆๅบฆใƒปใ‚ตใ‚คใ‚บใซๅฟœใ˜ใฆ้šŽๅฑค็š„ใซ่จญๅฎšใ—ใพใ™ใ€‚
ใ‚นใƒšใƒผใ‚ทใƒณใ‚ฐใ‚นใ‚ฑใƒผใƒซ
่ง’ไธธ๏ผˆborder-radius๏ผ‰
RADIUS SYSTEM
๐Ÿชž ใ‚ทใƒฃใƒ‰ใ‚ฆใƒปใ‚ฐใƒฉใƒ‡ใƒผใ‚ทใƒงใƒณใƒปๆž ็ทš
้ป’ใ„ๅฝฑใฎไปฃใ‚ใ‚Šใซใƒ†ใƒผใƒžใ‚ซใƒฉใƒผใฎใ‚ฐใƒชใƒผใƒณ็ณปใ‚ทใƒฃใƒ‰ใ‚ฆใ‚’ไฝฟ็”จใ€‚้‡ใŸใใชใ‚‰ใšใ€็ฉบๆฐ—ๆ„Ÿใฎใ‚ใ‚‹ๅฅฅ่กŒใใ‚’ๆผ”ๅ‡บใ—ใพใ™ใ€‚
ใ‚ทใƒฃใƒ‰ใ‚ฆใ‚นใ‚ฑใƒผใƒซ
ใ‚ฐใƒฉใƒ‡ใƒผใ‚ทใƒงใƒณ
ๆž ็ทš
css
/* ้€šๅธธใฎใ‚ซใƒผใƒ‰ใƒปๅ…ฅๅŠ› */
border: 1.5px solid #d4ede3;

/* ใƒ•ใ‚ฉใƒผใ‚ซใ‚นใƒปใƒใ‚คใƒฉใ‚คใƒˆ */
border: 2px solid #a8d5ba;

/* ็‚น็ทš๏ผˆ่จˆ็ฎ—ๅผใƒป่ฃœ่ถณ๏ผ‰ */
border: 1px dashed #d4ede3;

/* ๅทฆใ‚ขใ‚ฏใ‚ปใƒณใƒˆใƒฉใ‚คใƒณ */
border-left: 3px solid #a8d5ba;

/* ใƒ•ใ‚ฉใƒผใ‚ซใ‚นใƒชใƒณใ‚ฐ */
box-shadow: 0 0 0 4px rgba(168,213,186,0.25);
๐Ÿงฉ UIใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ
ๅ†ๅˆฉ็”จๅฏ่ƒฝใชใ‚ณใƒณใƒใƒผใƒใƒณใƒˆไธ€่ฆงใ€‚ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆๅ‹•ไฝœใ‚’็ขบ่ชใงใใพใ™ใ€‚
ใƒใƒƒใ‚ธ
โœจ ๅนดๆœซ่ชฟๆ•ดใƒป็ตฆไธŽๆ‰€ๅพ—ๆŽง้™ค ไปคๅ’Œ7ๅนดๅˆ†๏ผˆๆœ€ๆ–ฐ๏ผ‰ Draft
ใƒœใ‚ฟใƒณ
ใ‚ปใ‚ฐใƒกใƒณใƒˆใ‚ณใƒณใƒˆใƒญใƒผใƒซ๏ผˆๅนดๅบฆๅˆ‡ใ‚Šๆ›ฟใˆ็ญ‰๏ผ‰
html + css
<!-- ใ‚ปใ‚ฐใƒกใƒณใƒˆใ‚ณใƒณใƒˆใƒญใƒผใƒซ -->
<div class="year-toggle">
  <button class="year-btn"        onclick="setYear(6)">ไปคๅ’Œ6ๅนดๅˆ†</button>
  <button class="year-btn active" onclick="setYear(7)">ไปคๅ’Œ7ๅนดๅˆ†๏ผˆๆœ€ๆ–ฐ๏ผ‰</button>
</div>

.year-toggle {
  display: flex; gap: 8px; background: var(--mint-pale);
  padding: 5px; border-radius: 14px;
}
.year-btn {
  flex: 1; padding: 10px 8px; border: none; border-radius: 10px;
  cursor: pointer; transition: all 0.3s cubic-bezier(0.34,1.56,0.64,1);
  color: #7a9a8e; background: transparent;
}
.year-btn.active {
  background: var(--card-bg); color: var(--accent-deep);
  box-shadow: 0 2px 10px var(--shadow); transform: scale(1.02);
}
็ตๆžœใ‚ซใƒผใƒ‰
็ตฆไธŽๆ‰€ๅพ—ๆŽง้™ค้ก
1,292,000ๅ††
ๅนดๅŽใฎ็ด„ 26.0% ใ‚’ๆŽง้™ค
็ตฆไธŽๆ‰€ๅพ—ๆŽง้™คๅพŒใฎ็ตฆไธŽ็ญ‰ใฎ้‡‘้ก๏ผˆๆ‰€ๅพ—๏ผ‰
3,668,000ๅ††
ใƒŽใƒผใƒˆใƒœใƒƒใ‚ฏใ‚น
๐Ÿ“‹ ไปคๅ’Œ7ๅนด๏ผˆ2025ๅนด๏ผ‰ๅˆ† ๆ‰€ๅพ—็จŽๆณ• ๅˆฅ่กจ็ฌฌไบ”ใซๅŸบใฅใ่จˆ็ฎ—ใงใ™ใ€‚
่จˆ็ฎ—ๅผ๏ผš4,960,000ๅ†† ร— 80% โˆ’ 440,000ๅ†† = 3,528,000ๅ††
โ‘ก WarningInline โ€” ใ‚คใƒณใƒฉใ‚คใƒณ่ญฆๅ‘Šใƒœใƒƒใ‚ฏใ‚น
โš  ่ฉ•ไพก้กใŒๆŠ•่ณ‡็ดฏ่จˆ้กใ‚’ไธ‹ๅ›žใฃใฆใ„ใพใ™๏ผˆๅซใฟๆใฎ็Šถๆ…‹๏ผ‰
โš  ๆ–ฐNISAๆž ๏ผˆ1,800ไธ‡ๅ††๏ผ‰ใฏใ™ใงใซไฝฟใ„ๅˆ‡ใฃใฆใ„ใพใ™ใ€‚ๆ–ฐ่ฆ็ฉ็ซ‹ใฏใงใใพใ›ใ‚“ใ€‚
html + css
<!-- WarningInline -->
<div class="ds-warning-inline">
  <span class="wi-icon">โš </span>
  <span>่ฉ•ไพก้กใŒๆŠ•่ณ‡็ดฏ่จˆ้กใ‚’ไธ‹ๅ›žใฃใฆใ„ใพใ™</span>
</div>

.ds-warning-inline {
  display: flex; gap: 8px;
  padding: 10px 14px;
  background: rgba(224,122,58,0.08);
  border-left: 3px solid var(--warn-color);
  border-radius: 10px;
  font-size: 12px; color: var(--warn-color);
  line-height: 1.7;
}
/* ่กจ็คบๅˆ‡ใ‚Šๆ›ฟใˆใฏ .show ใ‚ฏใƒฉใ‚นใงๅˆถๅพก */
.ds-warning-inline { display: none; }
.ds-warning-inline.show { display: flex; }
โœ๏ธ ใƒ•ใ‚ฉใƒผใƒ ๅ…ฅๅŠ›
ๅ…ฅๅŠ›ใƒ•ใ‚ฉใƒผใƒ ใฎ3ใคใฎใƒขใƒผใƒ‰๏ผˆใƒ†ใ‚ญใ‚นใƒˆใƒปใ‚นใƒฉใ‚คใƒ€ใƒผใƒปใ‚ฏใ‚คใƒƒใ‚ฏใƒœใ‚ฟใƒณ๏ผ‰ใฏๅŒไธ€ใฎๅ€คใ‚’ๅ…ฑๆœ‰ใ—ใพใ™ใ€‚ใƒ—ใƒฌใƒผใ‚นใƒ›ใƒซใƒ€ใƒผใฏๆ–‡ๅญ—่‰ฒใƒปใ‚ตใ‚คใ‚บใจใ‚‚ใซๅ…ฅๅŠ›ๅ€คใ‚ˆใ‚ŠๆŽงใˆใ‚ใซ่จญๅฎšใ—ใพใ™ใ€‚
ใƒ†ใ‚ญใ‚นใƒˆๅ…ฅๅŠ›๏ผˆๆ•ฐๅญ—๏ผ‰
ๅ††
css
input[type="text"] {
  padding: 18px 64px 18px 22px;
  font-size: 22px; font-family: 'Roboto'; font-weight: 300;
  border: 2px solid var(--mint-light);
  border-radius: 16px; background: var(--mint-pale);
  transition: all 0.3s ease;
}
input::placeholder {
  color: #b8d4cc; /* ๅ…ฅๅŠ›ๅ€คใ‚ˆใ‚Šๆ˜Ž็ขบใซ่–„ใ */
  font-weight: 300;
  font-size: 18px; /* ๅ…ฅๅŠ›ๅ€ค(22px)ใ‚ˆใ‚Šๅฐใ•ใ */
}
input:focus {
  border-color: var(--accent);
  background: var(--card-bg);
  box-shadow: 0 0 0 4px rgba(168,213,186,0.25);
}
ใ‚นใƒฉใ‚คใƒ€ใƒผ
0500ไธ‡1,000ไธ‡1,500ไธ‡+
ใ‚ฏใ‚คใƒƒใ‚ฏใƒœใ‚ฟใƒณ
ใ‚ˆใไฝฟใ‚ใ‚Œใ‚‹ๅนดๅŽ
โ‘  InputStepper โ€” ยฑใƒœใ‚ฟใƒณไป˜ใใ‚นใƒฉใ‚คใƒ€ใƒผ
LIVE DEMO โ€” Fintechใ‚ขใƒ—ใƒชใง้ ปๅ‡บใฎใ‚ปใƒƒใƒˆ
ไธ‡ๅ†† / ๆœˆ
html + css + js
<!-- InputStepper -->
<div class="ds-val-row">
  <input class="ds-num-edit" type="number" id="inMonthly"
         min="0" max="30" step="0.1" value="5">
  <span class="ds-val-unit">ไธ‡ๅ††</span>
</div>
<div class="ds-input-stepper">
  <button class="ds-pm-btn" data-target="slMonthly" data-step="-0.1">๏ผ</button>
  <input class="ds-stepper-range" type="range" id="slMonthly"
         min="0" max="30" step="0.1" value="5">
  <button class="ds-pm-btn" data-target="slMonthly" data-step="0.1">๏ผ‹</button>
</div>

/* JS: ใ‚นใƒฉใ‚คใƒ€ใƒผ่ƒŒๆ™ฏใ‚’ใƒชใ‚ขใƒซใ‚ฟใ‚คใƒ ๆ›ดๆ–ฐ */
function updateStepperBg(sl) {
  const pct = ((sl.value - sl.min) / (sl.max - sl.min)) * 100;
  sl.style.setProperty('--pct', pct + '%');
}
โ‘ข SelectUnderline โ€” ใ‚ขใƒณใƒ€ใƒผใƒฉใ‚คใƒณใ‚นใ‚ฟใ‚คใƒซใฎใ‚ปใƒฌใ‚ฏใƒˆ
LIVE DEMO โ€” ็”Ÿๅนดๆœˆๆ—ฅใƒปๅนดๆœˆ้ธๆŠžใฎๅฎš็•ชใ‚นใ‚ฟใ‚คใƒซ
ๅนด ๆœˆ
html + css
<!-- SelectUnderline โ€” ็”Ÿๅนดๆœˆๆ—ฅไพ‹ -->
<div class="ds-select-row">
  <select class="ds-select-underline" id="dobYear"></select>
  <span class="ds-select-unit">ๅนด</span>
  <select class="ds-select-underline" id="dobMonth"></select>
  <span class="ds-select-unit">ๆœˆ</span>
</div>

.ds-select-underline {
  font-size: clamp(1.4rem, 5vw, 1.8rem);
  font-weight: 300;
  border: none;
  border-bottom: 2px solid var(--mint-light);
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  padding: 0 4px 4px;
  transition: border-color .25s ease;
}
.ds-select-underline:focus {
  border-bottom-color: var(--accent-deep);
  outline: none;
}
ใ‚ซใƒณใƒžๅŒบๅˆ‡ใ‚Šๅ…ฅๅŠ›๏ผˆJS๏ผ‰
javascript
function onInputChange(el) {
  const pos    = el.selectionStart;
  const oldLen = el.value.length;
  // ๆ•ฐๅญ—ไปฅๅค–ใ‚’้™คๅŽป
  const raw = el.value.replace(/[^0-9]/g, '');
  const num = parseInt(raw) || 0;
  el.value = num ? num.toLocaleString('ja-JP') : '';
  // ใ‚ซใƒผใ‚ฝใƒซไฝ็ฝฎ่ฃœๆญฃ๏ผˆใ‚ซใƒณใƒžๆŒฟๅ…ฅๅˆ†ใฎใšใ‚Œ๏ผ‰
  const diff = el.value.length - oldLen;
  el.setSelectionRange(pos + diff, pos + diff);
}
โœจ ใ‚ขใƒ‹ใƒกใƒผใ‚ทใƒงใƒณ
12็จฎ้กžใฎใ‚ขใƒ‹ใƒกใƒผใ‚ทใƒงใƒณใ‚’ไฝฟใ„ๅˆ†ใ‘ใ€UIๅ…จไฝ“ใซใ€Œ็”Ÿใ็‰ฉๆ„Ÿใ€ใ‚’ไธŽใˆใพใ™ใ€‚ใ‚ฟใ‚คใƒซใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใƒฉใ‚คใƒ–็ขบ่ชใงใใพใ™ใ€‚
ใ‚คใƒผใ‚ธใƒณใ‚ฐ้–ขๆ•ฐ๏ผˆใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆๆฏ”่ผƒ๏ผ‰
CLICK TO ANIMATE
ๆ•ฐๅญ—ใ‚ซใ‚ฆใƒณใƒˆใ‚ขใƒƒใƒ—๏ผˆใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆ่ฉฆใ™๏ผ‰
0
javascript
function animateNum(el, from, to, ms) {
  const t0 = performance.now();
  function step(now) {
    const p    = Math.min((now - t0) / ms, 1);
    const ease = 1 - Math.pow(1 - p, 4); // easeOutQuart
    el.textContent = Math.round(from + (to - from) * ease)
                         .toLocaleString('ja-JP');
    if (p < 1) requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
}
ๅ…จใ‚ขใƒ‹ใƒกใƒผใ‚ทใƒงใƒณไธ€่ฆง
๐Ÿ‘† ใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณ
ใƒฆใƒผใ‚ถใƒผใฎๆ“ไฝœใซๅฏพใ—ใฆใ€่ค‡ๆ•ฐใƒฌใ‚คใƒคใƒผใฎใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏใ‚’่ฟ”ใ—ใพใ™ใ€‚ใ€Œ่งฆใฃใฆๆฅฝใ—ใ„ใ€ใ‚’ๅฎŸ็พใ™ใ‚‹ใŸใ‚ใฎ่จญ่จˆใงใ™ใ€‚
ใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏ่จญ่จˆ
ๆ“ไฝœใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏ
ๆ•ฐๅญ—ๅ…ฅๅŠ›ใ‚ซใ‚ฆใƒณใƒˆใ‚ขใƒƒใƒ— + ใƒใƒผใ‚ขใƒ‹ใƒกใƒผใ‚ทใƒงใƒณ + ใƒ‰ใƒผใƒŠใƒ„ๆ›ดๆ–ฐ
ใ‚ฏใ‚คใƒƒใ‚ฏใƒœใ‚ฟใƒณใƒœใ‚ฟใƒณใƒใ‚คใƒฉใ‚คใƒˆ๏ผˆใ‚นใƒ—ใƒชใƒณใ‚ฐ๏ผ‰+ ๆ•ฐๅญ—ๆ›ดๆ–ฐ
ๅนดๅŽใŒๅคงใใๅค‰ๅŒ–ใ‚ณใƒณใƒ•ใ‚งใƒƒใƒ†ใ‚ฃ + ใƒˆใƒผใ‚นใƒˆ้€š็Ÿฅ
ๅนดๅบฆๅˆ‡ใ‚Šๆ›ฟใˆใ‚ปใ‚ฐใƒกใƒณใƒˆๅˆ‡ใ‚Šๆ›ฟใˆ๏ผˆใ‚นใƒ—ใƒชใƒณใ‚ฐ๏ผ‰+ ใƒˆใƒผใ‚นใƒˆ้€š็Ÿฅ
ใ‚ซใƒผใƒ‰ใƒ›ใƒใƒผ2pxๆตฎใไธŠใŒใ‚Š + ใ‚ฐใƒชใƒผใƒณๅฝฑๅผท่ชฟ
ใƒšใƒผใ‚ธใƒญใƒผใƒ‰ใƒ˜ใƒƒใƒ€ใƒผ๏ผšไธŠใ‹ใ‚‰ใƒ•ใ‚งใƒผใƒ‰ใ‚คใƒณ โ†’ ใ‚ซใƒผใƒ‰๏ผšไธ‹ใ‹ใ‚‰ใƒ•ใ‚งใƒผใƒ‰ใ‚คใƒณ๏ผˆ0.2s้…ๅปถ๏ผ‰
ใ‚ณใƒณใƒ•ใ‚งใƒƒใƒ†ใ‚ฃ๏ผˆใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆ่ฉฆใ™๏ผ‰

ๅฎŸ้š›ใฎใ‚ขใƒ—ใƒชใงใฏๅนดๅŽๅค‰ๅŒ–ใŒ20ไธ‡ๅ††่ถ…ใฎใจใใซ็™บ็ซใ—ใพใ™

javascript
function fireConfetti() {
  const wrap   = document.getElementById('confetti-wrap');
  const colors = ['#a8d5ba','#4a8c6f','#d4ede3',
                   '#e8f5f1','#7fc49e','#2d7a5a'];
  for (let i = 0; i < 50; i++) {
    const c = document.createElement('div');
    c.style.cssText = `
      position:absolute;
      left: ${10 + Math.random()*80}%;
      width: ${6 + Math.random()*8}px;
      height: ${6 + Math.random()*8}px;
      background: ${colors[Math.floor(Math.random()*colors.length)]};
      border-radius: ${Math.random() > 0.5 ? '50%' : '2px'};
      animation: confettiFall ${1.2+Math.random()*1.3}s linear forwards;
    `;
    wrap.appendChild(c);
    setTimeout(() => c.remove(), 3000);
  }
}
ใƒˆใƒผใ‚นใƒˆ้€š็Ÿฅ๏ผˆใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆ่ฉฆใ™๏ผ‰
css + javascript
/* CSS */
.toast {
  position: fixed; bottom: 30px; left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--accent-deep); color: #fff;
  padding: 12px 28px; border-radius: 40px;
  opacity: 0; pointer-events: none;
  transition: transform 0.4s cubic-bezier(0.34,1.56,0.64,1), opacity 0.4s ease;
}
.toast.show {
  transform: translateX(-50%) translateY(0); opacity: 1;
}

/* JS */
let toastTimer;
function showToast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.classList.add('show');
  clearTimeout(toastTimer);
  toastTimer = setTimeout(() => t.classList.remove('show'), 2600);
}
๐Ÿ“Š Fintechใƒ‘ใ‚ฟใƒผใƒณ
่ณ‡็”ฃ้‹็”จใƒป้‡‘่žใ‚ทใƒŸใƒฅใƒฌใƒผใ‚ทใƒงใƒณ็”ป้ขใง็นฐใ‚Š่ฟ”ใ—ไฝฟใ‚ใ‚Œใ‚‹UIใƒ‘ใ‚ฟใƒผใƒณใงใ™ใ€‚SummaryGrid / StatCardใ€ใ‚ทใƒŸใƒฅใƒฌใƒผใ‚ทใƒงใƒณๆฃ’ใ‚ฐใƒฉใƒ•ใ‚’ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใจใ—ใฆๅฎš็พฉใ—ใพใ™ใ€‚
โ‘ฃ SummaryGrid / StatCard โ€” KPIใƒปใ‚ตใƒžใƒชใƒผใ‚ฐใƒชใƒƒใƒ‰
LIVE DEMO โ€” 3ใ‚ซใƒฉใƒ ใ‚ฐใƒชใƒƒใƒ‰๏ผˆใƒขใƒใ‚คใƒซใฏ2ใ‚ซใƒฉใƒ ๏ผ‰
65ๆญณๆ™‚ใฎ่ณ‡็”ฃ๏ผˆ29ๅนดๅพŒ๏ผ‰
4,106ไธ‡ๅ††
ใ†ใก้‹็”จๅŽ็›Š
2,306ไธ‡ๅ††
ๆ–ฐNISAๆž ไฝฟใ„ๅˆ‡ใ‚Š
19ๅนด4ใƒถๆœˆ็›ฎ
54ๆญณ3ใƒถๆœˆ
html + css
<!-- SummaryGrid / StatCard -->
<div class="ds-summary-grid">
  <!-- ใƒใ‚คใƒฉใ‚คใƒˆใ‚ซใƒผใƒ‰๏ผˆ1็•ช็›ฎใƒปๅผท่ชฟ่กจ็คบ๏ผ‰ -->
  <div class="ds-stat-card highlight">
    <div class="ds-stat-label">65ๆญณๆ™‚ใฎ่ณ‡็”ฃ</div>
    <div><span class="ds-stat-num">4,106</span><span class="ds-stat-unit">ไธ‡ๅ††</span></div>
  </div>
  <!-- ้€šๅธธใ‚ซใƒผใƒ‰ -->
  <div class="ds-stat-card">
    <div class="ds-stat-label">ใ†ใก้‹็”จๅŽ็›Š</div>
    <div><span class="ds-stat-num">2,306</span><span class="ds-stat-unit">ไธ‡ๅ††</span></div>
  </div>
</div>

.ds-summary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr; /* ใƒขใƒใ‚คใƒซ: 2ๅˆ— */
  gap: 12px;
}
@media (min-width: 480px) {
  .ds-summary-grid {
    grid-template-columns: repeat(3, 1fr); /* ใ‚ฟใƒ–ใƒฌใƒƒใƒˆไปฅไธŠ: 3ๅˆ— */
    gap: 14px;
  }
}
โ‘ค SimulationChart โ€” ็ฉ็ซ‹ใ‚ทใƒŸใƒฅใƒฌใƒผใ‚ทใƒงใƒณๆฃ’ใ‚ฐใƒฉใƒ•
LIVE DEMO โ€” ใƒ›ใƒใƒผใงใƒ„ใƒผใƒซใƒใƒƒใƒ—่กจ็คบ๏ผˆ30ๅนดๅˆ†ใƒ‡ใƒผใ‚ฟ๏ผ‰
ๅ…ƒๆœฌ
้‹็”จๅŽ็›Š
โ€ป ๆ–ฐNISAๆž ๏ผˆ1,800ไธ‡ๅ††๏ผ‰ๅˆฐ้”ๅพŒใฏๆ–ฐ่ฆ็ฉ็ซ‹ๅœๆญขใƒป้‹็”จใฎใฟ็ถ™็ถš
javascript โ€” canvas ๆฃ’ใ‚ฐใƒฉใƒ•ๆ็”ป
function renderSimChart(data, canvas) {
  const dpr  = window.devicePixelRatio || 1;
  const cW   = canvas.parentElement.clientWidth;
  const PAD  = { t:14, r:14, b:42, l:64 };
  const n    = data.length;
  const plotW= cW - PAD.l - PAD.r;
  const BAR  = Math.max(3, plotW/n - Math.max(1, plotW/n*0.28));
  const GAP  = Math.max(1, plotW/n - BAR);

  const ctx = canvas.getContext('2d');
  const max = Math.max(...data.map(d => d.total));

  data.forEach((d, i) => {
    const x        = PAD.l + i * (BAR+GAP);
    const pH       = 300 - PAD.t - PAD.b;
    const totalH   = (d.total     / max) * pH;
    const principH = (d.principal / max) * pH;
    // ๅ…ƒๆœฌ: --accent
    ctx.fillStyle = '#a8d5ba';
    rRect(ctx, x, baseY-principH, BAR, principH, [0,0,4,4]);
    // ้‹็”จๅŽ็›Š: --accent-deep
    ctx.fillStyle = '#4a8c6f';
    rRect(ctx, x, baseY-totalH, BAR, totalH-principH, [4,4,0,0]);
  });
}
๐Ÿ“ฑ ใƒขใƒใ‚คใƒซใƒ•ใ‚กใƒผใ‚นใƒˆ
ใ“ใฎใƒ‡ใ‚ถใ‚คใƒณใ‚ทใ‚นใƒ†ใƒ ใฏใ‚นใƒžใƒ›ใƒฆใƒผใ‚ถใƒผใ‚’ๆœ€ๅ„ชๅ…ˆใซ่จญ่จˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใ‚ฟใƒผใ‚ฒใƒƒใƒˆใงใ‚ใ‚‹30ไปฃๅฅณๆ€งใฎๅคšใใŒใ€Œใ‚นใƒžใƒ›ใงๆฐ—่ปฝใซ็ขบ่ชใ€ใ™ใ‚‹ใŸใ‚ใ€ใƒขใƒใ‚คใƒซไฝ“้จ“ใ‚’ๅŸบๆบ–ใซPCใธๆ‹กๅผตใ™ใ‚‹ๆˆฆ็•ฅใ‚’ใจใ‚Šใพใ™ใ€‚
ใƒ–ใƒฌใƒผใ‚ฏใƒใ‚คใƒณใƒˆๅฎš็พฉ
BREAKPOINTS
css โ€” mobile-first
/* ใƒ™ใƒผใ‚น = ใƒขใƒใ‚คใƒซ๏ผˆใ€œ479px๏ผ‰ใซๆ›ธใ */
.card {
  padding: 28px 20px;
  border-radius: 20px;
}

/* ใ‚ฟใƒ–ใƒฌใƒƒใƒˆไปฅไธŠใซไธŠๆ›ธใ */
@media (min-width: 480px) {
  .card {
    padding: 40px 36px;
    border-radius: 28px;
  }
}

/* PCไปฅไธŠใซใ•ใ‚‰ใซไธŠๆ›ธใ */
@media (min-width: 768px) {
  .container { max-width: 560px; }
}
ใ‚ฟใƒƒใƒใ‚ฟใƒผใ‚ฒใƒƒใƒˆใ‚ตใ‚คใ‚บ
TOUCH TARGET โ€” ๆœ€ๅฐ44px ร— 44px
css
/* Apple HIG / Google Material ๆŽจๅฅจ: ๆœ€ๅฐ 44ร—44px */

/* โœ… ใ‚ฏใ‚คใƒƒใ‚ฏใƒœใ‚ฟใƒณ โ€” padding ใง้ซ˜ใ•ใ‚’็ขบไฟ */
.quick-btn {
  min-height: 44px;
  padding: 11px 20px;
}

/* โœ… ใ‚นใƒฉใ‚คใƒ€ใƒผใฎใคใพใฟ โ€” ๅๅˆ†ใชๅฝ“ใŸใ‚Šๅˆคๅฎš */
input[type="range"]::-webkit-slider-thumb {
  width: 24px; height: 24px; /* ๅฎŸใ‚ตใ‚คใ‚บ */
  /* ่ฆ–่ฆšใฏ24pxใงใ‚‚ใ€ใ‚ฟใƒƒใƒ—้ ˜ๅŸŸใฏใƒ–ใƒฉใ‚ฆใ‚ถใŒ44pxใซๆ‹กๅผต */
}

/* โœ… ๅ…ฅๅŠ›ใƒ•ใ‚ฃใƒผใƒซใƒ‰ โ€” ้ซ˜ใ•ใ‚’ๅๅˆ†ใซ็ขบไฟ */
input[type="text"] {
  padding: 18px 64px 18px 22px; /* ็ธฆ56px็›ธๅฝ“ */
}
ใƒขใƒใ‚คใƒซใƒ•ใ‚ฉใƒณใƒˆใ‚ตใ‚คใ‚บๆˆฆ็•ฅ
FLUID TYPOGRAPHY โ€” clamp() ใƒ™ใƒผใ‚น
css
/* clamp(ๆœ€ๅฐ, ๆตๅ‹•ๅ€ค, ๆœ€ๅคง) ใง็”ป้ขๅน…ใซ่‡ชๅ‹•่ฟฝๅพ“ */
h1          { font-size: clamp(20px, 5vw, 32px); }
.result-val { font-size: clamp(22px, 6vw, 30px); }
.input-num  { font-size: clamp(18px, 5vw, 22px); }

/* iOS ใ‚บใƒผใƒ ้˜ฒๆญข: input ใฏ 16px ไปฅไธŠๅฟ…้ ˆ */
input { font-size: 16px; } /* 16pxๆœชๆบ€ใ ใจ่‡ชๅ‹•ใ‚บใƒผใƒ ใŒ็™บ็”Ÿ */

/* NG ไพ‹ */
input { font-size: 14px; } /* โ† iOS SafariใŒ่‡ชๅ‹•ใ‚บใƒผใƒ ใ—ใฆใ—ใพใ† */
ใƒฌใ‚คใ‚ขใ‚ฆใƒˆๅค‰ๅŒ–๏ผˆใƒขใƒใ‚คใƒซ โ†’ PC๏ผ‰
LAYOUT COMPARISON โ€” ใ‚ฏใƒชใƒƒใ‚ฏใงๅˆ‡ใ‚Šๆ›ฟใˆ
css โ€” ใƒฌใ‚คใ‚ขใ‚ฆใƒˆๅค‰ๅŒ–
/* ใƒขใƒใ‚คใƒซ๏ผˆใƒ™ใƒผใ‚น๏ผ‰ */
.donut-wrap     { flex-direction: column; }
.result-value   { font-size: 24px; }
.card           { border-radius: 20px; padding: 28px 20px; }
.quick-btns     { gap: 8px; }

/* ใ‚ฟใƒ–ใƒฌใƒƒใƒˆไปฅไธŠ (min-width: 480px) */
@media (min-width: 480px) {
  .donut-wrap   { flex-direction: row; }
  .result-value { font-size: 30px; }
  .card         { border-radius: 28px; padding: 40px 36px; }
}

/* PCใƒฌใ‚คใ‚ขใ‚ฆใƒˆ: ใ‚ณใƒณใƒ†ใƒŠๅน…ใ‚’ๅˆถ้™ */
@media (min-width: 768px) {
  .container    { max-width: 560px; margin: 36px auto; }
}
ใ‚นใ‚ฏใƒญใƒผใƒซใƒปใ‚ฟใƒƒใƒ—ๆœ€้ฉๅŒ–
css + html
/* ใ‚ฟใƒƒใƒ—ๆ™‚ใฎใƒใ‚คใƒฉใ‚คใƒˆ้™คๅŽป */
button, input, a {
  -webkit-tap-highlight-color: transparent;
}

/* ใ‚นใƒ ใƒผใ‚บใ‚นใ‚ฏใƒญใƒผใƒซ */
html { scroll-behavior: smooth; }

/* ๆ•ฐๅญ—ๅ…ฅๅŠ›: ใƒขใƒใ‚คใƒซใ‚ญใƒผใƒœใƒผใƒ‰ใ‚’ใƒ†ใƒณใ‚ญใƒผใซ */
<input type="text" inputmode="numeric" />
/* โ†‘ type="number" ใ‚ˆใ‚Š type="text" + inputmode="numeric" ใŒ
   ใ‚ซใƒณใƒžๅŒบๅˆ‡ใ‚Š่กจ็คบใฎใŸใ‚ใซใƒ™ใ‚ฟใƒผ */

/* overflow: hidden ใงๆจชใ‚นใ‚ฏใƒญใƒผใƒซ้˜ฒๆญข */
body { overflow-x: hidden; }

/* ้•ทๆŠผใ—ใƒกใƒ‹ใƒฅใƒผๆŠ‘ๅˆถ๏ผˆUI่ฆ็ด ๏ผ‰ */
.card, .result-item {
  -webkit-user-select: none;
  user-select: none;
}
ใƒขใƒใ‚คใƒซใƒ•ใ‚กใƒผใ‚นใƒˆๅฎŸ่ฃ…ใƒใ‚งใƒƒใ‚ฏใƒชใ‚นใƒˆ
CHECKLIST
Safe Area๏ผˆใƒŽใƒƒใƒใƒปใƒ›ใƒผใƒ ใƒใƒผๅฏพๅฟœ๏ผ‰
html + css
<!-- viewport ใซ viewport-fit=cover ใ‚’่ฟฝๅŠ  -->
<meta name="viewport"
  content="width=device-width, initial-scale=1.0, viewport-fit=cover">

/* Safe Area ๅฏพๅฟœ: ใƒ•ใƒƒใ‚ฟใƒผใƒปๅ›บๅฎš่ฆ็ด ใซ้ฉ็”จ */
footer {
  padding-bottom: calc(40px + env(safe-area-inset-bottom));
}

/* ใƒˆใƒผใ‚นใƒˆ้€š็Ÿฅ โ€” ใƒ›ใƒผใƒ ใƒใƒผใจ่ขซใ‚‰ใชใ„ใ‚ˆใ† */
.toast {
  bottom: calc(30px + env(safe-area-inset-bottom));
}

/* ๅ›บๅฎšใƒŠใƒ“็ญ‰ใŒใ‚ใ‚‹ๅ ดๅˆ */
.fixed-nav {
  padding-top: env(safe-area-inset-top);
}
๐Ÿ’ก ใƒ‡ใ‚ถใ‚คใƒณๅŽŸๅ‰‡
ใ“ใฎใƒ‡ใ‚ถใ‚คใƒณใ‚ทใ‚นใƒ†ใƒ ใ‚’่ฒซใ10ใฎๅŽŸๅ‰‡ใ€‚ๆ–ฐใ—ใ„ๆฉŸ่ƒฝใƒปใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’่ฟฝๅŠ ใ™ใ‚‹้š›ใฎๅˆคๆ–ญๅŸบๆบ–ใจใ—ใฆไฝฟ็”จใ—ใฆใใ ใ•ใ„ใ€‚
็ตตๆ–‡ๅญ—ๆดป็”จใ‚ฌใ‚คใƒ‰
STRATEGIC EMOJI USE
ๆƒณๅฎšใ‚ฟใƒผใ‚ฒใƒƒใƒˆ
TARGET USER
๐Ÿ‘ฉ 30ไปฃๅฅณๆ€งใƒปไผš็คพๅ“ก
๐Ÿ’ญ ใŠ้‡‘ใƒป็จŽ้‡‘ใŒ่‹ฆๆ‰‹
๐Ÿ“ฑ ใ‚นใƒžใƒ›ใงๆฐ—่ปฝใซ็ขบ่ช
โฐ ๅนดๆœซ่ชฟๆ•ดใ‚ทใƒผใ‚บใƒณใซไฝฟ็”จ
DESIGN MISSION
โœ… ้›ฃใ—ใใชใ„
โœ… ๆ€–ใใชใ„
โœ… ่งฆใฃใฆใ„ใฆๆฅฝใ—ใ„
โœ… ๆฏŽๆ—ฅ่ฆ‹ใŸใใชใ‚‹
โ† ใƒžใƒใƒผใƒ„ใƒผใƒซใธๆˆปใ‚‹