diff --git a/apps/web/src/lib/styles/letterhead.css b/apps/web/src/lib/styles/letterhead.css new file mode 100644 index 0000000..54eebd0 --- /dev/null +++ b/apps/web/src/lib/styles/letterhead.css @@ -0,0 +1,203 @@ +/* The letterhead: palette, type, and control skin for the app's own pages + (admin, login). Mirrors the site theme (SiteLayout.svelte). Structural + layout stays with each page; this file owns the look of the paper and + everything written on it. */ + +.letterhead { + --paper: #f7f3ea; + --paper-sunk: #efe9dc; + --ink: #161d2b; + --muted: #6f6757; + --accent: #9c3218; + --accent-ink: #fdfbf6; + --rule: #e0d8c8; + --airmail-blue: #1c3f6e; + --warn: #7c2144; + --ok: #256c3f; + /* The stripe's pale bands stay paper-white in both schemes; on the dark + scheme's page color the pole stops reading as airmail. */ + --stripe-paper: #f7f3ea; + + --font-serif: 'Iowan Old Style', 'Hoefler Text', 'Palatino Linotype', Palatino, + 'Book Antiqua', Georgia, serif; + --font-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'Cascadia Mono', Menlo, Consolas, + monospace; + + background: var(--paper); + color: var(--ink); + font-family: var(--font-serif); + font-size: 1.05rem; + line-height: 1.6; + min-height: 100vh; + display: flex; + flex-direction: column; + background-image: repeating-linear-gradient( + 45deg, + color-mix(in srgb, var(--ink) 1.4%, transparent) 0 1px, + transparent 1px 4px + ); +} + +@media (prefers-color-scheme: dark) { + .letterhead { + --paper: #101520; + --paper-sunk: #161c29; + --ink: #e9e3d6; + --muted: #948b78; + --accent: #d4714f; + --accent-ink: #101520; + --rule: #242c3a; + --airmail-blue: #3a6ea8; + --warn: #e39aae; + --ok: #86c294; + } +} + +.letterhead .airmail { + height: 6px; + background: repeating-linear-gradient( + -45deg, + var(--accent) 0 10px, + var(--stripe-paper) 10px 20px, + var(--airmail-blue) 20px 30px, + var(--stripe-paper) 30px 40px + ); +} + +.letterhead .wordmark { + font-size: 1.15rem; + font-weight: 600; + letter-spacing: 0.01em; + color: var(--accent); + text-decoration: none; +} + +.letterhead h1 { + margin: 0 0 0.75rem; + font-size: 1.7rem; + font-weight: 600; + line-height: 1.2; + letter-spacing: -0.01em; + text-wrap: balance; +} + +.letterhead h2 { + margin: 2.25rem 0 0.75rem; + font-family: var(--font-mono); + font-size: 0.72rem; + font-weight: 500; + letter-spacing: 0.1em; + text-transform: uppercase; + color: color-mix(in srgb, var(--airmail-blue) 75%, var(--ink)); + border-bottom: 1px solid var(--rule); + padding-bottom: 0.4rem; +} + +.letterhead a { + color: var(--accent); + text-underline-offset: 0.18em; +} + +.letterhead code { + font-family: var(--font-mono); + font-size: 0.82em; + background: var(--paper-sunk); + border: 1px solid var(--rule); + border-radius: 2px; + padding: 0.05em 0.3em; + overflow-wrap: anywhere; +} + +.letterhead small, +.letterhead .meta { + color: var(--muted); + font-size: 0.88rem; +} + +.letterhead input:not([type='checkbox']), +.letterhead select, +.letterhead textarea { + box-sizing: border-box; + padding: 0.5rem 0.7rem; + font-family: var(--font-mono); + /* 16px floor: anything smaller makes iOS Safari zoom on focus. */ + font-size: 1rem; + color: var(--ink); + background: var(--paper); + border: 1px solid color-mix(in srgb, var(--muted) 80%, var(--rule)); + border-radius: 2px; +} + +.letterhead input::placeholder, +.letterhead textarea::placeholder { + color: var(--muted); + opacity: 1; +} + +.letterhead input[type='checkbox'] { + accent-color: var(--accent); + width: 1rem; + height: 1rem; +} + +.letterhead button, +.letterhead a.btn { + box-sizing: border-box; + padding: 0.5rem 1.1rem; + font-family: var(--font-mono); + font-size: 0.8rem; + letter-spacing: 0.04em; + color: var(--accent-ink); + background: var(--accent); + border: 1px solid var(--accent); + border-radius: 2px; + cursor: pointer; + transition: filter 160ms ease; +} + +.letterhead a.btn { + display: inline-block; + text-decoration: none; +} + +.letterhead button:hover, +.letterhead button:focus-visible, +.letterhead a.btn:hover, +.letterhead a.btn:focus-visible { + filter: brightness(1.12); +} + +.letterhead button.quiet { + color: var(--muted); + background: transparent; + border-color: color-mix(in srgb, var(--muted) 55%, var(--rule)); + transition: + color 160ms ease, + border-color 160ms ease; +} + +.letterhead button.quiet:hover, +.letterhead button.quiet:focus-visible { + filter: none; + color: var(--warn); + border-color: var(--warn); +} + +.letterhead .notice { + color: var(--ok); +} + +.letterhead .error, +.letterhead [role='alert'] { + color: var(--warn); +} + +.letterhead :focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +.letterhead ::selection { + background: var(--accent); + color: var(--accent-ink); +} diff --git a/apps/web/src/routes/admin/+layout.svelte b/apps/web/src/routes/admin/+layout.svelte index 58aab06..d9acfcb 100644 --- a/apps/web/src/routes/admin/+layout.svelte +++ b/apps/web/src/routes/admin/+layout.svelte @@ -1,5 +1,6 @@ -
+
@@ -35,67 +36,6 @@
diff --git a/apps/web/src/routes/login/+page.svelte b/apps/web/src/routes/login/+page.svelte index 5655005..03e196e 100644 --- a/apps/web/src/routes/login/+page.svelte +++ b/apps/web/src/routes/login/+page.svelte @@ -1,4 +1,5 @@