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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/00-product.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ Follow `docs/DMRC_API.md` for upstream calls. Follow `docs/DECISIONS.md` for def

Files that stay on this machine and out of git are listed in the local-files rule. Do not delete them, and do not add them to a commit.

Ship through a branch and a pull request. Follow the deployment rule. Do not push straight to `main`.
Do not push or open a pull request until the user has verified the change locally and said to deploy. Follow the deployment rule.

Commits use `type(scope): description`. `type` is `feat`, `fix`, `docs`, `test`, `refactor`, or `chore`. `scope` is the area that changed, such as `plan`, `map`, `city`, `offline`, `deploy`, `data`, or `docs`. The description is the change itself, in lowercase, with no period. One commit is one change. Do not use a label that does not name the work.
6 changes: 5 additions & 1 deletion .cursor/rules/60-deployment.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ alwaysApply: true

# Deployment

Every change goes through a branch and a pull request. Do not commit or push directly to `main`.
Do not deploy until the user has used the change on this machine and said to deploy. A push that opens a pull request uploads a preview. A merge to `main` uploads production. Both are a deploy. Do not push, do not open a pull request, and do not merge before that.

Check the change with `npm run dev` at `http://127.0.0.1:5173`, including a phone-width window.

When the user says to deploy:

1. Branch from `main`.
2. Commit on that branch. `type(scope): description`. One commit is one change.
Expand Down
1 change: 1 addition & 0 deletions .cursor/rules/70-phone.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Check 320, 390, and 430 CSS pixels. The page does not scroll sideways.
- The header is the mark plus four tabs. It stays on screen, clears the safe area, and does not cover the first line of the page.
- On City, the map is visible without scrolling. The trip sheet is the part that scrolls.
- Do not add a banner, a tutorial, or extra chrome to fix spacing.
- Default type on a phone is compact. Help has a text-size slider. Do not leave a layout that only becomes readable after the user drags that slider.
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Routes are calculated from station order. A packed journey supplies the fare, pl
- Do not add a Hindi language control. Hindi strings in `src/i18n/copy.ts` exist so the types compile.
- Do not load fonts from a CDN. Vendored font files are allowed.
- Do not claim live arrivals, live lifts, or official affiliation.
- Ship through a branch and a pull request. Follow `docs/DEPLOYMENT.md`. Do not push straight to `main`. Do not add analytics, ads, or a paid service.
- Do not push or open a pull request until the user has verified the change locally and said to deploy. Follow `docs/DEPLOYMENT.md`. Do not add analytics, ads, or a paid service.

## Local files

Expand Down
20 changes: 5 additions & 15 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { savedJourneys } from "./lib/offline/saved"
import { alternateRide, planRoute, sameRide } from "./lib/transit/route"
import { startLineCode } from "./lib/transit/routeMap"
import { readSelection, writeSelection } from "./lib/plan/selection"
import { readTextSize, textDefault } from "./lib/plan/textSize"
import { createPlanState, planReducer, routeBlockReason } from "./lib/plan/state"
import { clearTrips, readTripQuery, readTrips, removeTrip, saveTrip, tripQuery, type SavedTrip } from "./lib/plan/trips"
import type { Journey, Lang, Suggestion } from "./lib/transit/types"
Expand Down Expand Up @@ -120,7 +121,7 @@ export function App() {
const [cityMessage, setCityMessage] = useState<string | null>(null)
const [routeOpen, setRouteOpen] = useState(false)
const cityRequest = useRef(0)
const [textSize, setTextSize] = useState<"small" | "normal" | "large">(readTextSize)
const [textSize, setTextSize] = useState(readTextSize)
const [helpNotice, setHelpNotice] = useState<string | null>(null)
const [trips, setTrips] = useState<SavedTrip[]>(readStoredTrips)
const [online, setOnline] = useState(() => navigator.onLine)
Expand All @@ -129,11 +130,10 @@ export function App() {

useEffect(() => {
document.documentElement.lang = lang
document.documentElement.style.fontSize =
textSize === "large" ? "22px" : textSize === "normal" ? "18px" : "14px"
document.documentElement.style.fontSize = `${textSize}px`
try {
localStorage.removeItem("dms-lang")
localStorage.setItem("dms-text", textSize)
localStorage.setItem("dms-text", String(textSize))
} catch {
// The planner still works when storage is blocked.
}
Expand Down Expand Up @@ -390,7 +390,7 @@ export function App() {
} catch {
// The controls still reset on screen.
}
setTextSize("small")
setTextSize(textDefault)
setTrips([])
dispatch({ type: "apply-language", names: namesFor(snapshot.stations, "en") })
clearResult()
Expand Down Expand Up @@ -580,16 +580,6 @@ export function App() {
)
}

function readTextSize(): "small" | "normal" | "large" {
try {
const saved = localStorage.getItem("dms-text")
if (saved === "large" || saved === "normal" || saved === "small") return saved
return "small"
} catch {
return "small"
}
}

function readStoredTrips(): SavedTrip[] {
try {
return readTrips(localStorage)
Expand Down
Loading
Loading