feat: roomier BO2 companion with +/- rank stepping
All checks were successful
Test and deploy staging / staging (push) Successful in 2m29s
All checks were successful
Test and deploy staging / staging (push) Successful in 2m29s
- Scale the COD page to the screen: larger gun art, text and progress ribbon, sized from one viewport unit so it fills a MacBook Pro 16" and big monitors and still fits 1280x720 without scrolling. - Five columns on wide screens and four below, picked by CSS, so the server-rendered page already has the final layout. - Replace the tabs/filters/overview rows with one toolbar of matching controls. - Player and weapon ranks step with + and -: level 55 + 1 is the next prestige at level 1, up to max prestige. Presses show at once, batch while a save is running, and stepRank does the arithmetic in SQL. - Clicking a rank still opens exact entry for big jumps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,33 +2,107 @@
|
||||
import { base } from '$app/paths';
|
||||
import ChevronsUp from 'lucide-svelte/icons/chevrons-up';
|
||||
import Award from 'lucide-svelte/icons/award';
|
||||
let { game, level, prestige }: { game: string; level: number; prestige: number } = $props();
|
||||
let {
|
||||
game,
|
||||
level,
|
||||
prestige,
|
||||
levelCap = null,
|
||||
prestigeCap = null,
|
||||
onedit
|
||||
}: {
|
||||
game: string;
|
||||
level: number;
|
||||
prestige: number;
|
||||
levelCap?: number | null;
|
||||
prestigeCap?: number | null;
|
||||
/** Makes the badge a button for typing an exact rank. */
|
||||
onedit?: () => void;
|
||||
} = $props();
|
||||
const master = $derived(game === 'black-ops-2' && prestige === 10 && level === 55);
|
||||
</script>
|
||||
|
||||
<div class="flex items-center gap-4" aria-label="Player level and prestige">
|
||||
<div class="flex items-center gap-2">
|
||||
<ChevronsUp class="size-7 text-amber-500" aria-label="Level icon" role="img" />
|
||||
<div>
|
||||
<span class="block text-[9px] tracking-widest text-muted-foreground">LEVEL</span><strong
|
||||
class="text-sm tabular-nums">{level}</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<svelte:element
|
||||
this={onedit ? 'button' : 'div'}
|
||||
type={onedit ? 'button' : undefined}
|
||||
class="badge"
|
||||
class:editable={!!onedit}
|
||||
aria-label="Player level and prestige"
|
||||
title={onedit ? 'Type an exact level and prestige' : undefined}
|
||||
onclick={onedit}
|
||||
role={onedit ? undefined : 'group'}
|
||||
>
|
||||
<span class="stat">
|
||||
{#if game === 'black-ops-2' && prestige > 0 && prestige <= 10}
|
||||
<img
|
||||
src={`${base}/game-art/call-of-duty/ranks/black-ops-2-prestige-${master ? 11 : prestige}.webp`}
|
||||
alt={master ? 'Prestige Master emblem' : `Prestige ${prestige} emblem`}
|
||||
width="36"
|
||||
height="36"
|
||||
class="size-9 object-contain"
|
||||
width="48"
|
||||
height="48"
|
||||
class="emblem"
|
||||
/>
|
||||
{:else}<Award class="size-7 text-muted-foreground" aria-label="Prestige icon" role="img" />{/if}
|
||||
<div>
|
||||
<span class="block text-[9px] tracking-widest text-muted-foreground">PRESTIGE</span><strong
|
||||
class="text-sm tabular-nums">{master ? 'Master' : prestige}</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}<Award class="icon text-muted-foreground" aria-label="Prestige icon" role="img" />{/if}
|
||||
<span
|
||||
><span class="label">PRESTIGE</span><strong
|
||||
>{master ? 'Master' : prestige}{#if prestigeCap !== null && !master}<small
|
||||
>/{prestigeCap}</small
|
||||
>{/if}</strong
|
||||
></span
|
||||
>
|
||||
</span>
|
||||
<span class="stat">
|
||||
<ChevronsUp class="icon text-amber-500" aria-label="Level icon" role="img" />
|
||||
<span
|
||||
><span class="label">LEVEL</span><strong
|
||||
>{level}{#if levelCap !== null}<small>/{levelCap}</small>{/if}</strong
|
||||
></span
|
||||
>
|
||||
</span>
|
||||
</svelte:element>
|
||||
|
||||
<style>
|
||||
.badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: calc(18 * var(--u, 1px));
|
||||
border-radius: calc(10 * var(--u, 1px));
|
||||
padding: calc(2 * var(--u, 1px)) calc(8 * var(--u, 1px));
|
||||
text-align: left;
|
||||
}
|
||||
.editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.editable:hover {
|
||||
background: color-mix(in srgb, #f59e0b 10%, transparent);
|
||||
}
|
||||
.editable:focus-visible {
|
||||
outline: 2px solid #f59e0b;
|
||||
}
|
||||
.stat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: calc(8 * var(--u, 1px));
|
||||
}
|
||||
.emblem,
|
||||
.stat :global(.icon) {
|
||||
width: calc(44 * var(--u, 1px));
|
||||
height: calc(44 * var(--u, 1px));
|
||||
object-fit: contain;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
font-size: calc(11 * var(--u, 1px));
|
||||
letter-spacing: 0.14em;
|
||||
color: var(--site-muted);
|
||||
}
|
||||
strong {
|
||||
display: block;
|
||||
font-size: calc(24 * var(--u, 1px));
|
||||
line-height: 1.05;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
small {
|
||||
font-size: 0.6em;
|
||||
font-weight: 500;
|
||||
color: var(--site-muted);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user