diff --git a/src/app.css b/src/app.css index d22767e7..726a0c09 100644 --- a/src/app.css +++ b/src/app.css @@ -1,8 +1,8 @@ /* -Taking lots of inspiration from Distill.pub -https://github.com/distillpub/template/blob/master/src/styles/d-article.css -g*/ + Inspired by Distill.pub: https://github.com/distillpub/template/blob/master/src/styles/d-article.css +*/ +@import './design-tokens.css'; @import './fonts.css'; @import './code.css'; @import './utils.css'; @@ -10,146 +10,346 @@ g*/ @import './flair.css'; @import './classes.css'; -:root { - --breakpoint: 1200px; - --font: 'overpassregular', sans-serif; - --mono: 'Overpass Mono', monospace; - --dark-blue: #083c64; - --med-blue: #0371b5; - --light-blue: #1ca4fc; - --max-text-width: 70ch; - --min-text-width: 30ch; - --footer-height: 55px; - --event-flair: rgb(235, 161, 23); - --article-flair: var(--med-blue); - --reference-flair: rgb(34, 140, 34); - --podcast-flair: palevioletred; - --tutorial-flair: rgba(102, 103, 171, 255); - --grey: rgb(89, 89, 89); -} - -* { +/* ── Reset & Base ────────────────────────────────────────── */ + +*, +*::before, +*::after { box-sizing: border-box; } html { - font-family: var(--font); + font-family: var(--font-sans); font-size: 16px; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; + scroll-behavior: smooth; } body { margin: 0; - line-height: 1.5; + line-height: var(--leading-normal); text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - color: #333; /* Default text color */ + color: var(--color-text); + background-color: var(--color-background); +} + +/* ── Typography ──────────────────────────────────────────── */ + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-sans); + color: var(--color-neutral-900); + text-wrap: balance; +} + +h1 { + font-size: var(--text-4xl); + font-weight: var(--font-extrabold); + line-height: var(--leading-tight); + letter-spacing: var(--tracking-tight); + margin: 0 0 0.5em; +} + +h2 { + font-size: var(--text-3xl); + font-weight: var(--font-bold); + line-height: var(--leading-snug); + letter-spacing: var(--tracking-tight); + margin: var(--heading-spacing) 0 var(--heading-spacing); + padding: 0; +} + +h3 { + font-size: var(--text-2xl); + font-weight: var(--font-semibold); + line-height: var(--leading-snug); + margin: 1.25em 0 0.5em; +} + +h4 { + font-size: var(--text-xl); + font-weight: var(--font-semibold); + line-height: var(--leading-snug); + margin: 1em 0 0.4em; } -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: var(--font); - margin: 0.6em 0; - line-height: 1.3; +h5, h6 { + font-size: var(--text-lg); + font-weight: var(--font-bold); + line-height: var(--leading-snug); + margin: 1em 0 0.4em; +} + +/* Body text with consistent rhythm */ +p { + margin: 0 0 var(--paragraph-spacing); + line-height: var(--leading-relaxed); } -ul, -ol, -p, blockquote { - margin-top: 0; - margin-bottom: 1em; - margin-left: 0; - margin-right: 0; - line-height: 1.7em; + margin: var(--space-8) 0; + padding: 0; } -li > p { - line-height: 1.2em; +/* ── Lists ───────────────────────────────────────────────── */ + +ul, ol { + margin: 0 0 var(--paragraph-spacing); + padding-left: 1.75em; + line-height: var(--leading-relaxed); } li { - margin-left: 0; - margin-right: 0; + margin-bottom: 0.35em; } -h1 { - font-size: 2.625em; - line-height: 1.2; +li:last-child { + margin-bottom: 0; } -h2 { - font-size: 1.625em; - line-height: 1.2; +li > p { + line-height: var(--leading-normal); + margin-bottom: 0.3em; } -h3 { - font-size: 1.3125em; - line-height: 1.24; +/* Nested lists */ +li > ul, li > ol { + margin-top: 0.35em; + margin-bottom: 0; } -h4 { - font-size: 1.1875em; - line-height: 1.23; +/* Custom bullet for unordered lists in articles */ +main ul { + list-style: none; + padding-left: 1.5em; +} + +main ul > li { + position: relative; +} + +main ul > li::before { + content: ''; + position: absolute; + left: -1.25em; + top: 0.6em; + width: 6px; + height: 6px; + border-radius: 50%; + background-color: var(--color-primary-300); +} + +main ul ul > li::before { + width: 5px; + height: 5px; + border-radius: 50%; + border: 1.5px solid var(--color-primary-300); + background-color: transparent; + top: 0.55em; +} + +/* ── Definition Lists ────────────────────────────────────── */ + +dl { + margin: var(--space-6) 0; +} + +dt { + font-weight: var(--font-bold); + font-size: var(--text-base); + color: var(--color-primary-800); + margin-top: var(--space-4); + margin-bottom: var(--space-1); +} + +dt:first-child { + margin-top: 0; +} + +dd { + margin-left: var(--space-5); + margin-bottom: var(--space-3); + color: var(--color-text-muted); + line-height: var(--leading-normal); + font-size: var(--text-sm); +} + +dd:last-child { + margin-bottom: 0; +} + +/* ── Tables ──────────────────────────────────────────────── */ + +table { + width: 100%; + margin: var(--space-6) 0; + border-collapse: collapse; + font-size: var(--text-sm); + line-height: var(--leading-normal); + border-radius: var(--radius-md); + overflow: hidden; + box-shadow: var(--shadow-sm); +} + +thead { + background-color: var(--color-primary-50); +} + +th { + text-align: left; + padding: var(--space-3) var(--space-4); + font-weight: var(--font-bold); + color: var(--color-primary-800); + font-size: var(--text-xs); + text-transform: uppercase; + letter-spacing: var(--tracking-wide); + border-bottom: 2px solid var(--color-primary-200); +} + +td { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--color-neutral-200); + color: var(--color-text); } -h5, -h6 { - font-size: 1em; - font-weight: bold; +tbody tr:last-child td { + border-bottom: none; } +tbody tr:nth-child(even) { + background-color: var(--color-neutral-50); +} + +tbody tr:hover { + background-color: rgba(28, 164, 252, 0.04); +} + +/* Responsive table wrapper — wrap tables in a div.table-wrap */ +.table-wrap { + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + margin: var(--space-6) 0; +} + +.table-wrap table { + margin: 0; + min-width: 100%; +} + +/* ── Links ───────────────────────────────────────────────── */ + a { - color: var(--med-blue); - max-width: max-content; + color: var(--color-link); + text-decoration-thickness: 1px; + text-underline-offset: 2px; + transition: color var(--transition-fast), background-color var(--transition-fast); + border-radius: 2px; } a:hover { - color: white; - background: var(--med-blue); + color: var(--color-link-hover-text); + background: var(--color-link-hover-bg); + text-decoration-color: transparent; } -.title-box:after { - margin-top: 0.5em; - margin-bottom: 0.5em; +/* Inline links in paragraphs get subtler treatment */ +p a, li a, figcaption a { + text-decoration: underline; + text-decoration-color: rgba(3, 113, 181, 0.3); +} + +p a:hover, li a:hover, figcaption a:hover { + text-decoration-color: transparent; +} + +/* ── Code ────────────────────────────────────────────────── */ + +code { + font-family: var(--font-mono); + font-size: 0.9em; + color: var(--color-code-text); + background-color: var(--color-code-bg); + padding: 0.15em 0.35em; + border-radius: 3px; + border: 1px solid var(--color-neutral-200); +} + +pre code { + border: none; + padding: 0; + background: none; + font-size: 0.875rem; +} + +/* ── Title Box ───────────────────────────────────────────── */ + +.title-box::after { + margin-top: var(--space-4); + margin-bottom: var(--space-4); height: 1px; - content: ' '; + content: ''; display: block; - border-top: 0.5px solid #dcdee0; + border: none; + background: linear-gradient( + to right, + var(--color-border), + transparent 80% + ); } -code { - font-family: var(--mono); - font-size: 1em; - color: #555; - background-color: #f0f0f0; - padding: 0.1em 0.1em; - border-radius: 2px; +/* ── Horizontal Rules ────────────────────────────────────── */ + +hr { + border: none; + height: 1px; + margin: var(--space-8) 0; + background: linear-gradient( + to right, + transparent, + var(--color-neutral-300) 20%, + var(--color-neutral-300) 80%, + transparent + ); } +/* ── Heading Anchor Links ────────────────────────────────── */ + .autolink { width: 16px; height: 16px; padding-left: 0.3em; padding-right: 0.3em; + opacity: 0; + transition: opacity var(--transition-fast); +} + +h2:hover .autolink, +h3:hover .autolink, +h4:hover .autolink { + opacity: 0.5; } h2 > a:hover { background-color: transparent; } -/* New styles for consistency across components */ +/* ── Selection ───────────────────────────────────────────── */ + +::selection { + background-color: rgba(28, 164, 252, 0.2); + color: var(--color-neutral-900); +} + +/* ── Shared Utility Classes ──────────────────────────────── */ + .component-title { - font-size: 1.2rem; - font-weight: bold; - margin-bottom: 0.5em; - line-height: 1.3; + font-size: var(--text-md); + font-weight: var(--font-bold); + margin-bottom: var(--space-2); + line-height: var(--leading-snug); } .component-text { @@ -158,24 +358,24 @@ h2 > a:hover { } .small-text { - font-size: 0.8rem; + font-size: var(--text-xs); } .flair, .url { - font-size: 0.75rem; - font-weight: bold; + font-size: var(--text-xs); + font-weight: var(--font-bold); } .hover-effect { - transition: transform 0.3s ease, box-shadow 0.3s ease; + transition: transform var(--transition-slow), box-shadow var(--transition-slow); } .hover-effect:hover { transform: translateY(-2px); - box-shadow: 0 8px 12px rgba(0, 0, 0, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08); + box-shadow: var(--shadow-md); } .rounded-corners { - border-radius: 12px; + border-radius: var(--radius-lg); overflow: hidden; } diff --git a/src/classes.css b/src/classes.css index c3e2f072..5c1836ec 100644 --- a/src/classes.css +++ b/src/classes.css @@ -1,11 +1,10 @@ .interactive-example-container { - margin-top: 2em; - margin-bottom: 2em; + margin-top: var(--space-8); + margin-bottom: var(--space-8); display: flex; flex-direction: column; - gap: 1em; - border-width: 2px; - border-style: solid; - border-color: rgba(28, 164, 252, 0.3); - padding: 1em; -} \ No newline at end of file + gap: var(--space-4); + border: 2px solid rgba(28, 164, 252, 0.3); + padding: var(--space-4); + border-radius: var(--radius-md); +} diff --git a/src/design-tokens.css b/src/design-tokens.css new file mode 100644 index 00000000..19c304c8 --- /dev/null +++ b/src/design-tokens.css @@ -0,0 +1,177 @@ +/* FluCoMa Learn — Design Tokens */ + +:root { + /* ── Color Palette ─────────────────────────────────────── */ + + /* Primary (Brand Blue) */ + --color-primary-50: #e6f2fa; + --color-primary-100: #b3d8f0; + --color-primary-200: #80bef0; + --color-primary-300: #4da8f5; + --color-primary-400: #1ca4fc; + --color-primary-500: #0390d6; + --color-primary-600: #0371b5; + --color-primary-700: #025891; + --color-primary-800: #083c64; + --color-primary-900: #042038; + + /* Neutral (Gray) */ + --color-neutral-50: #f8f9fa; + --color-neutral-100: #f0f0f0; + --color-neutral-200: #e0e0e0; + --color-neutral-300: #dcdee0; + --color-neutral-400: #b0b3b5; + --color-neutral-500: #8a8d90; + --color-neutral-600: #595959; + --color-neutral-700: #4a4d50; + --color-neutral-800: #333333; + --color-neutral-900: #1a1a1a; + + /* Content-Type Accents (flairs) */ + --color-article: #1ca4fc; + --color-event: #eba117; + --color-reference: #228c22; + --color-podcast: #db7093; + --color-tutorial: #6667ab; + + /* Admonition / Semantic */ + --color-note-bg: rgba(52, 52, 171, 0.2); + --color-note-border: rgba(31, 31, 136, 0.63); + --color-note-text: #414141; + --color-warning-bg: rgba(255, 204, 0, 0.2); + --color-warning-border: rgba(255, 204, 0, 0.63); + --color-danger-bg: rgba(204, 51, 0, 0.2); + --color-danger-border: rgba(204, 51, 0, 0.63); + --color-success-bg: rgba(230, 252, 224, 1); + --color-success-border: rgb(133, 229, 106); + + /* Semantic Aliases (consume these in components) */ + --color-text: var(--color-neutral-800); + --color-text-muted: var(--color-neutral-600); + --color-text-inverted: #ffffff; + --color-background: #ffffff; + --color-surface: var(--color-neutral-50); + --color-border: var(--color-neutral-300); + --color-link: var(--color-primary-600); + --color-link-hover-bg: var(--color-primary-600); + --color-link-hover-text: #ffffff; + --color-code-bg: var(--color-neutral-100); + --color-code-text: #555555; + --color-code-block-bg: #f7f7f7; + + /* ── Typography ────────────────────────────────────────── */ + + --font-sans: 'overpassregular', sans-serif; + --font-mono: 'Overpass Mono', monospace; + + /* Type Scale (1.25 major-third ratio) */ + --text-xs: 0.75rem; /* 12px */ + --text-sm: 0.875rem; /* 14px */ + --text-base: 1rem; /* 16px */ + --text-md: 1.125rem; /* 18px */ + --text-lg: 1.25rem; /* 20px */ + --text-xl: 1.5rem; /* 24px */ + --text-2xl: 1.75rem; /* 28px */ + --text-3xl: 2.125rem; /* 34px */ + --text-4xl: 2.5rem; /* 40px (h1) */ + + /* Font Weights */ + --font-normal: 400; + --font-semibold: 600; + --font-bold: 700; + --font-extrabold: 800; + + /* Letter Spacing */ + --tracking-tight: -0.015em; + --tracking-normal: 0; + --tracking-wide: 0.02em; + + /* Line Heights */ + --leading-tight: 1.15; + --leading-snug: 1.25; + --leading-normal: 1.6; + --leading-relaxed: 1.75; + + /* Content Rhythm */ + --paragraph-spacing: 1.25em; + --heading-spacing: 0.5em; + --section-spacing: 2em; + + /* ── Spacing Scale (4px base) ──────────────────────────── */ + + --space-0: 0; + --space-1: 0.25rem; /* 4px */ + --space-2: 0.5rem; /* 8px */ + --space-3: 0.75rem; /* 12px */ + --space-4: 1rem; /* 16px */ + --space-5: 1.25rem; /* 20px */ + --space-6: 1.5rem; /* 24px */ + --space-8: 2rem; /* 32px */ + --space-10: 2.5rem; /* 40px */ + --space-12: 3rem; /* 48px */ + --space-16: 4rem; /* 64px */ + + /* ── Border Radius ─────────────────────────────────────── */ + + --radius-none: 0; + --radius-sm: 0.25rem; /* 4px — subtle rounding */ + --radius-md: 0.5rem; /* 8px — cards, inputs */ + --radius-lg: 0.75rem; /* 12px — containers, modals */ + --radius-xl: 1rem; /* 16px */ + --radius-full: 9999px; /* pills, badges */ + + /* ── Shadows / Elevation ───────────────────────────────── */ + + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.08), 0 4px 6px rgba(0, 0, 0, 0.05); + --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04); + + /* Interactive shadow (brand-tinted for raised cards/buttons) */ + --shadow-interactive: var(--color-primary-600) -5px 5px 0px -3px, + rgba(3, 113, 181, 0.2) -10px 10px, + rgba(3, 113, 181, 0.1) -15px 15px, + rgba(3, 113, 181, 0.05) -20px 20px; + + /* ── Transitions ───────────────────────────────────────── */ + + --transition-fast: 150ms ease; + --transition-base: 200ms ease; + --transition-slow: 300ms ease; + + /* ── Breakpoints (reference; use in media queries) ─────── */ + + --bp-tablet: 768px; + --bp-desktop: 1200px; + + /* ── Layout ────────────────────────────────────────────── */ + + --max-text-width: 70ch; + --min-text-width: 30ch; + --header-height: 55px; + --footer-height: 55px; + + /* ── Cards ─────────────────────────────────────────────── */ + + --card-radius: var(--radius-lg); + --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 4px 12px rgba(0, 0, 0, 0.04); + --card-shadow-hover: 0 2px 6px rgba(0, 0, 0, 0.08), 0 8px 24px rgba(0, 0, 0, 0.06); + --card-image-overlay: linear-gradient(180deg, transparent 55%, rgba(8, 60, 100, 0.75) 100%); + --card-transition: transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), + box-shadow 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); + + /* ── Backwards-compat aliases (keep old var names working) ─ */ + + --font: var(--font-sans); + --mono: var(--font-mono); + --dark-blue: var(--color-primary-800); + --med-blue: var(--color-primary-600); + --light-blue: var(--color-primary-400); + --grey: var(--color-neutral-600); + --breakpoint: var(--bp-desktop); + --event-flair: var(--color-event); + --article-flair: var(--color-article); + --reference-flair: var(--color-reference); + --podcast-flair: var(--color-podcast); + --tutorial-flair: var(--color-tutorial); +} diff --git a/src/flair.css b/src/flair.css index 63c00313..63e5875f 100644 --- a/src/flair.css +++ b/src/flair.css @@ -1,19 +1,7 @@ -.event { - background-color: rgb(235, 161, 23); -} +/* Flair (content-type) colors — used as background pills/badges */ -.article { - background-color: var(--light-blue); -} - -.reference { - background-color: forestgreen; -} - -.podcast { - background-color: palevioletred; -} - -.tutorial { - background-color: rgba(102, 103, 171, 255); -} +.flair-event { background-color: var(--color-event); } +.flair-article { background-color: var(--color-article); } +.flair-reference { background-color: var(--color-reference); } +.flair-podcast { background-color: var(--color-podcast); } +.flair-tutorial { background-color: var(--color-tutorial); } diff --git a/src/lib/components/Admonition.svelte b/src/lib/components/Admonition.svelte index e9ba0c0a..d1770056 100644 --- a/src/lib/components/Admonition.svelte +++ b/src/lib/components/Admonition.svelte @@ -1,64 +1,64 @@ -
-
{lookup.get(type)}
-
+
+
{labels[type] ?? 'Note'}
+
diff --git a/src/lib/components/Audio.svelte b/src/lib/components/Audio.svelte index 3a15d122..698fd9d1 100644 --- a/src/lib/components/Audio.svelte +++ b/src/lib/components/Audio.svelte @@ -6,7 +6,7 @@ * @param {string} label - The caption to render underneath the element. * @param {boolean} waveform - Toggle for waveform display. */ - import { onMount } from 'svelte'; + import { onMount, onDestroy } from 'svelte'; export let src = ''; export let label = ''; export let waveform = false; @@ -47,6 +47,11 @@ }); } }); + + onDestroy(() => { + if (instance) instance.destroy(); + if (ctx) ctx.close(); + });
diff --git a/src/lib/components/AuthorTag.svelte b/src/lib/components/AuthorTag.svelte index 900926cc..d14cac20 100644 --- a/src/lib/components/AuthorTag.svelte +++ b/src/lib/components/AuthorTag.svelte @@ -1,53 +1,47 @@ - + diff --git a/src/lib/components/BigQuote.svelte b/src/lib/components/BigQuote.svelte index 3f79080a..17f2d2cd 100644 --- a/src/lib/components/BigQuote.svelte +++ b/src/lib/components/BigQuote.svelte @@ -2,33 +2,77 @@ export let txt = ''; -
- {@html txt} -
+
+
+ {@html txt} +
+
diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte index 16521dfc..e6e57de7 100644 --- a/src/lib/components/Button.svelte +++ b/src/lib/components/Button.svelte @@ -1,47 +1,106 @@ - +{#if href} + + {label} + +{:else} + +{/if} - diff --git a/src/lib/components/CodeBlock.svelte b/src/lib/components/CodeBlock.svelte index ea86b4fb..558dc6db 100644 --- a/src/lib/components/CodeBlock.svelte +++ b/src/lib/components/CodeBlock.svelte @@ -4,11 +4,12 @@ export let title = ''; export let snippet = false; + let block; const copyCode = () => { if (browser) { - let code = block.querySelectorAll('pre > code'); + const code = block.querySelectorAll('pre > code'); code.forEach(c => { navigator.clipboard.writeText(c.innerText); }); @@ -16,41 +17,55 @@ }; -
- {#if !snippet} -
- {title} - -
+
+ {#if title} +
+ {title} + +
{/if} -
+
diff --git a/src/lib/components/Copy.svelte b/src/lib/components/Copy.svelte index 62e1bcd8..ff03498a 100644 --- a/src/lib/components/Copy.svelte +++ b/src/lib/components/Copy.svelte @@ -17,36 +17,38 @@ }; - diff --git a/src/lib/components/Flair.svelte b/src/lib/components/Flair.svelte index dceecae3..e2aa11ca 100644 --- a/src/lib/components/Flair.svelte +++ b/src/lib/components/Flair.svelte @@ -1,44 +1,27 @@ -
+
{flair}
- diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index cea2b774..7fc0ca15 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -2,8 +2,8 @@ import ArrowRight from '$lib/components/ArrowRight.svelte'; const links = [ - { href: "https://github.com/flucoma/learn-website/issues/new", text: "File an issue" }, - { href: "https://flucoma.org", text: "FluCoMa Home" } + { href: 'https://github.com/flucoma/learn-website/issues/new', text: 'File an issue' }, + { href: 'https://flucoma.org', text: 'FluCoMa Home' } ]; @@ -20,7 +20,7 @@ diff --git a/src/lib/components/HR.svelte b/src/lib/components/HR.svelte index a8f00b5e..ece2a4e2 100644 --- a/src/lib/components/HR.svelte +++ b/src/lib/components/HR.svelte @@ -1,9 +1,4 @@
diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index a1dbb92a..a0c96436 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -15,79 +15,75 @@
{#if w > 1200} - - - {:else} - - - - - + {/if}
- diff --git a/src/lib/components/RelatedLinks.svelte b/src/lib/components/RelatedLinks.svelte index df95f5ea..0b266e84 100644 --- a/src/lib/components/RelatedLinks.svelte +++ b/src/lib/components/RelatedLinks.svelte @@ -12,6 +12,7 @@ $: articles = links.filter(x => x.flair === 'article') || []; $: tutorials = links.filter(x => x.flair === 'tutorial') || []; $: renderables = [articles, tutorials, references]; + let hoverable; let hover = false; let hoverInfo = { flair: '', blurb: '' }; @@ -33,108 +34,121 @@ {#if hover}
-
{hoverInfo.flair}
-
-
{hoverInfo.blurb}
+
{hoverInfo.flair}
+
+
{hoverInfo.blurb}
{/if} -
+ diff --git a/src/lib/components/ResourceLink.svelte b/src/lib/components/ResourceLink.svelte index b0db5fc3..04ac20e4 100644 --- a/src/lib/components/ResourceLink.svelte +++ b/src/lib/components/ResourceLink.svelte @@ -2,65 +2,115 @@ export let title = ''; export let url = ''; export let blurb = ''; + + $: domain = (() => { + try { + const u = new URL(url); + return u.hostname.replace(/^www\./, ''); + } catch { + return url; + } + })(); - + + +
+

{title}

+ {#if blurb} +

{blurb}

+ {/if} + {domain} +
+
diff --git a/src/lib/components/Search.svelte b/src/lib/components/Search.svelte index fbdca473..bfac90de 100644 --- a/src/lib/components/Search.svelte +++ b/src/lib/components/Search.svelte @@ -19,14 +19,12 @@ function blurSearch() { focused = false; - // $blur = false; searchBar.blur(); } - function focusSearch(e) { + function focusSearch() { searchBar.focus(); focused = true; - // $blur = true; } function updateFocus() { @@ -53,13 +51,11 @@ focusedEntry -= 1; updateFocus(); } - if (e.key === 'ArrowDown') { e.preventDefault(); focusedEntry += 1; updateFocus(); } - if (e.key === 'Enter') { if (focusedEntry !== -1) { clickResult(results[focusedEntry].item.url); @@ -86,34 +82,34 @@ {#if results.length >= 1 && focused} -
- {#each results as r, i} -
clickResult(r.item.url)} - on:mouseleave={() => { focusedEntry = -1 }} - on:mouseenter={() => { focusedEntry = i }} - class:entryhover={i === focusedEntry} - on:click={() => clickResult(r.item.url)} - on:keypress={() => clickResult(r.item.url)} - on:focus={focusSearch} - on:blur={blurSearch} - bind:this={entries[i]} - role="button" - tabindex="0" - > -
-

{r.item.title}

- {#if r.item.flair} -
{r.item.flair}
- {/if} +
+ {#each results as r, i} +
clickResult(r.item.url)} + on:mouseleave={() => { focusedEntry = -1; }} + on:mouseenter={() => { focusedEntry = i; }} + on:click={() => clickResult(r.item.url)} + on:keypress={() => clickResult(r.item.url)} + on:focus={focusSearch} + on:blur={blurSearch} + bind:this={entries[i]} + role="button" + tabindex="0" + class:hovered={i === focusedEntry} + > +
+

{r.item.title}

+ {#if r.item.flair} +
{r.item.flair}
+ {/if} +
+

+ {r.item.blurb.slice(0, 150) + '...'} +

-

- {r.item.blurb.slice(0, 150) + '...'} -

-
- {/each} -
+ {/each} +
{/if}
@@ -122,86 +118,103 @@ z-index: 999; position: relative; } + .query { - font-family: var(--font); + font-family: var(--font-sans); font-size: 0.9rem; - border: 1px solid #e0e0e0; - padding: 0.5em 0.75em; - border-radius: 12px; + border: 1px solid var(--color-border); + padding: var(--space-2) var(--space-3); + border-radius: var(--radius-lg); width: 100%; height: 36px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); - transition: all 0.3s ease; + transition: all var(--transition-slow); + background-color: var(--color-background); + color: var(--color-text); } - .query:hover, .query:focus { - border-color: var(--med-blue); - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + + .query:hover, + .query:focus { + border-color: var(--color-primary-600); + box-shadow: var(--shadow-sm); outline: none; } + .results { display: flex; flex-direction: column; position: absolute; right: 0; width: min(90vw, 400px); - background: white; - border-radius: 12px; + background: var(--color-background); + border-radius: var(--radius-lg); overflow: hidden; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08); + box-shadow: var(--shadow-md); z-index: 1000; - margin-top: 0.5em; + margin-top: var(--space-2); } + .result { - padding: 1em; + padding: var(--space-4); display: flex; flex-direction: column; text-align: left; - transition: all 0.3s ease; + transition: all var(--transition-slow); border-left: 4px solid transparent; } - .entryhover, .result:hover, .result:focus { + + .hovered, + .result:hover, + .result:focus { background-color: rgba(146, 200, 246, 0.15); - border-left-color: var(--med-blue); + border-left-color: var(--color-primary-600); cursor: pointer; } - .result:hover .title, .result:focus .title { - color: var(--med-blue); + + .result:hover .title, + .result:focus .title { + color: var(--color-primary-600); } + .top { display: flex; justify-content: space-between; align-items: center; - gap: 0.5em; - margin-bottom: 0.5em; + gap: var(--space-2); + margin-bottom: var(--space-2); } + .title { - font-weight: bold; - font-size: 1.1rem; - line-height: 1.3; + font-weight: var(--font-bold); + font-size: var(--text-md); + line-height: var(--leading-snug); margin: 0; - color: var(--dark-blue); - transition: color 0.3s ease; + color: var(--color-primary-800); + transition: color var(--transition-slow); } + .bottom { - color: #595959; + color: var(--color-text-muted); font-size: 0.9rem; margin: 0; line-height: 1.4; } - .flair { + + .result-flair { align-self: flex-start; text-transform: capitalize; - font-size: 0.75rem; - font-weight: bold; + font-size: var(--text-xs); + font-weight: var(--font-bold); padding: 0.3em 0.8em; - border-radius: 20px; - color: white; - } - .item-event { background-color: var(--event-flair); } - .item-article { background-color: var(--article-flair); } - .item-reference { background-color: var(--reference-flair); } - .item-podcast { background-color: var(--podcast-flair); } - .item-tutorial { background-color: var(--tutorial-flair); } + border-radius: var(--radius-full); + color: var(--color-text-inverted); + } + + .flair-event { background-color: var(--color-event); } + .flair-article { background-color: var(--color-article); } + .flair-reference { background-color: var(--color-reference); } + .flair-podcast { background-color: var(--color-podcast); } + .flair-tutorial { background-color: var(--color-tutorial); } .visually-hidden { position: absolute; diff --git a/src/lib/components/TOC.svelte b/src/lib/components/TOC.svelte index 39b8a665..fcc9c010 100644 --- a/src/lib/components/TOC.svelte +++ b/src/lib/components/TOC.svelte @@ -1,71 +1,92 @@ {#if headings.length > 0} -
+
+ {/if} diff --git a/src/lib/components/YouTubeChapters.svelte b/src/lib/components/YouTubeChapters.svelte index 13bc68c0..cb9c3d65 100644 --- a/src/lib/components/YouTubeChapters.svelte +++ b/src/lib/components/YouTubeChapters.svelte @@ -24,22 +24,24 @@

Chapters

-
    +
    {#each chapters as chapter, i} -
  1. chapterClick(chapter)} - on:click={() => chapterClick(chapter)} +
  2. + + {chapter.label} + {/each} -
+
diff --git a/src/lib/components/cards/Article.svelte b/src/lib/components/cards/Article.svelte index d6e00fae..4b80ef75 100644 --- a/src/lib/components/cards/Article.svelte +++ b/src/lib/components/cards/Article.svelte @@ -6,102 +6,110 @@ export let data = {}; - -
-

{data.title}

+
+
+

{data.title}

-
+
-

{data.blurb}

-
Learn More +

{data.blurb}

+ Learn More diff --git a/src/lib/components/cards/Landing.svelte b/src/lib/components/cards/Landing.svelte index d3b5f767..b3df673a 100644 --- a/src/lib/components/cards/Landing.svelte +++ b/src/lib/components/cards/Landing.svelte @@ -4,50 +4,50 @@ export let link = '/'; -
+ diff --git a/src/lib/components/explore/ArtistCard.svelte b/src/lib/components/explore/ArtistCard.svelte index e60cde4e..7bee1854 100644 --- a/src/lib/components/explore/ArtistCard.svelte +++ b/src/lib/components/explore/ArtistCard.svelte @@ -4,44 +4,59 @@ export let website = ''; - -
+ +
{`${name} -

{name}

+ {name}
- - - + + {#if $$slots.bio} +
+ +
+ {/if}
- diff --git a/src/lib/components/front-page/Wave.svelte b/src/lib/components/front-page/Wave.svelte index fb740caa..d37fdf68 100644 --- a/src/lib/components/front-page/Wave.svelte +++ b/src/lib/components/front-page/Wave.svelte @@ -1,6 +1,5 @@ - -
-
-

Welcome to the Fluid Corpus Manipulation Learn Platform!

-

The Fluid Corpus Manipulation project (FluCoMa) instigates new musical ways of exploiting ever-growing banks of sound and gestures within the digital composition process, by bringing breakthroughs of signal decomposition DSP and machine learning to the toolset of techno-fluent computer composers, creative coders and digital artists.

-
- - - - +
+
+

Welcome to the Fluid Corpus Manipulation Learn Platform

+

+ The Fluid Corpus Manipulation project (FluCoMa) instigates new musical ways of + exploiting ever-growing banks of sound and gestures within the digital composition + process, by bringing breakthroughs of signal decomposition DSP and machine learning + to the toolset of techno-fluent computer composers, creative coders and digital artists. +

+
+
-
- +
+
\ No newline at end of file + @media (max-width: 768px) { + .welcome-right { + display: none; + } + .welcome-left { + max-width: 100%; + } + .welcome-banner { + padding: var(--space-8) var(--space-5); + } + .welcome-left h1 { + font-size: var(--text-2xl); + } + } + diff --git a/src/lib/components/front-page/WelcomeButton.svelte b/src/lib/components/front-page/WelcomeButton.svelte deleted file mode 100644 index 193784a6..00000000 --- a/src/lib/components/front-page/WelcomeButton.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - {text} - - - \ No newline at end of file diff --git a/src/lib/components/mosaic/Article.svelte b/src/lib/components/mosaic/Article.svelte index 995541da..ada59ad2 100644 --- a/src/lib/components/mosaic/Article.svelte +++ b/src/lib/components/mosaic/Article.svelte @@ -1,116 +1,131 @@ -
- -
- {item.title} -
+
+ +
+

{item.title}

+

{item.blurb}

+
+ diff --git a/src/lib/components/mosaic/List.svelte b/src/lib/components/mosaic/List.svelte index ef8e7ffd..54cecdad 100644 --- a/src/lib/components/mosaic/List.svelte +++ b/src/lib/components/mosaic/List.svelte @@ -1,19 +1,14 @@ - diff --git a/src/lib/components/mosaic/Masonry.svelte b/src/lib/components/mosaic/Masonry.svelte new file mode 100644 index 00000000..6496e17f --- /dev/null +++ b/src/lib/components/mosaic/Masonry.svelte @@ -0,0 +1,56 @@ + + +
+ {#each cols as col (col)} +
+ {#each col as { item, idx } (keyOf(item))} + + {/each} +
+ {/each} +
diff --git a/src/lib/components/mosaic/RefCategory.svelte b/src/lib/components/mosaic/RefCategory.svelte index 86f05a36..edd4673b 100644 --- a/src/lib/components/mosaic/RefCategory.svelte +++ b/src/lib/components/mosaic/RefCategory.svelte @@ -1,18 +1,13 @@ -
-

{item.category}

-
    +
    +

    {item.category}

    +
      {#each item.refs as r}
    • {r.title}
    • {/each} @@ -20,36 +15,42 @@
    diff --git a/src/lib/components/mosaic/References.svelte b/src/lib/components/mosaic/References.svelte index 00808340..43d1dc49 100644 --- a/src/lib/components/mosaic/References.svelte +++ b/src/lib/components/mosaic/References.svelte @@ -4,17 +4,16 @@ export let items = []; -
    +
    {#each items as item} {/each}
    \ No newline at end of file + diff --git a/src/lib/components/tabs/Tab.svelte b/src/lib/components/tabs/Tab.svelte index 345a6e85..356c517c 100644 --- a/src/lib/components/tabs/Tab.svelte +++ b/src/lib/components/tabs/Tab.svelte @@ -8,7 +8,12 @@ registerTab(tab); - @@ -16,25 +21,27 @@ button { background: none; border: 1px solid transparent; - padding: 1em; + padding: var(--space-2) var(--space-4); cursor: pointer; - color: #495057; - font-size: 1rem; - font-family: var(--font); + color: var(--color-text-muted); + font-size: var(--text-sm); + font-family: var(--font-sans); + font-weight: var(--font-semibold); margin: 0; - min-width: 13ch; /* Number of characters in the word SuperCollider */ - transition: border-bottom 0.05s linear; - transition: background-color 0.05s linear; + border-radius: var(--radius-md); + transition: all var(--transition-fast); + white-space: nowrap; } button:hover { - background-color: rgba(28, 164, 252, 0.05); + color: var(--color-primary-700); + background-color: rgba(28, 164, 252, 0.08); } .selected { - background-color: #fff; - border-bottom: 4px solid var(--light-blue); - color: black; - background-color: rgba(28, 164, 252, 0.1); + background-color: var(--color-background) !important; + color: var(--color-primary-800) !important; + box-shadow: var(--shadow-sm); + border-color: var(--color-neutral-200); } diff --git a/src/lib/components/tabs/TabList.svelte b/src/lib/components/tabs/TabList.svelte index f4e41596..2e2cb3c4 100644 --- a/src/lib/components/tabs/TabList.svelte +++ b/src/lib/components/tabs/TabList.svelte @@ -1,4 +1,4 @@ -
    +
    @@ -6,7 +6,11 @@ .tab-list { display: flex; flex-direction: row; - gap: 0; - box-shadow: 0, 0, rgba(60, 64, 67, 1), 0; + flex-wrap: wrap; + gap: var(--space-1); + padding: var(--space-1); + background-color: var(--color-neutral-100); + border-radius: var(--radius-lg); + border: 1px solid var(--color-neutral-200); } diff --git a/src/lib/components/tabs/TabPanel.svelte b/src/lib/components/tabs/TabPanel.svelte index f63dd027..781b42de 100644 --- a/src/lib/components/tabs/TabPanel.svelte +++ b/src/lib/components/tabs/TabPanel.svelte @@ -9,14 +9,17 @@ {#if $selectedPanel === panel} -
    +
    {/if} diff --git a/src/lib/components/tabs/Tabs.svelte b/src/lib/components/tabs/Tabs.svelte index 5feded3c..cb4a2616 100644 --- a/src/lib/components/tabs/Tabs.svelte +++ b/src/lib/components/tabs/Tabs.svelte @@ -45,12 +45,12 @@ }); -
    +
    diff --git a/src/lib/layouts/Content.svelte b/src/lib/layouts/Content.svelte index fa9afe5a..391f3eea 100644 --- a/src/lib/layouts/Content.svelte +++ b/src/lib/layouts/Content.svelte @@ -86,7 +86,6 @@ .navigation { grid-area: navigation; - height: max-content; } .blank { diff --git a/src/lib/widget/comparing-scalers/Comparison.svelte b/src/lib/widget/comparing-scalers/Comparison.svelte index d903eac3..b20680e7 100644 --- a/src/lib/widget/comparing-scalers/Comparison.svelte +++ b/src/lib/widget/comparing-scalers/Comparison.svelte @@ -1,9 +1,5 @@
    -