@import 'tailwindcss'; @import '@fontsource-variable/rubik'; @import '@fontsource-variable/inter'; @plugin '@tailwindcss/typography'; @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); /* * Palette: Huemint "Magazine" — #f2efee #d5d09b #111012 #c95748 * Contrast notes (WCAG): ink on red = 4.46 → only large/bold text (≥19px bold) on --accent. * Small text on a red fill uses --accent-fill + --on-accent-fill (5.3 light / 6.5 dark). * Small red text uses --accent-text, which falls back to --fg on khaki sections (red/khaki < 4.5). */ :root { color-scheme: light; --bg: #f2efee; --bg-alt: #d5d09b; --surface: #f8f6f5; --fg: #111012; --fg-muted: #4a474b; --line: color-mix(in oklab, #111012 18%, transparent); --accent: #c95748; --accent-strong: #a8412f; --on-accent: #111012; --accent-fill: #a8412f; --on-accent-fill: #f2efee; --accent-on-alt: var(--fg); --accent-text: var(--accent-strong); } [data-theme='dark'] { color-scheme: dark; --bg: #111012; --bg-alt: #1c1b17; --surface: #19181a; --fg: #ebe7e4; --fg-muted: #b3ad8a; --line: color-mix(in oklab, #d5d09b 16%, transparent); --accent: #e07a6b; --accent-strong: #e07a6b; --on-accent: #111012; --accent-fill: #e07a6b; --on-accent-fill: #111012; --accent-on-alt: var(--accent); --accent-text: var(--accent-strong); } @theme inline { --color-bg: var(--bg); --color-bg-alt: var(--bg-alt); --color-surface: var(--surface); --color-fg: var(--fg); --color-fg-muted: var(--fg-muted); --color-line: var(--line); --color-accent: var(--accent); --color-accent-strong: var(--accent-strong); --color-accent-text: var(--accent-text); --color-accent-fill: var(--accent-fill); --color-on-accent: var(--on-accent); --color-on-accent-fill: var(--on-accent-fill); --color-khaki: #d5d09b; --color-paper: #f2efee; --color-ink: #111012; --font-display: 'Rubik Variable', ui-sans-serif, system-ui, sans-serif; --font-sans: 'Inter Variable', ui-sans-serif, system-ui, sans-serif; --font-mono: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace; } @layer base { html { @apply bg-bg font-sans text-fg antialiased; scroll-padding-top: 5rem; } body { @apply min-h-dvh text-[1.0625rem] leading-relaxed; } h1, h2, h3, h4 { @apply font-display; } :focus-visible { @apply outline-3 outline-offset-2 outline-accent; } ::selection { @apply bg-accent text-on-accent; } } @layer components { /* Khaki (alt) section: switches small red text to an accessible colour. */ .surface-alt { @apply bg-bg-alt; --accent-text: var(--accent-on-alt); } /* Magazine headline: heavy, uppercase, tight. */ .headline { @apply font-display leading-[0.95] font-black tracking-tight uppercase; } /* "Learn More" style link: thick underline that turns red on hover. */ .link-strong { @apply font-display font-bold underline decoration-fg decoration-3 underline-offset-[0.35em] transition-colors hover:decoration-accent; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* ---------- Article typography (unlayered: overrides the typography plugin) ---------- */ .article-prose { --tw-prose-body: var(--fg); --tw-prose-headings: var(--fg); --tw-prose-lead: var(--fg-muted); --tw-prose-links: var(--accent-strong); --tw-prose-bold: var(--fg); --tw-prose-counters: var(--fg-muted); --tw-prose-bullets: var(--accent); --tw-prose-hr: var(--line); --tw-prose-quotes: var(--fg); --tw-prose-quote-borders: var(--accent); --tw-prose-captions: var(--fg-muted); --tw-prose-kbd: var(--fg); --tw-prose-code: var(--fg); --tw-prose-pre-code: var(--fg); --tw-prose-pre-bg: var(--surface); --tw-prose-th-borders: var(--fg); --tw-prose-td-borders: var(--line); } .article-prose :where(h2, h3, h4) { font-family: var(--font-display); font-weight: 800; scroll-margin-top: 2rem; } .article-prose :where(a) { text-decoration-thickness: 2px; text-underline-offset: 0.2em; } .article-prose :where(:not(pre) > code) { background: var(--bg-alt); padding: 0.1em 0.35em; border-radius: 2px; font-weight: 500; } .article-prose :where(:not(pre) > code)::before, .article-prose :where(:not(pre) > code)::after { content: none; } .article-prose :where(blockquote) { font-style: normal; background: var(--surface); padding-block: 0.25em; } .article-prose :where(blockquote p)::before, .article-prose :where(blockquote p)::after { content: none; } .article-prose :where(figure) { margin-inline: 0; } .article-prose :where(figcaption) { border-left: 3px solid var(--accent); padding-left: 0.75em; } /* Shiki dual theme (defaultColor: false) */ .astro-code { color: var(--shiki-light); background-color: var(--surface) !important; border: 1px solid var(--line); border-radius: 2px; } .astro-code span { color: var(--shiki-light); } [data-theme='dark'] .astro-code, [data-theme='dark'] .astro-code span { color: var(--shiki-dark); } .code-block { position: relative; } /* Room for the copy button so it never covers the first line. */ .code-block > pre { padding-top: 2.5rem; } .code-copy { position: absolute; top: 0.5rem; right: 0.5rem; padding: 0.15rem 0.6rem; font: 700 0.75rem/1.5 var(--font-display); text-transform: uppercase; letter-spacing: 0.04em; color: var(--bg); background: var(--fg); border-radius: 2px; cursor: pointer; } .code-copy:hover { background: var(--accent-fill); color: var(--on-accent-fill); } /* ---------- Contact map (Leaflet) ---------- */ .tower-marker { background: none; border: 0; } /* Rotate an inner element: `rotate` on the marker itself would also rotate Leaflet's translate3d. */ .tower-pin { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; background: var(--accent-fill); color: var(--on-accent-fill); border: 2px solid var(--fg); border-radius: 50% 50% 50% 0; rotate: -45deg; } .tower-pin svg { rotate: 45deg; } .leaflet-container .leaflet-control-attribution { background: var(--surface); color: var(--fg); } .leaflet-container .leaflet-control-attribution a { color: var(--accent-strong); } .leaflet-container { font: inherit; background: var(--bg-alt); } .leaflet-popup-content { font-family: var(--font-display); font-weight: 700; } /* Dark tiles without a second tile provider. */ [data-theme='dark'] .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(0.85) contrast(0.9); } .leaflet-container .leaflet-popup-content-wrapper, .leaflet-container .leaflet-popup-tip { background: var(--surface); color: var(--fg); }