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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Link>` for internal routes and `<a target="_blank">` for external ones instead of always using `<a target="_blank">`

### 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
Expand Down
42 changes: 21 additions & 21 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions packages/core/constants/game/hytale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ 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",
priceGBP: 10,
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",
},
]

Expand Down
16 changes: 16 additions & 0 deletions packages/core/constants/game/minecraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
]

/**
Expand Down
10 changes: 10 additions & 0 deletions packages/core/constants/game/rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@ export const RUST_PLANS: GamePlanSpec[] = [
priceGBP: 5.75,
ramGB: 8,
storageGB: 150,
url: "https://billing.nodebyte.host/products/rust-hosting/starter"
},
{
id: "standard",
priceGBP: 8.95,
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"
},
]

Expand Down
2 changes: 1 addition & 1 deletion packages/core/constants/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 6 additions & 6 deletions packages/core/constants/vps/amd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
},
]

Expand Down
26 changes: 20 additions & 6 deletions packages/ui/components/Layouts/Contact/contact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,28 @@ 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"),
t("contact.github.features.1"),
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"),
],
},
Comment on lines +60 to +70
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The new support ticket card on the Contact page uses translation keys that might be missing. If the translations submodule isn't updated, the page could crash or render incorrectly.
Severity: HIGH

Suggested Fix

Before merging, verify that the translations git submodule has been updated to include the new contact.ticket.* keys in both messages/en-US.json and templates/en.json. Ensure the submodule commit is correctly referenced in this PR.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/ui/components/Layouts/Contact/contact.tsx#L57-L70

Potential issue: The component `contact.tsx` now uses new translation keys like
`t("contact.ticket.title")`. These translations are managed in a separate git submodule.
If the submodule was not updated and synced correctly before merging, these keys will be
missing at runtime. The `next-intl` library is not configured with `onError` or
`getMessageFallback` handlers, meaning it will likely throw an error or render the raw
keys, causing the Contact page to crash or display incorrectly. This is a common
integration issue with submodules.

Did we get this right? 👍 / 👎 to inform future reviews.

]

const emailContacts = [
Expand Down Expand Up @@ -116,7 +130,7 @@ export function Contact() {
</div>

{/* Social Links & Warning - Now at top */}
<div className="max-w-4xl mx-auto mb-16">
<div className="max-w-5xl mx-auto mb-16">
<Card className="border-border/50 bg-card/30 backdrop-blur-sm p-6 sm:p-8">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-6">
<div>
Expand Down Expand Up @@ -159,13 +173,13 @@ export function Contact() {
</div>

{/* Support Channels */}
<div className="grid md:grid-cols-2 gap-6 max-w-4xl mx-auto mb-16">
<div className="grid md:grid-cols-3 gap-6 max-w-5xl mx-auto mb-16">
{supportChannels.map((channel) => (
<Card
key={channel.title}
className="group relative overflow-hidden border-border/50 bg-card/30 backdrop-blur-sm hover:border-primary/30 transition-all duration-300"
>
<div className="p-6 sm:p-8">
<div className="p-6 sm:p-8 flex flex-col h-full">
<div className={cn(
"inline-flex items-center justify-center w-12 h-12 rounded-xl mb-4 transition-colors",
channel.color,
Expand All @@ -177,7 +191,7 @@ export function Contact() {
<h3 className="text-xl font-bold mb-2">{channel.title}</h3>
<p className="text-muted-foreground mb-4">{channel.description}</p>

<ul className="space-y-2 mb-6">
<ul className="space-y-2 mb-6 flex-1">
{channel.features.map((feature, i) => (
<li key={i} className="flex items-center gap-2 text-sm text-muted-foreground">
<CheckCircle2 className="w-4 h-4 text-primary shrink-0" />
Expand All @@ -198,7 +212,7 @@ export function Contact() {
</div>

{/* Email Contacts */}
<div className="max-w-4xl mx-auto mb-16">
<div className="max-w-5xl mx-auto mb-16">
<div className="text-center mb-8">
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-accent/10 border border-accent/20 text-sm text-accent mb-4">
<Mail className="w-4 h-4" />
Expand Down
Loading
Loading