feat(focus-rings): branded focus ring tokens (#167) #170
88
frontend/e2e/focus-rings.spec.ts
Normal file
88
frontend/e2e/focus-rings.spec.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
// Expected focus ring resolved colors
|
||||||
|
// Light: --c-focus-ring: #012851 (brand-navy)
|
||||||
|
const FOCUS_RING_LIGHT = 'rgb(1, 40, 81)';
|
||||||
|
// Dark: --c-focus-ring: #a1dcd8 (brand-mint)
|
||||||
|
const FOCUS_RING_DARK = 'rgb(161, 220, 216)';
|
||||||
|
|
||||||
|
test.describe('Focus ring token — CSS custom property', () => {
|
||||||
|
test('--c-focus-ring is defined in light mode', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|
||||||
|
const value = await page.evaluate(() =>
|
||||||
|
getComputedStyle(document.documentElement).getPropertyValue('--c-focus-ring').trim()
|
||||||
|
);
|
||||||
|
expect(value).toBe('#012851');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('--c-focus-ring is defined in dark mode', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
await page.evaluate(() => document.documentElement.setAttribute('data-theme', 'dark'));
|
||||||
|
|
||||||
|
const value = await page.evaluate(() =>
|
||||||
|
getComputedStyle(document.documentElement).getPropertyValue('--c-focus-ring').trim()
|
||||||
|
);
|
||||||
|
expect(value).toBe('#a1dcd8');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Focus ring — header interactive elements', () => {
|
||||||
|
test('ThemeToggle has brand-navy ring in light mode', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: /dark mode|dunkelmodus/i }).focus();
|
||||||
|
const boxShadow = await page.evaluate(
|
||||||
|
() => getComputedStyle(document.activeElement as HTMLElement).boxShadow
|
||||||
|
);
|
||||||
|
expect(boxShadow).toContain(FOCUS_RING_LIGHT);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('AppNav link has brand-mint ring in dark mode', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
await page.evaluate(() => document.documentElement.setAttribute('data-theme', 'dark'));
|
||||||
|
|
||||||
|
// Focus first desktop nav link
|
||||||
|
await page.locator('header nav').getByRole('link').first().focus();
|
||||||
|
const boxShadow = await page.evaluate(
|
||||||
|
() => getComputedStyle(document.activeElement as HTMLElement).boxShadow
|
||||||
|
);
|
||||||
|
expect(boxShadow).toContain(FOCUS_RING_DARK);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Focus ring — form inputs', () => {
|
||||||
|
test.use({ storageState: { cookies: [], origins: [] } });
|
||||||
|
|
||||||
|
test('login username input has brand-mint ring in dark mode', async ({ page }) => {
|
||||||
|
await page.goto('/login');
|
||||||
|
await page.evaluate(() => document.documentElement.setAttribute('data-theme', 'dark'));
|
||||||
|
|
||||||
|
await page.locator('#username').focus();
|
||||||
|
const boxShadow = await page.evaluate(
|
||||||
|
() => getComputedStyle(document.activeElement as HTMLElement).boxShadow
|
||||||
|
);
|
||||||
|
expect(boxShadow).toContain(FOCUS_RING_DARK);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Focus ring — PersonTypeahead', () => {
|
||||||
|
test('PersonTypeahead input has brand-navy ring in light mode', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|
||||||
|
// Open advanced filter panel to expose the sender PersonTypeahead
|
||||||
|
await page.getByRole('button', { name: /filter/i }).click();
|
||||||
|
await page.waitForSelector('#senderId-search');
|
||||||
|
|
||||||
|
await page.locator('#senderId-search').focus();
|
||||||
|
const boxShadow = await page.evaluate(
|
||||||
|
() => getComputedStyle(document.activeElement as HTMLElement).boxShadow
|
||||||
|
);
|
||||||
|
expect(boxShadow).toContain(FOCUS_RING_LIGHT);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -312,7 +312,7 @@ onMount(async () => {
|
|||||||
<div
|
<div
|
||||||
data-comment-id={thread.id}
|
data-comment-id={thread.id}
|
||||||
class={highlightedCommentId === thread.id
|
class={highlightedCommentId === thread.id
|
||||||
? 'rounded ring-2 ring-accent ring-offset-1 transition-shadow'
|
? 'rounded outline-2 outline-offset-1 outline-accent transition-shadow outline-dotted'
|
||||||
: ''}
|
: ''}
|
||||||
>
|
>
|
||||||
{@render commentEntry(thread, thread.id, thread.replies.length === 0)}
|
{@render commentEntry(thread, thread.id, thread.replies.length === 0)}
|
||||||
@@ -323,7 +323,7 @@ onMount(async () => {
|
|||||||
<div
|
<div
|
||||||
data-comment-id={reply.id}
|
data-comment-id={reply.id}
|
||||||
class="mt-3 ml-6 border-l-2 border-line pl-4 {highlightedCommentId === reply.id
|
class="mt-3 ml-6 border-l-2 border-line pl-4 {highlightedCommentId === reply.id
|
||||||
? 'rounded ring-2 ring-accent ring-offset-1 transition-shadow'
|
? 'rounded outline-2 outline-offset-1 outline-accent transition-shadow outline-dotted'
|
||||||
: ''}"
|
: ''}"
|
||||||
>
|
>
|
||||||
{@render commentEntry(reply, thread.id, ri === thread.replies.length - 1)}
|
{@render commentEntry(reply, thread.id, ri === thread.replies.length - 1)}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const activeLocale = $derived(getLocale().toUpperCase());
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => setLocale(localeMap[locale])}
|
onclick={() => setLocale(localeMap[locale])}
|
||||||
class="rounded px-1 font-sans tracking-widest transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent
|
class="rounded px-1 font-sans tracking-widest transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring
|
||||||
{activeLocale === locale
|
{activeLocale === locale
|
||||||
? inverted
|
? inverted
|
||||||
? 'font-bold text-white'
|
? 'font-bold text-white'
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ const popupOpen = $derived(query !== null);
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<textarea
|
<textarea
|
||||||
{@attach attachTextarea}
|
{@attach attachTextarea}
|
||||||
class="w-full resize-none rounded border border-line px-3 py-2 font-serif text-sm text-ink focus:ring-1 focus:ring-accent focus:outline-none"
|
class="w-full resize-none rounded border border-line px-3 py-2 font-serif text-sm text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
rows={rows}
|
rows={rows}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ onDestroy(() => {
|
|||||||
: m.notification_bell_label()}
|
: m.notification_bell_label()}
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="relative rounded-sm p-2 text-white/65 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
class="relative rounded-sm p-2 text-white/65 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
<!-- Bell SVG -->
|
<!-- Bell SVG -->
|
||||||
<svg
|
<svg
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ $effect(() => {
|
|||||||
<select
|
<select
|
||||||
id="compare-a"
|
id="compare-a"
|
||||||
bind:value={compareA}
|
bind:value={compareA}
|
||||||
class="w-full rounded border border-line bg-surface px-2 py-1 font-sans text-xs text-ink focus:ring-1 focus:ring-accent focus:outline-none"
|
class="w-full rounded border border-line bg-surface px-2 py-1 font-sans text-xs text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
<option value="">—</option>
|
<option value="">—</option>
|
||||||
{#each versions as v, i (v.id)}
|
{#each versions as v, i (v.id)}
|
||||||
@@ -317,7 +317,7 @@ $effect(() => {
|
|||||||
<select
|
<select
|
||||||
id="compare-b"
|
id="compare-b"
|
||||||
bind:value={compareB}
|
bind:value={compareB}
|
||||||
class="w-full rounded border border-line bg-surface px-2 py-1 font-sans text-xs text-ink focus:ring-1 focus:ring-accent focus:outline-none"
|
class="w-full rounded border border-line bg-surface px-2 py-1 font-sans text-xs text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
<option value="">—</option>
|
<option value="">—</option>
|
||||||
{#each versions as v, i (v.id)}
|
{#each versions as v, i (v.id)}
|
||||||
|
|||||||
@@ -154,8 +154,8 @@ function clickOutside(node: HTMLElement) {
|
|||||||
onfocus={handleFocus}
|
onfocus={handleFocus}
|
||||||
placeholder={placeholder ?? m.comp_typeahead_placeholder()}
|
placeholder={placeholder ?? m.comp_typeahead_placeholder()}
|
||||||
class={compact
|
class={compact
|
||||||
? 'mt-1 block h-9 w-full rounded border border-line bg-surface px-2 text-sm text-ink placeholder:text-ink-3 focus:border-primary focus:outline-none'
|
? 'mt-1 block h-9 w-full rounded border border-line bg-surface px-2 text-sm text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring'
|
||||||
: 'mt-1 block w-full rounded-md border border-line bg-surface p-2 text-ink shadow-sm placeholder:text-ink-3 focus:border-accent focus:ring-accent'}
|
: 'mt-1 block w-full rounded-md border border-line bg-surface p-2 text-ink shadow-sm placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if showDropdown && (results.length > 0 || loading)}
|
{#if showDropdown && (results.length > 0 || loading)}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function toggle() {
|
|||||||
onclick={toggle}
|
onclick={toggle}
|
||||||
aria-label={theme === 'dark' ? 'light mode' : 'dark mode'}
|
aria-label={theme === 'dark' ? 'light mode' : 'dark mode'}
|
||||||
title={theme === 'dark' ? 'light mode' : 'dark mode'}
|
title={theme === 'dark' ? 'light mode' : 'dark mode'}
|
||||||
class="rounded p-1.5 text-white/65 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
class="rounded p-1.5 text-white/65 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
{#if theme === 'dark'}
|
{#if theme === 'dark'}
|
||||||
<!-- Sun icon — click to go light -->
|
<!-- Sun icon — click to go light -->
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ let titleValue = $derived(titleDirty ? titleOverride : suggestedTitle || titleOv
|
|||||||
titleDirty = true;
|
titleDirty = true;
|
||||||
}}
|
}}
|
||||||
required={titleRequired}
|
required={titleRequired}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -65,7 +65,7 @@ let titleValue = $derived(titleDirty ? titleOverride : suggestedTitle || titleOv
|
|||||||
name="documentLocation"
|
name="documentLocation"
|
||||||
value={initialDocumentLocation}
|
value={initialDocumentLocation}
|
||||||
placeholder={m.form_placeholder_archive_location()}
|
placeholder={m.form_placeholder_archive_location()}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<p class="mt-1 text-xs text-ink-3">{m.form_helper_archive_location()}</p>
|
<p class="mt-1 text-xs text-ink-3">{m.form_helper_archive_location()}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,7 +87,7 @@ let titleValue = $derived(titleDirty ? titleOverride : suggestedTitle || titleOv
|
|||||||
name="summary"
|
name="summary"
|
||||||
rows="5"
|
rows="5"
|
||||||
placeholder={m.form_placeholder_content()}
|
placeholder={m.form_placeholder_content()}
|
||||||
class="block w-full rounded border border-line p-2 font-serif text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 font-serif text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{initialSummary}</textarea
|
>{initialSummary}</textarea
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ let { initialTranscription = '' }: { initialTranscription?: string } = $props();
|
|||||||
name="transcription"
|
name="transcription"
|
||||||
rows="12"
|
rows="12"
|
||||||
placeholder={m.form_placeholder_transcription()}
|
placeholder={m.form_placeholder_transcription()}
|
||||||
class="block w-full rounded border border-line p-2 font-serif text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 font-serif text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{initialTranscription}</textarea
|
>{initialTranscription}</textarea
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ $effect(() => {
|
|||||||
placeholder={m.form_placeholder_date()}
|
placeholder={m.form_placeholder_date()}
|
||||||
maxlength="10"
|
maxlength="10"
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm
|
||||||
{dateInvalid ? 'border-red-400 focus:border-red-500 focus:ring-red-500' : 'focus:border-ink focus:ring-ink'}"
|
{dateInvalid ? 'border-red-400 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500' : 'focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring'}"
|
||||||
aria-describedby={dateInvalid ? 'date-error' : undefined}
|
aria-describedby={dateInvalid ? 'date-error' : undefined}
|
||||||
/>
|
/>
|
||||||
<input type="hidden" name="documentDate" value={dateIso} />
|
<input type="hidden" name="documentDate" value={dateIso} />
|
||||||
@@ -91,7 +91,7 @@ $effect(() => {
|
|||||||
name="location"
|
name="location"
|
||||||
value={initialLocation}
|
value={initialLocation}
|
||||||
placeholder={m.form_placeholder_location()}
|
placeholder={m.form_placeholder_location()}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ let selected = $derived([...selectedGroupIds]);
|
|||||||
name="groupIds"
|
name="groupIds"
|
||||||
value={group.id}
|
value={group.id}
|
||||||
bind:group={selected}
|
bind:group={selected}
|
||||||
class="rounded border-line text-ink focus:ring-accent"
|
class="rounded border-line text-ink focus:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
{group.name}
|
{group.name}
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ let { required = false }: { required?: boolean } = $props();
|
|||||||
type="password"
|
type="password"
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
required={required}
|
required={required}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ let { required = false }: { required?: boolean } = $props();
|
|||||||
type="password"
|
type="password"
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
required={required}
|
required={required}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="text"
|
type="text"
|
||||||
name="firstName"
|
name="firstName"
|
||||||
value={firstName}
|
value={firstName}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="text"
|
type="text"
|
||||||
name="lastName"
|
name="lastName"
|
||||||
value={lastName}
|
value={lastName}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,7 +63,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
placeholder="TT.MM.JJJJ"
|
placeholder="TT.MM.JJJJ"
|
||||||
value={birthDateDisplay}
|
value={birthDateDisplay}
|
||||||
oninput={handleBirthDateInput}
|
oninput={handleBirthDateInput}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<input type="hidden" name="birthDate" value={birthDateIso} />
|
<input type="hidden" name="birthDate" value={birthDateIso} />
|
||||||
</label>
|
</label>
|
||||||
@@ -76,7 +76,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
value={email}
|
value={email}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
name="contact"
|
name="contact"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder={m.profile_contact_placeholder()}
|
placeholder={m.profile_contact_placeholder()}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{contact}</textarea
|
>{contact}</textarea
|
||||||
>
|
>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
<nav class="hidden items-stretch lg:flex lg:space-x-1">
|
<nav class="hidden items-stretch lg:flex lg:space-x-1">
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-accent
|
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-focus-ring
|
||||||
{page.url.pathname === '/' || page.url.pathname.startsWith('/documents')
|
{page.url.pathname === '/' || page.url.pathname.startsWith('/documents')
|
||||||
? 'border-b-2 border-accent text-white'
|
? 'border-b-2 border-accent text-white'
|
||||||
: 'text-white/70 hover:text-white'}"
|
: 'text-white/70 hover:text-white'}"
|
||||||
@@ -51,7 +51,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href="/persons"
|
href="/persons"
|
||||||
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-accent
|
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-focus-ring
|
||||||
{page.url.pathname.startsWith('/persons')
|
{page.url.pathname.startsWith('/persons')
|
||||||
? 'border-b-2 border-accent text-white'
|
? 'border-b-2 border-accent text-white'
|
||||||
: 'text-white/70 hover:text-white'}"
|
: 'text-white/70 hover:text-white'}"
|
||||||
@@ -61,7 +61,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href="/korrespondenz"
|
href="/korrespondenz"
|
||||||
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-accent
|
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-focus-ring
|
||||||
{page.url.pathname.startsWith('/korrespondenz')
|
{page.url.pathname.startsWith('/korrespondenz')
|
||||||
? 'border-b-2 border-accent text-white'
|
? 'border-b-2 border-accent text-white'
|
||||||
: 'text-white/70 hover:text-white'}"
|
: 'text-white/70 hover:text-white'}"
|
||||||
@@ -71,7 +71,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
{#if isAdmin}
|
{#if isAdmin}
|
||||||
<a
|
<a
|
||||||
href="/admin"
|
href="/admin"
|
||||||
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-accent
|
class="my-2 inline-flex items-center px-3 font-sans text-xs font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-focus-ring
|
||||||
{page.url.pathname.startsWith('/admin')
|
{page.url.pathname.startsWith('/admin')
|
||||||
? 'border-b-2 border-accent text-white'
|
? 'border-b-2 border-accent text-white'
|
||||||
: 'text-white/70 hover:text-white'}"
|
: 'text-white/70 hover:text-white'}"
|
||||||
@@ -83,7 +83,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
|
|
||||||
<!-- Hamburger toggle (mobile only) -->
|
<!-- Hamburger toggle (mobile only) -->
|
||||||
<button
|
<button
|
||||||
class="ml-auto flex h-11 w-11 items-center justify-center self-center rounded text-white/70 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-accent lg:hidden"
|
class="ml-auto flex h-11 w-11 items-center justify-center self-center rounded text-white/70 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring lg:hidden"
|
||||||
aria-label={mobileNavOpen ? 'Menü schließen' : 'Menü öffnen'}
|
aria-label={mobileNavOpen ? 'Menü schließen' : 'Menü öffnen'}
|
||||||
aria-expanded={mobileNavOpen}
|
aria-expanded={mobileNavOpen}
|
||||||
aria-controls="mobile-nav"
|
aria-controls="mobile-nav"
|
||||||
@@ -142,7 +142,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
<nav id="mobile-nav">
|
<nav id="mobile-nav">
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset
|
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset
|
||||||
{page.url.pathname === '/' || page.url.pathname.startsWith('/documents')
|
{page.url.pathname === '/' || page.url.pathname.startsWith('/documents')
|
||||||
? 'bg-accent-bg text-ink'
|
? 'bg-accent-bg text-ink'
|
||||||
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
||||||
@@ -152,7 +152,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href="/persons"
|
href="/persons"
|
||||||
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset
|
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset
|
||||||
{page.url.pathname.startsWith('/persons')
|
{page.url.pathname.startsWith('/persons')
|
||||||
? 'bg-accent-bg text-ink'
|
? 'bg-accent-bg text-ink'
|
||||||
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
||||||
@@ -162,7 +162,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href="/korrespondenz"
|
href="/korrespondenz"
|
||||||
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset
|
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset
|
||||||
{page.url.pathname.startsWith('/korrespondenz')
|
{page.url.pathname.startsWith('/korrespondenz')
|
||||||
? 'bg-accent-bg text-ink'
|
? 'bg-accent-bg text-ink'
|
||||||
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
||||||
@@ -173,7 +173,7 @@ function handleOverlayKeydown(event: KeyboardEvent) {
|
|||||||
{#if isAdmin}
|
{#if isAdmin}
|
||||||
<a
|
<a
|
||||||
href="/admin"
|
href="/admin"
|
||||||
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset
|
class="block flex min-h-[44px] w-full items-center px-4 py-3 font-sans text-sm font-bold tracking-widest uppercase transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset
|
||||||
{page.url.pathname.startsWith('/admin')
|
{page.url.pathname.startsWith('/admin')
|
||||||
? 'bg-accent-bg text-ink'
|
? 'bg-accent-bg text-ink'
|
||||||
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
: 'text-ink-2 hover:bg-muted hover:text-ink'}"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ let {
|
|||||||
onblur={onblur}
|
onblur={onblur}
|
||||||
aria-label={m.docs_search_placeholder()}
|
aria-label={m.docs_search_placeholder()}
|
||||||
placeholder={m.docs_search_placeholder()}
|
placeholder={m.docs_search_placeholder()}
|
||||||
class="block w-full border-line py-2.5 pr-10 pl-3 placeholder-ink-3 shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full border-line py-2.5 pr-10 pl-3 placeholder-ink-3 shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ function clickOutside(node: HTMLElement) {
|
|||||||
aria-expanded={userMenuOpen}
|
aria-expanded={userMenuOpen}
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
onclick={() => (userMenuOpen = !userMenuOpen)}
|
onclick={() => (userMenuOpen = !userMenuOpen)}
|
||||||
class="flex h-8 w-8 items-center justify-center rounded-full bg-white font-sans text-xs font-bold text-brand-navy transition-opacity hover:opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
class="flex h-8 w-8 items-center justify-center rounded-full bg-white font-sans text-xs font-bold text-brand-navy transition-opacity hover:opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
{userInitials}
|
{userInitials}
|
||||||
</button>
|
</button>
|
||||||
@@ -44,7 +44,7 @@ function clickOutside(node: HTMLElement) {
|
|||||||
aria-expanded={userMenuOpen}
|
aria-expanded={userMenuOpen}
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
onclick={() => (userMenuOpen = !userMenuOpen)}
|
onclick={() => (userMenuOpen = !userMenuOpen)}
|
||||||
class="group rounded-sm p-2 transition-colors hover:bg-white/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
class="group rounded-sm p-2 transition-colors hover:bg-white/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="/degruyter-icons/Simple/Small-16px/SVG/Action/Account-SM.svg"
|
src="/degruyter-icons/Simple/Small-16px/SVG/Action/Account-SM.svg"
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ const ADMIN_PERMISSIONS = $derived([
|
|||||||
name="name"
|
name="name"
|
||||||
value={data.group.name}
|
value={data.group.name}
|
||||||
required
|
required
|
||||||
class="bg-background w-full rounded-sm border border-line px-3 py-2 font-sans text-sm text-ink placeholder:text-ink-3 focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none"
|
class="bg-background w-full rounded-sm border border-line px-3 py-2 font-sans text-sm text-ink placeholder:text-ink-3 focus:border-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ const ADMIN_PERMISSIONS = $derived([
|
|||||||
name="permissions"
|
name="permissions"
|
||||||
value={perm.value}
|
value={perm.value}
|
||||||
checked={data.group.permissions.includes(perm.value)}
|
checked={data.group.permissions.includes(perm.value)}
|
||||||
class="h-4 w-4 rounded border-line text-primary focus:ring-primary"
|
class="h-4 w-4 rounded border-line text-primary focus:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
{perm.label}
|
{perm.label}
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ beforeNavigate(({ cancel, to }) => {
|
|||||||
name="name"
|
name="name"
|
||||||
placeholder={m.admin_group_name_placeholder()}
|
placeholder={m.admin_group_name_placeholder()}
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line bg-surface px-3 py-2 text-sm text-ink placeholder:text-ink-3 focus:ring-1 focus:ring-primary focus:outline-none"
|
class="w-full rounded-sm border border-line bg-surface px-3 py-2 text-sm text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ beforeNavigate(({ cancel, to }) => {
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="permissions"
|
name="permissions"
|
||||||
value={perm.value}
|
value={perm.value}
|
||||||
class="rounded border-line text-primary focus:ring-primary"
|
class="rounded border-line text-primary focus:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<span class="font-mono text-xs font-bold uppercase">{perm.value}</span>
|
<span class="font-mono text-xs font-bold uppercase">{perm.value}</span>
|
||||||
<span class="text-ink-3">— {perm.label}</span>
|
<span class="text-ink-3">— {perm.label}</span>
|
||||||
@@ -146,7 +146,7 @@ beforeNavigate(({ cancel, to }) => {
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="permissions"
|
name="permissions"
|
||||||
value={perm.value}
|
value={perm.value}
|
||||||
class="rounded border-line text-primary focus:ring-primary"
|
class="rounded border-line text-primary focus:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<span class="font-mono text-xs font-bold uppercase">{perm.value}</span>
|
<span class="font-mono text-xs font-bold uppercase">{perm.value}</span>
|
||||||
<span class="font-normal text-ink-3">— {perm.label}</span>
|
<span class="font-normal text-ink-3">— {perm.label}</span>
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ $effect(() => {
|
|||||||
name="name"
|
name="name"
|
||||||
value={data.tag.name}
|
value={data.tag.name}
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line bg-surface px-3 py-2 text-sm text-ink focus:ring-1 focus:ring-primary focus:outline-none"
|
class="w-full rounded-sm border border-line bg-surface px-3 py-2 text-sm text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const filtered = $derived(
|
|||||||
type="search"
|
type="search"
|
||||||
bind:value={searchQuery}
|
bind:value={searchQuery}
|
||||||
placeholder={m.admin_users_search_placeholder()}
|
placeholder={m.admin_users_search_placeholder()}
|
||||||
class="w-full rounded-sm border border-line bg-surface px-2 py-1.5 text-sm text-ink placeholder:text-ink-3 focus:ring-1 focus:ring-primary focus:outline-none"
|
class="w-full rounded-sm border border-line bg-surface px-2 py-1.5 text-sm text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { m } from '$lib/paraglide/messages.js';
|
|||||||
type="text"
|
type="text"
|
||||||
name="username"
|
name="username"
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -26,6 +26,6 @@ import { m } from '$lib/paraglide/messages.js';
|
|||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ let {
|
|||||||
<div class="mb-6 grid grid-cols-1 items-end gap-4 md:grid-cols-[1fr_auto_1fr] md:gap-6">
|
<div class="mb-6 grid grid-cols-1 items-end gap-4 md:grid-cols-[1fr_auto_1fr] md:gap-6">
|
||||||
<!-- Sender -->
|
<!-- Sender -->
|
||||||
<div
|
<div
|
||||||
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_input]:focus:border-ink [&_input]:focus:ring-ink [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
||||||
>
|
>
|
||||||
<PersonTypeahead
|
<PersonTypeahead
|
||||||
name="senderId"
|
name="senderId"
|
||||||
@@ -73,7 +73,7 @@ let {
|
|||||||
|
|
||||||
<!-- Receiver -->
|
<!-- Receiver -->
|
||||||
<div
|
<div
|
||||||
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_input]:focus:border-ink [&_input]:focus:ring-ink [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
||||||
>
|
>
|
||||||
<PersonTypeahead
|
<PersonTypeahead
|
||||||
name="receiverId"
|
name="receiverId"
|
||||||
@@ -99,7 +99,7 @@ let {
|
|||||||
type="date"
|
type="date"
|
||||||
bind:value={fromDate}
|
bind:value={fromDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
class="block w-full border-line py-2.5 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full border-line py-2.5 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ let {
|
|||||||
type="date"
|
type="date"
|
||||||
bind:value={toDate}
|
bind:value={toDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
class="block w-full border-line py-2.5 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full border-line py-2.5 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ $effect(() => {
|
|||||||
titleOverride = (e.target as HTMLInputElement).value;
|
titleOverride = (e.target as HTMLInputElement).value;
|
||||||
titleDirty = true;
|
titleDirty = true;
|
||||||
}}
|
}}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
placeholder="Titel eingeben…"
|
placeholder="Titel eingeben…"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ let { form }: { form?: { error?: string; success?: boolean } } = $props();
|
|||||||
id="email"
|
id="email"
|
||||||
required
|
required
|
||||||
autocomplete="email"
|
autocomplete="email"
|
||||||
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ let {
|
|||||||
<div class="mb-6 grid grid-cols-1 items-end gap-4 md:grid-cols-[1fr_auto_1fr] md:gap-6">
|
<div class="mb-6 grid grid-cols-1 items-end gap-4 md:grid-cols-[1fr_auto_1fr] md:gap-6">
|
||||||
<!-- Sender -->
|
<!-- Sender -->
|
||||||
<div
|
<div
|
||||||
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_input]:focus:border-ink [&_input]:focus:ring-ink [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
||||||
>
|
>
|
||||||
<PersonTypeahead
|
<PersonTypeahead
|
||||||
name="senderId"
|
name="senderId"
|
||||||
@@ -73,7 +73,7 @@ let {
|
|||||||
|
|
||||||
<!-- Receiver -->
|
<!-- Receiver -->
|
||||||
<div
|
<div
|
||||||
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_input]:focus:border-ink [&_input]:focus:ring-ink [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
class="relative z-30 [&_input]:border-line [&_input]:py-2.5 [&_label]:mb-2 [&_label]:text-xs [&_label]:font-bold [&_label]:tracking-widest [&_label]:text-ink-2 [&_label]:uppercase"
|
||||||
>
|
>
|
||||||
<PersonTypeahead
|
<PersonTypeahead
|
||||||
name="receiverId"
|
name="receiverId"
|
||||||
@@ -99,7 +99,7 @@ let {
|
|||||||
type="date"
|
type="date"
|
||||||
bind:value={fromDate}
|
bind:value={fromDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
class="block w-full border-line py-2.5 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full border-line py-2.5 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ let {
|
|||||||
type="date"
|
type="date"
|
||||||
bind:value={toDate}
|
bind:value={toDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
class="block w-full border-line py-2.5 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full border-line py-2.5 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function getInitials(person: Correspondent): string {
|
|||||||
role="option"
|
role="option"
|
||||||
aria-selected="false"
|
aria-selected="false"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="flex cursor-pointer items-center gap-2 px-3 py-2 text-sm text-ink hover:bg-muted focus:bg-muted focus:outline-none"
|
class="flex cursor-pointer items-center gap-2 px-3 py-2 text-sm text-ink hover:bg-muted focus:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset"
|
||||||
onclick={() => onselect(person.id)}
|
onclick={() => onselect(person.id)}
|
||||||
onkeydown={(e) => e.key === 'Enter' && onselect(person.id)}
|
onkeydown={(e) => e.key === 'Enter' && onselect(person.id)}
|
||||||
>
|
>
|
||||||
@@ -103,7 +103,7 @@ function getInitials(person: Correspondent): string {
|
|||||||
role="option"
|
role="option"
|
||||||
aria-selected="false"
|
aria-selected="false"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="flex cursor-pointer items-center gap-2 px-3 py-2 text-sm text-ink hover:bg-muted focus:bg-muted focus:outline-none"
|
class="flex cursor-pointer items-center gap-2 px-3 py-2 text-sm text-ink hover:bg-muted focus:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-inset"
|
||||||
onclick={() => onselect('')}
|
onclick={() => onselect('')}
|
||||||
onkeydown={(e) => e.key === 'Enter' && onselect('')}
|
onkeydown={(e) => e.key === 'Enter' && onselect('')}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ let isActive = $derived(!!(fromDate || toDate || sortDir !== 'DESC'));
|
|||||||
bind:value={fromDate}
|
bind:value={fromDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
placeholder={m.conv_strip_from_placeholder()}
|
placeholder={m.conv_strip_from_placeholder()}
|
||||||
class="h-8 w-[100px] rounded border bg-surface px-2 text-xs text-ink focus:outline-none {fromDate ? 'border-primary' : 'border-line'}"
|
class="h-8 w-[100px] rounded border bg-surface px-2 text-xs text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring {fromDate ? 'border-primary' : 'border-line'}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span class="text-xs text-ink-3">–</span>
|
<span class="text-xs text-ink-3">–</span>
|
||||||
@@ -52,7 +52,7 @@ let isActive = $derived(!!(fromDate || toDate || sortDir !== 'DESC'));
|
|||||||
bind:value={toDate}
|
bind:value={toDate}
|
||||||
onchange={() => onapplyFilters()}
|
onchange={() => onapplyFilters()}
|
||||||
placeholder={m.conv_strip_to_placeholder()}
|
placeholder={m.conv_strip_to_placeholder()}
|
||||||
class="h-8 w-[100px] rounded border bg-surface px-2 text-xs text-ink focus:outline-none {toDate ? 'border-primary' : 'border-line'}"
|
class="h-8 w-[100px] rounded border bg-surface px-2 text-xs text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring {toDate ? 'border-primary' : 'border-line'}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Document count -->
|
<!-- Document count -->
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
/* Header surface — independent from canvas/surface for per-mode control */
|
/* Header surface — independent from canvas/surface for per-mode control */
|
||||||
--color-header: var(--c-header);
|
--color-header: var(--c-header);
|
||||||
|
|
||||||
|
/* Focus ring — keyboard focus indicator, mode-aware (navy in light, mint in dark) */
|
||||||
|
--color-focus-ring: var(--c-focus-ring);
|
||||||
|
|
||||||
/* Static brand tokens (not themed) */
|
/* Static brand tokens (not themed) */
|
||||||
--color-brand-navy: var(--palette-navy);
|
--color-brand-navy: var(--palette-navy);
|
||||||
--color-brand-mint: var(--palette-mint);
|
--color-brand-mint: var(--palette-mint);
|
||||||
@@ -87,6 +90,9 @@
|
|||||||
/* Header is brand-navy in light mode; same in dark mode for contrast compliance */
|
/* Header is brand-navy in light mode; same in dark mode for contrast compliance */
|
||||||
--c-header: #012851;
|
--c-header: #012851;
|
||||||
|
|
||||||
|
/* Focus ring: brand-navy in light mode — 14:1 on white, ~11:1 on sand */
|
||||||
|
--c-focus-ring: #012851;
|
||||||
|
|
||||||
--c-pdf-bg: #ebebeb;
|
--c-pdf-bg: #ebebeb;
|
||||||
--c-pdf-ctrl: #d8d8d8;
|
--c-pdf-ctrl: #d8d8d8;
|
||||||
--c-pdf-text: #333333;
|
--c-pdf-text: #333333;
|
||||||
@@ -123,6 +129,9 @@
|
|||||||
/* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */
|
/* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */
|
||||||
--c-header: #012851;
|
--c-header: #012851;
|
||||||
|
|
||||||
|
/* Focus ring: brand-mint in dark mode — 9.2:1 on canvas, 7.1:1 on surface */
|
||||||
|
--c-focus-ring: #a1dcd8;
|
||||||
|
|
||||||
--c-pdf-bg: #010e1e;
|
--c-pdf-bg: #010e1e;
|
||||||
--c-pdf-ctrl: #011526;
|
--c-pdf-ctrl: #011526;
|
||||||
--c-pdf-text: #f0efe9;
|
--c-pdf-text: #f0efe9;
|
||||||
@@ -155,6 +164,9 @@
|
|||||||
/* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */
|
/* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */
|
||||||
--c-header: #012851;
|
--c-header: #012851;
|
||||||
|
|
||||||
|
/* Focus ring: brand-mint in dark mode — 9.2:1 on canvas, 7.1:1 on surface */
|
||||||
|
--c-focus-ring: #a1dcd8;
|
||||||
|
|
||||||
--c-pdf-bg: #010e1e;
|
--c-pdf-bg: #010e1e;
|
||||||
--c-pdf-ctrl: #011526;
|
--c-pdf-ctrl: #011526;
|
||||||
--c-pdf-text: #f0efe9;
|
--c-pdf-text: #f0efe9;
|
||||||
@@ -232,4 +244,17 @@
|
|||||||
text-decoration-thickness: 2px;
|
text-decoration-thickness: 2px;
|
||||||
text-underline-offset: 4px;
|
text-underline-offset: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fallback focus ring for any interactive element not styled with ring-focus-ring */
|
||||||
|
:focus-visible {
|
||||||
|
outline: 2px solid var(--c-focus-ring);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure focus rings are visible in Windows High Contrast / forced-colors mode */
|
||||||
|
@media (forced-colors: active) {
|
||||||
|
:focus-visible {
|
||||||
|
outline: 3px solid ButtonText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ let { form }: { form?: { error?: string; success?: boolean } } = $props();
|
|||||||
id="username"
|
id="username"
|
||||||
required
|
required
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ let { form }: { form?: { error?: string; success?: boolean } } = $props();
|
|||||||
id="password"
|
id="password"
|
||||||
required
|
required
|
||||||
autocomplete="current-password"
|
autocomplete="current-password"
|
||||||
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ function typeBadgeLabel(type: NotificationItem['type']): string {
|
|||||||
aria-checked={activeType === null && activeReadFilter === null}
|
aria-checked={activeType === null && activeReadFilter === null}
|
||||||
onclick={() => setFilter({ type: null, read: null })}
|
onclick={() => setFilter({ type: null, read: null })}
|
||||||
class={[
|
class={[
|
||||||
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2',
|
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
|
||||||
activeType === null && activeReadFilter === null
|
activeType === null && activeReadFilter === null
|
||||||
? 'bg-primary text-primary-fg'
|
? 'bg-primary text-primary-fg'
|
||||||
: 'bg-muted text-ink'
|
: 'bg-muted text-ink'
|
||||||
@@ -126,7 +126,7 @@ function typeBadgeLabel(type: NotificationItem['type']): string {
|
|||||||
aria-checked={activeReadFilter === 'false'}
|
aria-checked={activeReadFilter === 'false'}
|
||||||
onclick={() => setFilter({ read: 'false', type: null })}
|
onclick={() => setFilter({ read: 'false', type: null })}
|
||||||
class={[
|
class={[
|
||||||
'inline-flex items-center gap-1.5 rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2',
|
'inline-flex items-center gap-1.5 rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
|
||||||
activeReadFilter === 'false'
|
activeReadFilter === 'false'
|
||||||
? 'bg-primary text-primary-fg'
|
? 'bg-primary text-primary-fg'
|
||||||
: 'bg-muted text-ink'
|
: 'bg-muted text-ink'
|
||||||
@@ -149,7 +149,7 @@ function typeBadgeLabel(type: NotificationItem['type']): string {
|
|||||||
aria-checked={activeType === 'MENTION'}
|
aria-checked={activeType === 'MENTION'}
|
||||||
onclick={() => setFilter({ type: 'MENTION', read: null })}
|
onclick={() => setFilter({ type: 'MENTION', read: null })}
|
||||||
class={[
|
class={[
|
||||||
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2',
|
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
|
||||||
activeType === 'MENTION'
|
activeType === 'MENTION'
|
||||||
? 'bg-primary text-primary-fg'
|
? 'bg-primary text-primary-fg'
|
||||||
: 'bg-muted text-ink'
|
: 'bg-muted text-ink'
|
||||||
@@ -164,7 +164,7 @@ function typeBadgeLabel(type: NotificationItem['type']): string {
|
|||||||
aria-checked={activeType === 'REPLY'}
|
aria-checked={activeType === 'REPLY'}
|
||||||
onclick={() => setFilter({ type: 'REPLY', read: null })}
|
onclick={() => setFilter({ type: 'REPLY', read: null })}
|
||||||
class={[
|
class={[
|
||||||
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2',
|
'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
|
||||||
activeType === 'REPLY'
|
activeType === 'REPLY'
|
||||||
? 'bg-primary text-primary-fg'
|
? 'bg-primary text-primary-fg'
|
||||||
: 'bg-muted text-ink'
|
: 'bg-muted text-ink'
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function handleSearch() {
|
|||||||
oninput={handleSearch}
|
oninput={handleSearch}
|
||||||
onfocus={() => (qFocused = true)}
|
onfocus={() => (qFocused = true)}
|
||||||
onblur={() => (qFocused = false)}
|
onblur={() => (qFocused = false)}
|
||||||
class="block w-56 rounded-sm border border-line bg-surface py-2.5 pr-10 pl-4 font-sans text-sm text-ink placeholder-ink-3 shadow-sm focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-56 rounded-sm border border-line bg-surface py-2.5 pr-10 pl-4 font-sans text-sm text-ink placeholder-ink-3 shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-ink-3"
|
class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-ink-3"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ let {
|
|||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
value={person.firstName}
|
value={person.firstName}
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -39,7 +39,7 @@ let {
|
|||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
value={person.lastName}
|
value={person.lastName}
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-2">
|
<div class="md:col-span-2">
|
||||||
@@ -51,7 +51,7 @@ let {
|
|||||||
name="alias"
|
name="alias"
|
||||||
type="text"
|
type="text"
|
||||||
value={person.alias ?? ''}
|
value={person.alias ?? ''}
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -66,7 +66,7 @@ let {
|
|||||||
max="2100"
|
max="2100"
|
||||||
placeholder={m.person_placeholder_year()}
|
placeholder={m.person_placeholder_year()}
|
||||||
value={person.birthYear ?? ''}
|
value={person.birthYear ?? ''}
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -81,7 +81,7 @@ let {
|
|||||||
max="2100"
|
max="2100"
|
||||||
placeholder={m.person_placeholder_year()}
|
placeholder={m.person_placeholder_year()}
|
||||||
value={person.deathYear ?? ''}
|
value={person.deathYear ?? ''}
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-2">
|
<div class="md:col-span-2">
|
||||||
@@ -93,7 +93,7 @@ let {
|
|||||||
name="notes"
|
name="notes"
|
||||||
rows="4"
|
rows="4"
|
||||||
placeholder={m.person_placeholder_notes()}
|
placeholder={m.person_placeholder_notes()}
|
||||||
class="block w-full resize-y rounded border border-line px-3 py-2 font-serif text-ink focus:border-ink focus:outline-none"
|
class="block w-full resize-y rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{person.notes ?? ''}</textarea
|
>{person.notes ?? ''}</textarea
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ let { form } = $props();
|
|||||||
name="firstName"
|
name="firstName"
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ let { form } = $props();
|
|||||||
name="lastName"
|
name="lastName"
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ let { form } = $props();
|
|||||||
name="alias"
|
name="alias"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={m.form_placeholder_alias()}
|
placeholder={m.form_placeholder_alias()}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ let { form } = $props();
|
|||||||
min="1"
|
min="1"
|
||||||
max="2100"
|
max="2100"
|
||||||
placeholder={m.person_placeholder_year()}
|
placeholder={m.person_placeholder_year()}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ let { form } = $props();
|
|||||||
min="1"
|
min="1"
|
||||||
max="2100"
|
max="2100"
|
||||||
placeholder={m.person_placeholder_year()}
|
placeholder={m.person_placeholder_year()}
|
||||||
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ let { form } = $props();
|
|||||||
name="notes"
|
name="notes"
|
||||||
rows="4"
|
rows="4"
|
||||||
placeholder={m.person_placeholder_notes()}
|
placeholder={m.person_placeholder_notes()}
|
||||||
class="block w-full resize-y rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
class="block w-full resize-y rounded border border-line p-2 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ let {
|
|||||||
type="password"
|
type="password"
|
||||||
name="currentPassword"
|
name="currentPassword"
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ let {
|
|||||||
type="password"
|
type="password"
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ let {
|
|||||||
type="password"
|
type="password"
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
required
|
required
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="text"
|
type="text"
|
||||||
name="firstName"
|
name="firstName"
|
||||||
value={user?.firstName ?? ''}
|
value={user?.firstName ?? ''}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="text"
|
type="text"
|
||||||
name="lastName"
|
name="lastName"
|
||||||
value={user?.lastName ?? ''}
|
value={user?.lastName ?? ''}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
placeholder="TT.MM.JJJJ"
|
placeholder="TT.MM.JJJJ"
|
||||||
value={birthDateDisplay}
|
value={birthDateDisplay}
|
||||||
oninput={handleBirthDateInput}
|
oninput={handleBirthDateInput}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
<input type="hidden" name="birthDate" value={birthDateIso} />
|
<input type="hidden" name="birthDate" value={birthDateIso} />
|
||||||
</label>
|
</label>
|
||||||
@@ -95,7 +95,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
value={user?.email ?? ''}
|
value={user?.email ?? ''}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ function handleBirthDateInput(e: Event) {
|
|||||||
name="contact"
|
name="contact"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder={m.profile_contact_placeholder()}
|
placeholder={m.profile_contact_placeholder()}
|
||||||
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:border-ink focus:outline-none"
|
class="w-full rounded-sm border border-line px-3 py-2 font-serif text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{user?.contact ?? ''}</textarea
|
>{user?.contact ?? ''}</textarea
|
||||||
>
|
>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ let {
|
|||||||
id="newPassword"
|
id="newPassword"
|
||||||
required
|
required
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ let {
|
|||||||
id="confirmPassword"
|
id="confirmPassword"
|
||||||
required
|
required
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:border-ink focus:ring-1 focus:ring-ink focus:outline-none"
|
class="block w-full border border-line px-3 py-2.5 font-serif text-sm text-ink placeholder-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user