Skip to content

Commit c79b20b

Browse files
Edwin ChanEdwin Chan
authored andcommitted
Fix shared outlines and dark mode contrast
1 parent d2760be commit c79b20b

7 files changed

Lines changed: 25 additions & 22 deletions

File tree

CENTRAL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Stack: Next.js, NextAuth (Google + dev bypass), Prisma, KaTeX for math, Lucide i
3333

3434
### Recently landed
3535

36-
- **Hand-drawn visual system** — `app/globals.css` now provides paper/ink design tokens, graph-paper backgrounds, asymmetric squircle cards and controls, marker-color accents, irregular badges/tabs, and stable two-pass SVG ink borders. Global wavy eyebrow/title underlines were removed so the hand-drawn character lives in the outlines instead. A signed-in production Chrome audit of `/problem-sets/1991-ajhsme` caught and removed percentage shape paths from variable-height panels, fixed oversized panel-header geometry, and removed the blue statement band. Desktop navigation is again a 64 px icon rail that expands to 240 px on hover/focus, while mobile retains the stable off-canvas sheet. The simplified Sigma in `public/dbsmo-mark.svg` is shared by favicon metadata and the landing brand. `app/layout.tsx` loads Shantell Sans for display/control text while Inter remains the body and math font. Route-specific coverage was visually audited across dashboard, problem catalog/detail, writeups, practice, classes, leaderboard, users/profiles, settings, and admin surfaces; FTW and Playground were intentionally excluded. Unsupported browsers retain ordinary border/radius fallbacks; details are in `docs/visual-system.md`.
36+
- **Hand-drawn visual system** — `app/globals.css` now provides paper/ink design tokens, graph-paper backgrounds, asymmetric squircle cards and controls, marker-color accents, and irregular badges/tabs. Shared surfaces use native asymmetric borders instead of `border-image`, which created rigid grey rectangles outside rounded controls. Dark structural borders are intentionally quieter, and search inputs are borderless at rest with one cyan focus stroke instead of cyan-plus-yellow highlighting. Global wavy eyebrow/title underlines remain removed. A signed-in production Chrome audit of `/problem-sets/1991-ajhsme` also removed percentage shape paths from variable-height panels, fixed oversized panel-header geometry, and removed the blue statement band. Desktop navigation is a 64 px icon rail that expands to 240 px on hover/focus, while mobile retains the stable off-canvas sheet. The simplified Sigma in `public/dbsmo-mark.svg` is shared by favicon metadata and the landing brand. `app/layout.tsx` loads Shantell Sans for display/control text while Inter remains the body and math font. Route-specific coverage was visually audited across dashboard, problem catalog/detail, writeups, practice, classes, leaderboard, users/profiles, settings, and admin surfaces; FTW and Playground were intentionally excluded. Unsupported browsers retain ordinary border/radius fallbacks; details are in `docs/visual-system.md`.
3737
- **Mobile/classes cleanup** — fixed mobile `/problem-sets` hiding task rows by restoring the responsive card table, stabilized the mobile sidebar grid to avoid icon reflow on tap/focus, and made dashboard auth/actions render as a compact mobile account card. `/classes` now has a teacher/admin `Announcements` subtab that lists existing class messages and supports author/admin deletion. Display-name fallbacks now treat literal `"null"`/`"undefined"` strings as empty via `lib/display-name.ts`.
3838
- **Mobile sidebar focus fix** — mobile sidebar sheet geometry now remains stable under `:hover`, `:focus`, and `:focus-within`, preventing the nav grid from jumping upward when a mobile tap focuses one of the upper links (source: `app/globals.css`).
3939
- **Answer previews and LaTeX grading** — Practice and problem-set answer boxes now render a small KaTeX preview above the input using `mathInputToTex(...)`. `lib/grading.ts` normalizes math delimiters and common LaTeX forms through `lib/math-input.ts`, so expression answers and answer keys can use `$...$`, `\sqrt{...}`, coefficients before functions like `5\sqrt{2}-7`, `\frac{...}{...}`, braced powers, and `\pi`.

DBSMO/Projects/dbsmo/Common Tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This note tells future agents where to edit [[dbsmo]] for common changes. It is
1717

1818
Start with the final `Hand-drawn shape system` and `Hand-drawn route coverage` sections in `app/globals.css`; they intentionally override the older 2026 refresh and light-mode rehaul sections. Shared paper/ink/marker tokens live in `:root` with dark equivalents in `html.dark`. Common panels, actions, inputs, badges, navigation, tables, analytics surfaces, and problem-set controls are grouped there (source: `app/globals.css`).
1919

20-
The public sign-in sketch markup lives in `app/page.tsx`. Keep it `aria-hidden` because it is decorative. Inter/Shantell Sans variables are configured in `app/layout.tsx`; do not apply the handwriting font to answer inputs, equations, or long body copy. Shared hand-drawn outlines use `--drawn-border-image`, a two-pass inline SVG sliced into fixed edges; update both light and dark variants together. Preserve ordinary border/radius fallbacks and test desktop plus mobile widths. Never use percentage-based `border-shape` paths on variable-height panels: a 7,000 px problem panel turns a 1% path offset into 70 px. Do not restore global wavy eyebrow/title underlines. Include a long problem set in visual QA. The current route audit excludes FTW and Playground. Implementation/support notes are in `docs/visual-system.md`.
20+
The public sign-in sketch markup lives in `app/page.tsx`. Keep it `aria-hidden` because it is decorative. Inter/Shantell Sans variables are configured in `app/layout.tsx`; do not apply the handwriting font to answer inputs, equations, or long body copy. Shared hand-drawn outlines use native borders with asymmetric radii and progressive `corner-shape`; do not restore `border-image`, because it paints rigid rectangular frames outside squircles. Update light and dark ink tokens together and test desktop plus mobile widths. Search inputs should remain borderless at rest inside the search panel and use one cyan focus border without an additional outline. Never use percentage-based `border-shape` paths on variable-height panels: a 7,000 px problem panel turns a 1% path offset into 70 px. Do not restore global wavy eyebrow/title underlines. Include a long problem set in visual QA. The current route audit excludes FTW and Playground. Implementation/support notes are in `docs/visual-system.md`.
2121

2222
## Add or Change an Answer Type
2323

DBSMO/Projects/dbsmo/Components.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This note maps important [[dbsmo]] UI/components to their source files and usage
1616
## Global Shell
1717

1818
- `RootLayout` in `app/layout.tsx`: imports KaTeX CSS/global CSS, configures Inter and Shantell Sans CSS variables, sets metadata/viewport, injects an early theme script from `localStorage`, renders `SiteSidebar`, optional mobile nav toggle, `AnimeRouteEffects`, and `.site-content`.
19-
- The two final hand-drawn override sections in `app/globals.css` define paper/ink tokens, graph-paper surfaces, asymmetric squircle card/control corners, marker accents, dark-mode equivalents, route-specific coverage, and two-pass inline SVG ink borders. Nine-slice border images keep the edge wobble stable on tall panels; `border-shape` is limited to bounded empty states and the landing orbit. Global wavy eyebrow/title underlines are intentionally disabled. Shantell Sans is scoped to headings, compact controls, and tabular display text; long-form content, inputs, and math stay in Inter. `app/page.tsx` supplies the decorative math-sketch spans used by the public sign-in composition. The route audit covers all primary non-game surfaces; FTW and Playground are excluded. See [[Common Tasks]] and `docs/visual-system.md`.
19+
- The two final hand-drawn override sections in `app/globals.css` define paper/ink tokens, graph-paper surfaces, asymmetric squircle card/control corners, marker accents, dark-mode equivalents, and route-specific coverage. Shared functional surfaces use native borders because `border-image` produced unclipped rectangular frames around squircles; `border-shape` remains limited to bounded empty states and the landing orbit. Dark structural borders use lower-opacity ink tokens, and search inputs show a single cyan border only while focused. Global wavy eyebrow/title underlines are intentionally disabled. Shantell Sans is scoped to headings, compact controls, and tabular display text; long-form content, inputs, and math stay in Inter. `app/page.tsx` supplies the decorative math-sketch spans used by the public sign-in composition. The route audit covers all primary non-game surfaces; FTW and Playground are excluded. See [[Common Tasks]] and `docs/visual-system.md`.
2020
- `AnimeRouteEffects` in `app/anime-route-effects.tsx`: client-only Anime.js v4 route reveal pass for visible page panels, rows, cards, and action controls; it reruns on pathname changes and exits for `prefers-reduced-motion`.
2121
- `SiteSidebar` in `app/site-sidebar.tsx`: server component that loads session/user and builds sidebar links based on raw admin role plus `hasPermission(...)`. It renders the Lucide Sigma/DBSMO wordmark, `SiteSidebarNav`, and `GlobalMobileNavScrim`. At desktop widths `app/globals.css` keeps it at 64 px until hover or keyboard focus expands it to 240 px and reveals labels; at mobile widths it remains the existing off-canvas sheet. Browser metadata and the public landing brand use the matching `public/dbsmo-mark.svg` asset.
2222
- `SiteSidebarNav` in `app/site-sidebar-nav.tsx`: client nav that maps link icon names to lucide icons and marks active links by pathname prefix.

DBSMO/Projects/dbsmo/Risks and Pitfalls.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Do not edit `.next/`, `node_modules/`, `.codegraph/`, `generated/`, `dist/`, or
7171

7272
## Experimental CSS Shape Support
7373

74-
The final visual-system blocks in `app/globals.css` use `corner-shape` across shared surfaces, two-pass SVG `border-image` outlines for stable pen wobble, and guarded `border-shape: shape(...)` only on bounded empty states and the landing orbit. These APIs are not uniformly supported: functional boxes must keep their asymmetric ordinary-border/radius fallback. Never put a percentage-based shape path on a variable-height panel: production exposed a 7,000 px problem panel where a 1-2% Y offset became a 70-140 px diagonal wedge. Do not move layout, hit targets, or required content into a shape-dependent clipped region. Keep the light and dark `--drawn-border-image` data URLs synchronized, and do not restore global wavy eyebrow/title underlines. Shantell Sans is intentionally limited to display/control text; broadening it to body copy or math hurts legibility (sources: `app/globals.css`, `app/layout.tsx`, `app/page.tsx`, `docs/visual-system.md`).
74+
The final visual-system blocks in `app/globals.css` use `corner-shape` across shared surfaces and guarded `border-shape: shape(...)` only on bounded empty states and the landing orbit. These APIs are not uniformly supported, so functional boxes must keep their asymmetric ordinary-border/radius fallback. Do not add `border-image` to rounded functional surfaces: it does not clip consistently to squircles and previously produced a second rigid grey rectangle around controls in both themes. Never put a percentage-based shape path on a variable-height panel: production exposed a 7,000 px problem panel where a 1-2% Y offset became a 70-140 px diagonal wedge. Do not move layout, hit targets, or required content into a shape-dependent clipped region. Keep dark structural border tokens quieter than text and interactive-state colors, and do not restore global wavy eyebrow/title underlines. Shantell Sans is intentionally limited to display/control text; broadening it to body copy or math hurts legibility (sources: `app/globals.css`, `app/layout.tsx`, `app/page.tsx`, `docs/visual-system.md`).
7575

7676
## Worktree Was Dirty at Scan Time
7777

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ Session updates from the CodeGraph/Second Brain indexing pass onward:
5353
- Rehauled the shared visual system around hand-drawn math-notebook shapes: graph-paper surfaces, irregular ink borders, marker accents, offset control shadows, mixed `corner-shape` geometry, and progressive `border-shape` contours with conventional browser fallbacks.
5454
- Audited and unified the non-game application routes around the same sketchbook language, including dashboard, catalog/set detail, writeups, practice, classes, leaderboard, users/profiles, settings, and admin surfaces. Added Shantell Sans for headings and controls while preserving Inter for dense content, tables, and math; FTW and Playground were intentionally excluded from the route-specific redesign.
5555
- Audited the signed-in production problem-set page in the real Chrome session and corrected the redesign: removed percentage shape paths from tall panels, normalized compact panel headers, removed the light-blue problem statement band, and switched functional surfaces to softer hand-drawn squircles.
56-
- Removed the global yellow wavy eyebrow/title underlines and moved the handwritten character into stable two-pass ink borders for cards, panels, controls, and form fields.
56+
- Removed the global yellow wavy eyebrow/title underlines and moved the handwritten character into asymmetric squircle borders for cards, panels, controls, and form fields.
5757
- Restored the desktop sidebar as a compact icon rail that expands on hover/focus, preserved the stable mobile sheet, and introduced a shared simplified Sigma favicon/landing mark.
5858
- Upgraded KaTeX to v0.17, enabled the official `mhchem` extension, and added secure compatibility rendering for document wrappers and table environments such as `tabular`, `tabular*`, `tabularx`, and `longtable`.
5959
- Fixed imported contest currency notation so full-LaTeX `\textdollar` and legacy sequences such as `\54` render as dollar amounts instead of KaTeX errors.
6060
- Replaced regex-based math splitting with an escape-aware tokenizer, fixing HTML-style `<math>\$2000</math>` imports such as 1996 AJHSME question 18; added conservative package-style aliases and security regression coverage for hostile HTML, trusted KaTeX commands, recursive macros, and macro leakage.
6161
- Fixed every unsupported expression found in a production sweep of the 1985-1998 AJHSME sets: position-qualified `tabular` layouts now convert to safe KaTeX arrays for 1987 Q8/Q23, 1989 Q14/Q22, 1990 Q9, and 1991 Q6. Added safely portable MathLive notation aliases without enabling HTML/resource-loading commands.
62+
- Removed the rectangular `border-image` frames that appeared outside existing rounded controls, simplified search focus to one cyan stroke, and softened repeated structural borders in dark mode.
6263

6364
© 2026 Cosmic Crusader

app/globals.css

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10497,7 +10497,6 @@ html:not(.light) .ftw-rank.rank-1 {
1049710497
--marker-green: #55a96b;
1049810498
--drawn-shadow: 2px 2px 0 rgba(32, 39, 51, 0.13);
1049910499
--drawn-shadow-small: 1px 1px 0 rgba(32, 39, 51, 0.11);
10500-
--drawn-border-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M13 3 C21 1 29 5 37 2 C45 0 53 5 62 2 C70 0 79 5 88 3 Q97 3 97 13 C95 25 99 36 97 47 C95 58 99 70 97 87 Q97 97 87 97 C77 95 68 99 58 97 C48 95 38 99 28 97 C21 96 16 98 12 97 Q3 97 3 87 C1 77 5 67 3 57 C1 47 5 37 3 27 C2 21 3 16 3 12 Q3 3 13 3Z' fill='none' stroke='%23171c24' stroke-width='2.35' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M12 4 C24 2 34 4 45 3 C56 2 67 4 88 3 Q96 4 96 13 C98 35 96 65 98 88 Q96 96 86 96 C65 98 35 96 13 98 Q4 96 4 86 C3 65 4 35 3 13 Q4 4 12 4Z' fill='none' stroke='%23171c24' stroke-opacity='.24' stroke-width='1.1' stroke-linecap='round'/%3E%3C/svg%3E");
1050110500
--drawn-card-radius: 19px 13px 21px 11px;
1050210501
--drawn-control-radius: 13px 9px 15px 8px;
1050310502
--color-bg: var(--paper);
@@ -10533,24 +10532,23 @@ html.dark {
1053310532
--paper-pink: #4d2838;
1053410533
--ink: #f2eee3;
1053510534
--ink-muted: #b6b3ac;
10536-
--ink-soft: rgba(242, 238, 227, 0.3);
10537-
--ink-line: rgba(242, 238, 227, 0.72);
10535+
--ink-soft: rgba(242, 238, 227, 0.18);
10536+
--ink-line: rgba(242, 238, 227, 0.36);
1053810537
--graph-line: rgba(93, 196, 219, 0.045);
1053910538
--marker-cyan: #5dc4db;
1054010539
--marker-pink: #ff75a3;
1054110540
--marker-yellow: #f5d467;
1054210541
--marker-green: #72c987;
1054310542
--drawn-shadow: 2px 2px 0 rgba(0, 0, 0, 0.34);
1054410543
--drawn-shadow-small: 1px 1px 0 rgba(0, 0, 0, 0.3);
10545-
--drawn-border-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M13 3 C21 1 29 5 37 2 C45 0 53 5 62 2 C70 0 79 5 88 3 Q97 3 97 13 C95 25 99 36 97 47 C95 58 99 70 97 87 Q97 97 87 97 C77 95 68 99 58 97 C48 95 38 99 28 97 C21 96 16 98 12 97 Q3 97 3 87 C1 77 5 67 3 57 C1 47 5 37 3 27 C2 21 3 16 3 12 Q3 3 13 3Z' fill='none' stroke='%23f2eee3' stroke-width='2.35' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M12 4 C24 2 34 4 45 3 C56 2 67 4 88 3 Q96 4 96 13 C98 35 96 65 98 88 Q96 96 86 96 C65 98 35 96 13 98 Q4 96 4 86 C3 65 4 35 3 13 Q4 4 12 4Z' fill='none' stroke='%23f2eee3' stroke-opacity='.22' stroke-width='1.1' stroke-linecap='round'/%3E%3C/svg%3E");
1054610544
--color-bg: var(--paper);
1054710545
--color-surface: var(--paper-raised);
1054810546
--color-surface-alt: #292f3c;
1054910547
--color-surface-glass: rgba(34, 39, 51, 0.94);
1055010548
--color-card-bg: var(--paper-raised);
1055110549
--color-input-bg: #1b202a;
10552-
--color-border: rgba(242, 238, 227, 0.18);
10553-
--color-border-strong: rgba(242, 238, 227, 0.4);
10550+
--color-border: rgba(242, 238, 227, 0.13);
10551+
--color-border-strong: rgba(242, 238, 227, 0.3);
1055410552
--color-text: #d9d6ce;
1055510553
--color-text-strong: var(--ink);
1055610554
--color-muted: var(--ink-muted);
@@ -10618,7 +10616,6 @@ html:is(.light, .dark) :is(
1061810616
.analytics-chart-panel
1061910617
) {
1062010618
border: 2px solid var(--ink-soft);
10621-
border-image: var(--drawn-border-image) 14 / 2px / 1px stretch;
1062210619
border-radius: 16px 12px 17px 11px;
1062310620
corner-shape: squircle;
1062410621
background-color: var(--paper-raised);
@@ -10642,7 +10639,6 @@ html:is(.light, .dark) :is(
1064210639

1064310640
html:is(.light, .dark) :is(.primary-action, .secondary-action, .icon-button, .auth-cta) {
1064410641
border: 2px solid var(--ink);
10645-
border-image: var(--drawn-border-image) 14 / 2px / 1px stretch;
1064610642
border-radius: 14px 11px 13px 10px;
1064710643
corner-shape: squircle;
1064810644
box-shadow: var(--drawn-shadow-small);
@@ -10659,6 +10655,10 @@ html:is(.light, .dark) .primary-action {
1065910655
color: #fff;
1066010656
}
1066110657

10658+
html.dark :is(.primary-action, .secondary-action, .icon-button, .auth-cta) {
10659+
border-color: var(--ink-line);
10660+
}
10661+
1066210662
html:is(.light, .dark)
1066310663
:is(.primary-action, .secondary-action, .icon-button, .auth-cta):hover:not(:disabled) {
1066410664
box-shadow: var(--drawn-shadow);
@@ -10687,7 +10687,6 @@ html:is(.light, .dark) :is(
1068710687
.searchable-select-trigger
1068810688
) {
1068910689
border: 2px solid var(--ink-soft);
10690-
border-image: var(--drawn-border-image) 14 / 2px / 1px stretch;
1069110690
border-radius: 13px 10px 14px 9px;
1069210691
corner-shape: squircle;
1069310692
background: var(--color-input-bg);
@@ -10710,8 +10709,7 @@ html:is(.light, .dark) :is(
1071010709
.searchable-select-trigger
1071110710
):focus {
1071210711
border-color: var(--marker-cyan);
10713-
outline: 3px solid color-mix(in srgb, var(--marker-yellow) 48%, transparent);
10714-
outline-offset: 2px;
10712+
outline: none;
1071510713
}
1071610714

1071710715
html:is(.light, .dark) :is(
@@ -11259,7 +11257,6 @@ html:is(.light, .dark)
1125911257
.submit-coaching-panel
1126011258
) {
1126111259
border: 2px solid var(--ink-soft);
11262-
border-image: var(--drawn-border-image) 14 / 2px / 1px stretch;
1126311260
border-radius: 16px 12px 17px 11px;
1126411261
corner-shape: squircle;
1126511262
background-color: var(--paper-raised);
@@ -11371,7 +11368,6 @@ html:is(.light, .dark)
1137111368
padding: 3px;
1137211369
overflow: visible;
1137311370
border: 2px solid var(--ink-line);
11374-
border-image: var(--drawn-border-image) 14 / 2px / 1px stretch;
1137511371
border-radius: 12px 10px 13px 9px;
1137611372
corner-shape: squircle;
1137711373
background: var(--paper-raised);
@@ -11450,6 +11446,12 @@ html:is(.light, .dark)
1145011446
background: var(--color-input-bg);
1145111447
}
1145211448

11449+
html:is(.light, .dark) .search-panel input:not([type="checkbox"]):not([type="radio"]) {
11450+
border-color: transparent;
11451+
background: transparent;
11452+
box-shadow: none;
11453+
}
11454+
1145311455
html:is(.light, .dark)
1145411456
:is(
1145511457
.search-panel input,
@@ -11462,8 +11464,7 @@ html:is(.light, .dark)
1146211464
.searchable-select-search
1146311465
):not([type="checkbox"]):not([type="radio"]):focus {
1146411466
border-color: var(--marker-cyan);
11465-
outline: 3px solid color-mix(in srgb, var(--marker-yellow) 48%, transparent);
11466-
outline-offset: 2px;
11467+
outline: none;
1146711468
}
1146811469

1146911470
html:is(.light, .dark) :is(.table-wrap, .test-answer-table-wrap, .profile-authored-table-wrap) {

0 commit comments

Comments
 (0)