feat: Quests page responsiveness and sidebar enhancements
This commit is contained in:
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
Sidebar,
|
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarFooter,
|
SidebarFooter,
|
||||||
@ -19,11 +18,12 @@ import {
|
|||||||
Target,
|
Target,
|
||||||
Zap,
|
Zap,
|
||||||
Trophy,
|
Trophy,
|
||||||
|
Map,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import logo from "../assets/ed_logo1.png";
|
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 { useAuthStore } from "../stores/authStore";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
|
||||||
|
|
||||||
@ -31,16 +31,199 @@ export function AppSidebar() {
|
|||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const user = useAuthStore((s) => s.user);
|
const user = useAuthStore((s) => s.user);
|
||||||
const navigate = useNavigate();
|
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 (
|
return (
|
||||||
<Sidebar
|
<>
|
||||||
variant="floating"
|
<style>{STYLES}</style>
|
||||||
className="pointer-events-none border-0 bg-transparent px-0 py-0"
|
<div
|
||||||
|
className={`as-sidebar-container${isQuestPage ? " quest-mode" : ""}`}
|
||||||
>
|
>
|
||||||
<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
|
||||||
<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%)]" />
|
className={`as-gradient-overlay ${isQuestPage ? "quest" : "default"}`}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="relative flex h-full flex-col">
|
<div className="as-sidebar-inner">
|
||||||
{/* HEADER */}
|
{/* HEADER */}
|
||||||
<SidebarHeader className="px-3 pb-4 pt-1">
|
<SidebarHeader className="px-3 pb-4 pt-1">
|
||||||
<div className="flex items-center justify-start gap-2">
|
<div className="flex items-center justify-start gap-2">
|
||||||
@ -76,12 +259,12 @@ export function AppSidebar() {
|
|||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
asChild
|
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
|
<NavLink
|
||||||
to="/student/home"
|
to="/student/home"
|
||||||
className={({ isActive }) =>
|
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
|
isActive
|
||||||
? "text-slate-900"
|
? "text-slate-900"
|
||||||
: "text-slate-500 group-hover:text-slate-900"
|
: "text-slate-500 group-hover:text-slate-900"
|
||||||
@ -92,11 +275,20 @@ export function AppSidebar() {
|
|||||||
<>
|
<>
|
||||||
<Home
|
<Home
|
||||||
size={18}
|
size={18}
|
||||||
|
strokeWidth={3}
|
||||||
className={
|
className={
|
||||||
isActive ? "text-orange-400" : "text-slate-400"
|
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>
|
</NavLink>
|
||||||
@ -109,13 +301,13 @@ export function AppSidebar() {
|
|||||||
onMouseLeave={() => setOpen(false)}
|
onMouseLeave={() => setOpen(false)}
|
||||||
>
|
>
|
||||||
<SidebarMenuButton
|
<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
|
asChild
|
||||||
>
|
>
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/student/practice"
|
to="/student/practice"
|
||||||
className={({ isActive }) =>
|
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
|
isActive
|
||||||
? "text-slate-900"
|
? "text-slate-900"
|
||||||
: "text-slate-500 group-hover:text-slate-900"
|
: "text-slate-500 group-hover:text-slate-900"
|
||||||
@ -126,13 +318,23 @@ export function AppSidebar() {
|
|||||||
<>
|
<>
|
||||||
<BookOpen
|
<BookOpen
|
||||||
size={18}
|
size={18}
|
||||||
|
strokeWidth={3}
|
||||||
className={
|
className={
|
||||||
isActive ? "text-purple-500" : "text-slate-400"
|
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
|
<ChevronDown
|
||||||
size={16}
|
size={16}
|
||||||
|
strokeWidth={3}
|
||||||
className={`ml-auto text-slate-400 transition-transform ${
|
className={`ml-auto text-slate-400 transition-transform ${
|
||||||
open ? "rotate-180" : ""
|
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>
|
<span>Targeted Practice</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<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>
|
<span>Drills</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<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>
|
<span>Hard Test Modules</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</SidebarMenuSub>
|
</SidebarMenuSub>
|
||||||
)}
|
)}
|
||||||
</SidebarMenuItem>
|
</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 */}
|
{/* LESSONS */}
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
asChild
|
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
|
<NavLink
|
||||||
to="/student/lessons"
|
to="/student/lessons"
|
||||||
className={({ isActive }) =>
|
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
|
isActive
|
||||||
? "text-slate-900"
|
? "text-slate-900"
|
||||||
: "text-slate-500 group-hover:text-slate-900"
|
: "text-slate-500 group-hover:text-slate-900"
|
||||||
@ -206,11 +480,20 @@ export function AppSidebar() {
|
|||||||
<>
|
<>
|
||||||
<Video
|
<Video
|
||||||
size={18}
|
size={18}
|
||||||
|
strokeWidth={3}
|
||||||
className={
|
className={
|
||||||
isActive ? "text-cyan-500" : "text-slate-400"
|
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>
|
</NavLink>
|
||||||
@ -221,12 +504,12 @@ export function AppSidebar() {
|
|||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
asChild
|
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
|
<NavLink
|
||||||
to="/student/rewards"
|
to="/student/rewards"
|
||||||
className={({ isActive }) =>
|
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
|
isActive
|
||||||
? "text-slate-900"
|
? "text-slate-900"
|
||||||
: "text-slate-500 group-hover:text-slate-900"
|
: "text-slate-500 group-hover:text-slate-900"
|
||||||
@ -237,11 +520,20 @@ export function AppSidebar() {
|
|||||||
<>
|
<>
|
||||||
<Trophy
|
<Trophy
|
||||||
size={18}
|
size={18}
|
||||||
|
strokeWidth={3}
|
||||||
className={
|
className={
|
||||||
isActive ? "text-emerald-500" : "text-slate-400"
|
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>
|
</NavLink>
|
||||||
@ -268,11 +560,15 @@ export function AppSidebar() {
|
|||||||
<span className="font-medium text-slate-900">{user?.name}</span>
|
<span className="font-medium text-slate-900">{user?.name}</span>
|
||||||
<span className="text-xs text-slate-400">{user?.email}</span>
|
<span className="text-xs text-slate-400">{user?.email}</span>
|
||||||
</div>
|
</div>
|
||||||
<ChevronDown size={16} className="ml-auto text-slate-400" />
|
<ChevronDown
|
||||||
|
size={16}
|
||||||
|
strokeWidth={3}
|
||||||
|
className="ml-auto text-slate-400"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Sidebar>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,12 @@ const STYLES = `
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.lm-content {
|
||||||
|
max-width: 1000px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.lm-dialog-header-hidden {
|
.lm-dialog-header-hidden {
|
||||||
position: absolute; width: 1px; height: 1px;
|
position: absolute; width: 1px; height: 1px;
|
||||||
padding: 0; margin: -1px; overflow: hidden;
|
padding: 0; margin: -1px; overflow: hidden;
|
||||||
|
|||||||
@ -25,7 +25,8 @@ const PALETTES = {
|
|||||||
activeBg: "bg-blue-600",
|
activeBg: "bg-blue-600",
|
||||||
activeText: "text-blue-900",
|
activeText: "text-blue-900",
|
||||||
pastBg: "bg-blue-400",
|
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",
|
dotBg: "bg-blue-100",
|
||||||
dotText: "text-blue-500",
|
dotText: "text-blue-500",
|
||||||
glassClass: "glass-blue",
|
glassClass: "glass-blue",
|
||||||
@ -34,7 +35,8 @@ const PALETTES = {
|
|||||||
activeBg: "bg-violet-600",
|
activeBg: "bg-violet-600",
|
||||||
activeText: "text-violet-900",
|
activeText: "text-violet-900",
|
||||||
pastBg: "bg-violet-400",
|
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",
|
dotBg: "bg-violet-100",
|
||||||
dotText: "text-violet-500",
|
dotText: "text-violet-500",
|
||||||
glassClass: "glass-violet",
|
glassClass: "glass-violet",
|
||||||
@ -43,7 +45,8 @@ const PALETTES = {
|
|||||||
activeBg: "bg-amber-600",
|
activeBg: "bg-amber-600",
|
||||||
activeText: "text-amber-900",
|
activeText: "text-amber-900",
|
||||||
pastBg: "bg-amber-400",
|
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",
|
dotBg: "bg-amber-100",
|
||||||
dotText: "text-amber-500",
|
dotText: "text-amber-500",
|
||||||
glassClass: "glass-amber",
|
glassClass: "glass-amber",
|
||||||
@ -52,7 +55,8 @@ const PALETTES = {
|
|||||||
activeBg: "bg-emerald-600",
|
activeBg: "bg-emerald-600",
|
||||||
activeText: "text-emerald-900",
|
activeText: "text-emerald-900",
|
||||||
pastBg: "bg-emerald-400",
|
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",
|
dotBg: "bg-emerald-100",
|
||||||
dotText: "text-emerald-500",
|
dotText: "text-emerald-500",
|
||||||
glassClass: "glass-emerald",
|
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">
|
<p className="text-[10px] font-bold uppercase tracking-[0.2em] text-slate-400 mb-3 px-1 hidden lg:block">
|
||||||
Sections
|
Sections
|
||||||
</p>
|
</p>
|
||||||
<nav className="space-y-1.5 bg-white">
|
<nav className="space-y-1.5 bg-white lg:bg-transparent">
|
||||||
{sections.map((sec, i) => {
|
{sections.map((sec, i) => {
|
||||||
const isActive = activeSection === i;
|
const isActive = activeSection === i;
|
||||||
const isPast = activeSection > i;
|
const isPast = activeSection > i;
|
||||||
@ -144,7 +148,9 @@ export default function LessonShell({
|
|||||||
key={i}
|
key={i}
|
||||||
onClick={() => scrollToSection(i)}
|
onClick={() => scrollToSection(i)}
|
||||||
className={`flex items-center gap-3 p-2.5 w-full rounded-xl transition-all text-left ${
|
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
|
<div
|
||||||
@ -174,7 +180,7 @@ export default function LessonShell({
|
|||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{/* ── Main content ── */}
|
{/* ── 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) => (
|
{childArray.map((child, i) => (
|
||||||
<section
|
<section
|
||||||
key={i}
|
key={i}
|
||||||
|
|||||||
@ -71,6 +71,15 @@ const STYLES = `
|
|||||||
display:flex; flex-direction:column; gap:1.5rem;
|
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 {
|
@keyframes lsPopIn {
|
||||||
from { opacity:0; transform:scale(0.92) translateY(12px); }
|
from { opacity:0; transform:scale(0.92) translateY(12px); }
|
||||||
to { opacity:1; transform:scale(1) translateY(0); }
|
to { opacity:1; transform:scale(1) translateY(0); }
|
||||||
|
|||||||
@ -72,6 +72,13 @@ const STYLES = `
|
|||||||
border-bottom: 1px solid rgba(251,191,36,0.12);
|
border-bottom: 1px solid rgba(251,191,36,0.12);
|
||||||
padding: 1.25rem 1.25rem 0;
|
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 {
|
.qm-page-title {
|
||||||
font-family: 'Sorts Mill Goudy', serif;
|
font-family: 'Sorts Mill Goudy', serif;
|
||||||
font-size: 1.3rem; font-weight: 900; letter-spacing: 0.05em;
|
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%);
|
linear-gradient(180deg, #071530 0%, #04101e 40%, #020a14 100%);
|
||||||
overflow:hidden;
|
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 {
|
.qm-sea-shimmer {
|
||||||
position:absolute; inset:0; pointer-events:none; z-index:0;
|
position:absolute; inset:0; pointer-events:none; z-index:0;
|
||||||
background:
|
background:
|
||||||
|
|||||||
@ -96,7 +96,7 @@ const STYLES = `
|
|||||||
.rw-empty { padding: 5rem 1rem; }
|
.rw-empty { padding: 5rem 1rem; }
|
||||||
|
|
||||||
/* Slightly larger island pill on wide screens and rebalance blobs */
|
/* 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; }
|
.rw-island-card { gap: 0.75rem; }
|
||||||
|
|
||||||
/* Rebalance decorative blobs on wide screens */
|
/* Rebalance decorative blobs on wide screens */
|
||||||
|
|||||||
@ -81,7 +81,7 @@ const CirclePropertiesLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Central vs Inscribed" icon={Target} />
|
<SectionMarker index={0} title="Central vs Inscribed" icon={Target} />
|
||||||
<SectionMarker index={1} title="Tangents" icon={Layers} />
|
<SectionMarker index={1} title="Tangents" icon={Layers} />
|
||||||
|
|||||||
@ -92,7 +92,7 @@ const CollectingDataLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Sampling & Bias" icon={Scale} />
|
<SectionMarker index={0} title="Sampling & Bias" icon={Scale} />
|
||||||
<SectionMarker index={1} title="Study Design" icon={Layers} />
|
<SectionMarker index={1} title="Study Design" icon={Layers} />
|
||||||
|
|||||||
@ -80,7 +80,7 @@ const CongruenceSimilarityLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Congruence Tests" icon={Target} />
|
<SectionMarker index={0} title="Congruence Tests" icon={Target} />
|
||||||
<SectionMarker index={1} title="Similarity Tests" icon={Layers} />
|
<SectionMarker index={1} title="Similarity Tests" icon={Layers} />
|
||||||
|
|||||||
@ -114,7 +114,7 @@ const DataAnalysisLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Data Changes" icon={Calculator} />
|
<SectionMarker index={0} title="Data Changes" icon={Calculator} />
|
||||||
<SectionMarker index={1} title="Distributions" icon={BarChart3} />
|
<SectionMarker index={1} title="Distributions" icon={BarChart3} />
|
||||||
|
|||||||
@ -116,7 +116,7 @@ const DataRepresentationLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Frequency & Mean" icon={Calculator} />
|
<SectionMarker index={0} title="Frequency & Mean" icon={Calculator} />
|
||||||
<SectionMarker index={1} title="Histograms" icon={BarChart3} />
|
<SectionMarker index={1} title="Histograms" icon={BarChart3} />
|
||||||
|
|||||||
@ -239,7 +239,7 @@ const EBRWCommasLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -117,7 +117,7 @@ const EBRWCraftStructureLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Craft & Purpose" icon={BookOpen} />
|
<SectionMarker index={0} title="Craft & Purpose" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -225,7 +225,7 @@ const EBRWDashesApostrophesLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -119,7 +119,7 @@ const EBRWExplicitMeaningLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -119,7 +119,7 @@ const EBRWExpressionIdeasLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Synthesis & Goals" icon={BookOpen} />
|
<SectionMarker index={0} title="Synthesis & Goals" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -287,7 +287,7 @@ const EBRWGraphicDisplaysLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Reading Graphics" icon={BookOpen} />
|
<SectionMarker index={0} title="Reading Graphics" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -119,7 +119,7 @@ const EBRWInferencesLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -116,7 +116,7 @@ const EBRWMainIdeaLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -238,7 +238,7 @@ const EBRWPronounsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Pronoun Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Pronoun Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -219,7 +219,7 @@ const EBRWSemicolonsColonsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Clause Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -244,7 +244,7 @@ const EBRWSentenceStructureLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Structure Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Structure Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -233,7 +233,7 @@ const EBRWSubjectVerbLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Agreement Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Agreement Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -237,7 +237,7 @@ const EBRWTransitionsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Transition Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Transition Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -241,7 +241,7 @@ const EBRWVerbsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker index={0} title="Verb Anatomy" icon={BookOpen} />
|
<SectionMarker index={0} title="Verb Anatomy" icon={BookOpen} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -185,7 +185,7 @@ const EBRWVocabMeaningLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -185,7 +185,7 @@ const EBRWVocabPreciseLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2 pt-6">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -81,7 +81,7 @@ const LinearParallelPerpendicularLesson: React.FC<LessonProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -78,7 +78,7 @@ const LinearTransformationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -88,7 +88,7 @@ const LinesAnglesLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Parallel Lines" icon={Target} />
|
<SectionMarker index={0} title="Parallel Lines" icon={Target} />
|
||||||
<SectionMarker index={1} title="Triangles" icon={Layers} />
|
<SectionMarker index={1} title="Triangles" icon={Layers} />
|
||||||
|
|||||||
@ -79,7 +79,7 @@ const PolynomialFunctionsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="End Behavior" icon={TrendingUp} />
|
<SectionMarker index={0} title="End Behavior" icon={TrendingUp} />
|
||||||
<SectionMarker index={1} title="Zeros & Multiplicity" icon={Grid} />
|
<SectionMarker index={1} title="Zeros & Multiplicity" icon={Grid} />
|
||||||
|
|||||||
@ -103,7 +103,7 @@ const ProportionalLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Ratios" icon={Scale} />
|
<SectionMarker index={0} title="Ratios" icon={Scale} />
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
|
|||||||
@ -88,7 +88,7 @@ const QuadraticEquationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ const RationalRadicalLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Rational Functions" icon={Grid} />
|
<SectionMarker index={0} title="Rational Functions" icon={Grid} />
|
||||||
<SectionMarker index={1} title="Radical Equations" icon={Target} />
|
<SectionMarker index={1} title="Radical Equations" icon={Target} />
|
||||||
|
|||||||
@ -79,7 +79,7 @@ const SystemsEquationsLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker index={0} title="Number of Solutions" icon={Grid} />
|
<SectionMarker index={0} title="Number of Solutions" icon={Grid} />
|
||||||
<SectionMarker index={1} title="Solving Methods" icon={RefreshCw} />
|
<SectionMarker index={1} title="Solving Methods" icon={RefreshCw} />
|
||||||
|
|||||||
@ -401,7 +401,7 @@ const TrigLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
<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">
|
<nav className="space-y-2">
|
||||||
<SectionMarker
|
<SectionMarker
|
||||||
index={0}
|
index={0}
|
||||||
|
|||||||
@ -359,7 +359,7 @@ const STYLES = `
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
padding: 0.85rem 1.25rem calc(0.85rem + env(safe-area-inset-bottom));
|
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);
|
backdrop-filter: blur(16px);
|
||||||
-webkit-backdrop-filter: blur(16px);
|
-webkit-backdrop-filter: blur(16px);
|
||||||
border-top: 2px solid #f3f4f6;
|
border-top: 2px solid #f3f4f6;
|
||||||
|
|||||||
Reference in New Issue
Block a user