1 parent
cc5d61af16
commit
0ce95688d5
15 files changed
+5015
-989
No files matched your search
@@ -1,308 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>墨水屏倒计时 Pro - 动态阵列版</title>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
||||||
<style>
|
|
||||||
:root { --ep-black: #000000; --ep-red: #ff0000; --ep-white: #ffffff; }
|
|
||||||
body { font-family: "PingFang SC", "STHeiti", sans-serif; background: #f0f2f5; display: flex; flex-direction: column; align-items: center; padding: 20px; gap: 20px; }
|
|
||||||
|
|
||||||
/* --- 4.2寸预览区 (400x300) --- */
|
|
||||||
#capture-area {
|
|
||||||
width: 400px; height: 300px;
|
|
||||||
background: var(--ep-white);
|
|
||||||
border: 1px solid #000;
|
|
||||||
display: flex; flex-direction: column;
|
|
||||||
box-sizing: border-box; overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-date {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px; right: 12px;
|
|
||||||
font-size: 10px;
|
|
||||||
color: var(--ep-black);
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: right;
|
|
||||||
line-height: 1.2;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
text-align: left;
|
|
||||||
padding: 12px 0 8px 15px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
#title-text {
|
|
||||||
color: var(--ep-black);
|
|
||||||
border-left: 5px solid var(--ep-red);
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 10px;
|
|
||||||
font-weight: 900;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- 阵列布局容器 --- */
|
|
||||||
.exam-grid-preview {
|
|
||||||
padding: 0 12px 12px 12px;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
align-content: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- 矩形卡片样式 --- */
|
|
||||||
.preview-card {
|
|
||||||
border: 2px solid var(--ep-black);
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px;
|
|
||||||
position: relative;
|
|
||||||
background: white;
|
|
||||||
text-align: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-important-card {
|
|
||||||
border: 4px solid var(--ep-red) !important;
|
|
||||||
}
|
|
||||||
.is-important-card::after {
|
|
||||||
content: "★";
|
|
||||||
position: absolute;
|
|
||||||
top: 4px; right: 6px;
|
|
||||||
color: var(--ep-red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ep-black);
|
|
||||||
margin-bottom: 5px;
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-days-info {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-days-val {
|
|
||||||
font-weight: 900;
|
|
||||||
color: var(--ep-red);
|
|
||||||
font-family: 'Arial Black', sans-serif;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.preview-unit {
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ep-black);
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- 管理区 --- */
|
|
||||||
.admin-panel { width: 520px; background: white; padding: 20px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
|
|
||||||
.input-card { display: flex; gap: 8px; margin-bottom: 15px; align-items: center; background: #f8f9fa; padding: 12px; border-radius: 8px; }
|
|
||||||
.input-card input { padding: 8px; border: 1px solid #ddd; border-radius: 4px; }
|
|
||||||
|
|
||||||
#sortable-list { list-style: none; padding: 0; margin: 0; }
|
|
||||||
.manage-item {
|
|
||||||
display: flex; align-items: center; gap: 12px;
|
|
||||||
background: #fff; border: 1px solid #eee; margin-bottom: 8px;
|
|
||||||
padding: 10px; border-radius: 6px; cursor: move;
|
|
||||||
}
|
|
||||||
.drag-handle { color: #ccc; cursor: grab; font-size: 20px; user-select: none; }
|
|
||||||
.manage-info { flex-grow: 1; display: flex; gap: 8px; }
|
|
||||||
.manage-info input[type="text"] { flex: 2; }
|
|
||||||
.btn-del { background: #ff4d4f; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; }
|
|
||||||
|
|
||||||
.action-btns { display: flex; gap: 10px; margin-top: 20px; }
|
|
||||||
.btn-main { flex: 1; padding: 12px; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; }
|
|
||||||
.btn-save { background: var(--ep-red); color: white; }
|
|
||||||
.btn-data { background: #555; color: white; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="capture-area">
|
|
||||||
<div class="top-date" id="live-date"></div>
|
|
||||||
<div class="header">
|
|
||||||
<h1 id="title-text">倒计时看板</h1>
|
|
||||||
</div>
|
|
||||||
<div class="exam-grid-preview" id="preview-container"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="admin-panel">
|
|
||||||
<h3 style="margin-top:0; border-left: 4px solid var(--ep-red); padding-left: 10px;">项目管理</h3>
|
|
||||||
|
|
||||||
<div class="input-card">
|
|
||||||
<input type="text" id="name-in" placeholder="项目名称">
|
|
||||||
<input type="date" id="date-in">
|
|
||||||
<label style="font-size:13px; cursor:pointer"><input type="checkbox" id="imp-in"> 重要</label>
|
|
||||||
<button onclick="addItem()" style="background:#000; color:white; border:none; padding:8px 15px; border-radius:4px; cursor:pointer">添加</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul id="sortable-list"></ul>
|
|
||||||
|
|
||||||
<div class="action-btns">
|
|
||||||
<button class="btn-main btn-data" onclick="exportJSON()">备份</button>
|
|
||||||
<button class="btn-main btn-data" onclick="document.getElementById('file-in').click()">恢复</button>
|
|
||||||
<input type="file" id="file-in" style="display:none" onchange="importJSON(this)">
|
|
||||||
<button class="btn-main btn-save" onclick="downloadImage()">保存 400x300 图片</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const getTodayStr = () => new Date().toISOString().split('T')[0];
|
|
||||||
|
|
||||||
let exams = JSON.parse(localStorage.getItem('dragExamGridV2')) || [
|
|
||||||
{ name: "期末大考", date: "2026-06-20", imp: true },
|
|
||||||
{ name: "驾照预约", date: getTodayStr(), imp: false }
|
|
||||||
];
|
|
||||||
|
|
||||||
function updateLiveDate() {
|
|
||||||
const now = new Date();
|
|
||||||
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
|
||||||
document.getElementById('live-date').innerHTML = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日<br>${weekDays[now.getDay()]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sortable.create(document.getElementById('sortable-list'), {
|
|
||||||
animation: 150, handle: '.drag-handle', onEnd: () => saveOrder()
|
|
||||||
});
|
|
||||||
|
|
||||||
function calculateDays(targetDate) {
|
|
||||||
const today = new Date().setHours(0,0,0,0);
|
|
||||||
const target = new Date(targetDate).setHours(0,0,0,0);
|
|
||||||
const diff = target - today;
|
|
||||||
return Math.ceil(diff / (1000 * 60 * 60 * 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderAll() {
|
|
||||||
renderPreview();
|
|
||||||
renderManageList();
|
|
||||||
updateLiveDate();
|
|
||||||
localStorage.setItem('dragExamGridV2', JSON.stringify(exams));
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderPreview() {
|
|
||||||
const container = document.getElementById('preview-container');
|
|
||||||
container.innerHTML = '';
|
|
||||||
const count = exams.length;
|
|
||||||
|
|
||||||
// 1. 动态确定网格布局
|
|
||||||
let cols = 2;
|
|
||||||
if (count === 1) cols = 1;
|
|
||||||
else if (count > 4) cols = 3;
|
|
||||||
container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
|
|
||||||
|
|
||||||
// 2. 根据数量动态计算字体大小 (单位 px)
|
|
||||||
// 逻辑:项目越少,字号越大
|
|
||||||
let baseNameSize, baseNumSize, starSize;
|
|
||||||
if (count <= 1) {
|
|
||||||
baseNameSize = 64; baseNumSize = 80; starSize = 36;
|
|
||||||
} else if (count <= 2) {
|
|
||||||
baseNameSize = 24; baseNumSize = 64; starSize = 20;
|
|
||||||
} else if (count <= 4) {
|
|
||||||
baseNameSize = 18; baseNumSize = 48; starSize = 16;
|
|
||||||
} else {
|
|
||||||
baseNameSize = 14; baseNumSize = 32; starSize = 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
exams.forEach(item => {
|
|
||||||
const days = calculateDays(item.date);
|
|
||||||
let dayHTML = '';
|
|
||||||
|
|
||||||
if (days === 0) {
|
|
||||||
dayHTML = `<span class="preview-days-val" style="font-size:${baseNumSize * 0.6}px">今天</span>`;
|
|
||||||
} else if (days < 0) {
|
|
||||||
dayHTML = `<span class="preview-days-val" style="font-size:${baseNumSize * 0.6}px; color:#666">已过</span>`;
|
|
||||||
} else {
|
|
||||||
dayHTML = `<span class="preview-days-val" style="font-size:${baseNumSize}px">${days}</span>
|
|
||||||
<span class="preview-unit" style="font-size:${baseNumSize * 0.3}px">天</span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.innerHTML += `
|
|
||||||
<div class="preview-card ${item.imp ? 'is-important-card' : ''}">
|
|
||||||
${item.imp ? `<style>.is-important-card::after{font-size:${starSize}px}</style>` : ''}
|
|
||||||
<div class="preview-name" style="font-size:${baseNameSize}px">${item.name}</div>
|
|
||||||
<div class="preview-days-info">
|
|
||||||
${dayHTML}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderManageList() {
|
|
||||||
const list = document.getElementById('sortable-list');
|
|
||||||
list.innerHTML = '';
|
|
||||||
exams.forEach((item, index) => {
|
|
||||||
list.innerHTML += `
|
|
||||||
<li class="manage-item" data-index="${index}">
|
|
||||||
<span class="drag-handle">☰</span>
|
|
||||||
<div class="manage-info">
|
|
||||||
<input type="text" value="${item.name}" onchange="updateItem(${index}, 'name', this.value)">
|
|
||||||
<input type="date" value="${item.date}" onchange="updateItem(${index}, 'date', this.value)">
|
|
||||||
<label><input type="checkbox" ${item.imp?'checked':''} onchange="updateItem(${index}, 'imp', this.checked)"> 重要</label>
|
|
||||||
</div>
|
|
||||||
<button class="btn-del" onclick="removeItem(${index})">×</button>
|
|
||||||
</li>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function updateItem(index, key, value) {
|
|
||||||
exams[index][key] = value;
|
|
||||||
renderPreview();
|
|
||||||
localStorage.setItem('dragExamGridV2', JSON.stringify(exams));
|
|
||||||
}
|
|
||||||
function saveOrder() {
|
|
||||||
const newExams = [];
|
|
||||||
document.querySelectorAll('.manage-item').forEach(el => {
|
|
||||||
newExams.push(exams[el.getAttribute('data-index')]);
|
|
||||||
});
|
|
||||||
exams = newExams;
|
|
||||||
renderAll();
|
|
||||||
}
|
|
||||||
function addItem() {
|
|
||||||
const n = document.getElementById('name-in').value;
|
|
||||||
const d = document.getElementById('date-in').value;
|
|
||||||
const i = document.getElementById('imp-in').checked;
|
|
||||||
if(n && d) {
|
|
||||||
exams.push({name:n, date:d, imp:i});
|
|
||||||
renderAll();
|
|
||||||
document.getElementById('name-in').value = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function removeItem(index) {
|
|
||||||
exams.splice(index, 1);
|
|
||||||
renderAll();
|
|
||||||
}
|
|
||||||
function downloadImage() {
|
|
||||||
html2canvas(document.getElementById('capture-area'), { width: 400, height: 300, scale: 2 })
|
|
||||||
.then(canvas => {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.download = `Grid_Countdown.png`;
|
|
||||||
link.href = canvas.toDataURL();
|
|
||||||
link.click();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function exportJSON() {
|
|
||||||
const blob = new Blob([JSON.stringify(exams)], {type: 'application/json'});
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = URL.createObjectURL(blob); a.download = 'exams.json'; a.click();
|
|
||||||
}
|
|
||||||
function importJSON(input) {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = e => { exams = JSON.parse(e.target.result); renderAll(); };
|
|
||||||
reader.readAsText(input.files[0]);
|
|
||||||
}
|
|
||||||
renderAll();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>墨水屏标语倒计时 - 红黑版</title>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
||||||
<style>
|
|
||||||
:root { --ep-black: #000000; --ep-red: #ff0000; --ep-white: #ffffff; }
|
|
||||||
body { font-family: "PingFang SC", "Microsoft YaHei", sans-serif; background: #f4f4f4; display: flex; flex-direction: column; align-items: center; padding: 30px; }
|
|
||||||
|
|
||||||
/* --- 4.2寸预览区 (400x300) --- */
|
|
||||||
#capture-area {
|
|
||||||
width: 400px; height: 300px;
|
|
||||||
background: var(--ep-white);
|
|
||||||
border: 2px solid #000;
|
|
||||||
display: flex; flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box; overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 顶部日期栏 */
|
|
||||||
.top-date {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ep-black);
|
|
||||||
letter-spacing: 1px;
|
|
||||||
border-bottom: 1px solid var(--ep-black);
|
|
||||||
padding-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 核心标语区 - 居中特大号 */
|
|
||||||
.motto-section {
|
|
||||||
width: 90%;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
#editable-motto {
|
|
||||||
font-size: 42px; /* 进一步放大 */
|
|
||||||
font-weight: 900;
|
|
||||||
color: var(--ep-black);
|
|
||||||
margin: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 1.1;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 分割点 */
|
|
||||||
.dot-divider {
|
|
||||||
margin: 15px 0;
|
|
||||||
font-size: 20px;
|
|
||||||
color: var(--ep-red);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 倒计时展示区 */
|
|
||||||
.countdown-section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.event-label {
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #444;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.days-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.days-num {
|
|
||||||
font-size: 85px; /* 巨型数字 */
|
|
||||||
font-family: 'Arial Black', sans-serif;
|
|
||||||
font-weight: 900;
|
|
||||||
line-height: 0.85;
|
|
||||||
color: var(--ep-red); /* 改为红色 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.days-unit {
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ep-black);
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 管理面板 */
|
|
||||||
.admin-panel {
|
|
||||||
width: 400px; background: white; padding: 25px;
|
|
||||||
border-radius: 12px; margin-top: 20px;
|
|
||||||
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.input-item { margin-bottom: 15px; display: flex; flex-direction: column; gap: 5px; }
|
|
||||||
.input-item label { font-size: 13px; font-weight: bold; color: #666; }
|
|
||||||
.input-item input { padding: 10px; border: 1px solid #ccc; border-radius: 6px; }
|
|
||||||
|
|
||||||
.btn-save {
|
|
||||||
width: 100%; padding: 12px; border: none; border-radius: 6px;
|
|
||||||
font-weight: bold; cursor: pointer; background: var(--ep-red); color: white;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="capture-area">
|
|
||||||
<div class="top-date" id="live-date">2026 / 04 / 17 FRIDAY</div>
|
|
||||||
|
|
||||||
<div class="motto-section">
|
|
||||||
<h1 id="editable-motto" onclick="editMotto()" title="点击修改标语">新婚快乐</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dot-divider">✦ ✦ ✦</div>
|
|
||||||
|
|
||||||
<div class="countdown-section" id="countdown-display">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="admin-panel">
|
|
||||||
<div class="input-item">
|
|
||||||
<label>目标事件描述</label>
|
|
||||||
<input type="text" id="event-name" placeholder="例如:距离考研/周年庆">
|
|
||||||
</div>
|
|
||||||
<div class="input-item">
|
|
||||||
<label>目标日期</label>
|
|
||||||
<input type="date" id="target-date">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn-save" onclick="saveImage()">下载 400x300 图片</button>
|
|
||||||
<p style="font-size:12px; color:#999; text-align:center; margin-top:12px">提示:直接点击图片中的“黑色大字”可改写标语</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let config = JSON.parse(localStorage.getItem('ep_red_cfg')) || {
|
|
||||||
motto: "保持热爱",
|
|
||||||
label: "距离考研",
|
|
||||||
date: "2026-12-21"
|
|
||||||
};
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
// 填充表单默认值
|
|
||||||
document.getElementById('event-name').value = config.label;
|
|
||||||
document.getElementById('target-date').value = config.date;
|
|
||||||
render();
|
|
||||||
updateDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDate() {
|
|
||||||
const n = new Date();
|
|
||||||
const weeks = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'];
|
|
||||||
document.getElementById('live-date').innerText = `${n.getFullYear()} / ${String(n.getMonth()+1).padStart(2,'0')} / ${String(n.getDate()).padStart(2,'0')} ${weeks[n.getDay()]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function editMotto() {
|
|
||||||
const val = prompt("请输入顶端大标语:", config.motto);
|
|
||||||
if (val) {
|
|
||||||
config.motto = val;
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function render() {
|
|
||||||
const label = document.getElementById('event-name').value || "距离目标";
|
|
||||||
const date = document.getElementById('target-date').value || "2026-12-31";
|
|
||||||
|
|
||||||
// 更新配置
|
|
||||||
config.label = label;
|
|
||||||
config.date = date;
|
|
||||||
document.getElementById('editable-motto').innerText = config.motto;
|
|
||||||
|
|
||||||
const target = new Date(date).setHours(0,0,0,0);
|
|
||||||
const today = new Date().setHours(0,0,0,0);
|
|
||||||
const diff = Math.ceil((target - today) / (1000 * 60 * 60 * 24));
|
|
||||||
|
|
||||||
let displayNum = diff;
|
|
||||||
let unit = "DAYS";
|
|
||||||
|
|
||||||
if (diff === 0) { displayNum = "0"; }
|
|
||||||
else if (diff < 0) { displayNum = "!"; unit = "OVER"; }
|
|
||||||
|
|
||||||
document.getElementById('countdown-display').innerHTML = `
|
|
||||||
<div class="event-label">${label}</div>
|
|
||||||
<div class="days-container">
|
|
||||||
<span class="days-num">${displayNum}</span>
|
|
||||||
<span class="days-unit">${unit}</span>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
localStorage.setItem('ep_red_cfg', JSON.stringify(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听输入
|
|
||||||
document.getElementById('event-name').addEventListener('input', render);
|
|
||||||
document.getElementById('target-date').addEventListener('input', render);
|
|
||||||
|
|
||||||
function saveImage() {
|
|
||||||
html2canvas(document.getElementById('capture-area'), {
|
|
||||||
width: 400,
|
|
||||||
height: 300,
|
|
||||||
scale: 2
|
|
||||||
}).then(canvas => {
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.download = `EInk_Countdown_Red.png`;
|
|
||||||
a.href = canvas.toDataURL();
|
|
||||||
a.click();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,619 @@
|
|||||||
|
:root {
|
||||||
|
--primary-color: #0d6efd;
|
||||||
|
--primary-hover: #0b5ed7;
|
||||||
|
--secondary-color: #6c757d;
|
||||||
|
--secondary-hover: #5c636a;
|
||||||
|
|
||||||
|
--dark-bg: #121212;
|
||||||
|
--dark-text: #e0e0e0;
|
||||||
|
--dark-fieldset-bg: #1e1e1e;
|
||||||
|
--dark-border: #333;
|
||||||
|
--dark-code-bg: #2d2d2d;
|
||||||
|
--dark-log-bg: #2a2a2a;
|
||||||
|
--dark-input-bg: #2d2d2d;
|
||||||
|
--dark-input-text: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
border: 1px solid var(--primary-color);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary:hover {
|
||||||
|
color: #fff;
|
||||||
|
border-color: var(--primary-hover);
|
||||||
|
background-color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.secondary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
border-color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.secondary:hover {
|
||||||
|
color: #fff;
|
||||||
|
border-color: var(--secondary-hover);
|
||||||
|
background-color: var(--secondary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
padding-bottom: .3em;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: none;
|
||||||
|
box-shadow: 0 .5rem 0.5rem rgba(0, 0, 0, 0.2);
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset legend {
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgba(0, 0, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: .2em .4em;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 85%;
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=date],
|
||||||
|
input[type=number],
|
||||||
|
select {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #212529;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: .2rem .75rem;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=file] {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #212529;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input::file-selector-button {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
border: 1px solid var(--primary-color);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: .3rem 2.25rem .3rem .75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
select:focus {
|
||||||
|
border: 1px solid #86b7fe;
|
||||||
|
box-shadow: 0 0 4px rgba(0, 120, 215, 0.8);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text]:disabled,
|
||||||
|
input[type=date]:disabled,
|
||||||
|
input[type=number]:disabled,
|
||||||
|
select:disabled {
|
||||||
|
opacity: 0.65;
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: #e9ecef;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-right: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 950px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 1rem;
|
||||||
|
background: #fff;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #666;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .links a {
|
||||||
|
color: #666;
|
||||||
|
text-decoration: none;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .links a:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .links a:not(:last-child)::after {
|
||||||
|
content: "•";
|
||||||
|
position: absolute;
|
||||||
|
right: -4px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a:hover {
|
||||||
|
color: #0d6efd;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-group.right {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
max-height: 300px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
background: #ddd;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
|
||||||
|
box-sizing: border-box;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container .log-line {
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container .time,
|
||||||
|
.log-container .action {
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container .time {
|
||||||
|
color: #333;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container .action {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-panel {
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tabs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab {
|
||||||
|
color: #495057;
|
||||||
|
background: #eef2f6;
|
||||||
|
border-color: #d0d7de;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab:hover {
|
||||||
|
background: #dde5ee;
|
||||||
|
border-color: #c1c9d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab.active {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-header {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-header span {
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-mode-panel {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-item {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-item input[type="text"] {
|
||||||
|
min-width: 120px;
|
||||||
|
flex: 1 1 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-item input[type="date"] {
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-item label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container canvas {
|
||||||
|
border: black solid 1px;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container.crop-mode canvas {
|
||||||
|
border: 2px dashed var(--primary-color);
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-bar {
|
||||||
|
display: none;
|
||||||
|
font-size: 85%;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px dotted #AAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.text-placement-mode {
|
||||||
|
border: 2px dashed var(--primary-color) !important;
|
||||||
|
cursor: text !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-title {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-tools {
|
||||||
|
margin-top: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brush-tools,
|
||||||
|
.text-tools,
|
||||||
|
.crop-tools {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container.brush-mode .brush-tools,
|
||||||
|
.canvas-container.text-mode .brush-tools,
|
||||||
|
.canvas-container.eraser-mode .brush-tools,
|
||||||
|
.canvas-container.text-mode .text-tools,
|
||||||
|
.canvas-container.crop-mode .crop-tools {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container.crop-mode .tool-buttons,
|
||||||
|
.canvas-container.crop-mode .brush-tools,
|
||||||
|
.canvas-container.crop-mode .text-tools {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-button {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 5px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-button:hover {
|
||||||
|
background-color: #e9ecef;
|
||||||
|
border-color: #ced4da;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-button.active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-button.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.flex-container {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tabs {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tab {
|
||||||
|
flex: 1 1 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container.options .flex-group label {
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-group.right {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-tools.flex-container {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-tools .flex-group {
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container {
|
||||||
|
height: 150px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=number],
|
||||||
|
select {
|
||||||
|
max-width: 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .debug {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode,
|
||||||
|
body.dark-mode .main {
|
||||||
|
background-color: var(--dark-bg);
|
||||||
|
color: var(--dark-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode fieldset {
|
||||||
|
background-color: var(--dark-fieldset-bg);
|
||||||
|
box-shadow: 0 .5rem 0.5rem rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode h3 {
|
||||||
|
border-bottom: 1px solid var(--dark-border);
|
||||||
|
color: var(--dark-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode code {
|
||||||
|
background: var(--dark-code-bg);
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type=text],
|
||||||
|
body.dark-mode input[type=date],
|
||||||
|
body.dark-mode input[type=number],
|
||||||
|
body.dark-mode select {
|
||||||
|
background-color: var(--dark-input-bg);
|
||||||
|
color: var(--dark-input-text);
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type=text]:disabled,
|
||||||
|
body.dark-mode input[type=date]:disabled,
|
||||||
|
body.dark-mode input[type=number]:disabled,
|
||||||
|
body.dark-mode select:disabled {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
color: #666;
|
||||||
|
border-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type=file] {
|
||||||
|
color: var(--dark-input-text);
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type=file]::file-selector-button {
|
||||||
|
background-color: var(--dark-fieldset-bg);
|
||||||
|
color: var(--dark-input-text);
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type=file]::file-selector-button:hover {
|
||||||
|
background-color: #333;
|
||||||
|
border-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .log-container {
|
||||||
|
background: var(--dark-log-bg);
|
||||||
|
border: 1px solid var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .log-container .time {
|
||||||
|
color: #8bc34a;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .log-container .action {
|
||||||
|
color: #03a9f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode fieldset legend {
|
||||||
|
color: #64b5f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .footer .links a:not(:last-child)::after {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .footer {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .footer a {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .footer a:hover {
|
||||||
|
color: #64b5f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .tool-button {
|
||||||
|
background-color: var(--dark-input-bg);
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
color: var(--dark-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .tool-button:hover {
|
||||||
|
background-color: #3a3a3a;
|
||||||
|
border-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .tool-button.active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .template-panel,
|
||||||
|
body.dark-mode .template-item {
|
||||||
|
background-color: var(--dark-fieldset-bg);
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .panel-tab {
|
||||||
|
color: var(--dark-text);
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .panel-tab:hover {
|
||||||
|
background-color: #333;
|
||||||
|
border-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .panel-tab.active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
border-color: var(--primary-hover);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .template-header span {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
Loaded 3 of 15 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user