9.6 KiB
9.6 KiB
ArchNest — Design Decisions & Lessons Learned
This file captures all visual/UX decisions made during Glance page development. Apply these consistently to ALL future pages to avoid repeated iteration.
Global Rules (Apply to Every Page)
Sidebar
- Expanded width: 200px (matches mockup proportions — needs room for labels)
- Collapsed width: 64px (icon only)
- User can manually collapse/expand via toggle button (not just responsive)
- Main content margin-left must match sidebar width exactly
Page Title (Top Bar)
- Color: Gold (#C8A434) — NOT white. Use inline
style={{ color: '#C8A434' }}if Tailwind class doesn't apply - Font: 18px, bold, uppercase, tracking-wide
- No border on top bar — blends into the page background
Colors — Use Inline Styles When Tailwind Fails
- Tailwind v4
@themecustom colors (text-gold, bg-card, etc.) may not always apply - If a color isn't rendering correctly, fall back to inline
style={{ color: '#C8A434' }} - Always verify visually after changes
Content Alignment
- All rows must share the same horizontal padding (
px-6applied once at the parent container level) - Do NOT use different padding for different rows — this causes misalignment
- The hero banner, status cards, middle row, and bottom row must all line up left and right edges
Hero Banner + KPI Overlap
- Banner height: 200px
- Status cards overlap via negative margin:
-mt-12 - Banner image:
object-coverwithobject-position: center 25%(show the top/skyline, not center) - Cards use
backdrop-blur-smandbg-card/95for glass effect over the banner
KPI Card Sizing
- KPI 1 (System Status) and KPI 4 (Network): wider —
1.3fr - KPI 2 (Infrastructure) and KPI 3 (Security): standard —
1fr - Grid:
grid-cols-[1.3fr_1fr_1fr_1.3fr] - Cards have compact padding:
p-4(not p-5 or p-6)
No Footer
- The mockup does NOT have a footer/status bar
- Do not add one unless explicitly requested
Target Display
- Primary design target: 16-inch screen / 1920px width
- Lots of horizontal space available — don't constrain content width unnecessarily
- Design should feel spacious, not cramped
Typography Sizes (smaller than default)
- Card titles: 10-11px, uppercase, tracking-[1.5px], secondary color, font-medium
- Large numbers: 24-28px, bold, primary color
- Subtitles/labels: 10-11px, secondary color
- Body text in lists: 13px, primary color
- Timestamps: 11px, secondary color
- Breakdowns: 9-10px, secondary color
Animations
- Card hover: border → gold, 0.2s ease
- Progress ring: animates from 0 to value in 1s
- Sparklines: draw animation 1s
- Progress bars: fill animation 0.8s
Icons
- Source: Lucide React (imported per component, tree-shaken)
- Size: 14-18px depending on context
- Color: gold for active/accent, text-secondary for inactive
- Gold glow on active sidebar items:
shadow-[0_0_6px_rgba(200,164,52,0.5)]
Page-Specific Notes
Glance Page
- No footer
- Status cards overlap hero banner
- Middle row: 3 equal-ish columns (30/40/30)
- Bottom row: 2 columns (65/35)
- Network Traffic card has its own background image at low opacity
- User avatar dropdown has: Profile, Appearance, Security, Help & Support, Sign Out
Infrastructure Page
- Hero banner rendered at the App.tsx layout level (not per-page), so it can extend
behind the sticky TopBar — conditional via
showHero = location.pathname === '/infrastructure'. TopBar and the search input are transparent on hero routes so the banner shows through. - Hero image:
object-position: center 5%to reveal the full arch + sky; faded out vialinear-gradientmask (vertical) + aradial-gradient(ellipse 70% 100% at center, ...)overlay (sides/corners) — borderless, blends into page background. - Sub-tabs trimmed to Overview only (Compute → Tags are future work, not built yet).
- Status cards:
rgba(10,10,12,0.5)background (more transparent than other pages), content centered (justify-content/alignItems: center) with a fixed row height (110px) so there's breathing room instead of empty space below left-aligned content. - Middle row (
grid-cols-[1fr_1.6fr]): Resource Distribution (donut) and Node Status (server tile grid). Both use the/blank-kpi-bg.pngbackground art with acardDim(semi-transparent dark overlay) +cardVignette(radial-gradientclosest-sideblend) combo — keeps the background pattern visible but subdued, with borders blended rather than hard-edged. Card titles are rendered as our own text, NOT baked into the image (baked-in labels got covered by the dim overlay). - Node Status card: originally a world-map-style region dot plot, replaced with a 4-column tile grid (one tile per server, colored status dot + name) — a world map didn't make sense for a small/single-site infra. Reuse this "small-scale" reasoning for any future map-like cards.
- Bottom row (
grid-cols-[1.4fr_1fr_1fr]): Resource Trend / Cost Breakdown / Recent Activity — left plain/regular, no dim/vignette blending (explicit user preference, only the middle row gets the hero-style blend). Resource Trend uses the/archnest-network-traffic-bg.pngbackground (plain, no dim/vignette) with 4 trend lines: blue#3B82F6(compute), orange#E67E22(storage), green#2ECC71(database), brown#8B5E3C(network). cardVignetteradial-gradient must use theclosest-sidekeyword (not a fixed%) — otherwise straight edges of the card don't reach full opacity and a hard border line remains visible (only corners fade correctly with a fixed percentage).
BookNest Page
- Hero banner reused at the App.tsx layout level (
showHeronow includes/booknest), with page-specific tuning via small lookup maps inApp.tsxkeyed onlocation.pathname:heroPaddingTop(how far content sits below the hero top) andheroObjectPosition(horizontal/vertical crop of the arch image) —70px/54% 8%for BookNest vs.72px/center 5%for Infrastructure. Extend these maps rather than hardcoding a single value when a future page needs different hero framing. - Large hero title + subtitle: unlike other pages, BookNest's TopBar title is NOT the
small 18px uppercase label — it's rendered at 28px with a subtitle line ("Your Digital
Library") underneath, driven by a new
pageSubtitlesmap inTopBar.tsx. When a page has a subtitle, the header height grows from 56px → 72px (TopBar.tsx), andApp.tsx'stopBarHeightlookup keeps the content section'scalc(100vh - Npx)in sync — both must be updated together or the layout will clip/gap. - Stats row lives directly under the hero subtitle (Links / Categories / Favorites), not in its own separate bar — matches the blueprint's hero-header block grouping.
- "Quick Access" section label added above the 5 quick-access category cards (gold,
same
sectionTitlestyle) — the row is intentionally pulled up via a small negative hero-padding tune so it slightly overlaps the bottom edge of the hero, like the blueprint. - "+ Add Bookmark" button: same gold-fill button style as Infrastructure's "+ Add Resource", placed inline next to the "Quick Access" label rather than the page-stats row.
- Right sidebar spans both grid rows (
gridRow: '1 / span 2'in agridTemplateRows: 'auto 1fr'grid) so the Favorites card can rise up near the hero while the main column's page-stats row stays in row 1 of column 1 only — keeps the two from overlapping/clipping. Negative margins were tried first and discarded: content pushed above the scroll container's natural top edge gets clipped byoverflow-y-auto, so prefer reshaping the grid/flow over negative-margin hacks when something needs to "reach upward." - Sidebar cards stretch to match the main column's full height so the last card's
(Category Breakdown) bottom border lines up with the bottom of the bookmark groups grid:
sidebar wrapper is
display:flex; flex-direction:column; height:100%(grid's defaultalign-items: stretchalready gives it the matching height), and each card usesflex: 1 0 auto(Favorites getsflex: 1.4 0 autoto read as visibly taller, per explicit request) so they share the leftover vertical space instead of all packing tight at content height. - lucide-react gotcha (see Global Rules candidate): the installed version does not
export brand/wordmark icons (
Github,Gitlab,Linkedin,Youtube) even though TypeScript's type declarations list them —tsc --noEmitstays clean while the page renders blank with a runtimeSyntaxErroronly visible in the Vite dev log. Verify icon names againstObject.keys(require('lucide-react'))before importing anything brand-flavored; substitutes used here:GitBranch/GitFork(GitHub/GitLab/Gitea),SquarePlay(YouTube),Briefcase(LinkedIn Learning).
Future Integration Notes
Live Provider Data (AWS, Linode, etc.)
- All KPI/status card data (resource counts, health, pricing, budgets, cost breakdowns, utilization, regions/map data) is currently mocked/static.
- The Infrastructure page (and likely Glance) should eventually integrate with real
cloud provider APIs — AWS, Linode, or any other VPC/cloud provider — via user-supplied
API keys, to pull live data such as:
- Resource inventory/counts and health status
- Pricing and budget/cost data (replacing the static Cost Breakdown numbers)
- Resource utilization metrics
- Region/datacenter info for the Infrastructure Map
- Design the data layer so it's provider-agnostic (a common interface/adapter per provider) since users may connect more than one provider's API key.