chore: scaffold Astro 5 project with token/style layer
- Astro 5 static config (trailing-slash canonical, i18n en-root/no-prefixed) - Tailwind 4 over CSS custom-property tokens (both themes via [data-theme]) - design tokens: colour/spacing/type/radius/motion per Phase 1 specs - motion layer with reduced-motion overrides - strict TypeScript, ESLint flat config, Prettier - self-hosted variable fonts (Space Grotesk / Inter / JetBrains Mono) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# Normalise line endings to LF in the repo; check out native on Windows.
|
||||
* text=auto eol=lf
|
||||
|
||||
# Binary assets — never touch.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.webp binary
|
||||
*.avif binary
|
||||
*.pdf binary
|
||||
*.woff binary
|
||||
*.woff2 binary
|
||||
*.ico binary
|
||||
|
||||
# Shell scripts and container files must stay LF even on Windows checkout.
|
||||
*.sh text eol=lf
|
||||
Dockerfile text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
@@ -0,0 +1,6 @@
|
||||
dist/
|
||||
.astro/
|
||||
node_modules/
|
||||
pnpm-lock.yaml
|
||||
public/
|
||||
*.pdf
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"trailingComma": "all",
|
||||
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
|
||||
"overrides": [{ "files": "*.astro", "options": { "parser": "astro" } }]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
// Canonical origin used for absolute URLs (sitemap, OG, hreflang, JSON-LD).
|
||||
// Overridable at build time so staging emits its own origin. See DOCKER_SPEC §3.
|
||||
const SITE = process.env.PUBLIC_SITE_URL ?? 'https://cesnimda.co.uk';
|
||||
|
||||
const r = (p) => fileURLToPath(new URL(p, import.meta.url));
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: SITE,
|
||||
// ROUTING_SPEC §1: trailing-slash canonical, directory output.
|
||||
trailingSlash: 'always',
|
||||
build: { format: 'directory', inlineStylesheets: 'auto' },
|
||||
// I18N_SPEC §1: en at root, no prefixed. Localised slugs are handled by explicit
|
||||
// page files + the slug map module (ARCHITECTURE A5), not automatic locale routing.
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'no'],
|
||||
routing: { prefixDefaultLocale: false, redirectToDefaultLocale: false },
|
||||
},
|
||||
prefetch: false,
|
||||
compressHTML: true,
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': r('./src'),
|
||||
'@i18n': r('./src/i18n'),
|
||||
'@components': r('./src/components'),
|
||||
'@layouts': r('./src/layouts'),
|
||||
'@styles': r('./src/styles'),
|
||||
'@scripts': r('./src/scripts'),
|
||||
'@lib': r('./src/lib'),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import astro from 'eslint-plugin-astro';
|
||||
|
||||
export default [
|
||||
{ ignores: ['dist/', '.astro/', 'node_modules/', '**/*.d.ts'] },
|
||||
js.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...astro.configs.recommended,
|
||||
{
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
// Behaviour modules run in the browser.
|
||||
files: ['src/scripts/**/*.ts'],
|
||||
languageOptions: { globals: { window: 'readonly', document: 'readonly', localStorage: 'readonly' } },
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "resumesite",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "Connor Babbington — bilingual portfolio (Astro static site)",
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.9",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"check": "astro check && tsc --noEmit",
|
||||
"lint": "eslint . && prettier --check .",
|
||||
"format": "prettier --write .",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource-variable/inter": "^5.1.1",
|
||||
"@fontsource-variable/jetbrains-mono": "^5.1.2",
|
||||
"@fontsource-variable/space-grotesk": "^5.1.1",
|
||||
"@resvg/resvg-js": "^2.6.2",
|
||||
"astro": "^5.2.5",
|
||||
"satori": "^0.12.1",
|
||||
"sharp": "^0.33.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.20.0",
|
||||
"@tailwindcss/vite": "^4.0.6",
|
||||
"@types/node": "^22.13.1",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint-plugin-astro": "^1.3.1",
|
||||
"typescript-eslint": "^8.24.0",
|
||||
"prettier": "^3.5.1",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.0.6",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.5"
|
||||
}
|
||||
}
|
||||
Generated
+6113
File diff suppressed because it is too large
Load Diff
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly PUBLIC_SITE_URL?: string;
|
||||
}
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/* Entry stylesheet. Order: Tailwind, tokens, theme mapping, base, motion. */
|
||||
@import 'tailwindcss';
|
||||
@import './tokens.css';
|
||||
@import './motion.css';
|
||||
|
||||
/*
|
||||
Map design tokens into Tailwind's theme namespaces with `inline` so generated
|
||||
utilities reference the live CSS variables — theme switching works at runtime
|
||||
without regenerating classes (ARCHITECTURE A4). Tailwind's default 0.25rem
|
||||
spacing scale already matches our 8pt grid, so no spacing override is needed.
|
||||
*/
|
||||
@theme inline {
|
||||
--color-surface-0: var(--surface-0);
|
||||
--color-surface-1: var(--surface-1);
|
||||
--color-surface-2: var(--surface-2);
|
||||
--color-ink: var(--ink);
|
||||
--color-ink-muted: var(--ink-muted);
|
||||
--color-ink-faint: var(--ink-faint);
|
||||
--color-line: var(--border);
|
||||
--color-line-strong: var(--border-strong);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-ink: var(--accent-ink);
|
||||
--color-amber: var(--amber);
|
||||
--color-danger: var(--danger);
|
||||
|
||||
--font-display: var(--font-display);
|
||||
--font-body: var(--font-body);
|
||||
--font-mono: var(--font-mono);
|
||||
|
||||
--text-display: var(--text-display);
|
||||
--text-h1: var(--text-h1);
|
||||
--text-h2: var(--text-h2);
|
||||
--text-h3: var(--text-h3);
|
||||
--text-h4: var(--text-h4);
|
||||
--text-body-lg: var(--text-body-lg);
|
||||
--text-body: var(--text-body);
|
||||
--text-small: var(--text-small);
|
||||
--text-mono-label: var(--text-mono-label);
|
||||
--text-mono-meta: var(--text-mono-meta);
|
||||
|
||||
--radius-xs: var(--radius-xs);
|
||||
--radius-sm: var(--radius-sm);
|
||||
--radius-md: var(--radius-md);
|
||||
--radius-lg: var(--radius-lg);
|
||||
--radius-full: var(--radius-full);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scroll-behavior: smooth;
|
||||
/* Anchor scroll offset = header + breathing room (SPACING_SYSTEM §6). */
|
||||
scroll-padding-top: calc(var(--header-h) + var(--space-5));
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: var(--surface-0);
|
||||
color: var(--ink);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-body);
|
||||
line-height: var(--leading-relaxed);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 600;
|
||||
line-height: var(--leading-snug);
|
||||
margin: 0;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img,
|
||||
svg,
|
||||
picture {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Visible focus in both themes (COLOUR_SYSTEM §5, TYPOGRAPHY §4). */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius-xs);
|
||||
}
|
||||
:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: var(--accent);
|
||||
color: var(--accent-ink);
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* Faint blueprint dot-grid — hero + section headers only (DESIGN_SYSTEM §4). */
|
||||
.dot-grid {
|
||||
background-image: radial-gradient(var(--dot-grid) 1px, transparent 1px);
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
|
||||
/* Single permitted gradient: hero accent halo (COLOUR_SYSTEM §4). */
|
||||
.hero-halo {
|
||||
background: radial-gradient(55% 55% at 28% 18%, var(--halo), transparent 70%);
|
||||
}
|
||||
|
||||
/* Mono metadata label — the identity voice (TYPOGRAPHY §2). */
|
||||
.mono-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-mono-label);
|
||||
font-weight: 500;
|
||||
letter-spacing: var(--tracking-label);
|
||||
text-transform: uppercase;
|
||||
color: var(--ink-faint);
|
||||
}
|
||||
.mono-meta {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-mono-meta);
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
/* Constrained prose measure for long-form case-study body (TYPOGRAPHY §3). */
|
||||
.prose-measure {
|
||||
max-width: var(--measure);
|
||||
}
|
||||
|
||||
/* Skip-link: off-screen until focused (MICRO_INTERACTIONS, a11y). */
|
||||
.skip-link {
|
||||
position: fixed;
|
||||
top: var(--space-3);
|
||||
left: var(--space-3);
|
||||
z-index: 100;
|
||||
padding: var(--space-2) var(--space-4);
|
||||
background: var(--accent);
|
||||
color: var(--accent-ink);
|
||||
border-radius: var(--radius-sm);
|
||||
font-weight: 600;
|
||||
transform: translateY(-150%);
|
||||
transition: transform var(--dur-quick) var(--ease-out);
|
||||
}
|
||||
.skip-link:focus {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* High-contrast / forced-colors: drop decorative texture (COLOUR_SYSTEM §5). */
|
||||
@media (forced-colors: active) {
|
||||
.dot-grid,
|
||||
.hero-halo {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Motion layer (ANIMATION_SPEC). Only transform / opacity / stroke-dashoffset animate.
|
||||
Reduced-motion is a single global override — not per-component JS (ANIMATION_SPEC §1).
|
||||
*/
|
||||
|
||||
/* ---- Reveal (A2): opacity + 12px rise, staggered by --reveal-index ---- */
|
||||
[data-reveal] {
|
||||
opacity: 0;
|
||||
transform: translateY(12px);
|
||||
transition:
|
||||
opacity var(--dur-entrance) var(--ease-out),
|
||||
transform var(--dur-entrance) var(--ease-out);
|
||||
transition-delay: calc(var(--reveal-index, 0) * 60ms);
|
||||
}
|
||||
[data-reveal].is-revealed {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* ---- Trace draw (A1) ---- */
|
||||
@keyframes trace-draw {
|
||||
from {
|
||||
stroke-dashoffset: var(--trace-len, 600);
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
@keyframes dot-blink {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
.trace-line {
|
||||
stroke-dasharray: var(--trace-len, 600);
|
||||
stroke-dashoffset: var(--trace-len, 600);
|
||||
animation: trace-draw var(--dur-signature) var(--ease-in-out) forwards;
|
||||
}
|
||||
[data-seen] .trace-line {
|
||||
animation: none;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
.trace-dot {
|
||||
animation: dot-blink 900ms var(--ease-out) 700ms 1;
|
||||
}
|
||||
|
||||
/* ---- Status chip pulse (A4): 2 iterations, ~1Hz ---- */
|
||||
@keyframes chip-pulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.4);
|
||||
opacity: 0.55;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.is-revealed .status-dot--active {
|
||||
animation: chip-pulse 900ms var(--ease-out) 2;
|
||||
}
|
||||
|
||||
/* ---- Timeline spine grow (A8) ---- */
|
||||
.timeline-spine {
|
||||
transform: scaleY(0);
|
||||
transform-origin: top;
|
||||
transition: transform var(--dur-entrance) var(--ease-out);
|
||||
}
|
||||
.is-revealed .timeline-spine {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
/* ---- 404 fray (A10) ---- */
|
||||
@keyframes fray {
|
||||
from {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Check-draw for form success (A9) ---- */
|
||||
@keyframes check-draw {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
.check-path {
|
||||
stroke-dasharray: 24;
|
||||
stroke-dashoffset: 24;
|
||||
animation: check-draw var(--dur-standard) var(--ease-out) forwards;
|
||||
}
|
||||
|
||||
/* ---- View-transition language/route cross-fade (A6/A7) ---- */
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation-duration: var(--dur-quick);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Reduced motion: durations collapse, translations disabled,
|
||||
animated states render at their final frame (no content lost).
|
||||
============================================================ */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 1ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 1ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
[data-reveal] {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
.trace-line {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
.timeline-spine {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Design tokens — single source of truth (Phase 1: COLOUR/SPACING/TYPOGRAPHY/MOTION specs).
|
||||
Dark is the design-lead theme (defaults on :root); light overrides under [data-theme='light'].
|
||||
Theme switching is a pure attribute swap — no JS re-render (ARCHITECTURE A4).
|
||||
*/
|
||||
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
|
||||
/* ---- Surfaces & ink (COLOUR_SYSTEM §2, dark) ---- */
|
||||
--surface-0: #0b0e14;
|
||||
--surface-1: #11151d;
|
||||
--surface-2: #171c26;
|
||||
--ink: #e8ecf2;
|
||||
--ink-muted: #9aa4b2;
|
||||
--ink-faint: #5c6675;
|
||||
--border: rgba(232, 236, 242, 0.08);
|
||||
--border-strong: rgba(232, 236, 242, 0.16);
|
||||
|
||||
/* ---- Accent & functional (status-LED usage only) ---- */
|
||||
--accent: #3ecfae;
|
||||
--accent-ink: #062a22;
|
||||
--amber: #e5a93d;
|
||||
--amber-chip-bg: rgba(229, 169, 61, 0.1);
|
||||
--danger: #e5606b;
|
||||
|
||||
/* ---- Effects ---- */
|
||||
--halo: rgba(62, 207, 174, 0.07); /* single permitted gradient, hero only */
|
||||
--dot-grid: rgba(232, 236, 242, 0.05);
|
||||
--shadow-card: none; /* dark uses border-strong instead of shadow */
|
||||
--shadow-overlay: 0 24px 60px -20px rgba(0, 0, 0, 0.7);
|
||||
|
||||
/* ---- Radius (DESIGN_SYSTEM §3) ---- */
|
||||
--radius-xs: 4px;
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* ---- Spacing scale, 8pt base (SPACING_SYSTEM §1) ---- */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 24px;
|
||||
--space-6: 32px;
|
||||
--space-7: 48px;
|
||||
--space-8: 64px;
|
||||
--space-9: 96px;
|
||||
--space-10: 128px;
|
||||
|
||||
/* ---- Type families (TYPOGRAPHY_GUIDE §1) ---- */
|
||||
--font-display: 'Space Grotesk Variable', 'Segoe UI', system-ui, sans-serif;
|
||||
--font-body: 'Inter Variable', 'Segoe UI', system-ui, sans-serif;
|
||||
--font-mono: 'JetBrains Mono Variable', ui-monospace, 'Cascadia Code', monospace;
|
||||
|
||||
/* ---- Type scale (TYPOGRAPHY_GUIDE §2), fluid where responsive ---- */
|
||||
--text-display: clamp(2.5rem, 1.8rem + 3.1vw, 3.8125rem); /* 40 → 61 */
|
||||
--text-h1: clamp(2.125rem, 1.6rem + 2.3vw, 3.0625rem); /* 34 → 49 */
|
||||
--text-h2: clamp(1.75rem, 1.4rem + 1.5vw, 2.4375rem); /* 28 → 39 */
|
||||
--text-h3: clamp(1.5rem, 1.3rem + 0.9vw, 1.9375rem); /* 24 → 31 */
|
||||
--text-h4: 1.25rem; /* 20 */
|
||||
--text-body-lg: 1.125rem; /* 18 */
|
||||
--text-body: 1rem; /* 16 */
|
||||
--text-small: 0.875rem; /* 14 */
|
||||
--text-mono-label: 0.75rem; /* 12 */
|
||||
--text-mono-meta: 0.8125rem; /* 13 */
|
||||
|
||||
--leading-tight: 1.1;
|
||||
--leading-snug: 1.2;
|
||||
--leading-normal: 1.5;
|
||||
--leading-relaxed: 1.65;
|
||||
--tracking-label: 0.08em;
|
||||
--measure: 68ch;
|
||||
|
||||
/* ---- Motion (MOTION_GUIDELINES §2) ---- */
|
||||
--dur-instant: 80ms;
|
||||
--dur-quick: 160ms;
|
||||
--dur-standard: 240ms;
|
||||
--dur-entrance: 400ms;
|
||||
--dur-signature: 700ms;
|
||||
--ease-out: cubic-bezier(0.2, 0, 0, 1);
|
||||
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||
|
||||
/* ---- Layout ---- */
|
||||
--content-max: 1200px;
|
||||
--header-h: 72px;
|
||||
--header-h-scrolled: 56px;
|
||||
}
|
||||
|
||||
:root[data-theme='light'] {
|
||||
color-scheme: light;
|
||||
|
||||
--surface-0: #fafaf8;
|
||||
--surface-1: #ffffff;
|
||||
--surface-2: #f1f2ef;
|
||||
--ink: #171a20;
|
||||
--ink-muted: #555e6b;
|
||||
--ink-faint: #8a93a0;
|
||||
--border: rgba(23, 26, 32, 0.1);
|
||||
--border-strong: rgba(23, 26, 32, 0.2);
|
||||
|
||||
--accent: #0e8c72;
|
||||
--accent-ink: #ffffff;
|
||||
--amber: #8a6114;
|
||||
--amber-chip-bg: #f5e5c2;
|
||||
--danger: #b3323e;
|
||||
|
||||
--halo: rgba(14, 140, 114, 0.06);
|
||||
--dot-grid: rgba(23, 26, 32, 0.05);
|
||||
--shadow-card: 0 2px 4px rgba(23, 26, 32, 0.06);
|
||||
--shadow-overlay: 0 24px 60px -20px rgba(23, 26, 32, 0.25);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"allowJs": false,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@i18n/*": ["src/i18n/*"],
|
||||
"@components/*": ["src/components/*"],
|
||||
"@layouts/*": ["src/layouts/*"],
|
||||
"@styles/*": ["src/styles/*"],
|
||||
"@scripts/*": ["src/scripts/*"],
|
||||
"@lib/*": ["src/lib/*"]
|
||||
}
|
||||
},
|
||||
"include": [".astro/types.d.ts", "src/**/*", "*.config.*"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user