mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-07 19:58:24 +00:00
01431468e4
- Palette: Patiun Teal, Midnight, night sky, Starlight, flat Alchemist Gold; violet/indigo only as nebula light. Starlight content sections, night-sky nav and heroes (.on-sky scope re-points accent/gold to on-dark values). - Type: Cinzel for headings, names and card titles; Montserrat for body, UI and eyebrows (font-eyebrow); JetBrains Mono kept for code-like blocks. - Header lockup: Patiun glyph + Cinzel "GREG KILMER" + "Web Development · a Patiun LLC company"; glyph also marks the footer and store nav. - Teal filled buttons with Midnight text; gold eyebrows; small links use a darker teal so they pass WCAG AA on Starlight. - Favicons, app icons and web manifest from the GregKilmer.com brand package. - docs/THEMING.md updated for the new palette and fonts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
67 lines
2.2 KiB
Plaintext
67 lines
2.2 KiB
Plaintext
---
|
|
/**
|
|
* SlotMeter.astro
|
|
* ---------------------------------------------------------------------------
|
|
* Visual "X of Y slots open" capacity meter for a store category. Reads a slot
|
|
* status (open + total) and renders a progress-style bar plus an open/closed
|
|
* pill. The fill width reflects open/total; when open === 0 it shows CLOSED.
|
|
*/
|
|
import Icon from '@components/Icon.astro';
|
|
|
|
interface Props {
|
|
/** Category label, e.g. "Card orders" or "3D-print slots". */
|
|
label: string;
|
|
/** mdi icon for the row. */
|
|
icon: string;
|
|
/** Number of currently open slots. */
|
|
open: number;
|
|
/** Total slots for the category. */
|
|
total: number;
|
|
}
|
|
|
|
const { label, icon, open, total } = Astro.props;
|
|
const closed = open <= 0;
|
|
const pct = total > 0 ? Math.max(0, Math.min(100, (open / total) * 100)) : 0;
|
|
---
|
|
|
|
<div
|
|
class="flex flex-col gap-3 rounded-xl border p-4"
|
|
style="border-color: var(--color-border); background: var(--color-surface-raised);"
|
|
>
|
|
<div class="flex items-center justify-between gap-3">
|
|
<span class="inline-flex items-center gap-2 font-sans text-sm font-semibold" style="color: var(--color-text);">
|
|
<Icon name={icon} class="h-5 w-5" style="color: var(--color-accent);" />
|
|
{label}
|
|
</span>
|
|
<span
|
|
class="pill"
|
|
style={closed
|
|
? 'background: color-mix(in srgb, #e55 15%, transparent); border-color: color-mix(in srgb, #e55 40%, transparent);'
|
|
: undefined}
|
|
>
|
|
{closed ? 'Closed' : 'Open'}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-between text-sm" style="color: var(--color-text-muted);">
|
|
<span>{open} of {total} slots open</span>
|
|
<span class="font-eyebrow text-xs" style="color: var(--color-text-subtle);">{closed ? '0%' : `${Math.round(pct)}%`}</span>
|
|
</div>
|
|
|
|
<div
|
|
class="h-2 w-full overflow-hidden rounded-full"
|
|
style="background: color-mix(in srgb, var(--color-border) 60%, transparent);"
|
|
role="meter"
|
|
aria-valuenow={open}
|
|
aria-valuemin="0"
|
|
aria-valuemax={total}
|
|
aria-label={`${label}: ${open} of ${total} slots open`}
|
|
>
|
|
<div
|
|
class="h-full rounded-full transition-[width] duration-500"
|
|
style={`width: ${pct}%; background: ${closed ? '#e55' : 'var(--color-accent)'};`}
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|