Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Opening Training | chessrepeat.com</title>

<!-- Resolve the theme before the first paint. This is inline and in <head>
on purpose: anything deferred to the module bundle runs after the
browser has already painted, which is a full white frame before a dark
page. Kept in sync with src/store/theme.ts, which reads the key below
and stamps the same attribute for every change after this one. -->
<script>
(function () {
var theme;
try {
theme = localStorage.getItem('chessrepeat:theme');
} catch (e) {}
if (theme !== 'light' && theme !== 'dark') {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
document.documentElement.dataset.theme = theme;
})();
</script>
</head>
<body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/CommentBox.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.comment-box {
padding: 0.5rem 0.75rem;
border-radius: 0.375rem;
background: var(--c-blue-50);
box-shadow: inset 0 0 0 1px var(--c-blue-200);
background: var(--c-info-bg);
box-shadow: inset 0 0 0 1px var(--c-info-line);
font-size: 0.875rem;
color: var(--c-brand-blue);
color: var(--c-info-accent);
}
9 changes: 7 additions & 2 deletions frontend/src/components/GoogleLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { useAuthStore } from '../store/auth';
import { useThemeStore } from '../store/theme';
import { useTrainerStore } from '../store/state';
import { parseChapters } from '../util/chapters';

Expand Down Expand Up @@ -31,6 +32,7 @@ export function applyLoginResponse(data: any) {

export function GoogleLoginButton({ onNeedsUsername, onSuccess }: Props) {
const [ready, setReady] = useState(false);
const theme = useThemeStore((s) => s.theme);
const updateDueCounts = useTrainerStore().updateDueCounts;

useEffect(() => {
Expand Down Expand Up @@ -74,14 +76,17 @@ export function GoogleLoginButton({ onNeedsUsername, onSuccess }: Props) {
setReady(true);
}, []);

// Google renders this button itself, so it can't inherit the palette — it
// only takes one of its own named themes. Re-rendered on a theme change
// because renderButton bakes the look in at call time.
useEffect(() => {
if (!ready) return;
// @ts-ignore
window.google.accounts.id.renderButton(document.getElementById('gbtn'), {
theme: 'outline',
theme: theme === 'dark' ? 'filled_black' : 'outline',
size: 'large',
});
}, [ready]);
}, [ready, theme]);

return <div id="gbtn" />;
}
23 changes: 22 additions & 1 deletion frontend/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SiDiscord, SiGithub } from 'react-icons/si';
import { LogIn, LogOut, User } from 'lucide-react';
import { LogIn, LogOut, Moon, Sun, User } from 'lucide-react';
import { useAuthStore } from '../store/auth';
import { useThemeStore } from '../store/theme';
import { useTrainerStore, type Peer } from '../store/state';

interface Props {
Expand All @@ -11,6 +12,10 @@ interface Props {
}

export function Header({ connectedUsers, incomingCollaboratorsCount = 0 }: Props) {
const theme = useThemeStore((s) => s.theme);
const toggleTheme = useThemeStore((s) => s.toggleTheme);
const isDark = theme === 'dark';

const authUser = useAuthStore((s) => s.user);
const clearAuth = useAuthStore((s) => s.clearAuth);
const openLogin = useAuthStore((s) => s.openLogin);
Expand Down Expand Up @@ -103,6 +108,22 @@ export function Header({ connectedUsers, incomingCollaboratorsCount = 0 }: Props
</div>

<div className="header-actions">
{/* Labelled by what it switches *to*, the way "hide comments" is, so
the icon and the words say the same thing. First in the cluster, so
the dot separator falls between it and the links rather than
before it. */}
<button
type="button"
onClick={toggleTheme}
className="header-link"
aria-pressed={isDark}
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
title={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
>
<span>{isDark ? 'light mode' : 'dark mode'}</span>
{isDark ? <Sun /> : <Moon />}
</button>

<a
href="https://discord.gg/xhjra9W6Bh"
target="_blank"
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/components/InsightChart.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,23 @@

/* five buckets, empty -> busiest day in the window */
.cr-heatmap .react-calendar-heatmap rect.color-cr-0 {
fill: #dfdfdf;
fill: var(--c-heat-0);
}

.cr-heatmap .react-calendar-heatmap rect.color-cr-1 {
fill: #c9deff;
fill: var(--c-heat-1);
}

.cr-heatmap .react-calendar-heatmap rect.color-cr-2 {
fill: #91bbff;
fill: var(--c-heat-2);
}

.cr-heatmap .react-calendar-heatmap rect.color-cr-3 {
fill: #6991ff;
fill: var(--c-heat-3);
}

.cr-heatmap .react-calendar-heatmap rect.color-cr-4 {
fill: #1856ff;
fill: var(--c-heat-4);
}

.cr-heatmap .react-calendar-heatmap rect.cr-today {
Expand All @@ -76,7 +76,7 @@
}

.cr-heatmap .react-calendar-heatmap rect:hover {
stroke: #555;
stroke: var(--c-heat-hover);
stroke-width: 1;
cursor: pointer;
}
2 changes: 1 addition & 1 deletion frontend/src/components/MobileCommentPopout.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
padding: 0.25rem 0.75rem;
border-radius: 0.25rem;
background: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
font-size: 0.75rem;
font-weight: 600;
transition: filter 150ms;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/PromotionOverlay.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
.promo-card {
padding: 0.75rem;
border-radius: 0.75rem;
background: rgb(255 255 255 / 0.9);
background: var(--c-glass);
box-shadow: var(--shadow-xl);
}

Expand All @@ -38,12 +38,12 @@
width: 56px;
height: 56px;
border-radius: 0.5rem;
background: rgb(0 0 0 / 0.05);
background: var(--c-well);
transition: background-color 150ms;
}

.promo-option:hover:not(:disabled) {
background: rgb(0 0 0 / 0.1);
background: var(--c-well-hover);
}

/* While learning, only the piece the line actually promotes to is selectable. */
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/TrainingControls.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@
--ring-pulse-out: rgb(59 130 246 / 0); /* fade out in blue, not toward black */
background: var(--c-brand-blue);
border-color: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
animation: ring-pulse 1.5s ease-out infinite;
}
12 changes: 9 additions & 3 deletions frontend/src/components/UserTip.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,20 @@
height: 2rem;
}

/* Same two tokens as .panel-icon in layout.css — the boxed glyph in a panel
header (the calendar on the schedule, the book on the repertoire). This tip
sits directly under those panels, so a glyph a step lighter read as a
different kind of object. Keep the pair in sync with that rule; matching by
token rather than by value is what holds it together in both themes.
Geometry stays local: this one is larger and grows again at 768px. */
.tip-icon {
padding: 0.375rem;
border-radius: 0.375rem;
color: var(--c-gray-500);
color: var(--c-gray-600);
}

.tip-icon.is-boxed {
background: var(--c-gray-100);
background: var(--c-gray-200);
}

.tip-icon svg {
Expand Down Expand Up @@ -101,7 +107,7 @@

/* the guessed move quoted inside the "ADD <move>" action */
.tip-action-move {
color: #000;
color: var(--c-gray-900);
}

/* ---------- the ✗ shown when a guess was wrong ----------
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/components/collaborators/CollaboratorsPanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@

.collab-badge-edit {
background: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
}

.collab-badge-train {
Expand Down Expand Up @@ -135,15 +135,18 @@
gap: 0.375rem;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
background: var(--c-slate-800);
color: var(--c-surface);
/* the app's primary fill, same as the repertoire's add button and the
settings dialog's save — this is the affirmative action of its form */
background: var(--c-brand-blue);
color: var(--c-on-accent);
font-size: 0.875rem;
font-weight: 600;
white-space: nowrap;
transition: background 150ms;
}

.collab-add-btn:hover {
background: var(--c-slate-700);
background: var(--c-accent-strong);
}

/* ---------- result message ---------- */
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/ToggleGroup.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@

.toggle-group-option.is-selected {
background: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
}
29 changes: 17 additions & 12 deletions frontend/src/components/modals/AddToRepertoireModal.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@
border-radius: 0 0.5rem 0.5rem 0;
}

/* The one fill in the app made of a neutral rather than an accent, so unlike
every other filled control this label does track --c-surface: the ramp step
under it flips with the theme, and the text has to flip back with it. */
.add-rep-color input:checked + .add-rep-color-label {
background: var(--c-gray-700);
color: var(--c-surface);
Expand All @@ -187,34 +190,34 @@
gap: 0.75rem;
margin-bottom: 0.5rem;
padding: 0.75rem 1rem;
border: 1px solid var(--c-amber-300);
border: 1px solid var(--c-warn-line);
border-radius: 0.5rem;
background: var(--c-amber-50);
background: var(--c-warn-bg);
}

.add-rep-signed-out svg {
flex-shrink: 0;
width: 1.25rem;
height: 1.25rem;
margin-top: 0.125rem;
color: var(--c-amber-500);
color: var(--c-warn-icon);
}

.add-rep-signed-out p {
font-size: 0.875rem;
line-height: 1.375;
color: var(--c-amber-900);
color: var(--c-warn-fg);
}

.add-rep-signed-out button {
font-weight: 600;
color: var(--c-amber-900);
color: var(--c-warn-fg);
text-decoration: underline;
text-underline-offset: 2px;
}

.add-rep-signed-out button:hover {
color: var(--c-amber-950);
color: var(--c-warn-fg-strong);
}

/* ---------- submit ---------- */
Expand All @@ -223,7 +226,7 @@
padding: 0.5rem 1rem;
border-radius: 0.25rem;
background: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
font-size: 1.125rem;
font-weight: 700;
transition: filter 150ms, background-color 150ms;
Expand Down Expand Up @@ -255,11 +258,11 @@
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.75rem;
border: 1px solid var(--c-green-200);
border: 1px solid var(--c-success-line);
border-radius: 0.375rem;
background: var(--c-green-50);
background: var(--c-success-bg);
font-size: 0.875rem;
color: var(--c-green-800);
color: var(--c-success-fg);
}

.add-rep-json-loaded svg {
Expand All @@ -275,7 +278,9 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: rgb(21 128 61 / 0.8);
/* a shade quieter than the "loaded" label it sits beside */
color: var(--c-success-fg);
opacity: 0.8;
}

.add-rep-json-idle {
Expand Down Expand Up @@ -312,7 +317,7 @@
padding: 0.5rem 1rem;
border-radius: 0.25rem;
background: var(--c-green-600);
color: var(--c-surface);
color: var(--c-on-accent);
font-size: 1.125rem;
font-weight: 700;
transition: background-color 150ms;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/modals/DownloadModal.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

.download-option.is-selected {
border-color: var(--c-brand-blue);
background: var(--c-blue-50);
color: var(--c-blue-900);
background: var(--c-info-bg);
color: var(--c-info-fg);
}

.download-option:disabled {
Expand Down Expand Up @@ -54,7 +54,7 @@
padding: 0.625rem 1rem;
border-radius: 0.5rem;
background: var(--c-brand-blue);
color: var(--c-surface);
color: var(--c-on-accent);
font-size: 0.875rem;
font-weight: 600;
transition: filter 150ms, transform 150ms;
Expand Down
Loading