diff --git a/.ai/rules/website.md b/.ai/rules/website.md
index f9658f0..5a4df91 100644
--- a/.ai/rules/website.md
+++ b/.ai/rules/website.md
@@ -6,4 +6,4 @@ paths:
# Website
## website/ is the live site, uploaded by hand
-website/ is a faithful copy of sealshare.nonameweb.ch (METANET hosting), hand-written HTML/CSS with no build step, uploaded wholesale when it changes. Colours in css/theme.css are copied from the indigo profile in resources/css/material-scheme.json: the standard light and dark values (profiles.indigo.light/dark) and the high-contrast light and dark values (profiles.indigo.contrast.high) — copy them again if indigo is regenerated differently; the site does not follow the admin's colour profile. The comparison tables are dated and every competitor value has a source from the product's own site, docs or repo; an unsourced value is "—", never a guess. Never call SealShare's encryption end-to-end (files are encrypted in the browser with a key the server issues, and the server decrypts them for downloads). Nothing may load from another host except plausible.io. tests/Feature/WebsiteTest.php guards all of this.
+website/ is a faithful copy of sealshare.nonameweb.ch (METANET hosting), hand-written HTML/CSS with no build step, uploaded wholesale when it changes. Colours in css/theme.css are copied from the indigo profile in resources/css/material-scheme.json: the standard light and dark values (profiles.indigo.light/dark) and the high-contrast light and dark values (profiles.indigo.contrast.high) — copy them again if indigo is regenerated differently; the site does not follow the admin's colour profile. Light or dark is , written before the first paint by each page's inline head script from the nav's Light/Dark/System toggle (localStorage sealshare-website-theme); the high-contrast values apply under prefers-contrast: more. The comparison tables are dated and every competitor value has a source from the product's own site, docs or repo; an unsourced value is "—", never a guess. Never call SealShare's encryption end-to-end (files are encrypted in the browser with a key the server issues, and the server decrypts them for downloads). Nothing may load from another host except plausible.io. tests/Feature/WebsiteTest.php guards all of this.
diff --git a/website/css/device-frame.css b/website/css/device-frame.css
index 5e4758a..656dbed 100644
--- a/website/css/device-frame.css
+++ b/website/css/device-frame.css
@@ -4,6 +4,10 @@
* Pro viewport). The screen keeps the capture's aspect ratio, so the frame holds its shape while an
* image loads. The screenshots come from `composer screenshots` (tests/Screenshots/).
*
+ * The bezels and the deck are hardware, drawn in fixed tints of their own; what shows through the
+ * screen before an image paints and the shadow under a device are colour roles from theme.css, which
+ * must be loaded first. Dark follows , and the system setting without JavaScript.
+ *
*
*
…
*
@@ -14,13 +18,21 @@
--bezel-edge: #3a3355;
--deck: #c9c2dd;
--deck-shadow: #8f88a8;
+ --device-shadow: color-mix(in srgb, var(--md-sys-color-shadow) 40%, transparent);
position: relative;
width: 100%;
}
+:root[data-theme="dark"] .device {
+ --bezel: #05020f;
+ --bezel-edge: #2a2244;
+ --deck: #4b426a;
+ --deck-shadow: #231649;
+}
+
@media (prefers-color-scheme: dark) {
- .device {
+ :root:not([data-theme]) .device {
--bezel: #05020f;
--bezel-edge: #2a2244;
--deck: #4b426a;
@@ -31,7 +43,7 @@
.device__screen {
position: relative;
overflow: hidden;
- background: var(--surface-container-high, #e8deff);
+ background-color: var(--md-sys-color-surface-container-high);
}
.device__screen img {
@@ -54,7 +66,7 @@
padding: 2.4% 2.4% 3%;
border-radius: 3.2% 3.2% 0 0 / 4.8% 4.8% 0 0;
background: var(--bezel);
- box-shadow: inset 0 0 0 1px var(--bezel-edge), 0 24px 48px -24px rgb(16 6 45 / 0.45);
+ box-shadow: inset 0 0 0 1px var(--bezel-edge), 0 24px 48px -24px var(--device-shadow);
}
.device--laptop .device__screen {
@@ -79,8 +91,7 @@
.device--laptop::after {
content: '';
position: absolute;
- left: -4%;
- right: -4%;
+ inset-inline: -4%;
bottom: 0;
height: 3.2%;
border-radius: 0 0 40% 40% / 0 0 100% 100%;
@@ -95,7 +106,7 @@
z-index: 1;
width: 14%;
height: 1.4%;
- border-radius: 0 0 12px 12px;
+ border-radius: 0 0 var(--md-sys-shape-corner-md) var(--md-sys-shape-corner-md);
background: var(--deck-shadow);
translate: -50% 0;
}
@@ -106,7 +117,7 @@
padding: 3.4%;
border-radius: 15% / 7%;
background: var(--bezel);
- box-shadow: inset 0 0 0 2px var(--bezel-edge), 0 24px 48px -20px rgb(16 6 45 / 0.5);
+ box-shadow: inset 0 0 0 2px var(--bezel-edge), 0 24px 48px -20px var(--device-shadow);
}
.device--phone .device__screen {
diff --git a/website/css/theme.css b/website/css/theme.css
index 0eee31e..c5b557e 100644
--- a/website/css/theme.css
+++ b/website/css/theme.css
@@ -1,12 +1,25 @@
/*
* SealShare website theme.
*
- * The colours are not an approximation of the app's: they are copied from
- * the indigo profile in resources/css/material-scheme.json (seed #4f46e5, Vibrant, Material 3 spec
- * 2025, contrast 0; the file's top-level light and dark), generated by `php artisan material:scheme`
- * from the app's colour profiles. When indigo is regenerated differently, copy the roles below again —
- * the site does not read the file, and does not follow the colour profile an admin chooses. Light is the default, dark follows the
- * visitor's system setting; the site has no theme toggle of its own.
+ * The site looks like the app: Material 3 Expressive as Livewire Material 2.1 draws it, written by hand
+ * in plain CSS, because the site has no build step. The tokens carry the app's names (--md-sys-*) and
+ * its values, copied here rather than imported, so nothing loads from another host:
+ *
+ * - Colour roles from the indigo profile in resources/css/material-scheme.json (seed #4f46e5,
+ * Vibrant, Material 3 spec 2025): profiles.indigo.light and .dark at standard contrast, and
+ * profiles.indigo.contrast.high.light and .dark for visitors whose system asks for more contrast
+ * (prefers-contrast: more). The medium contrast level is not used. Only the roles the site draws
+ * with are copied; copy them again when indigo is regenerated differently. The site does not
+ * follow the colour profile an admin chooses.
+ * - Shape, elevation, motion, state, type and spacing from Livewire Material's token files
+ * (vendor/nonameweb/livewire-material/resources/css/tokens/), only the tokens used below.
+ *
+ * Light or dark is , written before the first paint by the inline script in each
+ * page's from the visitor's choice in the nav (Light, Dark or System, remembered in
+ * localStorage). Without JavaScript the attribute is absent and the system setting decides.
+ *
+ * Widths are M3's window size classes: compact below 600px, medium from 600px, expanded from 840px,
+ * large from 1200px.
*
* Shared by index.html and privacy.html.
*/
@@ -22,85 +35,252 @@
font-display: swap;
}
+/* ---------------------------------------------------------------- tokens */
+
:root {
- color-scheme: light dark;
+ color-scheme: light;
- --surface: #faf4ff;
- --surface-container-lowest: #ffffff;
- --surface-container-low: #f5eeff;
- --surface-container: #ede4ff;
- --surface-container-high: #e8deff;
- --surface-container-highest: #e2d7ff;
- --on-surface: #32294f;
- --on-surface-variant: #5f557f;
- --outline: #7b719c;
- --outline-variant: #b2a6d5;
- --inverse-surface: #10062d;
- --inverse-on-surface: #a296c4;
- --primary: #4a3fe2;
- --on-primary: #f4f1ff;
- --primary-container: #9795ff;
- --on-primary-container: #14007e;
- --secondary: #6249b2;
- --secondary-container: #d8caff;
- --on-secondary-container: #4e339c;
- --tertiary-container: #fd8bca;
- --on-tertiary-container: #610244;
- --success: #006c45;
- --error: #b41340;
+ /* Colour: indigo, light, standard contrast (profiles.indigo.light). */
+ --md-sys-color-surface: #faf4ff;
+ --md-sys-color-surface-container-low: #f5eeff;
+ --md-sys-color-surface-container: #ede4ff;
+ --md-sys-color-surface-container-high: #e8deff;
+ --md-sys-color-surface-container-highest: #e2d7ff;
+ --md-sys-color-on-surface: #32294f;
+ --md-sys-color-on-surface-variant: #5f557f;
+ --md-sys-color-outline: #7b719c;
+ --md-sys-color-outline-variant: #b2a6d5;
+ --md-sys-color-primary: #4a3fe2;
+ --md-sys-color-on-primary: #f4f1ff;
+ --md-sys-color-primary-container: #9795ff;
+ --md-sys-color-on-primary-container: #14007e;
+ --md-sys-color-secondary: #6249b2;
+ --md-sys-color-secondary-container: #d8caff;
+ --md-sys-color-on-secondary-container: #4e339c;
+ --md-sys-color-tertiary-container: #fd8bca;
+ --md-sys-color-on-tertiary-container: #610244;
+ --md-sys-color-success: #006943;
+ --md-sys-color-shadow: #000000;
- /* The code block reads as a terminal in both themes. */
- --code-surface: #10062d;
- --code-ink: #eae1ff;
+ /* Shape (tokens/shape.css). */
+ --md-sys-shape-corner-xs: 4px;
+ --md-sys-shape-corner-sm: 8px;
+ --md-sys-shape-corner-md: 12px;
+ --md-sys-shape-corner-full: 9999px;
- --font: 'Google Sans Flex', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
- --mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
+ /* Elevation (tokens/elevation.css). */
+ --md-sys-elevation-1: 0 1px 2px 0 color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent), 0 1px 3px 1px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent);
+ --md-sys-elevation-2: 0 1px 2px 0 color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent), 0 2px 6px 2px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent);
- --corner-sm: 8px;
- --corner-md: 12px;
- --corner-lg: 16px;
- --corner-xl: 28px;
- --corner-xxl: 48px;
- --corner-full: 999px;
+ /* Motion (tokens/motion.css): Expressive springs sampled into linear(), each with its duration. */
+ --md-sys-motion-spatial-fast: linear(0, 0.0195, 0.0716, 0.1471, 0.2381, 0.3378, 0.4404, 0.5416, 0.6378, 0.7265, 0.806, 0.8754, 0.9342, 0.9826, 1.0211, 1.0503, 1.0713, 1.0849, 1.0924, 1.0948, 1.0931, 1.0882, 1.0812, 1.0726, 1.0632, 1.0534, 1.0438, 1.0347, 1.0263, 1.0187, 1.0121, 1.0064, 1.0018, 0.9981, 0.9953, 0.9933, 0.992, 0.9913, 0.991, 0.9912, 0.9916, 0.9923, 0.9931, 0.994, 0.9949, 0.9958, 0.9967, 0.9975, 1);
+ --md-sys-motion-spatial-fast-duration: 350ms;
+ --md-sys-motion-effects-fast: linear(0, 0.0163, 0.0576, 0.1147, 0.1807, 0.2507, 0.3214, 0.3902, 0.4558, 0.5172, 0.5737, 0.6253, 0.6718, 0.7136, 0.7508, 0.7837, 0.8128, 0.8383, 0.8606, 0.8801, 0.897, 0.9117, 0.9244, 0.9353, 0.9448, 0.9529, 0.9599, 0.9658, 0.9709, 0.9753, 0.979, 0.9822, 0.9849, 0.9872, 0.9892, 0.9909, 0.9923, 0.9935, 0.9945, 0.9954, 0.9961, 0.9967, 0.9972, 0.9977, 0.998, 0.9983, 0.9986, 0.9988, 1);
+ --md-sys-motion-effects-fast-duration: 150ms;
+ --md-sys-motion-effects-default: linear(0, 0.0124, 0.0446, 0.0902, 0.1443, 0.2032, 0.2642, 0.3253, 0.3849, 0.4422, 0.4963, 0.547, 0.594, 0.6372, 0.6768, 0.7127, 0.7452, 0.7745, 0.8009, 0.8244, 0.8454, 0.8641, 0.8807, 0.8954, 0.9084, 0.9199, 0.93, 0.9389, 0.9467, 0.9536, 0.9596, 0.9648, 0.9694, 0.9734, 0.9769, 0.98, 0.9826, 0.985, 0.987, 0.9887, 0.9902, 0.9916, 0.9927, 0.9937, 0.9946, 0.9953, 0.9959, 0.9965, 1);
+ --md-sys-motion-effects-default-duration: 200ms;
- --shadow-1: 0 1px 2px rgb(0 0 0 / 0.3), 0 1px 3px 1px rgb(0 0 0 / 0.15);
- --shadow-3: 0 4px 8px 3px rgb(0 0 0 / 0.15), 0 1px 3px rgb(0 0 0 / 0.3);
+ /* State (tokens/state.css). */
+ --md-sys-state-hover-state-layer-opacity: 0.08;
+ --md-sys-state-focus-state-layer-opacity: 0.1;
+ --md-sys-state-pressed-state-layer-opacity: 0.1;
+ --md-sys-state-disabled-content-opacity: 0.38;
+ --md-sys-state-disabled-container-opacity: 0.12;
- --ease-spatial: cubic-bezier(0.38, 1.21, 0.22, 1);
- --ease-effects: cubic-bezier(0.34, 0.8, 0.34, 1);
+ /* Type (tokens/type.css). */
+ --md-ref-typeface-brand: 'Google Sans Flex', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+ --md-ref-typeface-plain: var(--md-ref-typeface-brand);
+ --md-ref-typeface-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
+ --md-ref-typeface-weight-regular: 400;
+ --md-ref-typeface-weight-medium: 500;
- --container: 1200px;
- --gutter: clamp(16px, 4vw, 32px);
+ --md-sys-typescale-display-lg: var(--md-ref-typeface-weight-regular) 3.5625rem/4rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-display-lg-tracking: -0.0125rem;
+ --md-sys-typescale-display-md: var(--md-ref-typeface-weight-regular) 2.8125rem/3.25rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-display-md-tracking: 0rem;
+ --md-sys-typescale-display-sm: var(--md-ref-typeface-weight-regular) 2.25rem/2.75rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-display-sm-tracking: 0rem;
+ --md-sys-typescale-headline-lg: var(--md-ref-typeface-weight-regular) 2rem/2.5rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-headline-lg-tracking: 0rem;
+ --md-sys-typescale-headline-md: var(--md-ref-typeface-weight-regular) 1.75rem/2.25rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-headline-md-tracking: 0rem;
+ --md-sys-typescale-title-lg: var(--md-ref-typeface-weight-regular) 1.375rem/1.75rem var(--md-ref-typeface-brand);
+ --md-sys-typescale-title-lg-tracking: 0rem;
+ --md-sys-typescale-title-md: var(--md-ref-typeface-weight-medium) 1rem/1.5rem var(--md-ref-typeface-plain);
+ --md-sys-typescale-title-md-tracking: 0.0125rem;
+ --md-sys-typescale-title-sm: var(--md-ref-typeface-weight-medium) 0.875rem/1.25rem var(--md-ref-typeface-plain);
+ --md-sys-typescale-title-sm-tracking: 0.00625rem;
+ --md-sys-typescale-body-lg: var(--md-ref-typeface-weight-regular) 1rem/1.5rem var(--md-ref-typeface-plain);
+ --md-sys-typescale-body-lg-tracking: 0.03125rem;
+ --md-sys-typescale-body-md: var(--md-ref-typeface-weight-regular) 0.875rem/1.25rem var(--md-ref-typeface-plain);
+ --md-sys-typescale-body-md-tracking: 0.0125rem;
+ --md-sys-typescale-label-lg: var(--md-ref-typeface-weight-medium) 0.875rem/1.25rem var(--md-ref-typeface-plain);
+ --md-sys-typescale-label-lg-tracking: 0.00625rem;
+
+ /* Spacing (tokens/spacing.css). */
+ --md-sys-measurement-space25: 2px;
+ --md-sys-measurement-space50: 4px;
+ --md-sys-measurement-space75: 6px;
+ --md-sys-measurement-space100: 8px;
+ --md-sys-measurement-space200: 16px;
+ --md-sys-measurement-space300: 24px;
+ --md-sys-measurement-space400: 32px;
+ --md-sys-measurement-space500: 40px;
+ --md-sys-measurement-space600: 48px;
+ --md-sys-measurement-space700: 56px;
+ --md-sys-measurement-space800: 64px;
+ --md-sys-measurement-space900: 72px;
+
+ /* The site's own layout: M3's margins (16px compact, 24px from medium) and the page width. */
+ --site-margin: var(--md-sys-measurement-space200);
+ --site-width: 1200px;
+ --site-bar-height: var(--md-sys-measurement-space800);
+ --site-section-space: var(--md-sys-measurement-space700);
}
-@media (prefers-color-scheme: dark) {
- :root {
- --surface: #10062d;
- --surface-container-lowest: #000000;
- --surface-container-low: #160b36;
- --surface-container: #1c113f;
- --surface-container-high: #231649;
- --surface-container-highest: #291c53;
- --on-surface: #eae1ff;
- --on-surface-variant: #b0a4d3;
- --outline: #7a6f9b;
- --outline-variant: #4b426a;
- --inverse-surface: #fdf7ff;
- --inverse-on-surface: #594f78;
- --primary: #a7a5ff;
- --on-primary: #1c00a0;
- --primary-container: #9795ff;
- --on-primary-container: #14007e;
- --secondary: #a98ffd;
- --secondary-container: #4d329b;
- --on-secondary-container: #d6c9ff;
- --tertiary-container: #fa88c8;
- --on-tertiary-container: #5e0042;
- --success: #69dca1;
- --error: #ff6e84;
+/* Colour: indigo, dark, standard contrast (profiles.indigo.dark). */
+:root[data-theme="dark"] {
+ color-scheme: dark;
- --code-surface: #000000;
- --code-ink: #eae1ff;
+ --md-sys-color-surface: #10062d;
+ --md-sys-color-surface-container-low: #160b36;
+ --md-sys-color-surface-container: #1c113f;
+ --md-sys-color-surface-container-high: #231649;
+ --md-sys-color-surface-container-highest: #291c53;
+ --md-sys-color-on-surface: #eae1ff;
+ --md-sys-color-on-surface-variant: #b0a4d3;
+ --md-sys-color-outline: #7a6f9b;
+ --md-sys-color-outline-variant: #4b426a;
+ --md-sys-color-primary: #a7a5ff;
+ --md-sys-color-on-primary: #1c00a0;
+ --md-sys-color-primary-container: #9795ff;
+ --md-sys-color-on-primary-container: #14007e;
+ --md-sys-color-secondary: #a98ffd;
+ --md-sys-color-secondary-container: #4d329b;
+ --md-sys-color-on-secondary-container: #d6c9ff;
+ --md-sys-color-tertiary-container: #fa88c8;
+ --md-sys-color-on-tertiary-container: #5e0042;
+ --md-sys-color-success: #3bb27b;
+}
+
+/* Without JavaScript there is no data-theme, and the system decides: the same dark values. */
+@media (prefers-color-scheme: dark) {
+ :root:not([data-theme]) {
+ color-scheme: dark;
+
+ --md-sys-color-surface: #10062d;
+ --md-sys-color-surface-container-low: #160b36;
+ --md-sys-color-surface-container: #1c113f;
+ --md-sys-color-surface-container-high: #231649;
+ --md-sys-color-surface-container-highest: #291c53;
+ --md-sys-color-on-surface: #eae1ff;
+ --md-sys-color-on-surface-variant: #b0a4d3;
+ --md-sys-color-outline: #7a6f9b;
+ --md-sys-color-outline-variant: #4b426a;
+ --md-sys-color-primary: #a7a5ff;
+ --md-sys-color-on-primary: #1c00a0;
+ --md-sys-color-primary-container: #9795ff;
+ --md-sys-color-on-primary-container: #14007e;
+ --md-sys-color-secondary: #a98ffd;
+ --md-sys-color-secondary-container: #4d329b;
+ --md-sys-color-on-secondary-container: #d6c9ff;
+ --md-sys-color-tertiary-container: #fa88c8;
+ --md-sys-color-on-tertiary-container: #5e0042;
+ --md-sys-color-success: #3bb27b;
+ }
+}
+
+/* High contrast, when the system asks for more: profiles.indigo.contrast.high. Light first, which the
+ dark selectors below outrank by specificity. */
+@media (prefers-contrast: more) {
+ :root {
+ --md-sys-color-surface: #faf4ff;
+ --md-sys-color-surface-container-low: #f5eeff;
+ --md-sys-color-surface-container: #ede4ff;
+ --md-sys-color-surface-container-high: #e8deff;
+ --md-sys-color-surface-container-highest: #e2d7ff;
+ --md-sys-color-on-surface: #000000;
+ --md-sys-color-on-surface-variant: #22193f;
+ --md-sys-color-outline: #433961;
+ --md-sys-color-outline-variant: #524972;
+ --md-sys-color-primary: #110075;
+ --md-sys-color-on-primary: #d3d0ff;
+ --md-sys-color-primary-container: #3c2ed5;
+ --md-sys-color-on-primary-container: #ffffff;
+ --md-sys-color-secondary: #240069;
+ --md-sys-color-secondary-container: #553ba4;
+ --md-sys-color-on-secondary-container: #ffffff;
+ --md-sys-color-tertiary-container: #882964;
+ --md-sys-color-on-tertiary-container: #ffffff;
+ --md-sys-color-success: #002515;
+ }
+
+ :root[data-theme="dark"] {
+ --md-sys-color-surface: #10062d;
+ --md-sys-color-surface-container-low: #160b36;
+ --md-sys-color-surface-container: #1c113f;
+ --md-sys-color-surface-container-high: #231649;
+ --md-sys-color-surface-container-highest: #291c53;
+ --md-sys-color-on-surface: #ffffff;
+ --md-sys-color-on-surface-variant: #eae1ff;
+ --md-sys-color-outline: #beb2e2;
+ --md-sys-color-outline-variant: #a99dcc;
+ --md-sys-color-primary: #e6e2ff;
+ --md-sys-color-on-primary: #1a0099;
+ --md-sys-color-primary-container: #9b99ff;
+ --md-sys-color-on-primary-container: #000000;
+ --md-sys-color-secondary: #eae1ff;
+ --md-sys-color-secondary-container: #ac93ff;
+ --md-sys-color-on-secondary-container: #000000;
+ --md-sys-color-tertiary-container: #fa88c8;
+ --md-sys-color-on-tertiary-container: #000000;
+ --md-sys-color-success: #89fcbf;
+ }
+}
+
+@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
+ :root:not([data-theme]) {
+ --md-sys-color-surface: #10062d;
+ --md-sys-color-surface-container-low: #160b36;
+ --md-sys-color-surface-container: #1c113f;
+ --md-sys-color-surface-container-high: #231649;
+ --md-sys-color-surface-container-highest: #291c53;
+ --md-sys-color-on-surface: #ffffff;
+ --md-sys-color-on-surface-variant: #eae1ff;
+ --md-sys-color-outline: #beb2e2;
+ --md-sys-color-outline-variant: #a99dcc;
+ --md-sys-color-primary: #e6e2ff;
+ --md-sys-color-on-primary: #1a0099;
+ --md-sys-color-primary-container: #9b99ff;
+ --md-sys-color-on-primary-container: #000000;
+ --md-sys-color-secondary: #eae1ff;
+ --md-sys-color-secondary-container: #ac93ff;
+ --md-sys-color-on-secondary-container: #000000;
+ --md-sys-color-tertiary-container: #fa88c8;
+ --md-sys-color-on-tertiary-container: #000000;
+ --md-sys-color-success: #89fcbf;
+ }
+}
+
+@media (width >= 600px) {
+ :root {
+ --site-margin: var(--md-sys-measurement-space300);
+ --site-section-space: var(--md-sys-measurement-space900);
+ }
+}
+
+@media (width >= 1200px) {
+ :root {
+ --site-section-space: calc(var(--md-sys-measurement-space600) * 2);
+ }
+}
+
+/* Reduced motion zeroes every duration, so everything that moves through the tokens turns instant. */
+@media (prefers-reduced-motion: reduce) {
+ :root {
+ --md-sys-motion-spatial-fast-duration: 0ms;
+ --md-sys-motion-effects-fast-duration: 0ms;
+ --md-sys-motion-effects-default-duration: 0ms;
}
}
@@ -114,18 +294,22 @@
html {
scroll-behavior: smooth;
- scroll-padding-top: 88px;
+ scroll-padding-top: calc(var(--site-bar-height) + var(--md-sys-measurement-space200));
-webkit-text-size-adjust: 100%;
}
+@media (prefers-reduced-motion: reduce) {
+ html {
+ scroll-behavior: auto;
+ }
+}
+
body {
margin: 0;
- background: var(--surface);
- color: var(--on-surface);
- font-family: var(--font);
- font-size: 16px;
- line-height: 1.5;
- letter-spacing: 0.01em;
+ background-color: var(--md-sys-color-surface);
+ color: var(--md-sys-color-on-surface);
+ font: var(--md-sys-typescale-body-lg);
+ letter-spacing: var(--md-sys-typescale-body-lg-tracking);
-webkit-font-smoothing: antialiased;
}
@@ -136,36 +320,37 @@ svg {
}
a {
- color: var(--primary);
- text-underline-offset: 3px;
-}
-
-a:hover {
- text-decoration-thickness: 2px;
+ color: var(--md-sys-color-primary);
+ text-decoration-line: underline;
+ text-decoration-thickness: from-font;
+ text-underline-offset: 0.15em;
}
+/* M3's focus indicator: 3px in secondary, 2px out, for keyboard focus only. */
:focus-visible {
- outline: 3px solid var(--primary);
- outline-offset: 3px;
- border-radius: var(--corner-sm);
+ outline: 3px solid var(--md-sys-color-secondary);
+ outline-offset: 2px;
+}
+
+h1,
+h2,
+h3,
+p {
+ margin: 0;
}
h1,
h2,
h3 {
- margin: 0;
- font-weight: 500;
- letter-spacing: 0;
text-wrap: balance;
}
p {
- margin: 0;
text-wrap: pretty;
}
code {
- font-family: var(--mono);
+ font-family: var(--md-ref-typeface-mono);
font-size: 0.9em;
}
@@ -193,242 +378,365 @@ code {
width: 1px;
height: 1px;
overflow: hidden;
- clip: rect(0 0 0 0);
+ clip-path: inset(50%);
white-space: nowrap;
}
-.skip-link {
+a.skip-link {
position: absolute;
- top: 8px;
- left: 8px;
+ inset-block-start: var(--md-sys-measurement-space100);
+ inset-inline-start: var(--md-sys-measurement-space100);
z-index: 100;
- padding: 12px 20px;
- border-radius: var(--corner-full);
- background: var(--primary);
- color: var(--on-primary);
- font-weight: 500;
translate: 0 -200%;
}
-.skip-link:focus-visible {
+a.skip-link:focus-visible {
translate: 0 0;
}
.container {
width: 100%;
- max-width: var(--container);
+ max-width: var(--site-width);
margin-inline: auto;
- padding-inline: var(--gutter);
+ padding-inline: var(--site-margin);
}
/* ---------------------------------------------------------------- type */
+/* The hero's line: display, larger as the window grows. */
.display {
- font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.25rem);
- line-height: 1.06;
- font-weight: 500;
- letter-spacing: -0.02em;
+ font: var(--md-sys-typescale-display-sm);
+ letter-spacing: var(--md-sys-typescale-display-sm-tracking);
}
+@media (width >= 600px) {
+ .display {
+ font: var(--md-sys-typescale-display-md);
+ letter-spacing: var(--md-sys-typescale-display-md-tracking);
+ }
+}
+
+@media (width >= 1200px) {
+ .display {
+ font: var(--md-sys-typescale-display-lg);
+ letter-spacing: var(--md-sys-typescale-display-lg-tracking);
+ }
+}
+
+/* Page and section titles. */
.headline {
- font-size: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem);
- line-height: 1.15;
- letter-spacing: -0.01em;
+ font: var(--md-sys-typescale-headline-md);
+ letter-spacing: var(--md-sys-typescale-headline-md-tracking);
}
+@media (width >= 600px) {
+ .headline {
+ font: var(--md-sys-typescale-headline-lg);
+ letter-spacing: var(--md-sys-typescale-headline-lg-tracking);
+ }
+}
+
+/* Card titles. */
.title {
- font-size: 1.375rem;
- line-height: 1.27;
+ font: var(--md-sys-typescale-title-lg);
+ letter-spacing: var(--md-sys-typescale-title-lg-tracking);
}
.lede {
- color: var(--on-surface-variant);
- font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
- line-height: 1.5;
+ max-inline-size: 60ch;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-lg);
+ letter-spacing: var(--md-sys-typescale-body-lg-tracking);
}
+/* A section's label above its title: an icon and a word on a tonal pill, not interactive. */
.eyebrow {
display: inline-flex;
justify-self: start;
width: fit-content;
align-items: center;
- gap: 8px;
- padding: 6px 14px;
- border-radius: var(--corner-full);
- background: var(--secondary-container);
- color: var(--on-secondary-container);
- font-size: 0.875rem;
- font-weight: 500;
- letter-spacing: 0.02em;
+ gap: var(--md-sys-measurement-space100);
+ padding-block: var(--md-sys-measurement-space75);
+ padding-inline: calc(var(--md-sys-measurement-space100) + var(--md-sys-measurement-space50)) var(--md-sys-measurement-space200);
+ border-radius: var(--md-sys-shape-corner-full);
+ background-color: var(--md-sys-color-secondary-container);
+ color: var(--md-sys-color-on-secondary-container);
+ font: var(--md-sys-typescale-label-lg);
+ letter-spacing: var(--md-sys-typescale-label-lg-tracking);
}
.eyebrow .icon {
- width: 18px;
- height: 18px;
-}
-
-/* ---------------------------------------------------------------- buttons */
-
-.btn {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
- min-height: 48px;
- padding: 12px 24px;
- border: 1px solid transparent;
- border-radius: var(--corner-full);
- font: inherit;
- font-size: 1rem;
- font-weight: 500;
- line-height: 1.25;
- text-decoration: none;
- white-space: nowrap;
- cursor: pointer;
- transition: border-radius 250ms var(--ease-spatial), background-color 150ms var(--ease-effects);
-}
-
-.btn:hover {
- text-decoration: none;
-}
-
-.btn:active {
- border-radius: var(--corner-md);
-}
-
-.btn .icon {
width: 20px;
height: 20px;
}
-.btn--filled {
- background: var(--primary);
- color: var(--on-primary);
+/* ---------------------------------------------------------------- interaction */
+
+/* M3's state layer: the content colour over the element, 8% on hover, 10% on focus and press. */
+.btn,
+.icon-btn,
+.nav__links a:not(.btn),
+.faq summary {
+ position: relative;
+ isolation: isolate;
}
-.btn--filled:hover {
- background: color-mix(in srgb, var(--primary) 88%, var(--on-primary));
+.btn::before,
+.icon-btn::before,
+.nav__links a:not(.btn)::before,
+.faq summary::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+ border-radius: inherit;
+ background-color: currentColor;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
}
-.btn--tonal {
- background: var(--secondary-container);
- color: var(--on-secondary-container);
+@media (hover: hover) {
+ .btn:hover::before,
+ .icon-btn:hover::before,
+ .nav__links a:not(.btn):hover::before,
+ .faq summary:hover::before {
+ opacity: var(--md-sys-state-hover-state-layer-opacity);
+ }
}
-.btn--tonal:hover {
- background: color-mix(in srgb, var(--secondary-container) 88%, var(--on-secondary-container));
+.btn:focus-visible::before,
+.icon-btn:focus-visible::before,
+.nav__links a:not(.btn):focus-visible::before,
+.faq summary:focus-visible::before {
+ opacity: var(--md-sys-state-focus-state-layer-opacity);
}
-.btn--outlined {
- border-color: var(--outline-variant);
- color: var(--primary);
+.btn:active::before,
+.icon-btn:active::before,
+.nav__links a:not(.btn):active::before,
+.faq summary:active::before {
+ opacity: var(--md-sys-state-pressed-state-layer-opacity);
}
-.btn--outlined:hover {
- background: color-mix(in srgb, var(--primary) 8%, transparent);
+/* M3's 48px minimum target around a control drawn smaller. */
+.btn::after,
+.icon-btn::after,
+.nav__links a:not(.btn)::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 100%;
+ height: 100%;
+ min-width: var(--md-sys-measurement-space600);
+ min-height: var(--md-sys-measurement-space600);
+ transform: translate(-50%, -50%);
+}
+
+/* ---------------------------------------------------------------- buttons */
+
+/* M3 Expressive buttons. The default is the small size (40px, label-large); .btn--lg is the medium
+ size (56px, title-medium) for the page's main calls to action. Round at rest, squarer while
+ pressed, on the fast spatial spring; colours on the fast effects spring. */
+.btn {
+ --btn-height: 40px;
+ --btn-padding: var(--md-sys-measurement-space200);
+ --btn-icon: 20px;
+ --btn-pressed: var(--md-sys-shape-corner-sm);
+
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--md-sys-measurement-space100);
+ min-block-size: var(--btn-height);
+ padding-inline: var(--btn-padding);
+ border: 0;
+ border-radius: calc(var(--btn-height) / 2);
+ background-color: transparent;
+ color: var(--md-sys-color-primary);
+ font: var(--md-sys-typescale-label-lg);
+ letter-spacing: var(--md-sys-typescale-label-lg-tracking);
+ text-decoration: none;
+ white-space: nowrap;
+ cursor: pointer;
+ -webkit-user-select: none;
+ user-select: none;
+ transition-property: border-radius, background-color, color, box-shadow;
+ transition-duration: var(--md-sys-motion-spatial-fast-duration), var(--md-sys-motion-effects-fast-duration), var(--md-sys-motion-effects-fast-duration), var(--md-sys-motion-effects-fast-duration);
+ transition-timing-function: var(--md-sys-motion-spatial-fast), var(--md-sys-motion-effects-fast), var(--md-sys-motion-effects-fast), var(--md-sys-motion-effects-fast);
+}
+
+.btn:active {
+ border-radius: var(--btn-pressed);
+}
+
+.btn .icon {
+ width: var(--btn-icon);
+ height: var(--btn-icon);
}
.btn--lg {
- min-height: 56px;
- padding: 16px 28px;
- font-size: 1.0625rem;
+ --btn-height: 56px;
+ --btn-padding: var(--md-sys-measurement-space300);
+ --btn-icon: 24px;
+ --btn-pressed: var(--md-sys-shape-corner-md);
+
+ font: var(--md-sys-typescale-title-md);
+ letter-spacing: var(--md-sys-typescale-title-md-tracking);
+}
+
+.btn--filled {
+ background-color: var(--md-sys-color-primary);
+ color: var(--md-sys-color-on-primary);
+}
+
+.btn--tonal {
+ background-color: var(--md-sys-color-secondary-container);
+ color: var(--md-sys-color-on-secondary-container);
+}
+
+.btn--outlined {
+ border: 1px solid var(--md-sys-color-outline-variant);
+ color: var(--md-sys-color-on-surface-variant);
+}
+
+@media (hover: hover) {
+ .btn--filled:hover,
+ .btn--tonal:hover {
+ box-shadow: var(--md-sys-elevation-1);
+ }
+}
+
+.btn:is(:disabled, [aria-disabled="true"]) {
+ box-shadow: none;
+ color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity) * 100%), transparent);
+ cursor: not-allowed;
+}
+
+.btn:is(.btn--filled, .btn--tonal):is(:disabled, [aria-disabled="true"]) {
+ background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity) * 100%), transparent);
+}
+
+.btn:is(:disabled, [aria-disabled="true"])::before {
+ display: none;
+}
+
+/* A standard icon button: 40px drawn, a 48px target, on-surface-variant. */
+.icon-btn {
+ display: inline-flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ padding: 0;
+ border: 0;
+ border-radius: 20px;
+ background-color: transparent;
+ color: var(--md-sys-color-on-surface-variant);
+ cursor: pointer;
+ transition: border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);
+}
+
+.icon-btn:active {
+ border-radius: var(--md-sys-shape-corner-sm);
+}
+
+/* M3 Expressive's connected button group, the successor of segmented buttons: segments 2px apart,
+ round outer corners and small inner ones, and the chosen segment (aria-pressed) fully round in
+ secondary-container with a check. */
+.button-group {
+ display: inline-flex;
+ gap: var(--md-sys-measurement-space25);
+}
+
+.button-group .btn {
+ min-inline-size: var(--md-sys-measurement-space600);
+ border-radius: var(--md-sys-shape-corner-sm);
+ background-color: var(--md-sys-color-surface-container);
+ color: var(--md-sys-color-on-surface-variant);
+}
+
+.button-group .btn:first-child {
+ border-start-start-radius: calc(var(--btn-height) / 2);
+ border-end-start-radius: calc(var(--btn-height) / 2);
+}
+
+.button-group .btn:last-child {
+ border-start-end-radius: calc(var(--btn-height) / 2);
+ border-end-end-radius: calc(var(--btn-height) / 2);
+}
+
+.button-group .btn:active {
+ border-radius: var(--md-sys-shape-corner-xs);
+}
+
+.button-group .btn:first-child:active {
+ border-radius: calc(var(--btn-height) / 2) var(--md-sys-shape-corner-xs) var(--md-sys-shape-corner-xs) calc(var(--btn-height) / 2);
+}
+
+.button-group .btn:last-child:active {
+ border-radius: var(--md-sys-shape-corner-xs) calc(var(--btn-height) / 2) calc(var(--btn-height) / 2) var(--md-sys-shape-corner-xs);
+}
+
+.button-group .btn[aria-pressed="true"] {
+ border-radius: calc(var(--btn-height) / 2);
+ background-color: var(--md-sys-color-secondary-container);
+ color: var(--md-sys-color-on-secondary-container);
+}
+
+.button-group .btn .icon {
+ display: none;
+}
+
+.button-group .btn[aria-pressed="true"] .icon {
+ display: block;
}
/* ---------------------------------------------------------------- nav */
+/* The top app bar: surface at rest, surface-container once the page scrolls under it. */
.nav {
position: sticky;
top: 0;
z-index: 50;
- background: color-mix(in srgb, var(--surface) 86%, transparent);
- backdrop-filter: blur(16px);
- -webkit-backdrop-filter: blur(16px);
- border-bottom: 1px solid color-mix(in srgb, var(--outline-variant) 45%, transparent);
+ background-color: var(--md-sys-color-surface);
+ transition: background-color var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);
+}
+
+.nav[data-scrolled] {
+ background-color: var(--md-sys-color-surface-container);
}
.nav__bar {
display: flex;
align-items: center;
- gap: 16px;
- min-height: 72px;
+ gap: var(--md-sys-measurement-space100);
+ min-height: var(--site-bar-height);
}
.brand {
display: inline-flex;
align-items: center;
- gap: 10px;
- color: var(--on-surface);
- font-size: 1.375rem;
- font-weight: 500;
- text-decoration: none;
-}
-
-.brand:hover {
+ gap: var(--md-sys-measurement-space100);
+ min-block-size: var(--md-sys-measurement-space600);
+ color: var(--md-sys-color-on-surface);
+ font: var(--md-sys-typescale-title-lg);
+ letter-spacing: var(--md-sys-typescale-title-lg-tracking);
text-decoration: none;
}
.brand svg {
width: 32px;
height: 32px;
- color: var(--primary);
-}
-
-.nav__bar > nav {
- margin-left: auto;
-}
-
-.nav__links {
- display: flex;
- align-items: center;
- gap: 4px;
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-.nav__links a {
- display: inline-flex;
- align-items: center;
- min-height: 40px;
- padding: 8px 14px;
- border-radius: var(--corner-full);
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
- font-weight: 500;
- text-decoration: none;
-}
-
-.nav__links a:hover {
- background: color-mix(in srgb, var(--on-surface) 8%, transparent);
- color: var(--on-surface);
-}
-
-.nav__links .btn {
- margin-left: 8px;
- color: var(--on-primary);
-}
-
-.nav__links .btn:hover {
- color: var(--on-primary);
- background: color-mix(in srgb, var(--primary) 88%, var(--on-primary));
+ color: var(--md-sys-color-primary);
}
.nav__toggle {
display: none;
- margin-left: auto;
- width: 48px;
- height: 48px;
- align-items: center;
- justify-content: center;
- border: 0;
- border-radius: var(--corner-full);
- background: transparent;
- color: var(--on-surface);
- cursor: pointer;
-}
-
-.nav__toggle:hover {
- background: color-mix(in srgb, var(--on-surface) 8%, transparent);
+ margin-inline-start: auto;
+ color: var(--md-sys-color-on-surface);
}
.nav__toggle .icon-close {
@@ -443,44 +751,92 @@ code {
display: block;
}
-@media (max-width: 960px) {
+.nav__bar > nav {
+ margin-inline-start: auto;
+}
+
+.nav__links {
+ display: flex;
+ align-items: center;
+ gap: var(--md-sys-measurement-space50);
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.nav__links a:not(.btn) {
+ display: inline-flex;
+ align-items: center;
+ min-block-size: 40px;
+ padding-inline: calc(var(--md-sys-measurement-space100) + var(--md-sys-measurement-space50));
+ border-radius: 20px;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-label-lg);
+ letter-spacing: var(--md-sys-typescale-label-lg-tracking);
+ text-decoration: none;
+}
+
+.nav__links .btn {
+ margin-inline-start: var(--md-sys-measurement-space100);
+}
+
+/* Light, Dark or System. Without JavaScript there is nothing to switch, so it stays hidden. */
+.theme-toggle {
+ display: none;
+}
+
+:root[data-theme-choice] .theme-toggle {
+ display: inline-flex;
+}
+
+.theme-toggle .icon {
+ display: none;
+}
+
+:root[data-theme-choice="light"] .theme-toggle .icon-light-mode,
+:root[data-theme-choice="dark"] .theme-toggle .icon-dark-mode,
+:root[data-theme-choice="system"] .theme-toggle .icon-brightness-auto {
+ display: block;
+}
+
+/* Below expanded, the links fold into a menu under the bar. */
+@media (width < 840px) {
.nav__toggle {
display: inline-flex;
}
+ .nav__bar > nav {
+ margin-inline-start: 0;
+ }
+
.nav__links {
position: absolute;
- top: 100%;
- left: var(--gutter);
- right: var(--gutter);
+ inset-block-start: 100%;
+ inset-inline: var(--site-margin);
display: none;
flex-direction: column;
align-items: stretch;
- gap: 2px;
- margin: 8px 0 0;
- padding: 8px;
- border-radius: var(--corner-xl);
- background: var(--surface-container);
- box-shadow: var(--shadow-3);
+ gap: 0;
+ padding-block: var(--md-sys-measurement-space100);
+ border-radius: var(--md-sys-shape-corner-xs);
+ background-color: var(--md-sys-color-surface-container);
+ box-shadow: var(--md-sys-elevation-2);
}
.nav__links.is-open {
display: flex;
}
- .nav__links a {
- min-height: 48px;
- padding: 12px 16px;
- font-size: 1rem;
- }
-
- .nav__bar > nav {
- margin-left: 0;
+ .nav__links a:not(.btn) {
+ min-block-size: var(--md-sys-measurement-space600);
+ padding-inline: var(--md-sys-measurement-space200);
+ border-radius: 0;
+ color: var(--md-sys-color-on-surface);
}
.nav__links .btn {
- width: 100%;
- margin: 8px 0 0;
+ width: calc(100% - 2 * var(--md-sys-measurement-space200));
+ margin: var(--md-sys-measurement-space100) var(--md-sys-measurement-space200) 0;
}
}
@@ -489,113 +845,129 @@ code {
.hero {
position: relative;
overflow: clip;
- padding-block: clamp(40px, 7vw, 96px) clamp(56px, 8vw, 112px);
+ padding-block: var(--md-sys-measurement-space500) var(--md-sys-measurement-space700);
}
.hero__grid {
display: grid;
- grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
align-items: center;
- gap: clamp(32px, 5vw, 72px);
+ gap: var(--md-sys-measurement-space500);
}
.hero__copy {
display: grid;
- gap: 24px;
+ gap: var(--md-sys-measurement-space300);
justify-items: start;
}
.hero__actions {
display: flex;
flex-wrap: wrap;
- gap: 12px;
- margin-top: 8px;
+ gap: var(--md-sys-measurement-space200);
+ margin-block-start: var(--md-sys-measurement-space100);
}
.hero__facts {
display: flex;
flex-wrap: wrap;
- gap: 8px 20px;
- margin: 8px 0 0;
+ gap: var(--md-sys-measurement-space100) var(--md-sys-measurement-space300);
+ margin: var(--md-sys-measurement-space100) 0 0;
padding: 0;
list-style: none;
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
.hero__facts li {
display: inline-flex;
align-items: center;
- gap: 6px;
+ gap: var(--md-sys-measurement-space75);
}
.hero__facts .icon {
- width: 18px;
- height: 18px;
- color: var(--success);
+ width: 20px;
+ height: 20px;
+ color: var(--md-sys-color-success);
}
.hero__visual {
position: relative;
- padding: 0 0 48px;
+ padding-block-end: var(--md-sys-measurement-space500);
}
.hero__visual .device--phone {
position: absolute;
- right: -2%;
+ inset-inline-end: -2%;
bottom: 0;
width: 25%;
}
+/* Two Expressive shapes behind the devices: decoration only. */
.hero__shape {
position: absolute;
z-index: -1;
fill: currentColor;
- color: var(--secondary-container);
- opacity: 0.7;
}
.hero__shape--one {
top: -8%;
- right: -6%;
+ inset-inline-end: -6%;
width: 46%;
+ color: var(--md-sys-color-secondary-container);
rotate: 12deg;
}
.hero__shape--two {
bottom: -4%;
- left: -10%;
+ inset-inline-start: -10%;
width: 30%;
- color: var(--tertiary-container);
- opacity: 0.35;
+ color: var(--md-sys-color-surface-container-highest);
}
-@media (max-width: 960px) {
+@media (width >= 600px) {
+ .hero {
+ padding-block: var(--md-sys-measurement-space800) var(--md-sys-measurement-space900);
+ }
+}
+
+@media (width >= 840px) {
.hero__grid {
- grid-template-columns: 1fr;
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
+ gap: var(--md-sys-measurement-space600);
}
.hero__visual {
- padding-bottom: 36px;
+ padding-block-end: var(--md-sys-measurement-space600);
+ }
+}
+
+@media (width >= 1200px) {
+ .hero {
+ padding-block: calc(var(--md-sys-measurement-space600) * 2) calc(var(--md-sys-measurement-space700) * 2);
+ }
+
+ .hero__grid {
+ gap: var(--md-sys-measurement-space900);
}
}
/* ---------------------------------------------------------------- sections */
.section {
- padding-block: clamp(56px, 8vw, 104px);
+ padding-block: var(--site-section-space);
overflow-x: clip;
}
.section--tint {
- background: var(--surface-container-low);
+ background-color: var(--md-sys-color-surface-container-low);
}
.section__head {
display: grid;
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
max-width: 760px;
- margin-bottom: clamp(32px, 5vw, 56px);
+ margin-block-end: var(--md-sys-measurement-space400);
}
.section__head--center {
@@ -604,61 +976,73 @@ code {
justify-items: center;
}
+@media (width >= 600px) {
+ .section__head {
+ margin-block-end: var(--md-sys-measurement-space600);
+ }
+}
+
+/* M3's outlined card: surface, an outline-variant edge, the medium corner, and no shape change. */
+.reason,
+.step,
+.feature,
+.faq details,
+.contact,
+.table-scroll {
+ border: 1px solid var(--md-sys-color-outline-variant);
+ border-radius: var(--md-sys-shape-corner-md);
+ background-color: var(--md-sys-color-surface);
+}
+
/* "Why run your own": a statement beside four reasons. */
.why {
display: grid;
- grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
- gap: clamp(32px, 5vw, 72px);
+ gap: var(--md-sys-measurement-space500);
align-items: start;
}
.why__statement {
- position: sticky;
- top: 104px;
display: grid;
- gap: 20px;
+ gap: var(--md-sys-measurement-space300);
}
.reasons {
display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
}
.reason {
display: grid;
- gap: 12px;
+ gap: var(--md-sys-measurement-space200);
align-content: start;
- padding: 28px;
- border-radius: var(--corner-xl);
- background: var(--surface-container);
-}
-
-.reason:nth-child(1) {
- border-radius: var(--corner-xxl) var(--corner-xl) var(--corner-xl) var(--corner-xl);
-}
-
-.reason:nth-child(4) {
- border-radius: var(--corner-xl) var(--corner-xl) var(--corner-xxl) var(--corner-xl);
+ padding: var(--md-sys-measurement-space300);
}
.reason p {
- color: var(--on-surface-variant);
+ color: var(--md-sys-color-on-surface-variant);
}
-@media (max-width: 960px) {
+@media (width >= 600px) {
+ .reasons {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+
+@media (width >= 840px) {
.why {
- grid-template-columns: 1fr;
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
+ gap: var(--md-sys-measurement-space600);
}
.why__statement {
- position: static;
+ position: sticky;
+ top: calc(var(--site-bar-height) + var(--md-sys-measurement-space400));
}
}
-@media (max-width: 600px) {
- .reasons {
- grid-template-columns: 1fr;
+@media (width >= 1200px) {
+ .why {
+ gap: var(--md-sys-measurement-space900);
}
}
@@ -669,7 +1053,7 @@ code {
place-items: center;
width: 56px;
height: 56px;
- color: var(--on-primary-container);
+ color: var(--md-sys-color-on-primary-container);
}
.badge-icon > svg:first-child {
@@ -677,37 +1061,34 @@ code {
inset: 0;
width: 100%;
height: 100%;
- color: var(--primary-container);
+ color: var(--md-sys-color-primary-container);
fill: currentColor;
}
.badge-icon .icon {
position: relative;
- width: 26px;
- height: 26px;
}
.badge-icon--secondary {
- color: var(--on-secondary-container);
+ color: var(--md-sys-color-on-secondary-container);
}
.badge-icon--secondary > svg:first-child {
- color: var(--secondary-container);
+ color: var(--md-sys-color-secondary-container);
}
.badge-icon--tertiary {
- color: var(--on-tertiary-container);
+ color: var(--md-sys-color-on-tertiary-container);
}
.badge-icon--tertiary > svg:first-child {
- color: var(--tertiary-container);
+ color: var(--md-sys-color-tertiary-container);
}
/* How it works: three steps. */
.steps {
display: grid;
- grid-template-columns: repeat(3, minmax(0, 1fr));
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
margin: 0;
padding: 0;
list-style: none;
@@ -717,60 +1098,45 @@ code {
.step {
position: relative;
display: grid;
- gap: 14px;
+ gap: var(--md-sys-measurement-space200);
align-content: start;
- padding: 32px 28px 28px;
- border-radius: var(--corner-xl);
- background: var(--surface-container-lowest);
+ padding: var(--md-sys-measurement-space300);
counter-increment: step;
}
-@media (prefers-color-scheme: dark) {
- .step {
- background: var(--surface-container);
- }
-}
-
+/* The step's number, a decoration beside its title. */
.step::before {
content: counter(step);
position: absolute;
- top: 24px;
- right: 28px;
- color: var(--outline-variant);
- font-size: 3rem;
- font-weight: 500;
- line-height: 1;
+ inset-block-start: var(--md-sys-measurement-space300);
+ inset-inline-end: var(--md-sys-measurement-space300);
+ color: var(--md-sys-color-outline);
+ font: var(--md-sys-typescale-display-md);
+ letter-spacing: var(--md-sys-typescale-display-md-tracking);
}
.step p {
- color: var(--on-surface-variant);
+ color: var(--md-sys-color-on-surface-variant);
}
-@media (max-width: 840px) {
+@media (width >= 840px) {
.steps {
- grid-template-columns: 1fr;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
/* Features. */
.features {
display: grid;
- grid-template-columns: repeat(3, minmax(0, 1fr));
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
}
.feature {
display: grid;
grid-template-columns: auto 1fr;
- gap: 4px 16px;
+ gap: var(--md-sys-measurement-space50) var(--md-sys-measurement-space200);
align-content: start;
- padding: 24px;
- border-radius: var(--corner-xl);
- background: var(--surface-container-low);
-}
-
-.section--tint .feature {
- background: var(--surface-container);
+ padding: var(--md-sys-measurement-space300);
}
.feature .badge-icon {
@@ -779,31 +1145,28 @@ code {
height: 48px;
}
-.feature .badge-icon .icon {
- width: 22px;
- height: 22px;
-}
-
.feature h3 {
align-self: end;
- font-size: 1.0625rem;
- line-height: 1.4;
+ font: var(--md-sys-typescale-title-md);
+ letter-spacing: var(--md-sys-typescale-title-md-tracking);
}
.feature p {
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
-@media (max-width: 960px) {
+@media (width >= 600px) {
.features {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
-@media (max-width: 600px) {
+/* Three columns only from large: at expanded they leave too little room for the text. */
+@media (width >= 1200px) {
.features {
- grid-template-columns: 1fr;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@@ -813,78 +1176,21 @@ code {
display: flex;
flex-wrap: wrap;
justify-content: center;
- gap: 12px 16px;
- margin-bottom: 40px;
-}
-
-/* M3 segmented buttons. */
-.segmented {
- display: inline-flex;
- border: 1px solid var(--outline);
- border-radius: var(--corner-full);
-}
-
-.segmented button {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- min-height: 40px;
- padding: 8px 18px;
- border: 0;
- background: transparent;
- color: var(--on-surface);
- font: inherit;
- font-size: 0.875rem;
- font-weight: 500;
- cursor: pointer;
-}
-
-.segmented button + button {
- border-left: 1px solid var(--outline);
-}
-
-.segmented button:first-child {
- border-radius: var(--corner-full) 0 0 var(--corner-full);
-}
-
-.segmented button:last-child {
- border-radius: 0 var(--corner-full) var(--corner-full) 0;
-}
-
-.segmented button:hover {
- background: color-mix(in srgb, var(--on-surface) 8%, transparent);
-}
-
-.segmented button[aria-pressed="true"] {
- background: var(--secondary-container);
- color: var(--on-secondary-container);
-}
-
-.segmented .icon {
- display: none;
- width: 18px;
- height: 18px;
-}
-
-.segmented button[aria-pressed="true"] .icon {
- display: block;
+ gap: var(--md-sys-measurement-space200) var(--md-sys-measurement-space300);
+ margin-block-end: var(--md-sys-measurement-space500);
}
.gallery {
display: grid;
- gap: 40px 32px;
+ gap: var(--md-sys-measurement-space500) var(--md-sys-measurement-space400);
margin: 0;
padding: 0;
list-style: none;
}
-.gallery--desktop {
- grid-template-columns: repeat(2, minmax(0, 1fr));
- column-gap: clamp(40px, 6vw, 88px);
-}
-
.gallery--phone {
- grid-template-columns: repeat(4, minmax(0, 1fr));
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ column-gap: var(--md-sys-measurement-space200);
max-width: 1040px;
margin-inline: auto;
}
@@ -895,33 +1201,42 @@ code {
.shot {
display: grid;
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
margin: 0;
}
.shot figcaption {
display: grid;
- gap: 2px;
+ gap: var(--md-sys-measurement-space25);
text-align: center;
}
.shot figcaption strong {
- font-weight: 500;
+ font: var(--md-sys-typescale-title-md);
+ letter-spacing: var(--md-sys-typescale-title-md-tracking);
}
.shot figcaption span {
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
-@media (max-width: 840px) {
+@media (width >= 840px) {
.gallery--desktop {
- grid-template-columns: 1fr;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ column-gap: var(--md-sys-measurement-space600);
}
.gallery--phone {
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 32px 20px;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ column-gap: var(--md-sys-measurement-space400);
+ }
+}
+
+@media (width >= 1200px) {
+ .gallery--desktop {
+ column-gap: calc(var(--md-sys-measurement-space400) + var(--md-sys-measurement-space700));
}
}
@@ -929,137 +1244,117 @@ code {
.compare {
display: grid;
- gap: 48px;
+ gap: var(--md-sys-measurement-space600);
}
.compare__block {
display: grid;
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
}
.compare__block h3 {
- font-size: 1.375rem;
+ font: var(--md-sys-typescale-title-lg);
+ letter-spacing: var(--md-sys-typescale-title-lg-tracking);
}
.compare__block > p {
- color: var(--on-surface-variant);
+ color: var(--md-sys-color-on-surface-variant);
}
.table-scroll {
overflow-x: auto;
- border: 1px solid var(--outline-variant);
- border-radius: var(--corner-xl);
- background: var(--surface-container-lowest);
-webkit-overflow-scrolling: touch;
}
-@media (prefers-color-scheme: dark) {
- .table-scroll {
- background: var(--surface-container-low);
- }
-}
-
-.table-scroll:focus-visible {
- outline-offset: 2px;
- border-radius: var(--corner-xl);
-}
-
.compare table {
width: 100%;
min-width: 860px;
border-collapse: separate;
border-spacing: 0;
- font-size: 0.9375rem;
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
.compare caption {
- padding: 14px 20px;
- border-bottom: 1px solid var(--outline-variant);
- color: var(--on-surface-variant);
- font-size: 0.875rem;
- text-align: left;
+ padding: var(--md-sys-measurement-space200) var(--md-sys-measurement-space300);
+ border-block-end: 1px solid var(--md-sys-color-outline-variant);
+ color: var(--md-sys-color-on-surface-variant);
+ text-align: start;
}
.compare th,
.compare td {
- padding: 12px 16px;
- border-bottom: 1px solid color-mix(in srgb, var(--outline-variant) 60%, transparent);
- text-align: left;
+ padding: calc(var(--md-sys-measurement-space100) + var(--md-sys-measurement-space50)) var(--md-sys-measurement-space200);
+ border-block-end: 1px solid var(--md-sys-color-outline-variant);
+ text-align: start;
vertical-align: top;
}
.compare tbody tr:last-child > * {
- border-bottom: 0;
+ border-block-end: 0;
+}
+
+.compare thead tr {
+ background-color: var(--md-sys-color-surface);
}
.compare thead th {
- color: var(--on-surface);
- font-weight: 500;
+ color: var(--md-sys-color-on-surface);
+ font: var(--md-sys-typescale-title-sm);
+ letter-spacing: var(--md-sys-typescale-title-sm-tracking);
white-space: nowrap;
}
.compare tbody th {
position: sticky;
- left: 0;
+ inset-inline-start: 0;
z-index: 1;
min-width: 170px;
- background: var(--surface-container-lowest);
- color: var(--on-surface-variant);
- font-weight: 500;
-}
-
-@media (prefers-color-scheme: dark) {
- .compare tbody th {
- background: var(--surface-container-low);
- }
+ background-color: var(--md-sys-color-surface);
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-title-sm);
+ letter-spacing: var(--md-sys-typescale-title-sm-tracking);
}
.compare thead th:first-child {
position: sticky;
- left: 0;
+ inset-inline-start: 0;
z-index: 2;
- background: inherit;
+ background-color: var(--md-sys-color-surface);
}
-.compare thead tr {
- background: var(--surface-container-lowest);
-}
-
-@media (prefers-color-scheme: dark) {
- .compare thead tr {
- background: var(--surface-container-low);
- }
-}
-
-/* SealShare's own column. */
+/* SealShare's own column: its heading in the secondary-container pair, its cells a tone up. */
.compare .is-us {
- background: color-mix(in srgb, var(--secondary-container) 55%, transparent);
- color: var(--on-surface);
+ background-color: var(--md-sys-color-surface-container-high);
+ color: var(--md-sys-color-on-surface);
}
.compare thead .is-us {
- color: var(--on-secondary-container);
+ background-color: var(--md-sys-color-secondary-container);
+ color: var(--md-sys-color-on-secondary-container);
}
.compare__sources {
display: grid;
- gap: 6px;
+ gap: var(--md-sys-measurement-space100);
margin: 0;
- padding-left: 20px;
- color: var(--on-surface-variant);
- font-size: 0.875rem;
+ padding-inline-start: var(--md-sys-measurement-space300);
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
overflow-wrap: anywhere;
}
.compare__note {
- color: var(--on-surface-variant);
- font-size: 0.875rem;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
/* The numbered notes under the tables read as one block. */
.compare__notes {
display: grid;
- gap: 8px;
+ gap: var(--md-sys-measurement-space100);
}
.compare__notes sup,
@@ -1071,20 +1366,19 @@ code {
.install {
display: grid;
- grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
- gap: clamp(32px, 5vw, 64px);
+ gap: var(--md-sys-measurement-space500);
align-items: start;
}
.install__copy {
display: grid;
- gap: 20px;
+ gap: var(--md-sys-measurement-space300);
justify-items: start;
}
.install__list {
display: grid;
- gap: 12px;
+ gap: var(--md-sys-measurement-space200);
margin: 0;
padding: 0;
list-style: none;
@@ -1093,55 +1387,65 @@ code {
.install__list li {
display: grid;
grid-template-columns: auto 1fr;
- gap: 12px;
- color: var(--on-surface-variant);
+ gap: var(--md-sys-measurement-space200);
+ color: var(--md-sys-color-on-surface-variant);
}
.install__list .icon {
- width: 22px;
- height: 22px;
- color: var(--primary);
+ color: var(--md-sys-color-primary);
}
+/* The compose commands: a filled card (surface-container-highest) in the theme's own ink. */
.code {
overflow: hidden;
- border-radius: var(--corner-xl);
- background: var(--code-surface);
- color: var(--code-ink);
- box-shadow: var(--shadow-1);
+ border-radius: var(--md-sys-shape-corner-md);
+ background-color: var(--md-sys-color-surface-container-highest);
+ color: var(--md-sys-color-on-surface);
}
.code__bar {
display: flex;
align-items: center;
- gap: 8px;
- padding: 14px 20px;
- border-bottom: 1px solid rgb(255 255 255 / 0.1);
- color: rgb(234 225 255 / 0.7);
- font-size: 0.875rem;
+ gap: var(--md-sys-measurement-space100);
+ padding: var(--md-sys-measurement-space200) var(--md-sys-measurement-space300);
+ border-block-end: 1px solid var(--md-sys-color-outline-variant);
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-label-lg);
+ letter-spacing: var(--md-sys-typescale-label-lg-tracking);
}
.code__bar .icon {
- width: 18px;
- height: 18px;
+ width: 20px;
+ height: 20px;
}
.code pre {
margin: 0;
- padding: 20px;
+ padding: var(--md-sys-measurement-space300);
overflow-x: auto;
- font-family: var(--mono);
+ font-family: var(--md-ref-typeface-mono);
font-size: 0.875rem;
- line-height: 1.7;
+ line-height: 1.5rem;
+}
+
+.code pre code {
+ font-size: inherit;
}
.code .comment {
- color: rgb(234 225 255 / 0.55);
+ color: var(--md-sys-color-on-surface-variant);
}
-@media (max-width: 960px) {
+@media (width >= 840px) {
.install {
- grid-template-columns: 1fr;
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
+ gap: var(--md-sys-measurement-space600);
+ }
+}
+
+@media (width >= 1200px) {
+ .install {
+ gap: var(--md-sys-measurement-space800);
}
}
@@ -1149,42 +1453,37 @@ code {
.faq {
display: grid;
- gap: 8px;
+ gap: var(--md-sys-measurement-space100);
max-width: 860px;
margin-inline: auto;
}
-.faq details {
- border-radius: var(--corner-lg);
- background: var(--surface-container);
- transition: border-radius 250ms var(--ease-spatial);
-}
-
-.faq details[open] {
- border-radius: var(--corner-xl);
-}
-
.faq summary {
display: flex;
align-items: center;
justify-content: space-between;
- gap: 16px;
- min-height: 64px;
- padding: 16px 24px;
- border-radius: inherit;
- font-size: 1.0625rem;
- font-weight: 500;
+ gap: var(--md-sys-measurement-space200);
+ min-height: var(--md-sys-measurement-space800);
+ padding: var(--md-sys-measurement-space200) var(--md-sys-measurement-space300);
+ border-radius: calc(var(--md-sys-shape-corner-md) - 1px);
+ font: var(--md-sys-typescale-title-md);
+ letter-spacing: var(--md-sys-typescale-title-md-tracking);
cursor: pointer;
list-style: none;
}
+.faq details[open] summary {
+ border-end-start-radius: 0;
+ border-end-end-radius: 0;
+}
+
.faq summary::-webkit-details-marker {
display: none;
}
.faq summary .icon {
- color: var(--on-surface-variant);
- transition: rotate 250ms var(--ease-spatial);
+ color: var(--md-sys-color-on-surface-variant);
+ transition: rotate var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);
}
.faq details[open] summary .icon {
@@ -1193,9 +1492,9 @@ code {
.faq__answer {
display: grid;
- gap: 12px;
- padding: 0 24px 24px;
- color: var(--on-surface-variant);
+ gap: var(--md-sys-measurement-space200);
+ padding: 0 var(--md-sys-measurement-space300) var(--md-sys-measurement-space300);
+ color: var(--md-sys-color-on-surface-variant);
}
/* ---------------------------------------------------------------- contact */
@@ -1205,154 +1504,148 @@ code {
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
- gap: 24px;
- padding: clamp(28px, 5vw, 48px);
- border-radius: var(--corner-xxl);
- background: var(--primary-container);
- color: var(--on-primary-container);
+ gap: var(--md-sys-measurement-space300);
+ padding: var(--md-sys-measurement-space400) var(--md-sys-measurement-space300);
}
.contact > div {
display: grid;
- gap: 10px;
+ gap: var(--md-sys-measurement-space100);
}
.contact p {
- opacity: 0.9;
+ color: var(--md-sys-color-on-surface-variant);
}
.contact a:not(.btn) {
display: inline-flex;
align-items: center;
- gap: 8px;
- color: inherit;
- font-weight: 500;
+ gap: var(--md-sys-measurement-space100);
+ min-block-size: var(--md-sys-measurement-space600);
+ width: fit-content;
+ font: var(--md-sys-typescale-title-md);
+ letter-spacing: var(--md-sys-typescale-title-md-tracking);
}
-.contact .btn--filled {
- background: var(--on-primary-container);
- color: var(--primary-container);
-}
-
-.contact .btn--filled:hover {
- background: color-mix(in srgb, var(--on-primary-container) 88%, var(--primary-container));
+@media (width >= 840px) {
+ .contact {
+ padding: var(--md-sys-measurement-space600);
+ }
}
/* ---------------------------------------------------------------- footer */
.footer {
- padding-block: 56px 40px;
- background: var(--surface-container-low);
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
+ padding-block: var(--md-sys-measurement-space700) var(--md-sys-measurement-space500);
+ background-color: var(--md-sys-color-surface-container-low);
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
.footer__grid {
display: grid;
- grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr));
- gap: 32px;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: var(--md-sys-measurement-space400);
+}
+
+.footer__grid > :first-child {
+ grid-column: 1 / -1;
}
.footer__blurb {
max-width: 380px;
- margin-top: 12px;
+ margin-block-start: var(--md-sys-measurement-space100);
}
.footer h2 {
- margin-bottom: 12px;
- color: var(--on-surface);
- font-size: 1rem;
+ margin-block-end: var(--md-sys-measurement-space100);
+ color: var(--md-sys-color-on-surface);
+ font: var(--md-sys-typescale-title-sm);
+ letter-spacing: var(--md-sys-typescale-title-sm-tracking);
}
.footer ul {
display: grid;
- gap: 8px;
margin: 0;
padding: 0;
list-style: none;
}
+.footer ul a {
+ display: inline-flex;
+ align-items: center;
+ min-block-size: var(--md-sys-measurement-space500);
+}
+
.footer a {
- color: var(--on-surface-variant);
+ color: var(--md-sys-color-on-surface-variant);
text-decoration: none;
}
.footer a:hover {
- color: var(--on-surface);
- text-decoration: underline;
+ color: var(--md-sys-color-on-surface);
+ text-decoration-line: underline;
}
.footer__bottom {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
- gap: 8px 24px;
- margin-top: 40px;
- padding-top: 24px;
- border-top: 1px solid var(--outline-variant);
- font-size: 0.875rem;
+ gap: var(--md-sys-measurement-space100) var(--md-sys-measurement-space300);
+ margin-block-start: var(--md-sys-measurement-space500);
+ padding-block-start: var(--md-sys-measurement-space300);
+ border-block-start: 1px solid var(--md-sys-color-outline-variant);
}
-@media (max-width: 720px) {
+@media (width >= 600px) {
.footer__grid {
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr));
}
.footer__grid > :first-child {
- grid-column: 1 / -1;
+ grid-column: auto;
}
}
/* ---------------------------------------------------------------- legal page */
.legal {
- padding-block: clamp(40px, 6vw, 80px);
+ padding-block: var(--md-sys-measurement-space500) var(--md-sys-measurement-space800);
}
.legal article {
display: grid;
- gap: 16px;
+ gap: var(--md-sys-measurement-space200);
max-width: 760px;
margin-inline: auto;
}
.legal h1 {
- margin-bottom: 4px;
+ margin-block-end: var(--md-sys-measurement-space50);
}
.legal h2 {
- margin-top: 24px;
- font-size: 1.375rem;
-}
-
-.legal p,
-.legal li {
- color: var(--on-surface-variant);
+ margin-block-start: var(--md-sys-measurement-space300);
+ font: var(--md-sys-typescale-title-lg);
+ letter-spacing: var(--md-sys-typescale-title-lg-tracking);
}
.legal ul {
display: grid;
- gap: 8px;
+ gap: var(--md-sys-measurement-space100);
margin: 0;
- padding-left: 22px;
+ padding-inline-start: var(--md-sys-measurement-space300);
}
.legal .meta {
- color: var(--on-surface-variant);
- font-size: 0.9375rem;
+ color: var(--md-sys-color-on-surface-variant);
+ font: var(--md-sys-typescale-body-md);
+ letter-spacing: var(--md-sys-typescale-body-md-tracking);
}
-/* ---------------------------------------------------------------- motion */
-
-@media (prefers-reduced-motion: reduce) {
- html {
- scroll-behavior: auto;
- }
-
- *,
- *::before,
- *::after {
- transition-duration: 0.01ms !important;
- animation-duration: 0.01ms !important;
+@media (width >= 600px) {
+ .legal {
+ padding-block: var(--md-sys-measurement-space800) calc(var(--md-sys-measurement-space500) * 2);
}
}
diff --git a/website/index.html b/website/index.html
index 7748b0e..8f08196 100644
--- a/website/index.html
+++ b/website/index.html
@@ -7,6 +7,83 @@
+
@@ -25,7 +102,7 @@
-Skip to content
+Skip to content
@@ -64,12 +141,15 @@
+
+
+
@@ -112,8 +197,9 @@
-
-
+
+
@@ -123,8 +209,9 @@
-
-
+
+
@@ -286,13 +373,13 @@
The same interface on a laptop and a phone, in light or dark.
-
-
Desktop
-
Phone
+
+ Desktop
+ Phone
-
-
Light
-
Dark
+
+ Light
+ Dark
@@ -301,7 +388,7 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/website/privacy.html b/website/privacy.html
index d11ce50..49f63a4 100644
--- a/website/privacy.html
+++ b/website/privacy.html
@@ -7,6 +7,83 @@
+