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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions client/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
* The mobile-only footer at the bottom mirrors the items hidden from
* AppShell's top nav at `<sm` (Leagues link, Account button), so the user
* still has reach to them when those labels are clipped from the top bar.
* It is pinned: the `<nav>` above it is the only scroll region (`flex-1
* min-h-0 overflow-y-auto`). Without that, a long Teams list grows the nav
* past the drawer's height and pushes the footer off the bottom of the
* viewport — and since the drawer is `fixed`, nothing can scroll it back
* into reach. The footer also clears the iOS home indicator via
* `env(safe-area-inset-bottom)`.
*/
import { useEffect, useState } from "react";
import { NavLink, useLocation } from "react-router-dom";
Expand Down Expand Up @@ -235,7 +241,7 @@ export function Sidebar({
{collapsed ? <ChevronRight size={12} /> : <ChevronLeft size={12} />}
</button>

<nav className="flex flex-col gap-1 p-2 mt-8 md:mt-2">
<nav className="flex-1 min-h-0 overflow-y-auto overscroll-contain flex flex-col gap-1 p-2 mt-8 md:mt-2">
{TOP_NAV_ITEMS.map(({ label, to, icon: Icon, end, subItems }) => {
const isExpanded = expandedGroups.has(label);
return (
Expand Down Expand Up @@ -416,7 +422,7 @@ export function Sidebar({
</nav>

{/* Mobile-only secondary actions (mirror items hidden from top nav at sm) */}
<div className="md:hidden mt-auto p-2 border-t border-line flex flex-col gap-1">
<div className="md:hidden shrink-0 p-2 pb-[calc(0.5rem+env(safe-area-inset-bottom))] border-t border-line flex flex-col gap-1">
<NavLink
to="/huddles"
className="flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium text-muted hover:bg-highlight hover:text-ink transition-colors"
Expand Down
22 changes: 16 additions & 6 deletions client/src/widgets/dashboard/Ticker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
* list (`[...pairs, ...pairs]`) so when the first copy slides off the
* left edge the second copy is exactly where the first started — gives a
* seamless loop without any JS scheduling.
*
* Spacing note (matters most at mobile widths, where the cells are the
* densest thing on screen):
* Gaps encode grouping — 6px inside a team (avatar/name/score), 18px
* around the "vs" so it reads as the separator rather than as part of
* team 1's score. Cell padding is deliberately asymmetric (`pl-5 pr-6`):
* the week label is smaller and letter-spaced, so an equal geometric
* gap on both sides of the divider reads as tighter on the score side.
*/
import { Avatar } from "../../components/Avatar";
import { useLeagueMatchups } from "../../hooks/useSleeper";
Expand Down Expand Up @@ -79,7 +87,7 @@ export function Ticker({
<style>{`@keyframes ticker{from{transform:translateX(0)}to{transform:translateX(-50%)}}`}</style>
<div
style={{ animation: "ticker 60s linear infinite" }}
className="inline-flex whitespace-nowrap py-2.5"
className="inline-flex w-max whitespace-nowrap py-2.5"
>
{items.map((m, i) => {
const homeWon = m.homePts > m.awayPts;
Expand All @@ -94,9 +102,9 @@ export function Ticker({
return (
<div
key={i}
className="inline-flex items-center gap-3 px-5 border-r border-line"
className="inline-flex items-center gap-3 pl-5 pr-6 border-r border-line"
>
<span className="font-mono text-[10px] text-muted tracking-wider">
<span className="shrink-0 font-mono text-[10px] text-muted tracking-wider">
W{week.toString().padStart(2, "0")}
</span>
<TickerTeam
Expand All @@ -105,7 +113,9 @@ export function Ticker({
won={homeWon}
avatar={m.homeUser?.avatar ?? null}
/>
<span className="font-serif italic text-sm text-muted">vs</span>
<span className="shrink-0 px-1.5 font-serif italic text-sm text-muted">
vs
</span>
<TickerTeam
name={aName}
pts={m.awayPts}
Expand All @@ -132,15 +142,15 @@ function TickerTeam({
avatar: string | null;
}) {
return (
<span className="inline-flex items-center gap-1.5">
<span className="inline-flex shrink-0 items-center gap-1.5">
<Avatar avatar={avatar} name={name} size={16} />
<span
className={`font-serif text-sm leading-none translate-y-px ${won ? "font-bold italic text-ink" : "font-medium text-body"}`}
>
{name}
</span>
<span
className={`font-mono text-xs tabular-nums ${won ? "font-bold text-accent" : "text-muted"}`}
className={`shrink-0 font-mono text-xs tabular-nums ${won ? "font-bold text-accent" : "text-muted"}`}
>
{pts.toFixed(2)}
</span>
Expand Down