Refactor/reacrhitecture to fsd+ #49
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+16
-23
@@ -1,5 +1,6 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "tw-animate-css";
|
@import "tw-animate-css";
|
||||||
|
@import "./fonts.css";
|
||||||
|
|
||||||
@variant dark (&:where(.dark, .dark *));
|
@variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
@@ -216,9 +217,7 @@
|
|||||||
/* Monospace label tracking — used in Loader and Footnote */
|
/* Monospace label tracking — used in Loader and Footnote */
|
||||||
--tracking-wider-mono: 0.2em;
|
--tracking-wider-mono: 0.2em;
|
||||||
|
|
||||||
/* ============================================
|
/* Shadow tokens */
|
||||||
SHADOW TOKENS
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Default resting shadow — equivalent to Tailwind's shadow-sm. Used on
|
/* Default resting shadow — equivalent to Tailwind's shadow-sm. Used on
|
||||||
buttons, sliders, popover triggers in non-floating state. */
|
buttons, sliders, popover triggers in non-floating state. */
|
||||||
@@ -245,9 +244,7 @@
|
|||||||
/* Drawer / overlay shadow — full-strength shadow-2xl. */
|
/* Drawer / overlay shadow — full-strength shadow-2xl. */
|
||||||
--shadow-overlay: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
--shadow-overlay: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||||||
|
|
||||||
/* ============================================
|
/* Motion tokens */
|
||||||
MOTION TOKENS
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
--duration-fast: 150ms;
|
--duration-fast: 150ms;
|
||||||
--duration-normal: 200ms;
|
--duration-normal: 200ms;
|
||||||
@@ -274,7 +271,7 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
font-family: "Karla", system-ui, -apple-system, "Segoe UI", Inter, Roboto, Arial, sans-serif;
|
font-family: var(--font-secondary);
|
||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,9 +322,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* Design-system utilities.
|
||||||
DESIGN-SYSTEM UTILITIES
|
|
||||||
============================================
|
|
||||||
Defined via `@utility` (Tailwind v4) so they integrate with the variant
|
Defined via `@utility` (Tailwind v4) so they integrate with the variant
|
||||||
system (`hover:`, `dark:`, breakpoints) and don't rely on `@apply`
|
system (`hover:`, `dark:`, breakpoints) and don't rely on `@apply`
|
||||||
chains. Colors reference the mode-switching semantic vars defined in
|
chains. Colors reference the mode-switching semantic vars defined in
|
||||||
@@ -362,7 +357,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Surface utilities ────────────────────────────────────────── */
|
/* Surface utilities */
|
||||||
|
|
||||||
@utility surface-canvas {
|
@utility surface-canvas {
|
||||||
background-color: var(--color-surface);
|
background-color: var(--color-surface);
|
||||||
@@ -391,7 +386,7 @@
|
|||||||
border: 1px solid var(--color-border-subtle);
|
border: 1px solid var(--color-border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Shape / layout ───────────────────────────────────────────── */
|
/* Shape / layout */
|
||||||
|
|
||||||
@utility flex-center {
|
@utility flex-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -422,7 +417,7 @@
|
|||||||
background-size: 10px 10px;
|
background-size: 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Typography ───────────────────────────────────────────────── */
|
/* Typography */
|
||||||
|
|
||||||
@utility text-label-mono {
|
@utility text-label-mono {
|
||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
@@ -431,7 +426,7 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global utility - useful across your app */
|
/* Honor prefers-reduced-motion: collapse animation and transition timing. */
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
* {
|
* {
|
||||||
animation-duration: 0.01ms !important;
|
animation-duration: 0.01ms !important;
|
||||||
@@ -440,12 +435,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Performance optimization for collapsible elements */
|
/* Hint the upcoming height animation on open collapsibles. */
|
||||||
[data-state="open"] {
|
[data-state="open"] {
|
||||||
will-change: height;
|
will-change: height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth focus transitions - good globally */
|
/* Transition siblings of a focus-visible peer. */
|
||||||
.peer:focus-visible ~ * {
|
.peer:focus-visible ~ * {
|
||||||
transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
@@ -472,11 +467,9 @@
|
|||||||
animation: nudge 10s ease-in-out infinite;
|
animation: nudge 10s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* Scrollbar styling */
|
||||||
SCROLLBAR STYLES
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* ---- Modern API: color + width (Chrome 121+, FF 64+) ---- */
|
/* Standard API: color + width (Chrome 121+, Firefox 64+). */
|
||||||
@supports (scrollbar-width: auto) {
|
@supports (scrollbar-width: auto) {
|
||||||
* {
|
* {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
@@ -488,8 +481,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- Webkit layer: runs ON TOP in Chrome, standalone in old Safari ---- */
|
/* WebKit fallback: applies on top of the standard API in Chrome, standalone in
|
||||||
/* Handles things scrollbar-width can't: hiding buttons, exact sizing */
|
older Safari. Covers what scrollbar-width can't — hiding buttons, exact sizing. */
|
||||||
@supports selector(::-webkit-scrollbar) {
|
@supports selector(::-webkit-scrollbar) {
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
@@ -497,7 +490,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-button {
|
::-webkit-scrollbar-button {
|
||||||
display: none; /* kills arrows */
|
display: none; /* hide scrollbar buttons */
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Self-hosted interface fonts (latin subset only).
|
||||||
|
Vendored from @fontsource — see docs/interface-font-selfhost-benchmark.md.
|
||||||
|
Variable faces (Inter, Space Grotesk) keep their wght axis; Inter also keeps opsz.
|
||||||
|
url()s are resolved + content-hashed by Vite at build → immutable long-cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Inter — variable wght + opsz, the body/secondary UI font (--font-secondary) */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100 900;
|
||||||
|
src: url('../assets/fonts/inter-latin-opsz-normal.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter';
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100 900;
|
||||||
|
src: url('../assets/fonts/inter-latin-opsz-italic.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Space Grotesk — variable wght, the primary/display UI font (--font-primary) */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 300 700;
|
||||||
|
src: url('../assets/fonts/space-grotesk-latin-wght-normal.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Space Mono — static 400/700 × roman/italic (--font-mono) */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../assets/fonts/space-mono-latin-400-normal.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../assets/fonts/space-mono-latin-400-italic.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url('../assets/fonts/space-mono-latin-700-normal.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url('../assets/fonts/space-mono-latin-700-italic.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Syne — static 800, the logo font (--font-logo) */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Syne';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
src: url('../assets/fonts/syne-latin-800-normal.woff2') format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
Vendored
+5
@@ -38,6 +38,11 @@ declare module '*.jpg' {
|
|||||||
|
|
||||||
declare module '*.css';
|
declare module '*.css';
|
||||||
|
|
||||||
|
declare module '*.woff2?url' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
|
|||||||
+17
-24
@@ -9,6 +9,14 @@ import { ResponsiveProvider } from '$shared/lib';
|
|||||||
import { cn } from '$shared/lib';
|
import { cn } from '$shared/lib';
|
||||||
import { Footer } from '$widgets/Footer';
|
import { Footer } from '$widgets/Footer';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Preload the two render-critical interface faces (primary + secondary).
|
||||||
|
`?url` resolves to the content-hashed path Vite emits, so the binary is
|
||||||
|
fetched immediately rather than waiting for CSS @font-face discovery.
|
||||||
|
*/
|
||||||
|
import interWoff2 from '../assets/fonts/inter-latin-opsz-normal.woff2?url';
|
||||||
|
import spaceGroteskWoff2 from '../assets/fonts/space-grotesk-latin-wght-normal.woff2?url';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type Snippet,
|
type Snippet,
|
||||||
onDestroy,
|
onDestroy,
|
||||||
@@ -33,36 +41,21 @@ onDestroy(() => themeManager.destroy());
|
|||||||
<svelte:head>
|
<svelte:head>
|
||||||
<link rel="icon" href={G} type="image/svg+xml" />
|
<link rel="icon" href={G} type="image/svg+xml" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.fontshare.com" />
|
<!-- Self-hosted interface fonts (see src/app/styles/fonts/fonts.css). Preload the two critical faces. -->
|
||||||
<link
|
<link
|
||||||
rel="preconnect"
|
rel="preload"
|
||||||
href="https://cdn.fontshare.com"
|
as="font"
|
||||||
crossorigin="anonymous"
|
type="font/woff2"
|
||||||
/>
|
href={interWoff2}
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
||||||
<link
|
|
||||||
rel="preconnect"
|
|
||||||
href="https://fonts.gstatic.com"
|
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="preload"
|
rel="preload"
|
||||||
as="style"
|
as="font"
|
||||||
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Space+Grotesk:wght@300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&family=Syne:wght@800&display=swap"
|
type="font/woff2"
|
||||||
|
href={spaceGroteskWoff2}
|
||||||
|
crossorigin="anonymous"
|
||||||
/>
|
/>
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Space+Grotesk:wght@300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&family=Syne:wght@800&display=swap"
|
|
||||||
media="print"
|
|
||||||
onload={(e => ((e.currentTarget as HTMLLinkElement).media = 'all'))}
|
|
||||||
/>
|
|
||||||
<noscript>
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Space+Grotesk:wght@300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&family=Syne:wght@800&display=swap"
|
|
||||||
/>
|
|
||||||
</noscript>
|
|
||||||
<title>GlyphDiff | Typography & Typefaces</title>
|
<title>GlyphDiff | Typography & Typefaces</title>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
|
|||||||
Reference in New Issue
Block a user