feat: add colorful / accent color mode toggle
- CAT_COLORS: カテゴリ別カラーマップ(ダーク/ライト両対応) - 統一色モード: すべて var(--accent) Teal - カラフルモード: sns=Blue / media=Pink / news=Orange / tools=Slate / nav=Green / shop=Amber / posimai=Teal - カラフル時: アイコン stroke + カード背景・ボーダーに極薄カラーを適用 - セクションラベルもカテゴリ色に追従 - 設定パネルに色ドット付きトグルボタンを追加 - localStorage に設定を保存
This commit is contained in:
parent
9d3cd8510e
commit
d85b825bba
133
index.html
133
index.html
|
|
@ -208,6 +208,44 @@
|
|||
.empty-title { font-size: 14px; font-weight: 500; margin-bottom: 4px; }
|
||||
.empty-sub { font-size: 13px; }
|
||||
|
||||
/* ── Color mode selector ── */
|
||||
.color-mode-selector {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.color-mode-btn {
|
||||
flex: 1;
|
||||
padding: 7px 8px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: transparent;
|
||||
color: var(--text2);
|
||||
font-size: 12px;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: all 0.12s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.color-mode-btn.active {
|
||||
background: var(--surface2);
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.color-dots {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
.color-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* ── Settings extras ── */
|
||||
.settings-field-label {
|
||||
font-size: 12px;
|
||||
|
|
@ -293,6 +331,28 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:20px">
|
||||
<div class="settings-group-label">アイコンカラー</div>
|
||||
<div class="color-mode-selector">
|
||||
<button class="color-mode-btn" data-color-mode="accent" id="colorModeAccent">
|
||||
<span class="color-dots">
|
||||
<span class="color-dot" style="background:#6EE7B7"></span>
|
||||
<span class="color-dot" style="background:#6EE7B7"></span>
|
||||
<span class="color-dot" style="background:#6EE7B7"></span>
|
||||
</span>
|
||||
統一色
|
||||
</button>
|
||||
<button class="color-mode-btn" data-color-mode="colorful" id="colorModeColorful">
|
||||
<span class="color-dots">
|
||||
<span class="color-dot" style="background:#60A5FA"></span>
|
||||
<span class="color-dot" style="background:#F472B6"></span>
|
||||
<span class="color-dot" style="background:#4ADE80"></span>
|
||||
</span>
|
||||
カラフル
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:20px">
|
||||
<div class="settings-group-label">同期(オプション)</div>
|
||||
<p class="settings-field-label">
|
||||
|
|
@ -355,8 +415,31 @@
|
|||
|
||||
const ENABLED_KEY = 'posimai-veil-enabled';
|
||||
const API_KEY_KEY = 'posimai_api_key';
|
||||
const COLOR_MODE_KEY = 'posimai-veil-color-mode';
|
||||
const API_BASE = 'https://posimai-lab.tail72e846.ts.net/brain/api';
|
||||
|
||||
// ── カテゴリカラー(ダーク / ライト) ──────────────────────
|
||||
const CAT_COLORS = {
|
||||
dark: {
|
||||
posimai: '#6EE7B7', // Teal(ブランドカラー)
|
||||
sns: '#60A5FA', // Blue
|
||||
media: '#F472B6', // Pink
|
||||
news: '#FB923C', // Orange
|
||||
tools: '#94A3B8', // Slate
|
||||
nav: '#4ADE80', // Green
|
||||
shop: '#FBBF24', // Amber
|
||||
},
|
||||
light: {
|
||||
posimai: '#059669', // Emerald-600
|
||||
sns: '#2563EB', // Blue-600
|
||||
media: '#DB2777', // Pink-600
|
||||
news: '#EA580C', // Orange-600
|
||||
tools: '#475569', // Slate-600
|
||||
nav: '#16A34A', // Green-600
|
||||
shop: '#D97706', // Amber-600
|
||||
},
|
||||
};
|
||||
|
||||
// ── アプリDB ────────────────────────────────────────────────
|
||||
// android : Androidパッケージ名(_camera/_phone/_settings は特殊intent)
|
||||
// ios : iOS URLスキーム
|
||||
|
|
@ -501,8 +584,18 @@ let enabledIds = loadEnabled();
|
|||
let activeCat = 'all';
|
||||
let searchQ = '';
|
||||
let editMode = false;
|
||||
let colorMode = localStorage.getItem(COLOR_MODE_KEY) || 'accent'; // 'accent' | 'colorful'
|
||||
let apiKey = localStorage.getItem(API_KEY_KEY) || '';
|
||||
|
||||
function getTheme() {
|
||||
return document.documentElement.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
function getCatColor(cat) {
|
||||
if (colorMode !== 'colorful') return 'var(--accent)';
|
||||
return CAT_COLORS[getTheme()][cat] || 'var(--accent)';
|
||||
}
|
||||
|
||||
function loadEnabled() {
|
||||
try {
|
||||
const raw = localStorage.getItem(ENABLED_KEY);
|
||||
|
|
@ -608,21 +701,36 @@ function renderApps() {
|
|||
|
||||
container.innerHTML = orderedCats.map(cat => {
|
||||
const apps = groups[cat];
|
||||
const color = getCatColor(cat);
|
||||
const isColorful = colorMode === 'colorful';
|
||||
|
||||
// カラフルモード時: カードに極薄の色背景+ボーダー
|
||||
const cardColorStyle = isColorful
|
||||
? `--item-color:${color};`
|
||||
: '';
|
||||
|
||||
return `
|
||||
<div class="app-section">
|
||||
<div class="section-label">${CAT_LABELS[cat] || cat}</div>
|
||||
<div class="section-label"
|
||||
style="${isColorful ? `color:${color};opacity:.9` : ''}">${CAT_LABELS[cat] || cat}</div>
|
||||
<div class="app-grid">
|
||||
${apps.map(app => {
|
||||
const on = enabledIds.has(app.id);
|
||||
const hidden = !editMode && !on ? ' hidden' : '';
|
||||
const editCls = editMode ? ` edit-mode ${on ? 'on' : 'off'}` : '';
|
||||
const bgStyle = isColorful
|
||||
? `background:${color}14;border-color:${color}38;`
|
||||
: '';
|
||||
return `
|
||||
<div class="app-item${editCls}${hidden}"
|
||||
data-id="${app.id}" role="button" tabindex="0"
|
||||
aria-label="${app.label}">
|
||||
<i data-lucide="${app.icon}" class="app-icon"></i>
|
||||
aria-label="${app.label}"
|
||||
style="${bgStyle}${cardColorStyle}">
|
||||
<i data-lucide="${app.icon}" class="app-icon"
|
||||
style="stroke:${color}"></i>
|
||||
<span class="app-label">${app.label}</span>
|
||||
<span class="check-badge" aria-hidden="true">
|
||||
<span class="check-badge" aria-hidden="true"
|
||||
style="background:${color}">
|
||||
<i data-lucide="check"
|
||||
style="width:9px;height:9px;stroke-width:3;stroke:#0D0D0D"></i>
|
||||
</span>
|
||||
|
|
@ -666,6 +774,23 @@ document.getElementById('searchInput').addEventListener('input', e => {
|
|||
renderApps();
|
||||
});
|
||||
|
||||
// ── カラーモード切替 ────────────────────────────────────────
|
||||
function syncColorModeUI() {
|
||||
document.getElementById('colorModeAccent').classList.toggle('active', colorMode === 'accent');
|
||||
document.getElementById('colorModeColorful').classList.toggle('active', colorMode === 'colorful');
|
||||
}
|
||||
|
||||
['colorModeAccent', 'colorModeColorful'].forEach(id => {
|
||||
document.getElementById(id).addEventListener('click', () => {
|
||||
colorMode = id === 'colorModeAccent' ? 'accent' : 'colorful';
|
||||
localStorage.setItem(COLOR_MODE_KEY, colorMode);
|
||||
syncColorModeUI();
|
||||
renderApps();
|
||||
});
|
||||
});
|
||||
|
||||
syncColorModeUI();
|
||||
|
||||
// ── API キー保存 ────────────────────────────────────────────
|
||||
document.getElementById('apiKeyInput').value = apiKey;
|
||||
document.getElementById('apiKeySave').addEventListener('click', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue