{
  "config": {
    "argv": [
      "/opt/hostedtoolcache/node/20.20.2/x64/bin/node",
      "/home/runner/work/dr-card-web/dr-card-web/node_modules/.bin/playwright",
      "test",
      "tests/e2e/test-gate.spec.ts"
    ],
    "configFile": "/home/runner/work/dr-card-web/dr-card-web/playwright.config.ts",
    "rootDir": "/home/runner/work/dr-card-web/dr-card-web/tests/e2e",
    "failOnFlakyTests": false,
    "forbidOnly": true,
    "fullyParallel": true,
    "globalSetup": null,
    "globalTeardown": null,
    "globalTimeout": 0,
    "grep": {},
    "grepInvert": null,
    "maxFailures": 0,
    "metadata": {
      "ci": {
        "commitHref": "https://github.com/sanchuang-dev/dr-card-web/commit/d211ec1c8332f66a69adc96c1bf57f8586f27e79",
        "commitHash": "d211ec1c8332f66a69adc96c1bf57f8586f27e79",
        "prHref": "https://github.com/sanchuang-dev/dr-card-web/pull/227",
        "prTitle": "release(test): 晋级 10/14 首页周签到 UI 改版",
        "prBaseHash": "c667056f91f452b97bad109d1b7ed3f9b4029b28",
        "buildHref": "https://github.com/sanchuang-dev/dr-card-web/actions/runs/38514042441"
      },
      "gitCommit": {
        "shortHash": "d211ec1",
        "hash": "d211ec1c8332f66a69adc96c1bf57f8586f27e79",
        "subject": "Merge b3756f137cd6bec82f4ffe682accc13d4fe55cae into c667056f91f452b97bad109d1b7ed3f9b4029b28",
        "body": "Merge b3756f137cd6bec82f4ffe682accc13d4fe55cae into c667056f91f452b97bad109d1b7ed3f9b4029b28\n",
        "author": {
          "name": "Tomz Dang",
          "email": "dangjingtao@163.com",
          "time": 1791953816000
        },
        "committer": {
          "name": "GitHub",
          "email": "noreply@github.com",
          "time": 1791953816000
        },
        "branch": "HEAD"
      },
      "gitDiff": "diff --git a/src/pages/checkin/components/CheckinBoard.test.tsx b/src/pages/checkin/components/CheckinBoard.test.tsx\nindex e4062c3..36031cf 100644\n--- a/src/pages/checkin/components/CheckinBoard.test.tsx\n+++ b/src/pages/checkin/components/CheckinBoard.test.tsx\n@@ -95,4 +95,31 @@ describe('Issue #220: homepage natural week entry', () => {\n     expect(entry.textContent).not.toContain('已满勤')\n     expect(entry.textContent).toContain('周奖励以后台活动规则为准')\n   })\n+\n+  it('distinguishes completed-today and signed-day chip from their card backgrounds', () => {\n+    vi.useFakeTimers()\n+    vi.setSystemTime(new Date(2026, 9, 14, 12))\n+    render(\n+      <MemoryRouter>\n+        <CheckinBoard\n+          mode=\"home\"\n+          weekRecordsState=\"success\"\n+          records={[\n+            { id: 1, user_id: 3, points: 10, consecutive_days: 1, status: 10, year: '2026', month: '10', day: '12' },\n+            { id: 2, user_id: 3, points: 10, consecutive_days: 3, status: 10, year: '2026', month: '10', day: '14' },\n+          ]}\n+          signStatus={{ signed: true, consecutiveDays: 3, points: 10, rewardDesc: '' }}\n+        />\n+      </MemoryRouter>,\n+    )\n+\n+    const today = document.querySelector('[data-checkin-week-day=\"2026-10-14\"]')\n+    const monday = document.querySelector('[data-checkin-week-day=\"2026-10-12\"]')\n+    expect(today?.textContent).toContain('已签')\n+    expect(today?.querySelector('svg')).not.toBeNull()\n+    expect(monday?.querySelector(':scope > span:nth-child(2)')?.className).toContain('bg-[var(--premium-100)]')\n+    expect(screen.getByText('签到详情')).toBeTruthy()\n+    expect(screen.queryByText('签到规则')).toBeNull()\n+  })\n+\n })\ndiff --git a/src/pages/checkin/components/CheckinBoard.tsx b/src/pages/checkin/components/CheckinBoard.tsx\nindex 1b686b7..836034b 100644\n--- a/src/pages/checkin/components/CheckinBoard.tsx\n+++ b/src/pages/checkin/components/CheckinBoard.tsx\n@@ -379,76 +379,94 @@ export default function CheckinBoard({\n           data-checkin-week-state={weekRecordsReady ? 'success' : weekRecordsState ?? 'loading'}\n           aria-label={weeklyCompletedDays === null\n             ? '查看本周签到，进入本月签到日历'\n-            : `查看本周签到，已签到 ${weeklyCompletedDays} / 7 天，进入本月签到日历`}\n-          className=\"mx-4 block w-[calc(100%-2rem)] rounded-[16px] bg-checkin-home-surface px-3.5 pb-3.5 pt-3.5 text-left shadow-bubble transition active:scale-[0.995] active:bg-surface-pressed\"\n+            : '查看本周签到，已签到 ' + weeklyCompletedDays + ' / 7 天，进入本月签到日历'}\n+          className=\"mx-4 block w-[calc(100%-2rem)] rounded-[21px] border border-border-subtle bg-checkin-home-surface px-[15px] pb-3.5 pt-4 text-left shadow-bubble transition active:scale-[0.995] active:bg-surface-pressed max-[350px]:px-2.5\"\n         >\n-          <div className=\"flex items-center justify-between gap-3\">\n-            <span className=\"flex min-w-0 items-center gap-2 text-[14px] font-semibold leading-5 text-text-primary\">\n-              <span className=\"flex h-7 w-7 flex-none items-center justify-center rounded-[8px] bg-secondary text-reward-strong\" aria-hidden>\n-                <CalendarDays className=\"h-4 w-4\" />\n+          {/* UIUX-1014：将已验收的 375px 七日视觉移植到 #220 的真实自然周签到数据。 */}\n+          <span className=\"flex flex-wrap items-center justify-between gap-x-2 gap-y-2\">\n+            <span className=\"flex min-w-0 items-center gap-2\">\n+              <span className=\"flex h-[34px] w-[34px] flex-none items-center justify-center rounded-[10px] bg-reward-subtle text-reward-strong\" aria-hidden>\n+                <CalendarDays className=\"h-[19px] w-[19px]\" />\n               </span>\n-              <span>本周签到</span>\n-              <span className=\"text-[12px] font-semibold text-reward-text\">\n-                {weeklyCompletedDays === null ? '—/7' : `${weeklyCompletedDays}/7`}\n+              <span className=\"whitespace-nowrap text-[18px] font-bold tracking-tight text-text-primary max-[350px]:text-[16px]\">本周签到</span>\n+              <span className=\"whitespace-nowrap text-[17px] font-bold tabular-nums text-reward-text\">\n+                {weeklyCompletedDays === null ? '—/7' : weeklyCompletedDays + '/7'}\n               </span>\n             </span>\n-            <span className=\"flex flex-none items-center gap-0.5 rounded-pill bg-surface-subtle px-2.5 py-1 text-[11px] font-medium leading-4 text-text-secondary\">\n+            <span className=\"flex min-h-11 flex-none items-center gap-0.5 rounded-full bg-surface-subtle px-2.5 text-xs font-medium text-text-secondary max-[350px]:px-2\">\n               {weeklyCompletedDays === null\n                 ? weekRecordsState === 'error' ? '记录暂不可用' : '记录加载中'\n-                : weeklyCompletedDays === 7 ? '本周已满勤' : `已签到 ${weeklyCompletedDays} 天`}\n-              <ChevronRight className=\"h-3 w-3\" aria-hidden />\n+                : weeklyCompletedDays === 7 ? '本周已满勤' : '已签到 ' + weeklyCompletedDays + ' 天'}\n+              <ChevronRight className=\"h-4 w-4\" aria-hidden />\n             </span>\n-          </div>\n+          </span>\n \n-          <span className=\"mt-2 block text-[10px] text-text-tertiary\">周一至周日 · {weekLabel}</span>\n-          <div className=\"mt-3 grid grid-cols-7 gap-1\" aria-hidden>\n+          <span className=\"mt-1 block text-xs leading-[18px] text-text-tertiary\">\n+            周一至周日 · {weekLabel}\n+          </span>\n+\n+          <span className=\"mt-[19px] grid grid-cols-7 gap-[3px] max-[350px]:gap-0.5\" aria-hidden>\n             {cycleDays.map((item, index) => {\n               const completed = weekRecordsReady && item.signed\n+              const today = item.state === 'today'\n+              const missing = weekRecordsReady && item.state === 'makeup' && !completed\n               return (\n-                <span key={item.dateKey} className=\"flex min-w-0 flex-col items-center gap-1.5\">\n-                  <span className=\"text-[9px] leading-none text-checkin-home-muted\">\n+                <span\n+                  key={item.dateKey}\n+                  data-checkin-week-day={item.dateKey}\n+                  className={'flex min-h-[106px] min-w-0 flex-col items-center rounded-[13px] px-0 py-[9px] text-center max-[350px]:rounded-[10px] ' + (\n+                    today ? 'bg-checkin-home-today'\n+                      : completed ? 'bg-reward-subtle'\n+                        : 'bg-surface-subtle'\n+                  )}\n+                >\n+                  <span className={'text-xs font-medium leading-4 ' + (\n+                    today ? 'text-checkin-home-today-text' : completed ? 'text-reward-text' : 'text-checkin-home-muted'\n+                  )}>\n                     {CHECKIN_WEEK_LABELS[index]}\n                   </span>\n-                  <span\n-                    className={`flex h-7 w-7 items-center justify-center text-[10px] font-semibold ${\n-                      item.state === 'today' && !completed\n-                        ? 'flex-col rounded-[10px] bg-checkin-home-today text-checkin-home-today-text shadow-sm'\n-                        : completed\n-                          ? 'flex-col rounded-full bg-checkin-home-day-surface text-reward-strong'\n-                          : item.state === 'upcoming'\n-                            ? 'rounded-full bg-checkin-home-day-surface text-text-tertiary/60'\n-                            : 'rounded-full bg-checkin-home-day-surface text-checkin-home-day-text'\n-                    }`}\n-                  >\n-                    {item.state === 'today' && !completed ? (\n-                      <>\n-                        <span className=\"text-[10px] leading-3\">{item.day}</span>\n-                        <span className=\"mt-0.5 text-[8px] font-medium leading-3\">今天</span>\n-                      </>\n-                    ) : completed ? (\n-                      <>\n-                        <Check className=\"h-2.5 w-2.5\" strokeWidth={3} />\n-                        <span className=\"mt-0.5 text-[8px] leading-none\">{item.day}</span>\n-                      </>\n-                    ) : (\n-                      item.day\n-                    )}\n+                  <span className={'mt-2.5 flex h-[34px] w-[34px] items-center justify-center rounded-full text-[15px] font-semibold tabular-nums max-[350px]:h-[30px] max-[350px]:w-[30px] ' + (\n+                    today ? 'bg-reward-subtle text-reward-text'\n+                      : completed ? 'bg-[var(--premium-100)] text-reward-text'\n+                        : 'bg-checkin-home-day-surface text-checkin-home-day-text'\n+                  )}>\n+                    {completed ? <Check className=\"h-[21px] w-[21px]\" strokeWidth={3} /> : item.day}\n+                  </span>\n+                  <span className={'mt-2.5 min-h-[15px] text-[11px] leading-[15px] ' + (\n+                    today ? 'font-semibold text-checkin-home-today-text' : completed ? 'text-reward-text' : 'text-text-tertiary'\n+                  )}>\n+                    {completed ? '已签' : today ? '今天' : missing ? '漏签' : ''}\n                   </span>\n                 </span>\n               )\n             })}\n-          </div>\n+          </span>\n+\n+          <span className=\"mt-3.5 flex min-h-[70px] items-center gap-2.5 rounded-[13px] bg-reward-subtle px-2.5 py-3\">\n+            <span className=\"flex h-[30px] w-[30px] flex-none items-center justify-center text-reward-strong\" aria-hidden>\n+              <Gift className=\"h-6 w-6\" />\n+            </span>\n+            <span className=\"min-w-0 flex-1\">\n+              <span className=\"block text-sm font-semibold leading-5 text-text-primary\">每日签到得泡泡值</span>\n+              <span className=\"mt-0.5 block text-xs leading-[18px] text-text-tertiary\">\n+                {weeklyCompletedDays === null ? '签到记录加载后显示进度' : '本周累计已签 ' + weeklyCompletedDays + ' 天'}\n+              </span>\n+            </span>\n+            <span className=\"flex min-h-11 flex-none items-center gap-0.5 whitespace-nowrap text-xs font-semibold text-reward-text\">\n+              查看月历 <ChevronRight className=\"h-4 w-4\" aria-hidden />\n+            </span>\n+          </span>\n \n-          <span className=\"mt-3 flex items-center justify-between gap-2 text-[11px] leading-4 text-text-tertiary\">\n-            <span>周奖励以后台活动规则为准</span>\n-            <span className=\"flex items-center gap-0.5 whitespace-nowrap text-reward-text\">查看月历 <ChevronRight className=\"h-3 w-3\" aria-hidden /></span>\n+          <span className=\"flex min-h-11 items-center justify-between gap-2 px-0.5 text-xs text-text-tertiary\">\n+            <span className=\"min-w-0\">周奖励以后台活动规则为准</span>\n+            <span className=\"flex flex-none items-center gap-0.5 text-reward-text\">签到详情 <ChevronRight className=\"h-3.5 w-3.5\" aria-hidden /></span>\n           </span>\n           {signStatus && (\n             <span\n               data-checkin-sign-status={signStatus.signed ? 'signed' : 'unsigned'}\n-              className={`mt-2 flex items-center gap-1 text-[11px] leading-4 ${\n+              className={'flex items-center gap-1 border-t border-border-subtle pt-2 text-xs leading-5 ' + (\n                 signStatus.signed ? 'text-reward-text' : 'text-text-tertiary'\n-              }`}\n+              )}\n             >\n               {signStatus.signed && <Check className=\"h-3 w-3\" strokeWidth={3} aria-hidden />}\n               {buildSignStatusHint(signStatus)}",
      "actualWorkers": 2
    },
    "preserveOutput": "always",
    "projects": [
      {
        "outputDir": "/home/runner/work/dr-card-web/dr-card-web/test-results/artifacts",
        "repeatEach": 1,
        "retries": 1,
        "metadata": {
          "ci": {
            "commitHref": "https://github.com/sanchuang-dev/dr-card-web/commit/d211ec1c8332f66a69adc96c1bf57f8586f27e79",
            "commitHash": "d211ec1c8332f66a69adc96c1bf57f8586f27e79",
            "prHref": "https://github.com/sanchuang-dev/dr-card-web/pull/227",
            "prTitle": "release(test): 晋级 10/14 首页周签到 UI 改版",
            "prBaseHash": "c667056f91f452b97bad109d1b7ed3f9b4029b28",
            "buildHref": "https://github.com/sanchuang-dev/dr-card-web/actions/runs/38514042441"
          },
          "gitCommit": {
            "shortHash": "d211ec1",
            "hash": "d211ec1c8332f66a69adc96c1bf57f8586f27e79",
            "subject": "Merge b3756f137cd6bec82f4ffe682accc13d4fe55cae into c667056f91f452b97bad109d1b7ed3f9b4029b28",
            "body": "Merge b3756f137cd6bec82f4ffe682accc13d4fe55cae into c667056f91f452b97bad109d1b7ed3f9b4029b28\n",
            "author": {
              "name": "Tomz Dang",
              "email": "dangjingtao@163.com",
              "time": 1791953816000
            },
            "committer": {
              "name": "GitHub",
              "email": "noreply@github.com",
              "time": 1791953816000
            },
            "branch": "HEAD"
          },
          "gitDiff": "diff --git a/src/pages/checkin/components/CheckinBoard.test.tsx b/src/pages/checkin/components/CheckinBoard.test.tsx\nindex e4062c3..36031cf 100644\n--- a/src/pages/checkin/components/CheckinBoard.test.tsx\n+++ b/src/pages/checkin/components/CheckinBoard.test.tsx\n@@ -95,4 +95,31 @@ describe('Issue #220: homepage natural week entry', () => {\n     expect(entry.textContent).not.toContain('已满勤')\n     expect(entry.textContent).toContain('周奖励以后台活动规则为准')\n   })\n+\n+  it('distinguishes completed-today and signed-day chip from their card backgrounds', () => {\n+    vi.useFakeTimers()\n+    vi.setSystemTime(new Date(2026, 9, 14, 12))\n+    render(\n+      <MemoryRouter>\n+        <CheckinBoard\n+          mode=\"home\"\n+          weekRecordsState=\"success\"\n+          records={[\n+            { id: 1, user_id: 3, points: 10, consecutive_days: 1, status: 10, year: '2026', month: '10', day: '12' },\n+            { id: 2, user_id: 3, points: 10, consecutive_days: 3, status: 10, year: '2026', month: '10', day: '14' },\n+          ]}\n+          signStatus={{ signed: true, consecutiveDays: 3, points: 10, rewardDesc: '' }}\n+        />\n+      </MemoryRouter>,\n+    )\n+\n+    const today = document.querySelector('[data-checkin-week-day=\"2026-10-14\"]')\n+    const monday = document.querySelector('[data-checkin-week-day=\"2026-10-12\"]')\n+    expect(today?.textContent).toContain('已签')\n+    expect(today?.querySelector('svg')).not.toBeNull()\n+    expect(monday?.querySelector(':scope > span:nth-child(2)')?.className).toContain('bg-[var(--premium-100)]')\n+    expect(screen.getByText('签到详情')).toBeTruthy()\n+    expect(screen.queryByText('签到规则')).toBeNull()\n+  })\n+\n })\ndiff --git a/src/pages/checkin/components/CheckinBoard.tsx b/src/pages/checkin/components/CheckinBoard.tsx\nindex 1b686b7..836034b 100644\n--- a/src/pages/checkin/components/CheckinBoard.tsx\n+++ b/src/pages/checkin/components/CheckinBoard.tsx\n@@ -379,76 +379,94 @@ export default function CheckinBoard({\n           data-checkin-week-state={weekRecordsReady ? 'success' : weekRecordsState ?? 'loading'}\n           aria-label={weeklyCompletedDays === null\n             ? '查看本周签到，进入本月签到日历'\n-            : `查看本周签到，已签到 ${weeklyCompletedDays} / 7 天，进入本月签到日历`}\n-          className=\"mx-4 block w-[calc(100%-2rem)] rounded-[16px] bg-checkin-home-surface px-3.5 pb-3.5 pt-3.5 text-left shadow-bubble transition active:scale-[0.995] active:bg-surface-pressed\"\n+            : '查看本周签到，已签到 ' + weeklyCompletedDays + ' / 7 天，进入本月签到日历'}\n+          className=\"mx-4 block w-[calc(100%-2rem)] rounded-[21px] border border-border-subtle bg-checkin-home-surface px-[15px] pb-3.5 pt-4 text-left shadow-bubble transition active:scale-[0.995] active:bg-surface-pressed max-[350px]:px-2.5\"\n         >\n-          <div className=\"flex items-center justify-between gap-3\">\n-            <span className=\"flex min-w-0 items-center gap-2 text-[14px] font-semibold leading-5 text-text-primary\">\n-              <span className=\"flex h-7 w-7 flex-none items-center justify-center rounded-[8px] bg-secondary text-reward-strong\" aria-hidden>\n-                <CalendarDays className=\"h-4 w-4\" />\n+          {/* UIUX-1014：将已验收的 375px 七日视觉移植到 #220 的真实自然周签到数据。 */}\n+          <span className=\"flex flex-wrap items-center justify-between gap-x-2 gap-y-2\">\n+            <span className=\"flex min-w-0 items-center gap-2\">\n+              <span className=\"flex h-[34px] w-[34px] flex-none items-center justify-center rounded-[10px] bg-reward-subtle text-reward-strong\" aria-hidden>\n+                <CalendarDays className=\"h-[19px] w-[19px]\" />\n               </span>\n-              <span>本周签到</span>\n-              <span className=\"text-[12px] font-semibold text-reward-text\">\n-                {weeklyCompletedDays === null ? '—/7' : `${weeklyCompletedDays}/7`}\n+              <span className=\"whitespace-nowrap text-[18px] font-bold tracking-tight text-text-primary max-[350px]:text-[16px]\">本周签到</span>\n+              <span className=\"whitespace-nowrap text-[17px] font-bold tabular-nums text-reward-text\">\n+                {weeklyCompletedDays === null ? '—/7' : weeklyCompletedDays + '/7'}\n               </span>\n             </span>\n-            <span className=\"flex flex-none items-center gap-0.5 rounded-pill bg-surface-subtle px-2.5 py-1 text-[11px] font-medium leading-4 text-text-secondary\">\n+            <span className=\"flex min-h-11 flex-none items-center gap-0.5 rounded-full bg-surface-subtle px-2.5 text-xs font-medium text-text-secondary max-[350px]:px-2\">\n               {weeklyCompletedDays === null\n                 ? weekRecordsState === 'error' ? '记录暂不可用' : '记录加载中'\n-                : weeklyCompletedDays === 7 ? '本周已满勤' : `已签到 ${weeklyCompletedDays} 天`}\n-              <ChevronRight className=\"h-3 w-3\" aria-hidden />\n+                : weeklyCompletedDays === 7 ? '本周已满勤' : '已签到 ' + weeklyCompletedDays + ' 天'}\n+              <ChevronRight className=\"h-4 w-4\" aria-hidden />\n             </span>\n-          </div>\n+          </span>\n \n-          <span className=\"mt-2 block text-[10px] text-text-tertiary\">周一至周日 · {weekLabel}</span>\n-          <div className=\"mt-3 grid grid-cols-7 gap-1\" aria-hidden>\n+          <span className=\"mt-1 block text-xs leading-[18px] text-text-tertiary\">\n+            周一至周日 · {weekLabel}\n+          </span>\n+\n+          <span className=\"mt-[19px] grid grid-cols-7 gap-[3px] max-[350px]:gap-0.5\" aria-hidden>\n             {cycleDays.map((item, index) => {\n               const completed = weekRecordsReady && item.signed\n+              const today = item.state === 'today'\n+              const missing = weekRecordsReady && item.state === 'makeup' && !completed\n               return (\n-                <span key={item.dateKey} className=\"flex min-w-0 flex-col items-center gap-1.5\">\n-                  <span className=\"text-[9px] leading-none text-checkin-home-muted\">\n+                <span\n+                  key={item.dateKey}\n+                  data-checkin-week-day={item.dateKey}\n+                  className={'flex min-h-[106px] min-w-0 flex-col items-center rounded-[13px] px-0 py-[9px] text-center max-[350px]:rounded-[10px] ' + (\n+                    today ? 'bg-checkin-home-today'\n+                      : completed ? 'bg-reward-subtle'\n+                        : 'bg-surface-subtle'\n+                  )}\n+                >\n+                  <span className={'text-xs font-medium leading-4 ' + (\n+                    today ? 'text-checkin-home-today-text' : completed ? 'text-reward-text' : 'text-checkin-home-muted'\n+                  )}>\n                     {CHECKIN_WEEK_LABELS[index]}\n                   </span>\n-                  <span\n-                    className={`flex h-7 w-7 items-center justify-center text-[10px] font-semibold ${\n-                      item.state === 'today' && !completed\n-                        ? 'flex-col rounded-[10px] bg-checkin-home-today text-checkin-home-today-text shadow-sm'\n-                        : completed\n-                          ? 'flex-col rounded-full bg-checkin-home-day-surface text-reward-strong'\n-                          : item.state === 'upcoming'\n-                            ? 'rounded-full bg-checkin-home-day-surface text-text-tertiary/60'\n-                            : 'rounded-full bg-checkin-home-day-surface text-checkin-home-day-text'\n-                    }`}\n-                  >\n-                    {item.state === 'today' && !completed ? (\n-                      <>\n-                        <span className=\"text-[10px] leading-3\">{item.day}</span>\n-                        <span className=\"mt-0.5 text-[8px] font-medium leading-3\">今天</span>\n-                      </>\n-                    ) : completed ? (\n-                      <>\n-                        <Check className=\"h-2.5 w-2.5\" strokeWidth={3} />\n-                        <span className=\"mt-0.5 text-[8px] leading-none\">{item.day}</span>\n-                      </>\n-                    ) : (\n-                      item.day\n-                    )}\n+                  <span className={'mt-2.5 flex h-[34px] w-[34px] items-center justify-center rounded-full text-[15px] font-semibold tabular-nums max-[350px]:h-[30px] max-[350px]:w-[30px] ' + (\n+                    today ? 'bg-reward-subtle text-reward-text'\n+                      : completed ? 'bg-[var(--premium-100)] text-reward-text'\n+                        : 'bg-checkin-home-day-surface text-checkin-home-day-text'\n+                  )}>\n+                    {completed ? <Check className=\"h-[21px] w-[21px]\" strokeWidth={3} /> : item.day}\n+                  </span>\n+                  <span className={'mt-2.5 min-h-[15px] text-[11px] leading-[15px] ' + (\n+                    today ? 'font-semibold text-checkin-home-today-text' : completed ? 'text-reward-text' : 'text-text-tertiary'\n+                  )}>\n+                    {completed ? '已签' : today ? '今天' : missing ? '漏签' : ''}\n                   </span>\n                 </span>\n               )\n             })}\n-          </div>\n+          </span>\n+\n+          <span className=\"mt-3.5 flex min-h-[70px] items-center gap-2.5 rounded-[13px] bg-reward-subtle px-2.5 py-3\">\n+            <span className=\"flex h-[30px] w-[30px] flex-none items-center justify-center text-reward-strong\" aria-hidden>\n+              <Gift className=\"h-6 w-6\" />\n+            </span>\n+            <span className=\"min-w-0 flex-1\">\n+              <span className=\"block text-sm font-semibold leading-5 text-text-primary\">每日签到得泡泡值</span>\n+              <span className=\"mt-0.5 block text-xs leading-[18px] text-text-tertiary\">\n+                {weeklyCompletedDays === null ? '签到记录加载后显示进度' : '本周累计已签 ' + weeklyCompletedDays + ' 天'}\n+              </span>\n+            </span>\n+            <span className=\"flex min-h-11 flex-none items-center gap-0.5 whitespace-nowrap text-xs font-semibold text-reward-text\">\n+              查看月历 <ChevronRight className=\"h-4 w-4\" aria-hidden />\n+            </span>\n+          </span>\n \n-          <span className=\"mt-3 flex items-center justify-between gap-2 text-[11px] leading-4 text-text-tertiary\">\n-            <span>周奖励以后台活动规则为准</span>\n-            <span className=\"flex items-center gap-0.5 whitespace-nowrap text-reward-text\">查看月历 <ChevronRight className=\"h-3 w-3\" aria-hidden /></span>\n+          <span className=\"flex min-h-11 items-center justify-between gap-2 px-0.5 text-xs text-text-tertiary\">\n+            <span className=\"min-w-0\">周奖励以后台活动规则为准</span>\n+            <span className=\"flex flex-none items-center gap-0.5 text-reward-text\">签到详情 <ChevronRight className=\"h-3.5 w-3.5\" aria-hidden /></span>\n           </span>\n           {signStatus && (\n             <span\n               data-checkin-sign-status={signStatus.signed ? 'signed' : 'unsigned'}\n-              className={`mt-2 flex items-center gap-1 text-[11px] leading-4 ${\n+              className={'flex items-center gap-1 border-t border-border-subtle pt-2 text-xs leading-5 ' + (\n                 signStatus.signed ? 'text-reward-text' : 'text-text-tertiary'\n-              }`}\n+              )}\n             >\n               {signStatus.signed && <Check className=\"h-3 w-3\" strokeWidth={3} aria-hidden />}\n               {buildSignStatusHint(signStatus)}",
          "actualWorkers": 2
        },
        "id": "chromium-mobile",
        "name": "chromium-mobile",
        "testDir": "/home/runner/work/dr-card-web/dr-card-web/tests/e2e",
        "testIgnore": [],
        "testMatch": [
          "**/*.@(spec|test).?(c|m)[jt]s?(x)"
        ],
        "timeout": 30000
      }
    ],
    "quiet": false,
    "reporter": [
      [
        "line",
        null
      ],
      [
        "html",
        {
          "outputFolder": "playwright-report",
          "open": "never"
        }
      ],
      [
        "json",
        {
          "outputFile": "test-results/playwright-results.json"
        }
      ]
    ],
    "reportSlowTests": {
      "max": 5,
      "threshold": 300000
    },
    "shard": null,
    "tags": [],
    "updateSnapshots": "missing",
    "updateSourceMethod": "patch",
    "version": "1.63.0",
    "workers": 2,
    "webServer": null
  },
  "suites": [
    {
      "title": "test-gate.spec.ts",
      "file": "test-gate.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "@test-gate build identity matches the production-like test policy",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 71,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:01.424Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-c3b6e0ce5d8c5d8734e5",
          "file": "test-gate.spec.ts",
          "line": 31,
          "column": 1
        },
        {
          "title": "@test-gate browser entry does not start the app router",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1221,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:01.442Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8ed37c8041402a2a6b34",
          "file": "test-gate.spec.ts",
          "line": 40,
          "column": 1
        },
        {
          "title": "@test-gate / shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1220,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:01.583Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-b030d57053896c93a550",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate /profile shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1028,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:03.038Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8605535a2807e17fcccc",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate /settings shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1042,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:03.048Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-4a2fdc9884c1725de4f8",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate gated browser entry issues no business API request",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1066,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:04.091Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-09f38a2b8ed735e192d8",
          "file": "test-gate.spec.ts",
          "line": 65,
          "column": 1
        },
        {
          "title": "@test-gate injected native host bypasses the notice and starts the app",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1117,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-14T04:58:04.114Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8caf237c4d42513fff2f",
          "file": "test-gate.spec.ts",
          "line": 80,
          "column": 1
        }
      ]
    }
  ],
  "errors": [],
  "stats": {
    "startTime": "2026-10-14T04:58:00.510Z",
    "duration": 4783.925,
    "expected": 7,
    "skipped": 0,
    "unexpected": 0,
    "flaky": 0
  }
}