Repository navigation
Daylight redesign, true PPI radar, and a rebuilt great-circle globe - #17
Merged
Merged
Conversation
…oll-budget pass Surface - :root and [data-theme=light] now carry the daylight palette directly, so the white page paints before the bootstrap script runs; still no OS dark flip. - Body/page gradients and translucent card haze removed; panels are opaque white with a hairline border. Palette - One accent (#0369A1) absorbs cyan/sky; teal/emerald/amber/rose survive only as semantic status inks (--c-ok/-cold/-warn/-alert) with per-theme values. - Added --c-track and --c-hover so controls stop hard-coding slate pairs. - Removed the last 87 `dark:` utilities from components; theme switching is entirely token-driven now (pinned by src/test/design-contract.test.ts). - Dark instrument surfaces (`.avionics-panel`, `.avionics-well`) re-scope the tokens on themselves so night ink stays legible on a white page. Type - Inter is the single Latin family (400/500/600/700); Cairo keeps Arabic. - font-bold/extrabold/black collapsed to 600 (135 occurrences). Scroll - Smooth scrolling stays gated behind prefers-reduced-motion: no-preference. - Off-screen radar sweep/pings no longer animate; scrollbar-gutter avoids the modal scroll-lock reflow. Ships at 81.1 KiB CSS (was 110.8 KiB at HEAD) and 494.9 KiB app JS; all tests (125) and bundle budgets pass. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
dist/ is tracked in this repository, so when the next build starts the previous build's CSS, JS and sourcemaps are sitting on disk. Tailwind's automatic content detection reads them as source and regenerates utilities the app no longer uses: a clean checkout built to 110.6 KiB against a 109.4 KiB budget, and the bloat grew with every build. `@source not "../dist"` pins the scan to real source, making the CSS independent of whatever is in the output directory (80.4 KiB from an empty dist and from a stale one, identical content hash). Adds a design-contract assertion so the exclusion cannot be dropped silently, and rebuilds dist/ against the corrected graph. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…urfaces
Direction (requested)
- The layout is permanently left-to-right. Language switches the dictionary
and the Arabic font stack; it no longer flips `dir`. Root cause was
`root.dir = lang === 'ar' ? 'rtl' : 'ltr'` in both the provider and the
pre-paint bootstrap, plus 19 `rtl:` utilities and four per-component
`dir={isRtl ? ...}` overrides that mirrored charts, tables, radar and 3D
viewports. All removed; src/test/direction-contract.test.tsx pins it.
- Arabic copy, Arabic typography bindings and the language toggle are intact.
Radar (requested: precise, high quality, realistic smooth motion, legible)
- New RadarScope component. Geometry is real: the field is the origin, the
sweep is 8 s, rings are 20/40/60 NM on an 80 NM range, and every target is
placed from its bearing and range — so the tag numbers and the picture
cannot disagree.
- Legibility: bigger plot, bezel ticks every 5° (long at 30°), cardinal and
30°-interval labels, axis cross, range numbers on chips inside their rings
on a single radial, a plane glyph plus callsign/level beside each contact,
a leader line from the selected target to its data block and a legend in
words. Cursor readout gives bearing/range under the pointer.
- Motion: the sweep is one composited rotation with a conic-gradient trail;
each contact's afterglow is a keyframe delayed to its bearing, so a blip
brightens exactly as the beam crosses it and fades across the revolution;
the selected target glides between telemetry fixes in a rAF loop that
writes two transform attributes and never calls setState. Everything pauses
off-screen and under prefers-reduced-motion.
Simplification
- One instrument ground (--hud-bg), one hairline border, no inner glow. Four
ink levels and three signal colours now live in :root as hud tokens used by
the scope and the 3D viewports in both themes.
- Sensor tiles moved out of the dark well onto the page surface, so the scope
stays uncluttered and the tiles inherit the normal light-theme ink.
Protected logic is untouched: the chargeable-weight simulator, ULD digital
twin, corridor globe and AWB checksum keep their original modules and tests
(only direction-related class names changed in their shells). 141 tests pass;
CSS 75.4 KiB, app JS 501.4 KiB (ratchet raised to 509.8 KiB with a note).
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Replace the flat dot-shell globe with a shaded, textured planet and make the network overlay readable at rest and under focus. Surface: a 2048x1024 land mask rasterised offline from Natural Earth 1:50m coastlines drives land/ocean/climate-band/ice colouring, a separate cloud layer drifts on its own clock, and city lights appear only in deep night. Terminator still follows the real subsolar point, but the key light is clamped to 72 degrees of the viewing axis so the featured hemisphere never goes fully dark at an unlucky UTC. Overlay: corridors are tapered ribbons instead of hairlines, far-side lanes stay faintly visible via a shader occlusion test (one draw, no ghost pass), traffic sprites are larger and rotated to their ground track, and the rest pose now frames the network's centroid instead of the horizon. Textures live in public/assets/earth (305 KiB, no runtime fetches). The old landmask.ts/isLand module is superseded by the raster mask and removed. Gates: typecheck clean, 25 test files pass, bundle 507.6 KiB / 509.8 KiB. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
The globe is now a chart of the planet rather than a render of it: one 66 KiB coastline mask, flat land/ocean ink, a faint graticule and line-art corridors. No clouds, no atmosphere shells, no sun simulation, no noise — five draw calls, down from seven, and roughly a dozen fewer texture fetches per pixel. Colour follows the page. Daylight is a white ground with pale-blue land and deep-blue coasts and routes; dark mode is deep navy with cyan-glow arcs. The wrapper mirrors documentElement[data-theme] through a MutationObserver into a new optional setTheme(), so toggling the theme repaints a mounted scene instead of rebuilding it. One PALETTES table drives surface, lattice, arcs, traffic and beacons, with a uGlow uniform so additive blending is used only where it is actually light rather than ink. Idle frames are budgeted to 30 fps to keep scrolling smooth; drag, zoom and focus still render every frame. The now-unused clouds.png is removed. Gates: typecheck clean, 25 test files pass, 502.5 KiB / 509.8 KiB. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
The planet was mirrored in latitude. The coastline sheet was north-up, but three's TextureLoader flips loaded images by default while the shader's UV convention (v = 0 at the north pole) already matches image order, so the mask was sampled bottom-up. Antarctica rendered where the Arctic belongs and every airport beacon sat on the wrong continent. - set flipY = false on the land texture, with the convention documented - replace the 2048x1024 mask with a 4096x2048 sheet rasterised at 2x2 supersampling, with the coastal shelf packed into the alpha channel so the ocean gains a continental-shelf tint without a second texture (428 KiB) - derive the coastline outline width from the mask gradient for a constant hairline at any zoom, clamped so mip reduction cannot flood the ocean - add orientation.test.ts, which decodes the shipped PNG and asserts both the raster's north-up row order and the loader convention Gates: typecheck clean, 26 test files pass, 503.3 KiB / 509.8 KiB. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
The arcs read as random: three aircraft per route at arbitrary phases, each point-scaled by its view depth so every sprite was a different size, with two counter-rotating sparks travelling at unrelated rates. Each corridor is now a single movement, drawn the way an ops chart draws one: a quiet permanent line, a packet travelling origin -> destination, and a soft tail that shows the direction. One aircraft per route rides that packet's head, so the trail and the aircraft can never disagree. Packet phases are evenly spaced around the cycle rather than pseudo-random, and speed scales with the square root of route length so long-haul corridors stay readable without the Shanghai lane appearing frozen. Aircraft are now a constant screen size (13-22 CSS px, clamped) with a cleaner swept-wing silhouette, and the taper keeps body along the route instead of pinching to a hair near each airport. Motion is softer all round: gentler auto-spin, lower damping stiffness on rotation and zoom, clamped wheel delta so a trackpad flick eases instead of jumping, and a wider rest framing that gives the northern arcs room. Gates: typecheck clean, 26 test files pass, 504.3 KiB / 509.8 KiB. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Two symbols were dominating the card for the wrong reasons: airport beacons drew as fat depth-scaled donuts (CAI reached 38px and swallowed its neighbours), and the aircraft read as white streaks. - Beacons are now surveyor-style fixes: a solid centre, a hairline ring at a constant radius and one slow ping per airport, all at a constant screen size so neighbouring Gulf airports no longer merge into a blob. - The airliner is assembled from analytically swept masses — fuselage tapering aft, wings whose leading edge lags the root as span grows, and a short tailplane — so it reads as an aircraft at 11-18px rather than a snowflake. - Routes lose the exponential comet tail. Each corridor is a constant-width line that terminates cleanly at both airports, with a fixed-length leading segment ahead of the aircraft showing direction. - Aircraft and beacons are sized from the card in CSS pixels and clamped, rather than from view depth. - Minimum zoom raised so the sphere can never overflow the card. Gates: typecheck clean, 26 test files pass, 505.0 KiB / 509.8 KiB. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request. Check if the Files changed in this pull request are included in default exclusions.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This branch delivers the daylight redesign and the rebuilt great-circle globe for the corridor network. It is eight commits, split into three blocks.
1. Daylight surface and layout contract
--c-*tokens flipping per theme, and nodark:utilities anywhere (enforced bydesign-contract.test.ts).light/semiboldonly.prefers-reduced-motion: no-preference, so the OS reduced-motion setting always wins.dir="rtl", nortl:utilities, and no runtime direction switch. Pinned bydirection-contract.test.tsx.@source not "../dist";keeps the committed build output out of Tailwind's content scan, which was otherwise regenerating ~30 KiB of dead utilities.2. Radar scope
3. Great-circle globe
The globe went through three stages, which is why there are several commits. Final state:
documentElement[data-theme]through a MutationObserver into an optionalsetTheme(), so a toggle repaints a mounted scene rather than rebuilding it. OnePALETTEStable drives surface, lattice, arcs, traffic and beacons, with auGlowuniform so additive blending is only used where the pixels are light rather than ink.TextureLoaderflips loaded images by default while the shader's UV convention is already image-space.orientation.test.tsnow decodes the shipped PNG and asserts both the raster's north-up row order and the loader convention.Preserved behaviour
Context-loss recovery, the reduced-motion path, the off-screen gate, the deferred vendor-three import, the DPR cap, and the exact stats contract are all unchanged. The globe's public API is additive:
setThemeandonReadyare both optional, so the existing wrapper test's mock still satisfies it.Verification
npm run check: typecheck clean, 26 test files pass, build succeeds.Two notes for review: