ba-cafe

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit c4c747ba679c54096aa6a56d478be2b6d0267b25
parent bf2c42d1d07b6f1fb412e0268eaa73f3bf4ae2de
Author: Sunny <kajimalu10@gmail.com>
Date:   Wed, 20 Aug 2025 15:40:01 +0900

add fonts

Diffstat:
Msrc/app/globals.css | 172+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/app/layout.tsx | 5++++-
Msrc/app/page.tsx | 10+++++-----
Msrc/components/CountdownDisplay.tsx | 4+++-
Msrc/components/Header.tsx | 4++--
Msrc/components/SidePane.tsx | 10+++++-----
Msrc/components/StatsGraph.tsx | 24++++++++++++------------
Msrc/components/TimerDashboard.tsx | 34++++++++++++++++++----------------
8 files changed, 161 insertions(+), 102 deletions(-)

diff --git a/src/app/globals.css b/src/app/globals.css @@ -4,39 +4,33 @@ /* Theming & Color Palette (RGB) */ /* ================================== */ :root { - /* ライトモードの色定義 (RGB値) */ - --background: 255 255 255; /* Main background */ - --foreground: 10 10 10; /* Main text */ - - --card: 255 255 255; /* Card background */ - --card-foreground: 10 10 10; /* Card text */ - - --primary: 37 99 235; /* Primary buttons, links */ - --primary-foreground: 250 250 250; /* Text on primary buttons */ - - --secondary: 244 245 246; /* Secondary backgrounds */ - --secondary-foreground: 20 20 20; /* Text on secondary backgrounds */ - - --muted: 229 231 235; /* Subtle backgrounds, borders */ - --muted-foreground: 107 114 128; /* Subtle text */ + --background: #fbfbfb; /* Main background */ + --foreground: #000000; /* Main text */ + --card: #ffffff; /* Card background */ + --card-foreground: #000000; /* Card text */ + --primary: #00aee1; /* Primary buttons, links */ + --primary-foreground: #ffffff; /* Text on primary buttons */ + --secondary: #f259ce; /* Secondary backgrounds */ + --secondary-foreground: #ffffff; /* Text on secondary backgrounds */ + --invite: #333333; /* Secondary backgrounds */ + --invite-foreground: #ffffff; /* Text on secondary backgrounds */ + --muted: #eeeeee; /* Subtle backgrounds, borders */ + --muted-foreground: #666666; /* Subtle text */ } .dark { - /* ダークモードの色定義 (RGB値) */ - --background: 18 18 18; - --foreground: 250 250 250; - - --card: 24 24 27; - --card-foreground: 250 250 250; - - --primary: 59 130 246; - --primary-foreground: 250 250 250; - - --secondary: 30 30 33; - --secondary-foreground: 250 250 250; - - --muted: 30 30 33; - --muted-foreground: 156 163 175; + --background: #000000; + --foreground: #ffffff; + --card: #222222; + --card-foreground: #ffffff; + --primary: #4336db; + --primary-foreground: #dddddd; + --secondary: #a80e84; + --secondary-foreground: #dddddd; + --invite: #dddddd; + --invite-foreground: #333333; + --muted: #444444; + --muted-foreground: #aaaaaa; } /* ================================== */ @@ -44,14 +38,16 @@ /* ================================== */ body { - background-color: rgb(var(--background)); - color: rgb(var(--foreground)); - font-family: Arial, Helvetica, sans-serif; /* フォントは指定通り */ + background-color: var(--background); + color: var(--foreground); + font-family: sans-serif; + font-weight: 700; + font-style: normal; } .card { - background-color: rgb(var(--card)); - color: rgb(var(--card-foreground)); + background-color: var(--card); + color: var(--card-foreground); padding: 1.5rem; /* p-6 */ border-radius: 0.5rem; /* rounded-lg */ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); /* shadow-md */ @@ -67,7 +63,7 @@ body { margin-bottom: 0.75rem; /* mb-3 */ padding-bottom: 0.5rem; /* pb-2 */ border-bottom-width: 1px; /* border-b */ - border-bottom-color: rgb(var(--muted)); /* 線の色を指定 */ + border-bottom-color: var(--muted); /* 線の色を指定 */ } /* ================================== */ @@ -92,49 +88,49 @@ body { /* 1. プライマリボタン(塗りつぶし) */ .btn-primary { - background-color: rgb(var(--primary)); - color: rgb(var(--primary-foreground)); + background-color: var(--primary); + color: var(--primary-foreground); border-color: transparent; } .btn-primary:hover { filter: brightness(0.9); /* 少し暗くするホバー効果 */ } .btn-primary:disabled { - background-color: rgb(var(--muted)); - color: rgb(var(--muted-foreground)); + background-color: var(--muted); + color: var(--muted-foreground); cursor: not-allowed; } /* 2. アウトラインボタン */ .btn-outline { background-color: transparent; - border-color: rgb(var(--muted)); - color: rgb(var(--foreground)); + border-color: var(--muted); + color: var(--foreground); } .btn-outline:hover { - background-color: rgb(var(--secondary)); - border-color: rgb(var(--muted)); + background-color: var(--secondary); + border-color: var(--muted); } /* アウトラインボタンが選択中のスタイル */ /* .btn-outline.btn-outline-active のように両方のクラスを持つ要素に適用 */ .btn-outline.btn-outline-active { - background-color: rgb(var(--primary)); - border-color: rgb(var(--primary)); - color: rgb(var(--primary-foreground)); + background-color: var(--primary); + border-color: var(--primary); + color: var(--primary-foreground); } /* 3. ゴーストボタン(透明) */ .btn-ghost { background-color: transparent; border-color: transparent; - color: rgb(var(--primary)); + color: var(--primary); } .btn-ghost:hover { - background-color: rgb(var(--secondary)); + background-color: var(--secondary); } .btn-ghost:disabled { - color: rgb(var(--muted-foreground)); + color: var(--muted-foreground); cursor: not-allowed; } @@ -152,40 +148,96 @@ body { /* Side Pane Button Style */ /* ================================== */ .btn-sidepane { - @apply w-full flex items-center p-2 rounded-md text-slate-300 hover:bg-gray-700 hover:text-white transition-colors duration-200; + width: 100%; + display: flex; + align-items: center; + padding: 0.5rem; + border-radius: 0.375rem; + color: var(--muted-foreground); + background-color: transparent; + transition: background 0.2s, color 0.2s; +} +.btn-sidepane:hover { + background-color: var(--muted); + color: var(--foreground); } /* ================================== */ /* New Timer UI Styles */ /* ================================== */ .timer-dashboard-bg { - @apply bg-gray-900 text-gray-200; + background-color: var(--background); + color: var(--foreground); } .timer-card { - @apply bg-gray-800/50 border border-gray-700 rounded-2xl p-6 backdrop-blur-sm; + background-color: var(--card); + color: var(--card-foreground); + border: 1px solid var(--muted); + border-radius: 1rem; + padding: 1.5rem; + backdrop-filter: blur(6px); + margin-bottom: 1.5rem; } .timer-card-title { - @apply text-sm font-semibold text-gray-400 mb-2; + font-size: 0.875rem; + font-weight: 600; + color: var(--muted-foreground); + margin-bottom: 0.5rem; } .countdown-text { - @apply text-4xl font-mono font-bold tracking-wider; + font-size: 2.25rem; + font-weight: 700; + font-style: normal; + letter-spacing: 0.05em; } .timer-sub-info { - @apply text-xs text-gray-500 mt-2 flex items-center gap-2; + font-size: 0.75rem; + color: var(--muted-foreground); + margin-top: 0.5rem; + display: flex; + align-items: center; + gap: 0.5rem; } .btn-timer { - @apply w-full py-3 rounded-lg font-bold transition-colors duration-200 disabled:bg-gray-700 disabled:text-gray-500 disabled:cursor-not-allowed; + width: 100%; + padding: 0.75rem 0; + border-radius: 0.5rem; + font-weight: bold; + transition: background 0.2s, color 0.2s; + background-color: var(--primary); + color: var(--primary-foreground); +} +.btn-timer:disabled { + background-color: var(--muted); + color: var(--muted-foreground); + cursor: not-allowed; } -.btn-timer-action { - @apply bg-blue-600 text-white hover:bg-blue-700; +.btn-timer-tap { + background-color: var(--primary); + color: var(--primary-foreground); +} +.btn-timer-tap:hover { + filter: brightness(0.9); } .btn-timer-fave { - @apply bg-pink-600 text-white hover:bg-pink-700; + background-color: var(--secondary); + color: var(--secondary-foreground); +} +.btn-timer-fave:hover { + filter: brightness(0.9); +} + +.btn-timer-inv { + background-color: var(--invite); + color: var(--invite-foreground); +} +.btn-timer-inv:hover { + filter: brightness(0.9); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx @@ -9,6 +9,9 @@ import { ThemeProvider } from '@/hooks/useTheme'; import Header from '@/components/Header'; import SidePane from '@/components/SidePane'; import "./globals.css"; +import { Noto_Sans_JP } from "next/font/google"; +const NotoSansJPFont400 = Noto_Sans_JP({ weight: "400", subsets: ["latin"] }); +const NotoSansJPFont700 = Noto_Sans_JP({ weight: "700", subsets: ["latin"] }); function AppLayout({ children }: { children: React.ReactNode }) { const { user, logout } = useAuth(); @@ -37,7 +40,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) return ( <html lang="ja"> - <body> + <body className={`${NotoSansJPFont700.className}`}> <GoogleOAuthProvider clientId={clientId}> <AuthProvider> <ThemeProvider> diff --git a/src/app/page.tsx b/src/app/page.tsx @@ -163,15 +163,15 @@ export default function Home() { } return ( - <div className="timer-dashboard-bg min-h-screen"> + <div className="bg-background min-h-screen"> {!user ? ( <div className="flex flex-col items-center justify-center h-screen p-8"> - <div className="card text-center !bg-gray-800 border border-gray-700"> - <h2 className="text-xl font-bold mb-4 text-white">ようこそ!</h2> - <p className="mb-6 text-gray-400">タイマー機能を利用するには、Googleアカウントでログインしてください。</p> + <div className="card text-center !bg-card border border-muted"> + <h2 className="text-xl font-bold mb-4">ようこそ!</h2> + <p className="mb-6 text-muted-foreground">タイマー機能を利用するには、Googleアカウントでログインしてください。</p> <button onClick={() => login()} - className="btn btn-primary inline-flex items-center justify-center whitespace-nowrap" + className="btn btn-primary" > <span>Googleでログイン</span> </button> diff --git a/src/components/CountdownDisplay.tsx b/src/components/CountdownDisplay.tsx @@ -3,6 +3,8 @@ export const runtime = "edge"; import { useMemo } from 'react'; +import { Lekton } from "next/font/google"; +const LektonFont = Lekton({ weight: "700", subsets: ["latin"] }); interface CountdownDisplayProps { milliseconds: number; @@ -18,7 +20,7 @@ export default function CountdownDisplay({ milliseconds }: CountdownDisplayProps }, [milliseconds]); return ( - <div className="countdown-text"> + <div className={`countdown-text ${LektonFont.className}`}> <span>{hours}</span>: <span>{minutes}</span>: <span>{seconds}</span> diff --git a/src/components/Header.tsx b/src/components/Header.tsx @@ -17,8 +17,8 @@ interface HeaderProps { export default function Header({ onMenuClick }: HeaderProps) { return ( - <header className="fixed top-0 left-0 right-0 z-20 flex items-center h-12 justify-between p-4 backdrop-blur-md shadow-md"> - <h1 className="text-lg font-bold text-foreground">カフェタイマー</h1> + <header className="fixed top-0 left-0 right-0 z-20 flex items-center h-12 justify-between p-4 backdrop-blur-md shadow-md bg-background"> + <h1 className="text-lg font-bold" style={{ color: "var(--foreground)" }}>カフェタイマー</h1> <div className="flex items-center gap-2"> <ThemeToggleButton /> <button onClick={onMenuClick} className="p-2 rounded-md hover:bg-secondary"> diff --git a/src/components/SidePane.tsx b/src/components/SidePane.tsx @@ -31,9 +31,11 @@ export default function SidePane({ isOpen, onClose, user, logout }: SidePaneProp return ( <main> <div className={`fixed inset-0 bg-black/50 z-30 transition-opacity ${isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'}`} onClick={onClose}></div> - <aside className={`fixed top-0 right-0 h-full w-72 bg-gray-800 text-white shadow-lg transform transition-transform z-40 ${isOpen ? 'translate-x-0' : 'translate-x-full'}`}> + <aside + className={`fixed top-0 right-0 h-full w-72 shadow-lg transform transition-transform z-40 ${isOpen ? 'translate-x-0' : 'translate-x-full'}`} + style={{ background: "var(--card)", color: "var(--card-foreground)" }} + > <nav className="p-4 flex flex-col h-full"> - <ul className="space-y-1"> {menuItems.map(item => ( <li key={item}> @@ -44,14 +46,12 @@ export default function SidePane({ isOpen, onClose, user, logout }: SidePaneProp </li> ))} </ul> - <div className="mt-8"> - <p className="text-sm text-gray-400 mb-2 px-2">Language</p> + <p className="text-sm" style={{ color: "var(--muted-foreground)" }}>Language</p> <div className="flex space-x-3 px-2"> <span>🇯🇵</span><span>🇺🇸</span><span>🇨🇳</span><span>🇰🇷</span> </div> </div> - <div className="mt-auto"> {user && ( <> diff --git a/src/components/StatsGraph.tsx b/src/components/StatsGraph.tsx @@ -149,21 +149,21 @@ export default function StatsGraph({ tapHistory }: StatsGraphProps) { <div> <h3 className="text-lg font-bold mb-2 text-foreground">サマリー</h3> <div className="grid grid-cols-2 gap-4 text-center"> - <div className="p-4 bg-secondary rounded-lg"> - <div className="text-sm text-muted-foreground">今日</div> - <div className="text-xl font-bold text-foreground">{allTapsToday} <span className="text-pink-600">({oshiTapsToday})</span></div> + <div className="p-4 rounded-lg" style={{ background: "var(--secondary)" }}> + <div className="text-sm" style={{ color: "var(--muted-foreground)" }}>今日</div> + <div className="text-xl font-bold" style={{ color: "var(--foreground)" }}>{allTapsToday} <span style={{ color: "#db2777" }}>({oshiTapsToday})</span></div> </div> - <div className="p-4 bg-secondary rounded-lg"> - <div className="text-sm text-muted-foreground">今週</div> - <div className="text-xl font-bold text-foreground">{allTapsThisWeek} <span className="text-pink-600">({oshiTapsThisWeek})</span></div> + <div className="p-4 rounded-lg" style={{ background: "var(--secondary)" }}> + <div className="text-sm" style={{ color: "var(--muted-foreground)" }}>今週</div> + <div className="text-xl font-bold" style={{ color: "var(--foreground)" }}>{allTapsThisWeek} <span style={{ color: "#db2777" }}>({oshiTapsThisWeek})</span></div> </div> - <div className="p-4 bg-secondary rounded-lg"> - <div className="text-sm text-muted-foreground">今月</div> - <div className="text-xl font-bold text-foreground">{allTapsThisMonth} <span className="text-pink-600">({oshiTapsThisMonth})</span></div> + <div className="p-4 rounded-lg" style={{ background: "var(--secondary)" }}> + <div className="text-sm" style={{ color: "var(--muted-foreground)" }}>今月</div> + <div className="text-xl font-bold" style={{ color: "var(--foreground)" }}>{allTapsThisMonth} <span style={{ color: "#db2777" }}>({oshiTapsThisMonth})</span></div> </div> - <div className="p-4 bg-secondary rounded-lg"> - <div className="text-sm text-muted-foreground">今年</div> - <div className="text-xl font-bold text-foreground">{allTapsThisYear} <span className="text-pink-600">({oshiTapsThisYear})</span></div> + <div className="p-4 rounded-lg" style={{ background: "var(--secondary)" }}> + <div className="text-sm" style={{ color: "var(--muted-foreground)" }}>今年</div> + <div className="text-xl font-bold" style={{ color: "var(--foreground)" }}>{allTapsThisYear} <span style={{ color: "#db2777" }}>({oshiTapsThisYear})</span></div> </div> </div> </div> diff --git a/src/components/TimerDashboard.tsx b/src/components/TimerDashboard.tsx @@ -4,7 +4,6 @@ export const runtime = "edge"; import { useState, useEffect, useMemo } from 'react'; import { addHours, differenceInMilliseconds } from 'date-fns'; -import TimerCard from './TimerCard'; import CountdownDisplay from './CountdownDisplay'; // propsの型定義 @@ -63,22 +62,24 @@ export default function TimerDashboard({ return ( - <div className="p-4 sm:p-8 space-y-6"> - <TimerCard title="Next Students Change"> - <CountdownDisplay milliseconds={studentsChangeRemaining} /> + <div className="p-4 sm:p-8 space-y-6 max-w-md mx-auto timer-dashboard-bg"> + <div className="timer-card"> + <h2 className="timer-card-title">Next Students Change</h2> + <div className="countdown-text"><CountdownDisplay milliseconds={studentsChangeRemaining} /></div> <div className="timer-sub-info"> - <span>🔄</span> + <span>▶</span> <span>{now.getHours() < 4 || now.getHours() >= 16 ? "04:00" : "16:00"}</span> </div> - </TimerCard> + </div> - <TimerCard title="Next Cafe Tap"> - <CountdownDisplay milliseconds={cafeTapRemaining} /> + <div className="timer-card"> + <h2 className="timer-card-title">Next Cafe Tap</h2> + <div className="countdown-text"><CountdownDisplay milliseconds={cafeTapRemaining} /></div> <div className="grid grid-cols-2 gap-4 mt-4"> <button onClick={() => onTap(false)} disabled={cafeTapRemaining > 0 || isSyncing} - className="btn-timer btn-timer-action" + className="btn-timer btn-timer-tap" >{ isSyncing ? '保存中…' : 'Tap' }</button> <button onClick={() => onTap(true)} @@ -86,26 +87,27 @@ export default function TimerDashboard({ className="btn-timer btn-timer-fave" >{ isSyncing ? '保存中…' : 'Fave Tap' }</button> </div> - </TimerCard> + </div> - <TimerCard title="Next Invitation"> + <div className="timer-card"> + <h2 className="timer-card-title">Next Invitation</h2> <div className="grid grid-cols-2 gap-4"> - <CountdownDisplay milliseconds={ticket1Remaining} /> - <CountdownDisplay milliseconds={ticket2Remaining} /> + <div className="countdown-text"><CountdownDisplay milliseconds={ticket1Remaining} /></div> + <div className="countdown-text"><CountdownDisplay milliseconds={ticket2Remaining} /></div> </div> <div className="grid grid-cols-2 gap-4 mt-4"> <button onClick={() => onInvite(1)} disabled={ticket1Remaining > 0 || isSyncing} - className="btn-timer btn-timer-action" + className="btn-timer btn-timer-inv" >{ isSyncing ? '保存中…' : 'Ticket 1' }</button> <button onClick={() => onInvite(2)} disabled={ticket2Remaining > 0 || isSyncing} - className="btn-timer btn-timer-action" + className="btn-timer btn-timer-inv" >{ isSyncing ? '保存中…' : 'Ticket 2' }</button> </div> - </TimerCard> + </div> </div> ); } \ No newline at end of file