diff --git a/package-lock.json b/package-lock.json index 49ead6c..bebfb66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -844,9 +844,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -861,9 +858,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -878,9 +872,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -895,9 +886,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -912,9 +900,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -929,9 +914,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -946,9 +928,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -963,9 +942,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -980,9 +956,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -997,9 +970,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1014,9 +984,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1031,9 +998,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1048,9 +1012,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ diff --git a/src/components/HomeScreen.tsx b/src/components/HomeScreen.tsx index 4796713..f6a5531 100644 --- a/src/components/HomeScreen.tsx +++ b/src/components/HomeScreen.tsx @@ -32,110 +32,129 @@ export function HomeScreen({ return (
-
-

Study Note

-

ノートブックを作成して復習を始めましょう。

-
-
- setNewNotebookName(event.target.value)} - placeholder="新しいノートブック名" - aria-label="新しいノートブック名" - /> - -
+

Study Note

+

ノートブックを作成して復習を始めましょう。

-
+
+ setNewNotebookName(event.target.value)} + placeholder="新しいノートブック名" + aria-label="新しいノートブック名" + onKeyDown={(event) => { + if (event.key === 'Enter' && newNotebookName.trim()) { + onCreateNotebook(newNotebookName.trim()); + setNewNotebookName(''); + } + }} + /> + +
+ +
{notebooks.map((notebook) => { const isEditing = notebook.id === editingNotebookId; return ( -
-
+
+
{isEditing ? ( setEditingNotebookName(event.target.value)} - className="notebook-card__title-input" + className="notebook-item__title-input" aria-label="ノートブック名を編集" + autoFocus + onKeyDown={(event) => { + if (event.key === 'Enter') { + onRenameNotebook(notebook.id, editingNotebookName); + setEditingNotebookId(null); + setEditingNotebookName(''); + } else if (event.key === 'Escape') { + setEditingNotebookId(null); + setEditingNotebookName(''); + } + }} /> ) : ( -

{notebook.name}

+

{notebook.name}

)} -

{notebook.pages.length} ページ

- 更新: {formatUpdatedAt(notebook.updatedAt)} +

+ {notebook.pages.length} ページ 更新: {formatUpdatedAt(notebook.updatedAt)} +

-
- +
{!isEditing && ( - - )} - {isEditing && ( - + <> + + + + )} {isEditing && ( - + <> + + + )} -
-
+
); })} diff --git a/src/styles.css b/src/styles.css index fc81572..3d56d79 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,7 +1,8 @@ :root { font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif; - color: #0f172a; - background-color: #f3f4f7; + color: #1c1c1e; + background-color: #f2f2f7; + -webkit-font-smoothing: antialiased; } * { @@ -22,41 +23,48 @@ textarea { font: inherit; } +/* ── App shell ── */ + .app { height: 100dvh; display: grid; grid-template-rows: auto minmax(0, 1fr); overflow: hidden; - background: radial-gradient(circle at top, #f7f8fb 0%, #f2f4f8 52%, #eef1f6 100%); + background: #f2f2f7; } +/* ── Top bar ── */ + .topbar { display: grid; grid-template-columns: 1fr auto auto; - gap: 0.85rem; + gap: 0.75rem; align-items: center; - padding: 0.9rem 1.15rem; - border-bottom: 1px solid #dde3ec; - background: rgba(255, 255, 255, 0.86); - backdrop-filter: blur(8px); + padding: 0.75rem 1.25rem; + border-bottom: 1px solid rgba(60, 60, 67, 0.12); + background: rgba(255, 255, 255, 0.92); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); } .topbar__brand h1 { margin: 0; - font-size: 1.08rem; + font-size: 1.0625rem; + font-weight: 600; letter-spacing: -0.02em; + color: #1c1c1e; } .topbar__brand p { - margin: 0.08rem 0 0; - color: #64748b; - font-size: 0.82rem; + margin: 0.1rem 0 0; + color: rgba(60, 60, 67, 0.6); + font-size: 0.8125rem; } .topbar__actions, .topbar__stats { display: flex; - gap: 0.5rem; + gap: 0.375rem; align-items: center; } @@ -66,154 +74,201 @@ textarea { .metric-pill { border-radius: 999px; - border: 1px solid #d9e1eb; - background: #f8fafd; - color: #475569; + background: rgba(60, 60, 67, 0.08); + color: rgba(60, 60, 67, 0.6); font-size: 0.75rem; - padding: 0.34rem 0.58rem; + padding: 0.25rem 0.625rem; white-space: nowrap; } +/* ── Buttons ── */ + .primary-button, .ghost-button { - border: 1px solid #cdd6e2; - border-radius: 999px; + border: none; + border-radius: 8px; height: 2rem; - padding: 0 0.9rem; - background: #fff; - color: #111827; + padding: 0 0.875rem; + background: transparent; + color: #007aff; cursor: pointer; - transition: 140ms ease; + font-size: 0.9375rem; + font-weight: 500; + transition: opacity 100ms ease, background 100ms ease; + white-space: nowrap; } .primary-button { - border-color: #0f172a; + background: #007aff; color: #fff; - background: #0f172a; } .primary-button:hover { - opacity: 0.94; + opacity: 0.88; } .ghost-button:hover { - background: #f6f8fb; + background: rgba(0, 122, 255, 0.08); } .ghost-button.is-active { - border-color: #0f172a; - background: #eef2f7; + background: rgba(0, 122, 255, 0.12); + color: #0062cc; } .ghost-button.danger { - color: #b42318; + color: #ff3b30; +} + +.ghost-button.danger:hover { + background: rgba(255, 59, 48, 0.08); } .hidden-input { display: none; } +/* ── Home screen ── */ + .home-screen { min-height: 100dvh; - padding: 2rem clamp(1rem, 3vw, 2.2rem); - background: radial-gradient(circle at top, #f7f8fb 0%, #f1f4f8 56%, #edf1f7 100%); + background: #f2f2f7; + padding-bottom: 3rem; } .home-header { - display: grid; - gap: 1rem; - grid-template-columns: 1fr auto; - align-items: end; - margin-bottom: 1.4rem; + padding: 2rem 1.25rem 0; + margin-bottom: 1.5rem; } .home-header h1 { - margin: 0; - font-size: clamp(1.55rem, 2vw, 2rem); - letter-spacing: -0.02em; + margin: 0 0 0.25rem; + font-size: 2rem; + font-weight: 700; + letter-spacing: -0.03em; + color: #1c1c1e; } .home-header p { - margin: 0.4rem 0 0; - color: #64748b; + margin: 0; + color: rgba(60, 60, 67, 0.6); + font-size: 0.9375rem; + line-height: 1.6; } .home-create { display: flex; - gap: 0.55rem; + gap: 0.5rem; align-items: center; + padding: 0 1.25rem; + margin-bottom: 2rem; } .home-create input { - width: min(300px, 46vw); - border: 1px solid #d2dbe8; - border-radius: 999px; - height: 2rem; - padding: 0 0.8rem; + flex: 1; + border: none; + border-radius: 10px; + height: 2.5rem; + padding: 0 0.875rem; background: #fff; + font-size: 0.9375rem; + color: #1c1c1e; + outline: none; } -.notebook-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 0.85rem; +.home-create input:focus { + box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.25); } -.notebook-card { - border: 1px solid #d9e2ee; - border-radius: 16px; - background: rgba(255, 255, 255, 0.86); - box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08); - display: grid; - gap: 0.9rem; - padding: 1rem; +.home-create input::placeholder { + color: rgba(60, 60, 67, 0.4); } -.notebook-card__main h2 { - margin: 0; - font-size: 1rem; +/* ── Notebook list (Apple grouped list style) ── */ + +.notebook-list { + margin: 0 1.25rem; + background: #fff; + border-radius: 12px; + overflow: hidden; } -.notebook-card__main p { - margin: 0.38rem 0 0.16rem; - color: #334155; - font-size: 0.88rem; +.notebook-item { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.875rem 1rem; + border-bottom: 1px solid rgba(60, 60, 67, 0.1); + transition: background 100ms ease; } -.notebook-card__main span { - color: #64748b; - font-size: 0.75rem; +.notebook-item:last-child { + border-bottom: none; +} + +.notebook-item__main { + flex: 1; + min-width: 0; +} + +.notebook-item__name { + margin: 0 0 0.125rem; + font-size: 1rem; + font-weight: 500; + color: #1c1c1e; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.notebook-item__meta { + margin: 0; + font-size: 0.8125rem; + color: rgba(60, 60, 67, 0.6); + line-height: 1.6; } -.notebook-card__title-input { +.notebook-item__title-input { + display: block; width: 100%; - border: 1px solid #d2dbe8; - border-radius: 10px; + border: 1px solid rgba(0, 122, 255, 0.4); + border-radius: 8px; height: 2rem; - padding: 0 0.7rem; + padding: 0 0.625rem; + background: #f2f2f7; + font-size: 1rem; + color: #1c1c1e; + outline: none; +} + +.notebook-item__title-input:focus { + border-color: #007aff; + box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); } -.notebook-card__actions { +.notebook-item__actions { display: flex; - gap: 0.45rem; - flex-wrap: wrap; + gap: 0.25rem; + align-items: center; + flex-shrink: 0; } +/* ── Workspace (notebook view) ── */ + .workspace { min-height: 0; - padding: 0.7rem; + padding: 0.75rem 1rem; } .book-shell { position: relative; height: 100%; - border-radius: 20px; - background: linear-gradient(180deg, #f8fafd 0%, #f3f6fb 100%); - border: 1px solid #dde4ee; + border-radius: 16px; + background: #ffffff; + border: 1px solid rgba(60, 60, 67, 0.12); display: grid; place-items: center; - padding: 0.7rem 3.6rem; - box-shadow: 0 15px 35px rgba(15, 23, 42, 0.08); + padding: 0.75rem 3.25rem; } .book-spread { @@ -223,186 +278,193 @@ textarea { min-height: 0; display: grid; grid-template-columns: 1fr 1fr; - gap: 0.65rem; + gap: 1px; } .book-spread::after { content: ''; position: absolute; left: 50%; - top: 1.1rem; - bottom: 1.1rem; + top: 1rem; + bottom: 1rem; width: 1px; - background: linear-gradient(180deg, #e2e8f0 0%, #d5dde8 55%, #e2e8f0 100%); + background: rgba(60, 60, 67, 0.12); transform: translateX(-50%); } .book-page { min-height: 0; background: #ffffff; - border-radius: 14px; - border: 1px solid #d7e0eb; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; overflow: hidden; cursor: pointer; - transition: border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease; + transition: background 120ms ease; } .book-page.left { - border-top-right-radius: 7px; - border-bottom-right-radius: 7px; + border-right: none; } .book-page.right { - border-top-left-radius: 7px; - border-bottom-left-radius: 7px; + border-left: none; } .book-page.is-selected { - border-color: #0f172a; - box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08); + background: #fafafa; } .book-page.is-empty { cursor: default; - color: #9aa8b8; - background: #fcfdff; + color: rgba(60, 60, 67, 0.3); } .book-page__header { - border-bottom: 1px solid #e2e8f0; - padding: 0.45rem 0.6rem; + border-bottom: 1px solid rgba(60, 60, 67, 0.1); + padding: 0.5rem 0.75rem; } .book-page__select { width: 100%; - border: 1px solid transparent; + border: none; background: transparent; - color: #64748b; + color: rgba(60, 60, 67, 0.6); text-align: left; - border-radius: 8px; - padding: 0.12rem 0.35rem; - font-size: 0.82rem; + border-radius: 6px; + padding: 0.125rem 0.375rem; + font-size: 0.8125rem; + font-weight: 500; cursor: pointer; + transition: background 100ms ease, color 100ms ease; } .book-page__select:hover { - background: #f4f7fb; + background: rgba(60, 60, 67, 0.06); + color: #1c1c1e; } .book-page__select.is-selected { - border-color: #cbd5e1; - color: #334155; + color: #007aff; } .book-page__select:focus-visible { - outline: 2px solid #0f172a; + outline: 2px solid #007aff; outline-offset: 1px; } .book-page__content { overflow: auto; - padding: 1rem 1.05rem; - line-height: 1.62; - font-size: 0.99rem; + padding: 1rem 1.25rem; + line-height: 1.65; + font-size: 0.9375rem; + color: #1c1c1e; } .book-page__content h1, .book-page__content h2, .book-page__content h3 { margin-top: 0; - letter-spacing: -0.01em; + letter-spacing: -0.02em; + color: #1c1c1e; } .book-page__content p { - margin: 0 0 0.78rem; + margin: 0 0 0.75rem; } .book-page__empty { display: grid; place-items: center; - color: #a1afbf; - font-size: 1rem; + color: rgba(60, 60, 67, 0.3); + font-size: 0.9375rem; } .book-page__footer { - border-top: 1px solid #e2e8f0; - padding: 0.42rem 0.85rem; + border-top: 1px solid rgba(60, 60, 67, 0.1); + padding: 0.375rem 1rem; text-align: right; font-size: 0.75rem; - color: #8da0b4; + color: rgba(60, 60, 67, 0.4); } +/* ── Navigation arrows ── */ + .nav-arrow { - width: 3rem; - height: 3rem; + width: 2.75rem; + height: 2.75rem; border-radius: 999px; - border: 1px solid #cfd8e4; - background: rgba(255, 255, 255, 0.92); - color: #1f2937; - font-size: 1.45rem; + border: none; + background: rgba(60, 60, 67, 0.06); + color: #007aff; + font-size: 1.375rem; cursor: pointer; position: absolute; top: 50%; transform: translateY(-50%); - box-shadow: 0 6px 18px rgba(15, 23, 42, 0.12); z-index: 2; + transition: background 100ms ease; + display: flex; + align-items: center; + justify-content: center; } .nav-arrow:hover:not(:disabled) { - background: #ffffff; - border-color: #b9c6d6; + background: rgba(0, 122, 255, 0.12); } .nav-arrow--left { - left: 0.65rem; + left: 0.5rem; } .nav-arrow--right { - right: 0.65rem; + right: 0.5rem; } .nav-arrow:disabled { cursor: not-allowed; - opacity: 0.42; + opacity: 0.3; } +/* ── Hidden text tokens ── */ + .hidden-token { display: inline-flex; align-items: center; - gap: 0.33rem; - border-radius: 999px; - border: 1px dashed #8ea1b7; - background: #f4f8fc; - padding: 0.05rem 0.42rem 0.08rem; - margin: 0 0.08rem; + gap: 0.25rem; + border-radius: 6px; + border: 1px dashed rgba(0, 122, 255, 0.4); + background: rgba(0, 122, 255, 0.06); + padding: 0.0625rem 0.375rem 0.125rem; + margin: 0 0.0625rem; color: inherit; cursor: pointer; vertical-align: baseline; + transition: background 100ms ease, border-color 100ms ease; } .hidden-token.is-visible { border-style: solid; - border-color: #7d8da1; - background: #edf2f8; + border-color: rgba(0, 122, 255, 0.5); + background: rgba(0, 122, 255, 0.1); } .hidden-token__value { - line-height: 1.35; + line-height: 1.4; } .hidden-token__placeholder { font-weight: 600; - letter-spacing: 0.1em; - color: #64748b; + letter-spacing: 0.08em; + color: rgba(60, 60, 67, 0.5); } .hidden-token__count { - font-size: 0.69rem; - color: #64748b; + font-size: 0.6875rem; + color: rgba(60, 60, 67, 0.5); } +/* ── Editor panel ── */ + .editor-overlay { position: fixed; inset: 0; @@ -414,9 +476,9 @@ textarea { position: absolute; inset: 0; border: 0; - background: rgba(15, 23, 42, 0.2); + background: rgba(0, 0, 0, 0.25); opacity: 0; - transition: opacity 180ms ease; + transition: opacity 200ms ease; cursor: default; } @@ -427,10 +489,9 @@ textarea { width: min(460px, 100vw); height: 100%; background: #ffffff; - border-left: 1px solid #d8e1eb; - box-shadow: -14px 0 30px rgba(15, 23, 42, 0.15); + border-left: 1px solid rgba(60, 60, 67, 0.12); transform: translateX(100%); - transition: transform 180ms ease; + transition: transform 200ms ease; display: grid; grid-template-rows: auto minmax(0, 1fr); } @@ -451,56 +512,90 @@ textarea { display: flex; justify-content: space-between; align-items: center; - padding: 0.8rem 0.95rem; - border-bottom: 1px solid #e2e8f0; + padding: 1rem 1.25rem; + border-bottom: 1px solid rgba(60, 60, 67, 0.12); } .editor-panel__header h2 { margin: 0; - font-size: 0.95rem; + font-size: 1.0625rem; + font-weight: 600; + color: #1c1c1e; } .editor-close { - height: 1.8rem; - padding: 0 0.72rem; + height: 2rem; + padding: 0 0.875rem; } .editor-panel__body { display: grid; - gap: 0.8rem; - padding: 0.82rem 0.95rem 1rem; + gap: 1.25rem; + padding: 1.25rem; + align-content: start; min-height: 0; + overflow: auto; } .editor-field { display: grid; - gap: 0.38rem; - font-size: 0.81rem; - color: #475569; + gap: 0.375rem; + font-size: 0.8125rem; + font-weight: 500; + color: rgba(60, 60, 67, 0.6); + text-transform: uppercase; + letter-spacing: 0.04em; } .editor-field input, .editor-field textarea { width: 100%; - border: 1px solid #d6dfeb; + border: 1px solid rgba(60, 60, 67, 0.2); border-radius: 10px; - padding: 0.58rem 0.72rem; + padding: 0.625rem 0.875rem; + background: #f2f2f7; + color: #1c1c1e; + font-size: 0.9375rem; + font-weight: normal; + letter-spacing: normal; + text-transform: none; + outline: none; + transition: border-color 100ms ease, box-shadow 100ms ease; +} + +.editor-field input:focus, +.editor-field textarea:focus { + border-color: #007aff; background: #fff; + box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); } .editor-field textarea { - min-height: 210px; + min-height: 220px; resize: vertical; - line-height: 1.5; + line-height: 1.6; +} + +.editor-panel__empty { + margin: 0; + padding: 1.25rem; + color: rgba(60, 60, 67, 0.5); + font-size: 0.9375rem; + line-height: 1.6; } -.editor-panel__empty, .editor-help { margin: 0; - color: #64748b; - font-size: 0.8rem; + color: rgba(60, 60, 67, 0.5); + font-size: 0.8125rem; + line-height: 1.6; + font-weight: normal; + letter-spacing: normal; + text-transform: none; } +/* ── Responsive ── */ + @media (max-width: 1120px) { .topbar { grid-template-columns: 1fr auto; @@ -513,22 +608,16 @@ textarea { } @media (max-width: 900px) { - .home-screen { - padding-top: 1.3rem; - } - .home-header { - grid-template-columns: 1fr; - align-items: start; + padding-top: 1.5rem; } .home-create { - width: 100%; + flex-wrap: wrap; } .home-create input { - flex: 1; - width: auto; + flex-basis: 100%; } .topbar { @@ -544,11 +633,11 @@ textarea { } .workspace { - padding: 0.56rem; + padding: 0.5rem; } .book-shell { - padding-inline: 2.65rem; + padding-inline: 2.75rem; } } @@ -558,24 +647,24 @@ textarea { } .book-spread { - gap: 0.45rem; + gap: 0; } .book-page__content { - font-size: 0.92rem; - padding: 0.82rem; + font-size: 0.875rem; + padding: 0.875rem 1rem; } .nav-arrow { - width: 2.7rem; - height: 2.7rem; + width: 2.5rem; + height: 2.5rem; } } @media (max-width: 680px) { .book-shell { - padding-inline: 0.55rem; - padding-block: 2.75rem 0.6rem; + padding-inline: 0.5rem; + padding-block: 2.75rem 0.5rem; } .book-spread { @@ -591,19 +680,23 @@ textarea { } .nav-arrow { - top: 1.35rem; + top: 1.25rem; transform: none; } .nav-arrow--left { - left: 0.7rem; + left: 0.5rem; } .nav-arrow--right { - right: 0.7rem; + right: 0.5rem; } .editor-panel { width: 100vw; } + + .notebook-list { + margin: 0 1rem; + } }