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
52 changes: 30 additions & 22 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,19 @@ function App() {
>
<header>
<div className="grid gap-5 lg:gap-6">
<div className="max-w-4xl">
<div className="flex max-w-4xl gap-4">
<div
className="hidden w-3 shrink-0 flex-col items-center self-stretch sm:flex"
aria-hidden="true"
>
<span className="h-16 w-0.5 bg-ops-accent/75 shadow-[0_0_16px_rgba(110,231,183,0.22)]" />
<span className="mt-2 h-8 w-px bg-ops-accent-border" />
<span className="mt-2 h-full w-px flex-1 bg-ops-border-struct" />
</div>
<div className="min-w-0">
<div className="flex flex-wrap items-center gap-3">
<span
className="clip-notched ops-notch-chip tactical-chip-panel inline-flex h-9 w-9 items-center justify-center border border-ops-accent/35 bg-ops-accent/10 text-ops-accent-muted"
className="clip-notched ops-notch-chip tactical-chip-panel inline-flex h-8 w-8 items-center justify-center border border-ops-accent/30 text-ops-accent-muted"
aria-hidden="true"
>
<SectorGlyphMark sectorId="work-school" />
Expand All @@ -247,18 +255,18 @@ function App() {
Personal Readiness Tracker
</p>
</div>
<h1 className="mt-3 text-4xl font-semibold text-ops-text-primary sm:text-5xl">
<h1 className="ops-tracking-display mt-4 text-4xl font-semibold text-ops-text-primary uppercase sm:mt-5 sm:text-5xl">
OpsNormal
</h1>
<p className="mt-4 max-w-3xl text-sm leading-7 text-ops-text-secondary sm:text-base">
<p className="mt-4 max-w-2xl text-sm leading-7 text-ops-text-secondary sm:text-base">
A local-only mirror for daily balance across work or school,
household, relationships, body, and rest. No account. No
cloud sync. No analytics layer.
</p>
<div
className="mt-5 h-px bg-ops-accent/25"
aria-hidden="true"
/>
<div className="mt-5 space-y-1.5" aria-hidden="true">
<span className="block h-px max-w-2xl bg-ops-border-soft" />
<span className="clip-notched ops-notch-chip block h-1 w-12 bg-ops-accent/65 shadow-[0_0_14px_rgba(110,231,183,0.18)]" />
</div>
</div>
</div>
<ErrorBoundary
Expand Down Expand Up @@ -302,7 +310,6 @@ function App() {
role="alert"
aria-atomic="true"
titleId="database-upgrade-blocked-title"
intensity="inline"
/>
) : null}
<BackupActionBanner prompt={backupActionPrompt} />
Expand Down Expand Up @@ -368,20 +375,21 @@ function App() {
innerClassName="tactical-subpanel px-4 py-4 text-sm leading-7 text-ops-text-secondary"
>
<footer>
<div className="grid gap-5">
<div className="max-w-3xl">
<p className="ops-eyebrow font-semibold text-ops-text-primary">
Boundary
</p>
<p className="mt-2">
OpsNormal is a personal status tracking tool. It is not a
medical device and does not diagnose, treat, cure, or prevent
any disease or condition. It does not provide medical or
psychological advice.
</p>
<div className="border-t border-ops-panel-border-strong pt-6">
<div className="grid gap-5 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)] lg:items-start">
<div className="lg:max-w-2xl">
<p className="ops-eyebrow font-semibold text-ops-text-primary">
Boundary
</p>
<p className="mt-2">
OpsNormal is a personal status tracking tool. It is not a
medical device and does not diagnose, treat, cure, or
prevent any disease or condition. It does not provide
medical or psychological advice.
</p>
</div>
<FooterProvenance />
</div>
<div className="h-px bg-ops-border-soft" aria-hidden="true" />
<FooterProvenance />
</div>
</footer>
</NotchedFrame>
Expand Down
35 changes: 6 additions & 29 deletions src/components/AlertSurface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface AlertSurfaceProps
description?: ReactNode;
actions?: ReactNode;
as?: 'section' | 'div';
intensity?: 'standard' | 'compact' | 'inline';
intensity?: 'standard' | 'compact';
titleId?: string;
outerClassName?: string;
innerClassName?: string;
Expand Down Expand Up @@ -59,7 +59,6 @@ export function AlertSurface({
const resolvedTitleId = titleId ?? generatedTitleId;
const tonePalette = getAlertSurfaceTonePalette(tone);
const isCompact = intensity === 'compact';
const isInline = intensity === 'inline';
const resolvedAriaLabelledBy =
elementProps['aria-labelledby'] ??
(elementProps['aria-label'] ? undefined : resolvedTitleId);
Expand All @@ -70,9 +69,11 @@ export function AlertSurface({
<h2
id={resolvedTitleId}
className={joinClasses(
'text-sm font-semibold tracking-[0.14em] uppercase',
isCompact && 'text-xs tracking-[0.14em]',
tonePalette.titleClassName,
'font-semibold uppercase',
isCompact
? 'text-[11px] tracking-[0.10em] text-ops-text-secondary'
: 'text-sm tracking-[0.14em]',
!isCompact && tonePalette.titleClassName,
titleClassName,
)}
>
Expand Down Expand Up @@ -110,30 +111,6 @@ export function AlertSurface({
</>
);

if (isInline) {
return createElement(
as,
{
...elementProps,
...(resolvedAriaLabelledBy
? { 'aria-labelledby': resolvedAriaLabelledBy }
: {}),
className: joinClasses(
'ops-inline-alert p-4',
tonePalette.titleClassName,
className,
),
},
actions ? (
<div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
{content}
</div>
) : (
content
),
);
}

return (
<NotchedFrame
outerClassName={joinClasses(tonePalette.outerClassName, outerClassName)}
Expand Down
26 changes: 11 additions & 15 deletions src/components/DomainCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,7 @@ export function DomainCard({

const shellClassName = busy
? 'panel-shadow clip-notched ops-notch-panel-outer bg-ops-border-strong p-px'
: 'ops-domain-card panel-shadow group clip-notched ops-notch-panel-outer bg-ops-border-struct p-px transition-colors duration-150 ease-out hover:bg-ops-border-strong focus-within:bg-ops-border-strong';
const sigilClassName =
resolvedStatus === 'nominal'
? 'border-ops-accent/35 bg-ops-accent/10 text-ops-accent-muted'
: resolvedStatus === 'degraded'
? 'border-[var(--ops-status-degraded-border)] bg-[var(--ops-status-degraded-bg)] text-[var(--ops-status-degraded-text)]'
: 'border-ops-border-soft text-ops-text-muted';
: 'ops-domain-card panel-shadow group clip-notched ops-notch-panel-outer bg-ops-border-strong p-px transition-colors hover:bg-ops-accent/25 focus-within:bg-ops-accent/25';

useEffect(() => {
const pendingStatus = pendingKeyboardFocusStatusRef.current;
Expand Down Expand Up @@ -154,16 +148,13 @@ export function DomainCard({
<div className={shellClassName}>
<div
className={[
'ops-domain-card-surface clip-notched ops-notch-panel-inner tactical-panel flex transform-gpu flex-col gap-5 p-4 text-left transition-transform duration-150 ease-out group-hover:-translate-y-px group-focus-within:-translate-y-px sm:p-5',
'clip-notched ops-notch-panel-inner tactical-panel flex min-h-[15rem] transform-gpu flex-col justify-between bg-[linear-gradient(180deg,rgba(255,255,255,0.025),transparent_28%),var(--color-ops-surface-2)] p-4 text-left transition-transform duration-150 ease-out group-hover:-translate-y-px group-focus-within:-translate-y-px sm:p-5 xl:min-h-[16rem]',
spineClassName,
].join(' ')}
>
<div className="flex items-start gap-3">
<span
className={[
'clip-notched ops-notch-chip tactical-chip-panel inline-flex h-9 w-9 shrink-0 items-center justify-center border transition-colors duration-150 ease-out',
sigilClassName,
].join(' ')}
className="clip-notched ops-notch-chip tactical-chip-panel inline-flex h-9 w-9 shrink-0 items-center justify-center border border-ops-border-soft text-ops-text-muted"
aria-hidden="true"
>
<SectorGlyphMark sectorId={sector.id} />
Expand All @@ -177,7 +168,7 @@ export function DomainCard({
/>
<span>{sector.shortLabel}</span>
</span>
<h3 className="ops-headline-h3 mt-2 text-ops-text-primary">
<h3 className="mt-2 text-sm leading-5 font-semibold tracking-[0.04em] text-ops-text-primary uppercase">
{sector.label}
</h3>
<p className="mt-3 text-sm leading-6 text-ops-text-secondary">
Expand All @@ -186,7 +177,12 @@ export function DomainCard({
</div>
</div>

<div className="border-t border-ops-border-soft pt-4">
<div className="mt-6">
<div
className="ops-sector-caption border-t border-ops-border-soft pt-3"
aria-hidden="true"
/>

{busy ? (
<span id={busyHintId} className="sr-only">
Saving local write. Stand by.
Expand All @@ -197,7 +193,7 @@ export function DomainCard({
role="radiogroup"
aria-label={`${sector.label} status`}
aria-describedby={describedBy}
className="grid grid-cols-3 gap-2"
className="mt-3 grid grid-cols-3 gap-2"
>
{STATUS_OPTIONS.map((option, optionIndex) => {
const content = getStatusContent(option);
Expand Down
26 changes: 12 additions & 14 deletions src/components/FooterProvenance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const REPO_URL = 'https://github.com/bradsaucier/opsnormal';
export function FooterProvenance() {
return (
<div
className="ops-provenance flex flex-col gap-3 sm:w-full lg:items-start"
className="ops-provenance grid gap-3 sm:w-full sm:self-end lg:grid-cols-[auto_1fr_auto] lg:items-center lg:gap-8"
data-testid="footer-provenance"
>
<p className="ops-eyebrow-strong font-semibold text-ops-text-primary">
Expand All @@ -23,19 +23,17 @@ export function FooterProvenance() {
<dd>MIT</dd>
</div>
</dl>
<div className="w-full border-t border-ops-border-soft pt-4 sm:max-w-xs">
<a
className="ops-action-button ops-action-button-subtle ops-provenance-source"
href={REPO_URL}
target="_blank"
rel="noopener noreferrer"
aria-label="View OpsNormal source on GitHub. Opens in a new tab."
data-testid="footer-provenance-source"
>
<GitHubMark />
<span>Source</span>
</a>
</div>
<a
className="ops-action-button ops-action-button-subtle ops-provenance-source"
href={REPO_URL}
target="_blank"
rel="noopener noreferrer"
aria-label="View OpsNormal source on GitHub. Opens in a new tab."
data-testid="footer-provenance-source"
>
<GitHubMark />
<span>Source</span>
</a>
</div>
);
}
Loading
Loading