Improve accessibility and polish page styling
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 11m31s
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 11m31s
This commit is contained in:
@@ -6,7 +6,7 @@ export default async function About() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content prose">
|
||||
<main className="section page-content prose" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">{t("THE EXPLORER’S FIELD GUIDE")}</span>
|
||||
<h1>
|
||||
{t("You know this place.")}
|
||||
|
||||
@@ -9,7 +9,7 @@ export default async function AdminPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content moderation-page">
|
||||
<main className="section page-content moderation-page" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">MINEGEO ADMIN</span>
|
||||
<h1>{t("Admin Tools.")}</h1>
|
||||
<p className="lead">
|
||||
|
||||
@@ -30,7 +30,7 @@ export default async function ResetPassword() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<section className="auth-card reset-card">
|
||||
<span className="eyebrow">{t("ACCOUNT RECOVERY")}</span>
|
||||
<h1>{t("A fresh start.")}</h1>
|
||||
|
||||
@@ -12,7 +12,7 @@ export default async function AppealPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className={`section page-content ${styles.page}`}>
|
||||
<main className={`section page-content ${styles.page}`} id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">MINEGEO</span>
|
||||
<h1>{ru ? "Доступ и апелляции." : "Account access & appeals."}</h1>
|
||||
{account ? (
|
||||
|
||||
@@ -28,7 +28,7 @@ export default async function ChangelogsPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content changelog-page">
|
||||
<main className="section page-content changelog-page" id="main-content" tabIndex={-1}>
|
||||
{!before && <ChangelogRefresh />}
|
||||
<span className="eyebrow">{t("WHAT'S NEW")}</span>
|
||||
<h1>{t("Changelogs")}</h1>
|
||||
|
||||
@@ -18,7 +18,7 @@ export default async function Draft({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">{t("YOUR WORLD · YOUR LOCATIONS")}</span>
|
||||
<h1>{t("Map workshop")}</h1>
|
||||
<DraftEditor id={id} hostName={profile.display_name} />
|
||||
|
||||
@@ -28,7 +28,7 @@ export default async function DashboardPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
{account ? (
|
||||
<>
|
||||
<span className="eyebrow">{t("THE CARTOGRAPHER’S DESK")}</span>
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function DeveloperApiPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<DeveloperPanel signedIn={Boolean(account)} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -93,7 +93,7 @@ export default async function Docs({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className={`section page-content ${styles.layout}`}>
|
||||
<main className={`section page-content ${styles.layout}`} id="main-content" tabIndex={-1}>
|
||||
<aside>
|
||||
<h2>Player docs</h2>
|
||||
<nav aria-label="Documentation pages" className={styles.menu}>
|
||||
|
||||
@@ -14,8 +14,8 @@ export default async function Downloads() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<article className="tool-card" style={{ marginBottom: 40 }}>
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<article className="tool-card desktop-download-card">
|
||||
<span className="eyebrow">{t("MINEGEO DESKTOP")}</span>
|
||||
<h2>{t("Your next expedition, on your desktop.")}</h2>
|
||||
<p className="muted">
|
||||
@@ -26,7 +26,7 @@ export default async function Downloads() {
|
||||
<a className="button primary" href={desktopRelease.file} download>
|
||||
<Download size={16} /> {t("Download for Windows")}
|
||||
</a>
|
||||
<p className="muted" style={{ marginTop: 16 }}>
|
||||
<p className="muted desktop-download-version">
|
||||
{t(
|
||||
"Windows 10/11 · 64-bit · Version {version} · Internet required",
|
||||
{ version: desktopRelease.version },
|
||||
@@ -87,10 +87,9 @@ export default async function Downloads() {
|
||||
) ? (
|
||||
<a
|
||||
key={version}
|
||||
className="button primary"
|
||||
className="button primary download-build-link"
|
||||
href={`/tools/mod/minegeo-fabric-${version}-${release}.jar`}
|
||||
download
|
||||
style={{ marginRight: 8, marginBottom: 8 }}
|
||||
>
|
||||
<Download size={16} /> {t("Download Fabric mod")} · {version}
|
||||
</a>
|
||||
@@ -100,7 +99,7 @@ export default async function Downloads() {
|
||||
</p>
|
||||
),
|
||||
)}
|
||||
<p className="muted" style={{ fontSize: 11, marginTop: 20 }}>
|
||||
<p className="muted tool-card-note tool-card-note-spaced">
|
||||
{t(
|
||||
"Install the JAR in your Minecraft mods folder alongside Fabric API.",
|
||||
)}
|
||||
@@ -156,7 +155,7 @@ export default async function Downloads() {
|
||||
". The manifest appears when export finishes. Upload sends the latest completed export; it does not capture the world.",
|
||||
)}
|
||||
</p>
|
||||
<p className="muted" style={{ fontSize: 11 }}>
|
||||
<p className="muted tool-card-note">
|
||||
{t(
|
||||
"Put the JAR in plugins/ and restart. Set server-name and server-address in plugins/MineGeo/config.yml, then run /minegeo reload. Permission: minegeo.admin. The same plugin JAR supports all three versions.",
|
||||
)}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useI18n } from "@/components/I18nProvider";
|
||||
export default function ErrorPage({ retry }: { retry: () => void }) {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<h1>{t("Lost connection.")}</h1>
|
||||
<p>
|
||||
{t(
|
||||
|
||||
@@ -26,7 +26,12 @@ body {
|
||||
margin: 0;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -50,7 +55,7 @@ button {
|
||||
cursor: pointer;
|
||||
}
|
||||
button:disabled {
|
||||
cursor: wait;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
::selection {
|
||||
|
||||
@@ -44,16 +44,17 @@ export default async function RootLayout({
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [{ locale, preference, detectedLocale }, settings] = await Promise.all([
|
||||
getI18n(),
|
||||
initialSiteSettings(),
|
||||
]);
|
||||
const [{ locale, preference, detectedLocale, t }, settings] =
|
||||
await Promise.all([getI18n(), initialSiteSettings()]);
|
||||
return (
|
||||
<html lang={locale} data-theme="dark" suppressHydrationWarning>
|
||||
<head>
|
||||
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
|
||||
</head>
|
||||
<body>
|
||||
<a className="skip-link" href="#main-content">
|
||||
{t("Skip to content")}
|
||||
</a>
|
||||
<I18nProvider
|
||||
locale={locale}
|
||||
preference={preference}
|
||||
|
||||
@@ -6,6 +6,8 @@ export default async function LoadingLeaderboard() {
|
||||
className="section page-content leaderboard-page"
|
||||
aria-busy="true"
|
||||
aria-label={t("Loading leaderboard")}
|
||||
id="main-content"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<span className="eyebrow">{t("THE EXPLORERS’ BOARD")}</span>
|
||||
<h1>{t("Every block counts.")}</h1>
|
||||
|
||||
@@ -42,7 +42,7 @@ export default async function LeaderboardPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content leaderboard-page" id="main-content">
|
||||
<main className="section page-content leaderboard-page" id="main-content" tabIndex={-1}>
|
||||
<Link href="/" className="text-link leaderboard-back">
|
||||
<ArrowLeft size={14} /> {t("Back to home")}
|
||||
</Link>
|
||||
|
||||
@@ -22,7 +22,7 @@ export default async function LogIn({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content auth-page">
|
||||
<main className="section page-content auth-page" id="main-content" tabIndex={-1}>
|
||||
<SignIn
|
||||
next={next}
|
||||
initialError={
|
||||
|
||||
@@ -10,7 +10,7 @@ export default async function Review() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content moderation-page">
|
||||
<main className="section page-content moderation-page" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">{t("THE COMMUNITY’S COMPASS")}</span>
|
||||
<h1>{t("Moderation Tools.")}</h1>
|
||||
<p className="lead">
|
||||
|
||||
@@ -3,7 +3,7 @@ import Link from "next/link";
|
||||
export default async function NotFound() {
|
||||
const { t } = await getI18n();
|
||||
return (
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">{t("UNKNOWN COORDINATES")}</span>
|
||||
<h1>{t("Uncharted territory.")}</h1>
|
||||
<p>{t("This map or page isn’t available.")}</p>
|
||||
|
||||
18
app/page.tsx
18
app/page.tsx
@@ -30,10 +30,10 @@ export default async function Home() {
|
||||
<>
|
||||
<FirstVisitIntro />
|
||||
<Header />
|
||||
<main className="home-page" id="main-content">
|
||||
<main className="home-page" id="main-content" tabIndex={-1}>
|
||||
<section className="hero">
|
||||
<div className="hero-copy">
|
||||
<div className="status-label">{t("A MINECRAFT GUESSING GAME")}</div>
|
||||
<div className="status-label">{t("A Minecraft guessing game")}</div>
|
||||
<h1>
|
||||
{t("Guess where you are")}
|
||||
<br />
|
||||
@@ -131,8 +131,8 @@ export default async function Home() {
|
||||
<section className="section catalog-section">
|
||||
<div className="section-heading">
|
||||
<div>
|
||||
<span className="eyebrow">{t("COMMUNITY MAPS")}</span>
|
||||
<h2>{t("Where will you go today?")}</h2>
|
||||
<span className="eyebrow">{t("Community maps")}</span>
|
||||
<h2>{t("Explore community worlds.")}</h2>
|
||||
</div>
|
||||
<Link className="text-link" href="/servers">
|
||||
{t("All maps ({count})", { count: maps.length })}{" "}
|
||||
@@ -196,7 +196,7 @@ export default async function Home() {
|
||||
</Suspense>
|
||||
<section className="section home-panels">
|
||||
<article className="home-panel">
|
||||
<span className="eyebrow">{t("HOW TO PLAY")}</span>
|
||||
<span className="eyebrow">{t("How to play")}</span>
|
||||
<h2>{t("Know your blocks?")}</h2>
|
||||
<ol className="play-steps">
|
||||
<li>
|
||||
@@ -234,8 +234,8 @@ export default async function Home() {
|
||||
</Link>
|
||||
</article>
|
||||
<article className="home-panel">
|
||||
<span className="eyebrow">{t("CHOOSE YOUR CHALLENGE")}</span>
|
||||
<h2>{t("Find your challenge.")}</h2>
|
||||
<span className="eyebrow">{t("Choose a difficulty")}</span>
|
||||
<h2>{t("Pick a difficulty.")}</h2>
|
||||
<div className="mode-list">
|
||||
{[
|
||||
{
|
||||
@@ -287,8 +287,8 @@ export default async function Home() {
|
||||
<section className="section contribute-banner">
|
||||
<Blocks size={38} />
|
||||
<div>
|
||||
<span className="eyebrow">{t("BUILT BY THE COMMUNITY")}</span>
|
||||
<h2>{t("Your world deserves to be explored.")}</h2>
|
||||
<span className="eyebrow">{t("Made by MineGeo players")}</span>
|
||||
<h2>{t("Put your world on the map.")}</h2>
|
||||
<p>
|
||||
{t("Share your builds and your favorite corners of Minecraft.")}
|
||||
</p>
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function Pair({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
{!account ? (
|
||||
<>
|
||||
<p className="muted">
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
/* Responsive corrections shared by both languages. */
|
||||
.skip-link {
|
||||
position: fixed;
|
||||
inset-block-start: 12px;
|
||||
inset-inline-start: 12px;
|
||||
z-index: 1000;
|
||||
padding: 10px 14px;
|
||||
transform: translateY(calc(-100% - 16px));
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-control);
|
||||
color: var(--text);
|
||||
background: var(--panel);
|
||||
box-shadow: 0 4px 14px #03060a55;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.skip-link:focus-visible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.language-switcher {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -107,6 +124,22 @@ html[lang="ru"] .mode-row h3 span {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.desktop-download-card {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.desktop-download-version {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.download-build-link {
|
||||
margin-inline-end: 8px;
|
||||
margin-block-end: 8px;
|
||||
}
|
||||
.tool-card-note {
|
||||
font-size: 11px;
|
||||
}
|
||||
.tool-card-note-spaced {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.tool-card pre,
|
||||
.token-box code {
|
||||
max-width: 100%;
|
||||
|
||||
@@ -8,7 +8,7 @@ export default async function ResultPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<Results id={(await params).id} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
--text: #eef1f4;
|
||||
--board-stone: #1a222c;
|
||||
--board-edge: #35404c;
|
||||
--radius-panel: 16px;
|
||||
--radius-panel: 12px;
|
||||
--radius-control: 9px;
|
||||
}
|
||||
body {
|
||||
|
||||
@@ -33,7 +33,7 @@ export default async function ServerPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content map-detail-page">
|
||||
<main className="section page-content map-detail-page" id="main-content" tabIndex={-1}>
|
||||
<Link className="map-back-link" href="/servers">
|
||||
<ArrowLeft size={16} aria-hidden="true" />
|
||||
{t("All worlds")}
|
||||
|
||||
@@ -10,7 +10,7 @@ export default async function Servers() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<span className="eyebrow">
|
||||
{t("THE COMMUNITY AT YOUR COORDINATES")}
|
||||
</span>
|
||||
|
||||
@@ -35,7 +35,7 @@ export default async function Settings({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<Link
|
||||
className="text-link"
|
||||
href={active ? "/dashboard" : "/ban/appeal"}
|
||||
|
||||
@@ -13,7 +13,7 @@ export default async function Report({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<SupportConversation key={id} id={id} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -18,7 +18,7 @@ export default async function Support({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<main className="section page-content" id="main-content" tabIndex={-1}>
|
||||
<SupportInbox pagePath={pagePath} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -15,7 +15,7 @@ export default async function TournamentPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main id="main-content">
|
||||
<main id="main-content" tabIndex={-1}>
|
||||
<TournamentLobby id={id} signedIn={!!account} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function TournamentsPage({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main id="main-content">
|
||||
<main id="main-content" tabIndex={-1}>
|
||||
<TournamentIndex signedIn={!!account} initialMapId={initialMapId} />
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
Reference in New Issue
Block a user