diff --git a/CHANGELOG.md b/CHANGELOG.md index 658df15..7725ef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,31 @@ All notable changes to the NodeByte Hosting website will be documented in this f The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.5.3] - 2026-04-17 + +### Added +- **Contact Page — Support Ticket Channel** — third support channel card added to `contact.tsx` pointing to `https://billing.nodebyte.host/tickets/create` + - Uses `Headphones` icon with `bg-accent/10 text-accent` colour scheme + - Grid widened from `md:grid-cols-2 max-w-4xl` to `md:grid-cols-3 max-w-5xl` + - `contact.ticket.features` translation keys added to `translations/messages/en-US.json` and `translations/templates/en.json` + +### Changed +- **Contact Page — Card Button Alignment** — support channel card inner div converted to `flex flex-col h-full`; feature list gains `flex-1` so the CTA button is always pinned to the bottom of every card regardless of content height +- **Contact Page — GitHub Card Icon Colour** — icon box class corrected from `bg-muted text-foreground` to `bg-foreground/10 text-foreground` to match the `bg-color/10 text-color` pattern used by all other channel cards +- **Navigation — Dropdown Hover Colours** — row hover background changed from `hover:bg-accent/10` to `hover:bg-muted/60` across all three desktop dropdowns (Company, Services, Resources); icon box hover changed from solid `group-hover:bg-primary group-hover:text-primary-foreground` to a subtle `group-hover:bg-primary/20`; title text given explicit `text-foreground` to prevent blending on saturated themes +- **Navigation — `modal={false}`** — all three desktop `DropdownMenu` components now render with `modal={false}` so the Radix invisible overlay no longer blocks `mouseEnter` events on sibling nav items, fixing the hover-jump bug between dropdowns +- **Navigation — ExternalLink Icon** — `ExternalLink` indicator in the Resources dropdown is now conditionally rendered based on `resource.external` instead of always showing +- **Navigation — Mobile Resources Links** — mobile Resources items now render as `` for internal routes and `` for external ones instead of always using `` + +### Fixed +- **Theme Colour Contrast — Emerald / Amber / Teal** — `--primary` and `--accent` lightness values were too high (0.58–0.68) while `--primary-foreground` / `--accent-foreground` remained near-black (0.10–0.12), producing illegible black-on-dark text on buttons and icon boxes + - Emerald: `--primary` `0.58 → 0.42`, `--accent` `0.62 → 0.48`, foregrounds `0.10 → 0.98` + - Amber: `--primary` `0.62 → 0.46`, `--accent` `0.68 → 0.52`, foregrounds `0.12 → 0.98` + - Teal: `--primary` `0.60 → 0.44`, `--accent` `0.64 → 0.50`, foregrounds `0.10 → 0.98` +- **Translations — Rust `premium` Plan Keys** — `games.rust.plans.premium.name` and `games.rust.plans.premium.description` were missing from `en-US.json` and `en.json`, causing `MISSING_MESSAGE` errors at runtime; both files updated + +--- + ## [3.5.2] - 2026-03-19 ### Added diff --git a/app/globals.css b/app/globals.css index 851f9ef..046bb30 100644 --- a/app/globals.css +++ b/app/globals.css @@ -335,21 +335,21 @@ --card-foreground: oklch(0.98 0.01 160); --popover: oklch(0.13 0.02 160); --popover-foreground: oklch(0.98 0.01 160); - --primary: oklch(0.58 0.18 160); - --primary-foreground: oklch(0.10 0.01 160); + --primary: oklch(0.42 0.18 160); + --primary-foreground: oklch(0.98 0.01 160); --secondary: oklch(0.22 0.02 160); --secondary-foreground: oklch(0.98 0.01 160); --muted: oklch(0.18 0.02 160); --muted-foreground: oklch(0.60 0.02 160); - --accent: oklch(0.62 0.16 165); - --accent-foreground: oklch(0.10 0.01 160); + --accent: oklch(0.48 0.16 165); + --accent-foreground: oklch(0.98 0.01 160); --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.985 0 0); --border: oklch(0.20 0.02 160); --input: oklch(0.18 0.02 160); - --ring: oklch(0.58 0.18 160); - --chart-1: oklch(0.58 0.18 160); - --chart-2: oklch(0.62 0.16 165); + --ring: oklch(0.42 0.18 160); + --chart-1: oklch(0.42 0.18 160); + --chart-2: oklch(0.48 0.16 165); --chart-3: oklch(0.55 0.18 320); --chart-4: oklch(0.7 0.2 140); --chart-5: oklch(0.6 0.2 40); @@ -407,21 +407,21 @@ --card-foreground: oklch(0.98 0.01 60); --popover: oklch(0.15 0.02 60); --popover-foreground: oklch(0.98 0.01 60); - --primary: oklch(0.62 0.18 60); - --primary-foreground: oklch(0.12 0.01 60); + --primary: oklch(0.46 0.18 60); + --primary-foreground: oklch(0.98 0.01 60); --secondary: oklch(0.24 0.02 60); --secondary-foreground: oklch(0.98 0.01 60); --muted: oklch(0.20 0.02 60); --muted-foreground: oklch(0.62 0.02 60); - --accent: oklch(0.68 0.16 50); - --accent-foreground: oklch(0.12 0.01 60); + --accent: oklch(0.52 0.16 50); + --accent-foreground: oklch(0.98 0.01 60); --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.985 0 0); --border: oklch(0.22 0.02 60); --input: oklch(0.20 0.02 60); - --ring: oklch(0.62 0.18 60); - --chart-1: oklch(0.62 0.18 60); - --chart-2: oklch(0.68 0.16 50); + --ring: oklch(0.46 0.18 60); + --chart-1: oklch(0.46 0.18 60); + --chart-2: oklch(0.52 0.16 50); --chart-3: oklch(0.55 0.18 320); --chart-4: oklch(0.7 0.2 140); --chart-5: oklch(0.6 0.2 40); @@ -443,21 +443,21 @@ --card-foreground: oklch(0.98 0.01 180); --popover: oklch(0.13 0.02 180); --popover-foreground: oklch(0.98 0.01 180); - --primary: oklch(0.60 0.16 180); - --primary-foreground: oklch(0.10 0.01 180); + --primary: oklch(0.44 0.16 180); + --primary-foreground: oklch(0.98 0.01 180); --secondary: oklch(0.22 0.02 180); --secondary-foreground: oklch(0.98 0.01 180); --muted: oklch(0.18 0.02 180); --muted-foreground: oklch(0.62 0.02 180); - --accent: oklch(0.64 0.14 175); - --accent-foreground: oklch(0.10 0.01 180); + --accent: oklch(0.50 0.14 175); + --accent-foreground: oklch(0.98 0.01 180); --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.985 0 0); --border: oklch(0.20 0.02 180); --input: oklch(0.18 0.02 180); - --ring: oklch(0.60 0.16 180); - --chart-1: oklch(0.60 0.16 180); - --chart-2: oklch(0.64 0.14 175); + --ring: oklch(0.44 0.16 180); + --chart-1: oklch(0.44 0.16 180); + --chart-2: oklch(0.50 0.14 175); --chart-3: oklch(0.55 0.18 320); --chart-4: oklch(0.7 0.2 140); --chart-5: oklch(0.6 0.2 40); diff --git a/packages/core/constants/game/hytale.ts b/packages/core/constants/game/hytale.ts index 693ec18..6e45ef4 100644 --- a/packages/core/constants/game/hytale.ts +++ b/packages/core/constants/game/hytale.ts @@ -7,14 +7,14 @@ export const HYTALE_PLANS: GamePlanSpec[] = [ priceGBP: 5, ramGB: 4, storageGB: 40, - url: "https://billing.nodebyte.host/store/hytale-hosting/starter", + url: "https://billing.nodebyte.host/products/hytale-hosting/hytale-starter", }, { id: "standard", priceGBP: 7.5, ramGB: 6, storageGB: 60, - url: "https://billing.nodebyte.host/store/hytale-hosting/standard", + url: "https://billing.nodebyte.host/products/hytale-hosting/hytale-standard", }, { id: "performance", @@ -22,7 +22,7 @@ export const HYTALE_PLANS: GamePlanSpec[] = [ ramGB: 8, storageGB: 80, popular: true, - url: "https://billing.nodebyte.host/store/hytale-hosting/performance", + url: "https://billing.nodebyte.host/products/hytale-hosting/hytale-performance", }, ] diff --git a/packages/core/constants/game/minecraft.ts b/packages/core/constants/game/minecraft.ts index f242263..aa5aae4 100644 --- a/packages/core/constants/game/minecraft.ts +++ b/packages/core/constants/game/minecraft.ts @@ -27,6 +27,22 @@ export const MINECRAFT_PLANS: GamePlanSpec[] = [ popular: true, url: "https://billing.nodebyte.host/products/minecraft-server-hosting/inferno", }, + { + id: "firestorm", + priceGBP: 15, + ramGB: 16, + storageGB: 160, + popular: true, + url: "https://billing.nodebyte.host/products/minecraft-server-hosting/firestorm", + }, + { + id: "supernova", + priceGBP: 30, + ramGB: 32, + storageGB: 320, + popular: true, + url: "https://billing.nodebyte.host/products/minecraft-server-hosting/supernova", + }, ] /** diff --git a/packages/core/constants/game/rust.ts b/packages/core/constants/game/rust.ts index c2db1a9..3fe8779 100644 --- a/packages/core/constants/game/rust.ts +++ b/packages/core/constants/game/rust.ts @@ -6,6 +6,7 @@ export const RUST_PLANS: GamePlanSpec[] = [ priceGBP: 5.75, ramGB: 8, storageGB: 150, + url: "https://billing.nodebyte.host/products/rust-hosting/starter" }, { id: "standard", @@ -13,12 +14,21 @@ export const RUST_PLANS: GamePlanSpec[] = [ ramGB: 12, storageGB: 200, popular: true, + url: "https://billing.nodebyte.host/products/rust-hosting/standard" }, { id: "performance", priceGBP: 12.75, ramGB: 16, storageGB: 250, + url: "https://billing.nodebyte.host/products/rust-hosting/performance" + }, + { + id: "premium", + priceGBP: 18.99, + ramGB: 32, + storageGB: 350, + url: "https://billing.nodebyte.host/products/rust-hosting/premium" }, ] diff --git a/packages/core/constants/links.ts b/packages/core/constants/links.ts index 11accef..06a52a4 100644 --- a/packages/core/constants/links.ts +++ b/packages/core/constants/links.ts @@ -16,7 +16,7 @@ export const LINKS = { root: "https://billing.nodebyte.host", store: "https://billing.nodebyte.host/store", login: "https://billing.nodebyte.host/login", - submitTicket: "https://billing.nodebyte.host/submitticket.php", + submitTicket: "https://billing.nodebyte.host/tickets/create", freeTrial: "https://billing.nodebyte.host/store/free-trial", amdVps: "https://billing.nodebyte.host/store/vps-hosting", intelVps: "https://billing.nodebyte.host/store/vps-hosting", diff --git a/packages/core/constants/vps/amd.ts b/packages/core/constants/vps/amd.ts index 29688fb..85c71aa 100644 --- a/packages/core/constants/vps/amd.ts +++ b/packages/core/constants/vps/amd.ts @@ -20,7 +20,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ bandwidth: { amount: 1, unit: "GB" }, uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, - url: "https://billing.nodebyte.host/store/vps-hosting/2gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/base-rg1-2gb", }, { id: "4GB-R71700X", @@ -37,7 +37,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ bandwidth: { amount: 1, unit: "GB" }, uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, - url: "https://billing.nodebyte.host/store/vps-hosting/4gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/comp-rg1-4gb", }, { id: "8GB-R71700X", @@ -55,7 +55,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, popular: true, - url: "https://billing.nodebyte.host/store/vps-hosting/8gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/comp-rg1-8gb", }, { id: "16GB-R71700X", @@ -72,7 +72,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ bandwidth: null, uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, - url: "https://billing.nodebyte.host/store/vps-hosting/16gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/comp-rg1-16gb", }, { id: "32GB-R71700X", @@ -90,7 +90,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ bandwidth: null, uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, - url: "https://billing.nodebyte.host/store/vps-hosting/16gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/comp-rg1-32gb", }, { id: "64GB-R71700X", @@ -108,7 +108,7 @@ export const AMD_PLANS: VpsPlanSpec[] = [ bandwidth: null, uplink: { amount: 1, unit: "Gbps" }, ddos: { layers: [3, 4, 7], autoOn: true }, - url: "https://billing.nodebyte.host/store/vps-hosting/16gb-r71700x", + url: "https://billing.nodebyte.host/products/amdvps/comp-rg1-64gb", }, ] diff --git a/packages/ui/components/Layouts/Contact/contact.tsx b/packages/ui/components/Layouts/Contact/contact.tsx index f2aa9cd..66f3f3d 100644 --- a/packages/ui/components/Layouts/Contact/contact.tsx +++ b/packages/ui/components/Layouts/Contact/contact.tsx @@ -46,7 +46,7 @@ export function Contact() { icon: Github, href: LINKS.githubDiscussions, cta: t("contact.github.button"), - color: "bg-muted text-foreground", + color: "bg-foreground/10 text-foreground", hoverColor: "hover:bg-foreground hover:text-background", features: [ t("contact.github.features.0"), @@ -54,6 +54,20 @@ export function Contact() { t("contact.github.features.2"), ], }, + { + title: t("contact.ticket.title"), + description: t("contact.ticket.description"), + icon: Headphones, + href: "https://billing.nodebyte.host/tickets/create", + cta: t("contact.ticket.button"), + color: "bg-accent/10 text-accent", + hoverColor: "hover:bg-accent hover:text-white", + features: [ + t("contact.ticket.features.0"), + t("contact.ticket.features.1"), + t("contact.ticket.features.2"), + ], + }, ] const emailContacts = [ @@ -116,7 +130,7 @@ export function Contact() { {/* Social Links & Warning - Now at top */} -
+
@@ -159,13 +173,13 @@ export function Contact() {
{/* Support Channels */} -
+
{supportChannels.map((channel) => ( -
+
{channel.title}

{channel.description}

-
    +
      {channel.features.map((feature, i) => (
    • @@ -198,7 +212,7 @@ export function Contact() {
{/* Email Contacts */} -
+
diff --git a/packages/ui/components/Static/navigation.tsx b/packages/ui/components/Static/navigation.tsx index 3226890..f042b95 100644 --- a/packages/ui/components/Static/navigation.tsx +++ b/packages/ui/components/Static/navigation.tsx @@ -108,7 +108,7 @@ export function Navigation() { }, { title: t("resources.vpsPanel.title"), - href: "https://panel.nodebyte.host/", + href: "https://vps.nodebyte.host/", description: t("resources.vpsPanel.description"), icon: Cpu, external: true, @@ -118,12 +118,14 @@ export function Navigation() { href: "/kb", description: t("resources.kb.description"), icon: Book, + external: false }, { title: t("resources.changelog.title"), href: "/changelog", description: t("resources.changelog.description"), icon: Sparkles, + external: false }, ], [t]) @@ -276,7 +278,7 @@ export function Navigation() { {/* Desktop Navigation */}
{/* Company Dropdown */} - +
openDropdown(setCompanyOpen, () => { setServicesOpen(false); setResourcesOpen(false) })} onMouseLeave={() => closeDropdown(setCompanyOpen)} @@ -301,14 +303,14 @@ export function Navigation() { -
+
- {item.title} + {item.title}

{item.description} @@ -322,7 +324,7 @@ export function Navigation() { {/* Services Dropdown */} - +

openDropdown(setServicesOpen, () => { setCompanyOpen(false); setResourcesOpen(false) })} onMouseLeave={() => closeDropdown(setServicesOpen)} @@ -351,13 +353,13 @@ export function Navigation() { -
+
- {service.title} + {service.title}

{service.description}

@@ -374,13 +376,13 @@ export function Navigation() { -
+
- {service.title} + {service.title}

{service.description}

@@ -393,7 +395,7 @@ export function Navigation() { {/* Resources Dropdown */} - +
openDropdown(setResourcesOpen, () => { setCompanyOpen(false); setServicesOpen(false) })} onMouseLeave={() => closeDropdown(setResourcesOpen)} @@ -418,16 +420,16 @@ export function Navigation() {