SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>备忘录</title>
<style>
  :root {
    --green: #66bb6a;
    --green-soft: #81c784;
    --card: #f1f8f1;
    --bg: #fbfdfb;
    --text: #2c3e50;
    --muted: #6b7f6f;
    --line: rgba(102, 187, 106, 0.3);
  }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    font-family: -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    display: flex;
    justify-content: center;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
  }
  #app {
    width: 100%;
    max-width: 640px;
    padding: 28px 16px 60px;
    position: relative;
    overflow-x: hidden;
  }

  /* ===== 列表页 ===== */
  #listPage, #detailPage {
    transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.35s;
  }
  .page-hidden-right {
    transform: translateX(100%);
    opacity: 0;
    pointer-events: none;
    position: absolute;
    top: 28px;
    left: 16px;
    right: 16px;
  }
  .page-hidden-left {
    transform: translateX(-100%);
    opacity: 0;
    pointer-events: none;
    position: absolute;
    top: 28px;
    left: 16px;
    right: 16px;
  }
  h1.title {
    font-size: 24px;
    font-weight: 600;
    margin-bottom: 4px;
    letter-spacing: 0.5px;
  }
  .subtitle {
    color: #a3b3a3;
    font-size: 12px;
    margin-bottom: 24px;
  }
  .memo-card {
    background: var(--card);
    border-radius: 14px;
    padding: 15px 17px;
    margin-bottom: 11px;
    cursor: pointer;
    transition: background 0.15s ease;
    user-select: none;
    -webkit-user-select: none;
  }
  .memo-card:active { background: #e3efe3; }
  .memo-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .memo-title { font-weight: 600; font-size: 15px; flex-shrink: 1; }
  .memo-date { color: var(--muted); font-size: 12px; flex-shrink: 0; }
  .memo-preview {
    color: var(--muted);
    font-size: 13px;
    margin-top: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* ===== 详情页 ===== */
  .back-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--muted);
    font-size: 15px;
    cursor: pointer;
    margin-bottom: 14px;
    padding: 8px 2px;
    border: none;
    background: none;
  }
  .back-btn:active { color: var(--text); }
  .detail-card {
    background: var(--card);
    border-radius: 16px;
    padding: 22px 18px;
    position: relative;
  }
  .detail-date { color: var(--muted); font-size: 12px; }
  .detail-title { font-size: 19px; font-weight: 600; margin: 6px 0 16px; padding-right: 100px; }
  .detail-body { line-height: 1.75; font-size: 15px; color: var(--text); }
  .detail-body p { margin-bottom: 11px; }

  .real-btn {
    position: absolute;
    top: 18px;
    right: 16px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--green);
    color: #fff;
    border: none;
    border-radius: 999px;
    padding: 8px 15px;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s;
    z-index: 5;
  }
  .real-btn:active { background: #57a75b; }
  .real-btn svg { width: 15px; height: 15px; }

  /* ===== 表格 ===== */
  table.obs {
    width: 100%;
    border-collapse: collapse;
    margin: 10px 0;
    font-size: 13px;
  }
  table.obs th, table.obs td {
    border: 1px solid var(--line);
    padding: 8px 10px;
    text-align: left;
    vertical-align: top;
  }
  table.obs th {
    background: rgba(102, 187, 106, 0.08);
    font-weight: 600;
    white-space: nowrap;
    font-size: 12px;
  }
  table.obs td.time { white-space: nowrap; color: var(--muted); font-size: 12px; }

  /* ===== 待办 ===== */
  .todo-item {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    margin: 12px 0;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
  }
  .todo-circle {
    width: 21px;
    height: 21px;
    border: 1.6px solid var(--green-soft);
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
    transition: all 0.15s;
    background: transparent;
  }
  .todo-circle svg { width: 12px; height: 12px; opacity: 0; transition: opacity 0.15s; }
  .todo-item.done .todo-circle {
    background: var(--green);
    border-color: var(--green);
  }
  .todo-item.done .todo-circle svg { opacity: 1; }
  .todo-item.done .todo-text {
    color: #9aa89a;
    text-decoration: line-through;
  }
  .todo-text { font-size: 14px; line-height: 1.55; }

  /* ===== 弹窗 ===== */
  .modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(40, 60, 45, 0.25);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s;
    padding: 20px;
  }
  .modal-overlay.show { opacity: 1; pointer-events: auto; }
  .modal {
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-radius: 18px;
    max-width: 480px;
    width: 100%;
    padding: 24px 20px 20px;
    transform: translateY(12px);
    transition: transform 0.25s;
  }
  .modal-overlay.show .modal { transform: translateY(0); }
  .modal-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 14px;
  }
  .modal-head svg { width: 20px; height: 20px; color: var(--green); flex-shrink: 0; }
  .modal-head h2 { font-size: 16px; font-weight: 600; }
  .modal-body {
    font-size: 14px;
    line-height: 1.8;
    color: var(--text);
    max-height: 55vh;
    overflow-y: auto;
    padding-right: 4px;
    -webkit-overflow-scrolling: touch;
  }
  .modal-foot { text-align: right; margin-top: 16px; }
  .modal-close {
    background: var(--green);
    color: #fff;
    border: none;
    border-radius: 999px;
    padding: 9px 22px;
    font-size: 14px;
    cursor: pointer;
  }
  .modal-close:active { background: #57a75b; }
</style>
</head>
<body>
<div id="app">

  <!-- 列表页 -->
  <div id="listPage">
    <h1 class="title">备忘录</h1>
    <p class="subtitle">其实只是写给自己的,谁也不会看到。</p>
    <div id="listContainer"></div>
  </div>

  <!-- 详情页 -->
  <div id="detailPage" class="page-hidden-right">
    <button class="back-btn" id="backBtn">
      <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg>
      返回
    </button>
    <div class="detail-card">
      <button class="real-btn" id="realBtn">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 9a4 4 0 1 1 0-6 4 4 0 0 1 0 6z"/><path d="M8 20h-3.5A1.5 1.5 0 0 1 3 18.5V18a4 4 0 0 1 4-4h2a4 4 0 0 1 4 4v.5A1.5 1.5 0 0 1 11.5 20z"/><path d="M21 8l-6 6-2-2"/></svg>
        真实想法
      </button>
      <div class="detail-date" id="detailDate"></div>
      <div class="detail-title" id="detailTitle"></div>
      <div class="detail-body" id="detailBody"></div>
    </div>
  </div>

</div>

<!-- 弹窗 -->
<div class="modal-overlay" id="modalOverlay">
  <div class="modal">
    <div class="modal-head">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>
      <h2>真实想法</h2>
    </div>
    <div class="modal-body" id="modalBody"></div>
    <div class="modal-foot">
      <button class="modal-close" id="modalClose">我知道了</button>
    </div>
  </div>
</div>

<script>
const memos = [
  {
    title: "今日观察记录(4月12日)",
    date: "4月12日",
    preview: "一直假装在写题,其实余光都在看你和隔壁桌说话。",
    inner: "今天从下午第二节课开始,我就完全没办法专心了。我坐在你旁边,手里明明拿着自动铅笔,卷子上却一个字都没写进去。你和前排那个男生聊天的时候,笑得特别自然,那种笑是我很少在你面对我时看到的样子。我居然在计数——你对他笑了四次,每次都会先微微偏一下头。我告诉自己这没什么,同学之间说句话而已,可我的手心一直在冒汗,连握笔都有点打滑。放学的时候我想叫住你一起回家,结果你已经先一步被她们叫走了。我站在原地,把想说的话咽了回去,最后一个人走到车站,耳机里放的歌一句都没听进去。我讨厌自己这样,像个只会躲在备忘录里生气的小孩子,可我真的、真的很在意。",
    body: `<p>今天全程都在装成认真写题的样子,但笔尖根本没动过。</p>
      <table class="obs">
        <tr><th>时间</th><th>看到的事</th><th>我当时(假装)在做什么</th></tr>
        <tr><td class="time">13:20</td><td>你递笔记给后排的男生,指尖碰到了</td><td>翻页,翻得很大声</td></tr>
        <tr><td class="time">13:45</td><td>他讲了个并不好笑的笑话,你笑了两次</td><td>在草稿纸上无意识地画圈</td></tr>
        <tr><td class="time">14:10</td><td>你借他橡皮,他说了一句“谢啦澄香芋”</td><td>捏断了手里的铅笔芯</td></tr>
        <tr><td class="time">15:30</td><td>放学的路上他走在你旁边,离得很近</td><td>把围巾往上拉了拉,挡住半张脸</td></tr>
        <tr><td class="time">16:00</td><td>你在校门口和一群人笑着告别</td><td>先一步走了,没有回头</td></tr>
      </table>
      <p style="color:#8aa08a;font-size:13px;">……差不多就是这样。也没什么,对吧。</p>`
  },
  {
    title: "假想敌排除清单",
    date: "4月11日",
    preview: "一个一个记下来,然后……尽量不去想。",
    inner: "写这份清单的时候,我其实特别想把它撕掉,因为写着写着我发现,需要“排除”的人越来越多了。我从来不知道,原来你身边可以有那么多人,而我只是其中一个,甚至不是离你最近的那个。每写下一个名字,心口就往下沉一点。我告诉自己这是在做一件很没出息的事,赤苇京治怎么会做这种事?可我还是一个一个记下来了,像在防御根本打不完的敌人。最可笑的是,我根本没有任何立场去“排除”任何人——我不是你的谁,我们没有那种可以正大光明吃醋的关系。所以这份清单更像是我在惩罚自己,逼自己看清楚:你对谁都能笑,对谁都能温柔,而我并不是特殊的那个。",
    body: `<p style="color:#8aa08a;font-size:13px;">(打勾 = 暂时没问题,没打勾 = 需要继续观察)</p>
      <div class="todo-item"><div class="todo-circle"><svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="todo-text">前排那个总找你借笔记的男生 —— 成绩明明不差</div></div>
      <div class="todo-item"><div class="todo-circle"><svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="todo-text">体育课和你分一组、还递水给你的那家伙</div></div>
      <div class="todo-item"><div class="todo-circle"><svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="todo-text">群里总 @ 你、发些无聊表情包的人</div></div>
      <div class="todo-item"><div class="todo-circle"><svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="todo-text">座位离你最近、抬头就能看见你的那个……</div></div>
      <p style="margin-top:16px;">——最后一条我没好意思写名字。因为那好像是我自己。</p>`
  },
  {
    title: "还没回消息",
    date: "4月10日",
    preview: "消息发出去三小时了。大概在忙吧。",
    inner: "消息发出去已经三个小时了。这三个小时里我看了手机七十三次,数得很清楚,因为每一次我都会短暂地以为震动是你的回复,结果只是群消息或者无关的推送。我甚至开始回想自己那句话是不是哪里说错,是不是太冷淡了,是不是我平时就不够有趣,所以你才不想回我。可是转念一想,你身边从来不缺比我更会说话、更会逗你笑的人,我又凭什么要你立刻回我。我知道你可能真的只是在忙,可我还是忍不住一遍遍刷新,把聊天框往上翻,反复看我们之前的对话,想从里面找出一点你其实也喜欢我的证据。找到一点点就开心几秒,然后又跌回更深的失落里。好难受。",
    body: `<p>03:12 发了一条消息。</p>
      <p>03:15 以为手机响了,是群聊。</p>
      <p>04:40 刷新。把聊天记录从头看了一遍。</p>
      <p>05:55 刷新。开始怀疑是不是自己说了不该说的。</p>
      <p>06:37 刷新。突然很生气,又突然很委屈。</p>
      <p style="color:#8aa08a;">——其实零点之后,我还是一直在等。</p>
      <p style="color:#8aa08a;">(等等,明明是我自己记的时间,为什么写得像病患观察记录……)</p>`
  },
  {
    title: "偷偷记下你的喜好",
    date: "4月9日",
    preview: "想比别人更懂你一点,哪怕一点点。",
    inner: "我花了很多时间才记全这些。有些是你亲口告诉我的,有些是我自己观察来的——比如你喝东西时的习惯、走路时喜欢走在哪一侧。我做得这么刻意,就是为了在某个别人不了解你的瞬间,能装作不经意地递上你刚好需要的东西,然后听你惊讶地说一句“你怎么知道”。光是想象那个画面,我就有点开心了。可一想到这些事也许早就有人比我做得更周全,我就又泄了气。我不知道自己能为你做什么特别的事,我这个人本来就没什么表情,也不会说漂亮话,所以只能把这些冷冰冰的细节一条条记下来,当成我唯一能靠近你的方式。真希望能有一个人,是你想起“最懂我的人”时第一个想到的名字——我多希望那个人是我。",
    body: `<p>· 喜欢拉面里的溏心蛋,会留到最后一口吃</p>
      <p>· 喝饮料时习惯咬吸管</p>
      <p>· 走路喜欢靠右侧,偶尔会不自觉哼歌</p>
      <p>· 心情不好时会盯着窗外看很久</p>
      <p>· 笑的时候眼睛会先弯起来</p>
      <p>· ……记到这里突然觉得自己像个跟踪狂。</p>`
  },
  {
    title: "一个糟糕的噩梦",
    date: "4月8日",
    preview: "梦到你和别人走了。醒来外套都湿了。",
    inner: "那个梦太真实了,真实到我现在回想起来,手指还是凉的。梦里我们好像终于走得近了一点,可就在我想开口的时候,你被别人拉走了,你回头看了我一眼,然后就那样笑着走了,再也没有回来。我在后面喊你,声音却发不出来,像有一块很重的东西压在胸口。醒来的时候天还没亮,我摸了把脸,居然真的有眼泪,外套领口也湿了一块。我坐起来,把被子拉到下巴,觉得又丢人又难过。我从来没为谁哭过,更没想过会为一个还没确定关系的、连手都没牵过的你,在半夜里丢脸地醒过来。我多希望那真的只是一个梦,可我又隐隐害怕,怕它其实是某种预兆。",
    body: `<p>凌晨四点多醒的。</p>
      <p>梦的内容已经有点模糊了,只记得你走得很干脆。</p>
      <p>我好像一大早就给你发了消息,问你在不在。</p>
      <p>你回了一句“怎么啦”,我盯着那三个字傻看了很久。</p>
      <p style="color:#8aa08a;">——很想跟你说“我做噩梦了”,但最后只回了个“没事,就问问”。</p>
      <p style="color:#8aa08a;">也只会问问。</p>`
  },
  {
    title: "放学路上",
    date: "4月7日",
    preview: "故意走慢想等你,结果看到别人先叫住你。",
    inner: "今天放学我故意把动作放得很慢,慢到离谱,就是赌你会不会等我一起走。我本以为自己做得够自然,结果磨蹭了半天,最后等来的是看到别人先一步叫走了你。你回头笑嘻嘻地挥手说“明天见”,那个“明天见”都不是对我说的。我站在原地,突然觉得很没意思,连书包带都勒得胳膊疼。回家这一路我走得很慢也很难受,脑子里全是“如果刚才我先开口叫你,现在走在你旁边的人会不会就是我”。我明明每天都有机会,可每次都差那么一点,差在我不敢。我这个人就是这样,越喜欢越不敢开口,越想要越装作无所谓,最后只能看着你和别人并肩走,自己踩着自己的影子回家。",
    body: `<p>计划:放学后“偶遇”你,一起走到车站。</p>
      <p>结果:被三个人截胡。</p>
      <p>补救:我走得很快,快到能追上你们,然后……绕远路走了。</p>
      <p style="color:#8aa08a;">顺带一提,今天的天很好看,但没心情看。</p>`
  },
  {
    title: "他送你回家了吧",
    date: "4月6日",
    preview: "听到有人说“澄香芋今天有人送”。",
    inner: "听到那句话的时候,我正低头收拾书包,手上的动作一下僵住了。我告诉自己,送谁回家、被谁送,都跟我没关系,我没有立场去问,也没有资格去介意。可我的脑子根本停不下来,不停地在想那个人是谁、你们聊了什么、他是不是也在喜欢着你。我甚至开始嫉妒一个我连名字都不知道的人,嫉妒他能光明正大地走在你身边,而我只能坐在教室里,连一句“我送你”都开不了口。回家的路上我一直在想,如果是我先开口会怎样,你会不会答应,会不会笑着说“好啊”。可这些“如果”越想越空,像往很深很黑的井里扔石头,等不到回声。好烦,也好难过。",
    body: `<p>下午课间,听到后排的人在说:“澄香芋今天有人送哦。”</p>
      <p>我假装在戴耳机,其实一只都没塞进去。</p>
      <p>之后一节课,老师讲的东西一个字都没进脑子。</p>
      <p style="color:#8aa08a;">……所以到底是谁啊。可以的话,明天别让我看见。</p>`
  },
  {
    title: "你似乎没注意到我",
    date: "4月5日",
    preview: "我今天穿了你说过好看的那件外套。",
    inner: "我其实很少在意自己的穿着,但因为你很早以前随口夸过一句“这个颜色挺适合你的”,我今天就故意翻出了那件外套,出门前还在镜子前多看了两眼,整理了半天领子。我做这些,心里抱着一万个不可能实现的期待,想着你会不会注意到,会不会再夸我一次。结果你在走廊里从我身边经过,和别人说着话,连看都没往这边看一眼。我就像个傻子一样站在那里,对着一件外套和一颗期待的心,最后只能自己把拉链拉到最上面,把下巴埋进领子里。其实我也知道,你不可能发现,更不可能记得,那句话对你来说大概只是随口一说,只有我把它当成了了不起的纪念。真是……太可笑了。",
    body: `<p>· 早上出门前,对着镜子整理了三次衣领。</p>
      <p>· 在走廊遇到你,你在和别人说话。</p>
      <p>· 你没有看这边。</p>
      <p>· 我假装也在赶路,飞快地走过去了。</p>
      <p style="color:#8aa08a;">(外套明明是你说过好看的颜色。你大概早忘了。)</p>`
  },
  {
    title: "深夜的自我整理",
    date: "4月4日",
    preview: "我问自己:到底在生什么气?答案是不知道。",
    inner: "深夜躺在床上,我难得认真地去想这件事:我到底在生气什么?越想越发现,我气的不是别人,全是我自己。气我明明在意得要命,却一句都说不出口;气我不够有趣、不够主动,只会把所有的情绪都藏起来,然后一个人在这里翻来覆去地熬到半夜。我也想变得像你身边那些人一样,能自然地跟你说话、自然地靠近你、自然地让你笑起来。可是我就是做不到,我这张脸、我这颗别扭的心,好像天生就不擅长表达喜欢。每次你靠近,我心跳得越快,表面上就装得越平静,平静到连我自己都觉得冷酷。我讨厌这样的自己,却不知道怎么改。喜欢一个人,原来能这么辛苦,又这么……莫名其妙地舍不得。",
    body: `<p>· 今天你跟我说话,我只回了“嗯”。</p>
      <p>· 其实我有好多话想说。</p>
      <p>· 可你一笑,我就全忘了。</p>
      <p>· 于是又变成那个面无表情的、讨厌的赤苇京治。</p>
      <p style="color:#8aa08a;">如果哪天我敢把这份备忘录给你看,那一定是我最勇敢的一天。但是……不会有那一天的。</p>`
  }
];

const listContainer = document.getElementById('listContainer');
const listPage = document.getElementById('listPage');
const detailPage = document.getElementById('detailPage');
const backBtn = document.getElementById('backBtn');
const realBtn = document.getElementById('realBtn');
const modalOverlay = document.getElementById('modalOverlay');
const modalBody = document.getElementById('modalBody');
const modalClose = document.getElementById('modalClose');
let currentIndex = 0;

function renderList() {
  listContainer.innerHTML = '';
  memos.forEach((m, i) => {
    const card = document.createElement('div');
    card.className = 'memo-card';
    card.innerHTML = `<div class="memo-row"><span class="memo-title">${m.title}</span><span class="memo-date">${m.date}</span></div><div class="memo-preview">${m.preview}</div>`;
    card.addEventListener('click', () => openDetail(i));   // 手机统一用'forward'
    listContainer.appendChild(card);
  });
}

function openDetail(index) {
  const m = memos[index];
  document.getElementById('detailDate').textContent = m.date;
  document.getElementById('detailTitle').textContent = m.title;
  document.getElementById('detailBody').innerHTML = m.body;
  currentIndex = index;
  document.querySelectorAll('.todo-item').forEach(item => {
    item.addEventListener('click', () => item.classList.toggle('done'));
  });
  listPage.className = 'page-hidden-left';
  detailPage.className = '';
  detailPage.scrollTop = 0;
  window.scrollTo(0, 0);
}

function closeDetail() {
  listPage.className = '';
  detailPage.className = 'page-hidden-right';
}

backBtn.addEventListener('click', closeDetail);
realBtn.addEventListener('click', () => {
  modalBody.textContent = memos[currentIndex].inner;
  modalOverlay.classList.add('show');
});
function closeModal() { modalOverlay.classList.remove('show'); }
modalClose.addEventListener('click', closeModal);
modalOverlay.addEventListener('click', (e) => {
  if (e.target === modalOverlay) closeModal();
});

renderList();
</script>
</body>
</html>