feat: Quests page responsiveness and sidebar enhancements

This commit is contained in:
2026-03-04 03:22:22 +06:00
parent c35f328e30
commit 437c7a517f
37 changed files with 398 additions and 65 deletions

View File

@ -1,5 +1,4 @@
import {
Sidebar,
SidebarContent,
SidebarHeader,
SidebarFooter,
@ -19,11 +18,12 @@ import {
Target,
Zap,
Trophy,
Map,
} from "lucide-react";
import { useState } from "react";
import logo from "../assets/ed_logo1.png";
import { NavLink, useNavigate } from "react-router-dom";
import { NavLink, useNavigate, useLocation } from "react-router-dom";
import { useAuthStore } from "../stores/authStore";
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
@ -31,16 +31,199 @@ export function AppSidebar() {
const [open, setOpen] = useState(false);
const user = useAuthStore((s) => s.user);
const navigate = useNavigate();
const location = useLocation();
const isQuestPage = location.pathname.startsWith("/student/quests");
const STYLES = `
/* ══ DEFAULT sidebar (cream frosted glass) ══ */
.as-sidebar-container {
position: fixed;
top: 0.5rem;
bottom: 0.5rem;
left: 0.5rem;
width: 16rem;
z-index: 10;
border-radius: 1.75rem;
overflow: hidden;
pointer-events: auto;
background: rgba(255,251,244,0.72);
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
border: 1.5px solid rgba(255,255,255,0.7);
box-shadow:
0 8px 32px rgba(0,0,0,0.12),
0 2px 8px rgba(0,0,0,0.06),
inset 0 1px 0 rgba(255,255,255,0.8);
transition:
background 0.4s ease,
border-color 0.4s ease,
box-shadow 0.4s ease,
z-index 0.3s ease;
display: flex;
flex-direction: column;
height: calc(100vh - 1rem);
}
/* ══ QUEST mode sidebar (dark navy pirate + gold) ══ */
.as-sidebar-container.quest-mode {
background: linear-gradient(
180deg,
rgba(251,191,36,0.12) 0%,
rgba(251,191,36,0.08) 50%,
rgba(251,191,36,0.1) 100%
);
background-size: 100% 200%;
animation: asSweepDown 3s linear infinite;
border-color: rgba(251,191,36,0.28);
box-shadow:
0 8px 32px rgba(0,0,0,0.25),
0 2px 8px rgba(0,0,0,0.15),
inset 0 1px 0 rgba(255,255,255,0.08);
}
/* Shimmer animation from top to bottom */
@keyframes asSweepDown {
0% { background-position: 0% 200%; }
100% { background-position: 0% -200%; }
}
/* On quest page, sidebar stays visible above content */
.as-sidebar-container.quest-mode {
z-index: 40;
}
.as-sidebar-inner {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
height: 100%;
}
.as-gradient-overlay {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;
}
.as-gradient-overlay.default {
background: radial-gradient(
circle at top,
rgba(168,85,247,0.18),
transparent 55%
),
radial-gradient(
circle at bottom,
rgba(249,115,22,0.1),
transparent 55%
);
}
.as-gradient-overlay.quest {
background: transparent;
}
/* Ensure Sidebar sub-components are transparent */
.as-sidebar-inner > * {
background: transparent;
}
.as-sidebar-inner [class*="SidebarHeader"],
.as-sidebar-inner [class*="SidebarContent"],
.as-sidebar-inner [class*="SidebarFooter"],
.as-sidebar-inner [class*="SidebarGroup"],
.as-sidebar-inner [class*="SidebarMenu"] {
background: transparent;
}
/* Quest mode text visibility */
.as-sidebar-container.quest-mode [class*="SidebarGroupLabel"] {
color: rgba(255, 255, 255, 0.4) !important;
}
.as-sidebar-container.quest-mode a {
color: rgba(255, 255, 255, 0.6) !important;
background: transparent !important;
}
.as-sidebar-container.quest-mode a:hover {
color: rgba(255, 255, 255, 0.85) !important;
background: rgba(255, 255, 255, 0.08) !important;
}
.as-sidebar-container.quest-mode a.active {
color: #fbbf24 !important;
}
.as-sidebar-container.quest-mode span {
color: inherit;
}
/* Quest header text */
.as-sidebar-container.quest-mode .text-slate-900 {
color: rgba(255, 255, 255, 0.9) !important;
}
.as-sidebar-container.quest-mode .text-slate-400 {
color: rgba(255, 255, 255, 0.4) !important;
}
/* Quest mode removes white hover background from menu buttons */
.as-sidebar-container.quest-mode [class*="SidebarMenuButton"]:hover {
background: transparent !important;
}
.as-sidebar-container.quest-mode [class*="SidebarMenuButton"] {
background: transparent !important;
}
/* Prevent group-hover from adding white background in quest mode */
.as-sidebar-container.quest-mode .group:hover {
background: transparent !important;
}
/* Quest mode footer button styling */
.as-sidebar-container.quest-mode [class*="SidebarFooter"] button {
background: rgba(255, 255, 255, 0.08) !important;
--tw-ring-color: rgba(255, 255, 255, 0.05) !important;
border-color: rgba(255, 255, 255, 0.05) !important;
}
.as-sidebar-container.quest-mode [class*="SidebarFooter"] button:hover {
background: rgba(255, 255, 255, 0.12) !important;
}
/* Override Tailwind bg-white and ring classes for quest mode */
.as-sidebar-container.quest-mode button[class*="bg-white"] {
background-color: rgba(255, 255, 255, 0.08) !important;
}
.as-sidebar-container.quest-mode button[class*="ring-white"]:not(:hover) {
--tw-ring-color: rgba(255, 255, 255, 0.05) !important;
border-color: rgba(255, 255, 255, 0.05) !important;
}
.as-sidebar-container.quest-mode button:hover[class*="hover:bg-white"] {
background-color: rgba(255, 255, 255, 0.12) !important;
}
.as-sidebar-container.quest-mode a:hover {
--tw-ring-color: rgba(255, 255, 255, 0.05) !important;
}
`;
return (
<Sidebar
variant="floating"
className="pointer-events-none border-0 bg-transparent px-0 py-0"
>
<div className="pointer-events-auto fixed inset-y-2 left-2 flex w-64 flex-col overflow-hidden rounded-[1.75rem] bg-[rgba(249,240,255,0.82)] shadow-[0_18px_45px_rgba(15,23,42,0.16)] transition-colors duration-300">
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top,rgba(168,85,247,0.18),transparent_55%),radial-gradient(circle_at_bottom,rgba(249,115,22,0.1),transparent_55%)]" />
<>
<style>{STYLES}</style>
<div
className={`as-sidebar-container${isQuestPage ? " quest-mode" : ""}`}
>
<div
className={`as-gradient-overlay ${isQuestPage ? "quest" : "default"}`}
/>
<div className="relative flex h-full flex-col">
<div className="as-sidebar-inner">
{/* HEADER */}
<SidebarHeader className="px-3 pb-4 pt-1">
<div className="flex items-center justify-start gap-2">
@ -76,12 +259,12 @@ export function AppSidebar() {
<SidebarMenuItem>
<SidebarMenuButton
asChild
className="group cursor-pointer rounded-2xl px-2 py-2.5 transition-colors duration-200 hover:bg-white"
className="group cursor-pointer px-2 py-2.5 transition-colors duration-200"
>
<NavLink
to="/student/home"
className={({ isActive }) =>
`flex items-center gap-2.5 text-sm font-satoshi ${
`flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 ${
isActive
? "text-slate-900"
: "text-slate-500 group-hover:text-slate-900"
@ -92,11 +275,20 @@ export function AppSidebar() {
<>
<Home
size={18}
strokeWidth={3}
className={
isActive ? "text-orange-400" : "text-slate-400"
}
/>
<span>Home</span>
<span
className={
isActive
? "text-orange-400 font-extrabold"
: "text-slate-400 font-bold"
}
>
Home
</span>
</>
)}
</NavLink>
@ -109,13 +301,13 @@ export function AppSidebar() {
onMouseLeave={() => setOpen(false)}
>
<SidebarMenuButton
className="group cursor-pointer rounded-2xl px-2 py-2.5 transition-colors duration-200 hover:bg-white"
className="group cursor-pointer px-2 py-2.5 transition-colors duration-200"
asChild
>
<NavLink
to="/student/practice"
className={({ isActive }) =>
`flex items-center gap-2.5 text-sm font-satoshi ${
`flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 ${
isActive
? "text-slate-900"
: "text-slate-500 group-hover:text-slate-900"
@ -126,13 +318,23 @@ export function AppSidebar() {
<>
<BookOpen
size={18}
strokeWidth={3}
className={
isActive ? "text-purple-500" : "text-slate-400"
}
/>
<span>Practice</span>
<span
className={
isActive
? "text-purple-500 font-extrabold"
: "text-slate-400 font-bold"
}
>
Practice
</span>
<ChevronDown
size={16}
strokeWidth={3}
className={`ml-auto text-slate-400 transition-transform ${
open ? "rotate-180" : ""
}`}
@ -153,7 +355,11 @@ export function AppSidebar() {
}`
}
>
<Target size={18} className="text-slate-400" />
<Target
size={18}
strokeWidth={3}
className="text-slate-400"
/>
<span>Targeted Practice</span>
</NavLink>
<NavLink
@ -166,7 +372,11 @@ export function AppSidebar() {
}`
}
>
<Zap size={18} className="text-slate-400" />
<Zap
size={18}
strokeWidth={3}
className="text-slate-400"
/>
<span>Drills</span>
</NavLink>
<NavLink
@ -179,23 +389,87 @@ export function AppSidebar() {
}`
}
>
<Trophy size={18} className="text-slate-400" />
<Trophy
size={18}
strokeWidth={3}
className="text-slate-400"
/>
<span>Hard Test Modules</span>
</NavLink>
</SidebarMenuSub>
)}
</SidebarMenuItem>
{/* QUESTS */}
<SidebarMenuItem>
<SidebarMenuButton
asChild
className="group cursor-pointer px-2 py-2.5 transition-colors duration-200"
>
<NavLink
to="/student/quests"
className={({ isActive }) => {
if (isActive && isQuestPage) {
return "flex items-center gap-2.5 text-sm rounded-2xl px-2 py-2.5 transition-all duration-200";
}
if (isActive) {
return "flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 text-slate-900";
}
return "flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 text-slate-500 group-hover:text-slate-900";
}}
>
{({ isActive }) => (
<>
<Map
size={18}
strokeWidth={3}
className={
isActive && isQuestPage
? "text-amber-400"
: isActive
? "text-blue-500"
: "text-slate-400"
}
/>
<span
className={
isActive && isQuestPage
? ""
: isActive
? "text-blue-500 font-extrabold"
: "text-slate-400 font-bold"
}
style={
isActive && isQuestPage
? {
fontFamily: "'Sorts Mill Goudy', serif",
fontSize: "0.95rem",
fontWeight: 900,
letterSpacing: "0.05em",
color: "#fbbf24",
textShadow: "0 0 12px rgba(251,191,36,0.5)",
}
: {}
}
>
Quests
</span>
</>
)}
</NavLink>
</SidebarMenuButton>
</SidebarMenuItem>
{/* LESSONS */}
<SidebarMenuItem>
<SidebarMenuButton
asChild
className="group cursor-pointer rounded-2xl px-2 py-2.5 transition-colors duration-200 hover:bg-white"
className="group cursor-pointer px-2 py-2.5 transition-colors duration-200"
>
<NavLink
to="/student/lessons"
className={({ isActive }) =>
`flex items-center gap-2.5 text-sm font-satoshi ${
`flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 ${
isActive
? "text-slate-900"
: "text-slate-500 group-hover:text-slate-900"
@ -206,11 +480,20 @@ export function AppSidebar() {
<>
<Video
size={18}
strokeWidth={3}
className={
isActive ? "text-cyan-500" : "text-slate-400"
}
/>
<span>Lessons</span>
<span
className={
isActive
? "text-cyan-500 font-extrabold"
: "text-slate-400 font-bold"
}
>
Lessons
</span>
</>
)}
</NavLink>
@ -221,12 +504,12 @@ export function AppSidebar() {
<SidebarMenuItem>
<SidebarMenuButton
asChild
className="group cursor-pointer rounded-2xl px-2 py-2.5 transition-colors duration-200 hover:bg-white"
className="group cursor-pointer px-2 py-2.5 transition-colors duration-200"
>
<NavLink
to="/student/rewards"
className={({ isActive }) =>
`flex items-center gap-2.5 text-sm font-satoshi ${
`flex items-center gap-2.5 text-sm font-satoshi rounded-2xl px-2 py-2.5 transition-all duration-200 ${
isActive
? "text-slate-900"
: "text-slate-500 group-hover:text-slate-900"
@ -237,11 +520,20 @@ export function AppSidebar() {
<>
<Trophy
size={18}
strokeWidth={3}
className={
isActive ? "text-emerald-500" : "text-slate-400"
}
/>
<span>Rewards</span>
<span
className={
isActive
? "text-emerald-500 font-extrabold"
: "text-slate-400 font-bold"
}
>
Rewards
</span>
</>
)}
</NavLink>
@ -268,11 +560,15 @@ export function AppSidebar() {
<span className="font-medium text-slate-900">{user?.name}</span>
<span className="text-xs text-slate-400">{user?.email}</span>
</div>
<ChevronDown size={16} className="ml-auto text-slate-400" />
<ChevronDown
size={16}
strokeWidth={3}
className="ml-auto text-slate-400"
/>
</button>
</SidebarFooter>
</div>
</div>
</Sidebar>
</>
);
}

View File

@ -48,6 +48,12 @@ const STYLES = `
display: flex;
flex-direction: column;
}
@media (min-width: 1024px) {
.lm-content {
max-width: 1000px;
}
}
.lm-dialog-header-hidden {
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;

View File

@ -25,7 +25,8 @@ const PALETTES = {
activeBg: "bg-blue-600",
activeText: "text-blue-900",
pastBg: "bg-blue-400",
sidebarActive: "bg-white/80 shadow-md border border-blue-100",
sidebarActive:
"bg-white/80 shadow-md border border-blue-100 lg:bg-transparent lg:shadow-none lg:border-transparent",
dotBg: "bg-blue-100",
dotText: "text-blue-500",
glassClass: "glass-blue",
@ -34,7 +35,8 @@ const PALETTES = {
activeBg: "bg-violet-600",
activeText: "text-violet-900",
pastBg: "bg-violet-400",
sidebarActive: "bg-white/80 shadow-md border border-violet-100",
sidebarActive:
"bg-white/80 shadow-md border border-violet-100 lg:bg-transparent lg:shadow-none lg:border-transparent",
dotBg: "bg-violet-100",
dotText: "text-violet-500",
glassClass: "glass-violet",
@ -43,7 +45,8 @@ const PALETTES = {
activeBg: "bg-amber-600",
activeText: "text-amber-900",
pastBg: "bg-amber-400",
sidebarActive: "bg-white/80 shadow-md border border-amber-100",
sidebarActive:
"bg-white/80 shadow-md border border-amber-100 lg:bg-transparent lg:shadow-none lg:border-transparent",
dotBg: "bg-amber-100",
dotText: "text-amber-500",
glassClass: "glass-amber",
@ -52,7 +55,8 @@ const PALETTES = {
activeBg: "bg-emerald-600",
activeText: "text-emerald-900",
pastBg: "bg-emerald-400",
sidebarActive: "bg-white/80 shadow-md border border-emerald-100",
sidebarActive:
"bg-white/80 shadow-md border border-emerald-100 lg:bg-transparent lg:shadow-none lg:border-transparent",
dotBg: "bg-emerald-100",
dotText: "text-emerald-500",
glassClass: "glass-emerald",
@ -134,7 +138,7 @@ export default function LessonShell({
<p className="text-[10px] font-bold uppercase tracking-[0.2em] text-slate-400 mb-3 px-1 hidden lg:block">
Sections
</p>
<nav className="space-y-1.5 bg-white">
<nav className="space-y-1.5 bg-white lg:bg-transparent">
{sections.map((sec, i) => {
const isActive = activeSection === i;
const isPast = activeSection > i;
@ -144,7 +148,9 @@ export default function LessonShell({
key={i}
onClick={() => scrollToSection(i)}
className={`flex items-center gap-3 p-2.5 w-full rounded-xl transition-all text-left ${
isActive ? palette.sidebarActive : "hover:bg-white/50"
isActive
? palette.sidebarActive
: "hover:bg-white/50 lg:hover:bg-transparent"
}`}
>
<div
@ -174,7 +180,7 @@ export default function LessonShell({
</aside>
{/* ── Main content ── */}
<div className="flex-1 max-w-4xl mx-auto w-full">
<div className="flex-1 lg:ml-64 max-w-4xl mx-auto w-full">
{childArray.map((child, i) => (
<section
key={i}

View File

@ -71,6 +71,15 @@ const STYLES = `
display:flex; flex-direction:column; gap:1.5rem;
}
/* Desktop: wider centered layout matching rewards page */
@media (min-width: 900px) {
.ls-inner {
max-width: var(--content-max);
padding: 2rem 2rem 6rem;
}
}
@keyframes lsPopIn {
from { opacity:0; transform:scale(0.92) translateY(12px); }
to { opacity:1; transform:scale(1) translateY(0); }

View File

@ -72,6 +72,13 @@ const STYLES = `
border-bottom: 1px solid rgba(251,191,36,0.12);
padding: 1.25rem 1.25rem 0;
}
/* On desktop, account for sidebar */
@media (min-width: 768px) {
.qm-header {
padding-left: calc(17rem + 1.25rem);
}
}
.qm-page-title {
font-family: 'Sorts Mill Goudy', serif;
font-size: 1.3rem; font-weight: 900; letter-spacing: 0.05em;
@ -133,6 +140,15 @@ const STYLES = `
linear-gradient(180deg, #071530 0%, #04101e 40%, #020a14 100%);
overflow:hidden;
}
/* On desktop, account for sidebar (16rem + 1rem margins = 17rem) */
@media (min-width: 768px) {
.qm-sea {
padding-left: calc(17rem + 1.25rem);
margin-left: 0;
}
}
.qm-sea-shimmer {
position:absolute; inset:0; pointer-events:none; z-index:0;
background:

View File

@ -96,7 +96,7 @@ const STYLES = `
.rw-empty { padding: 5rem 1rem; }
/* Slightly larger island pill on wide screens and rebalance blobs */
.rw-island-wrap { max-width: 420px; left:auto; right:calc((100vw - 256px - var(--content-max)) / 2); top:240px; bottom:auto; transform:none; margin-left:150px; }
.rw-island-wrap { max-width: 420px; left:auto; right:calc((100vw - 256px - var(--content-max)) / 2); top:240px; bottom:auto; transform:none; margin-left:25px; }
.rw-island-card { gap: 0.75rem; }
/* Rebalance decorative blobs on wide screens */

View File

@ -81,7 +81,7 @@ const CirclePropertiesLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Central vs Inscribed" icon={Target} />
<SectionMarker index={1} title="Tangents" icon={Layers} />

View File

@ -92,7 +92,7 @@ const CollectingDataLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Sampling & Bias" icon={Scale} />
<SectionMarker index={1} title="Study Design" icon={Layers} />

View File

@ -80,7 +80,7 @@ const CongruenceSimilarityLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Congruence Tests" icon={Target} />
<SectionMarker index={1} title="Similarity Tests" icon={Layers} />

View File

@ -114,7 +114,7 @@ const DataAnalysisLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Data Changes" icon={Calculator} />
<SectionMarker index={1} title="Distributions" icon={BarChart3} />

View File

@ -116,7 +116,7 @@ const DataRepresentationLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Frequency & Mean" icon={Calculator} />
<SectionMarker index={1} title="Histograms" icon={BarChart3} />

View File

@ -239,7 +239,7 @@ const EBRWCommasLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -117,7 +117,7 @@ const EBRWCraftStructureLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Craft & Purpose" icon={BookOpen} />
<SectionMarker

View File

@ -225,7 +225,7 @@ const EBRWDashesApostrophesLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -119,7 +119,7 @@ const EBRWExplicitMeaningLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -119,7 +119,7 @@ const EBRWExpressionIdeasLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Synthesis & Goals" icon={BookOpen} />
<SectionMarker

View File

@ -287,7 +287,7 @@ const EBRWGraphicDisplaysLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Reading Graphics" icon={BookOpen} />
<SectionMarker

View File

@ -119,7 +119,7 @@ const EBRWInferencesLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -116,7 +116,7 @@ const EBRWMainIdeaLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -238,7 +238,7 @@ const EBRWPronounsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Pronoun Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -219,7 +219,7 @@ const EBRWSemicolonsColonsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -244,7 +244,7 @@ const EBRWSentenceStructureLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Structure Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -233,7 +233,7 @@ const EBRWSubjectVerbLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Agreement Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -237,7 +237,7 @@ const EBRWTransitionsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Transition Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -241,7 +241,7 @@ const EBRWVerbsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker index={0} title="Verb Anatomy" icon={BookOpen} />
<SectionMarker

View File

@ -185,7 +185,7 @@ const EBRWVocabMeaningLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -185,7 +185,7 @@ const EBRWVocabPreciseLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}

View File

@ -81,7 +81,7 @@ const LinearParallelPerpendicularLesson: React.FC<LessonProps> = ({
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker
index={0}

View File

@ -78,7 +78,7 @@ const LinearTransformationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker
index={0}

View File

@ -88,7 +88,7 @@ const LinesAnglesLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Parallel Lines" icon={Target} />
<SectionMarker index={1} title="Triangles" icon={Layers} />

View File

@ -79,7 +79,7 @@ const PolynomialFunctionsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="End Behavior" icon={TrendingUp} />
<SectionMarker index={1} title="Zeros & Multiplicity" icon={Grid} />

View File

@ -103,7 +103,7 @@ const ProportionalLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Ratios" icon={Scale} />
<SectionMarker

View File

@ -88,7 +88,7 @@ const QuadraticEquationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker
index={0}

View File

@ -80,7 +80,7 @@ const RationalRadicalLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Rational Functions" icon={Grid} />
<SectionMarker index={1} title="Radical Equations" icon={Target} />

View File

@ -79,7 +79,7 @@ const SystemsEquationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker index={0} title="Number of Solutions" icon={Grid} />
<SectionMarker index={1} title="Solving Methods" icon={RefreshCw} />

View File

@ -401,7 +401,7 @@ const TrigLesson: React.FC<LessonProps> = ({ onFinish }) => {
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 lg:bg-transparent z-0 hidden lg:block">
<nav className="space-y-2">
<SectionMarker
index={0}

View File

@ -359,7 +359,7 @@ const STYLES = `
right: 0;
z-index: 5;
padding: 0.85rem 1.25rem calc(0.85rem + env(safe-area-inset-bottom));
background: rgba(255, 251, 244, 0.9);
background: rgba(255, 251, 244, 0);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-top: 2px solid #f3f4f6;