initial commit

This commit is contained in:
nicolas arduin 2024-12-13 14:30:22 +01:00
commit c7c8fc4e67
24 changed files with 1328 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
node_modules
.DS_Store
dist
*.local
.vite-inspect
.remote-assets
.idea/
components.d.ts

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
# for pnpm
shamefully-hoist=true

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
# Ignore artifacts:
build
coverage

21
.prettierrc.json Normal file
View File

@ -0,0 +1,21 @@
{
"arrowParens": "always",
"bracketSameLine": false,
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": true,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleAttributePerLine": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false,
"vueIndentScriptAndStyle": false
}

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["antfu.slidev"]
}

11
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.fontSize": 16,
"editor.formatOnSave": true,
"slidev.force-enabled": true,
"slidev.include": ["**/slides.md", "example.md"],
"[markdown]": {
"editor.defaultFormatter": "antfu.slidev"
},
"prettier.configPath": ".prettierrc.json"
}

50
README.md Normal file
View File

@ -0,0 +1,50 @@
# slidev-theme-narduin
[![NPM version](https://img.shields.io/npm/v/slidev-theme-narduin?color=3AB9D4&label=)](https://www.npmjs.com/package/slidev-theme-narduin)
A (...) theme for [Slidev](https://github.com/slidevjs/slidev).
<!--
Learn more about how to write a theme:
https://sli.dev/guide/write-theme.html
--->
<!--
run `npm run dev` to check out the slides for more details of how to start writing a theme
-->
<!--
Put some screenshots here to demonstrate your theme
Live demo: [...]
-->
## Install
Add the following frontmatter to your `slides.md`. Start Slidev then it will prompt you to install the theme automatically.
<pre><code>---
theme: <b>narduin</b>
---</code></pre>
Learn more about [how to use a theme](https://sli.dev/guide/theme-addon#use-theme).
## Layouts
This theme provides the following layouts:
> TODO:
## Components
This theme provides the following components:
> TODO:
## Contributing
- `npm install`
- `npm run dev` to start theme preview of `example.md`
- Edit the `example.md` and style to see the changes
- `npm run export` to generate the preview PDF
- `npm run screenshot` to generate the preview PNG

BIN
bun.lockb Executable file

Binary file not shown.

0
components/.gitkeep Normal file
View File

574
example.md Normal file
View File

@ -0,0 +1,574 @@
---
author: Nicolas Arduin
download: true
exportFilename: intriduction-accessibilite-numerique
lineNumbers: true
remoteAssets: true
htmlAttrs:
dir: ltr
lang: fr
theme: ./
# some information about your slides (markdown enabled)
title: Introduction à l'accessibilité numérique
info: |
## Commencer avec l'accessibilité
Pourquoi, pour qui et comment&nbsp;?
Learn more at [Sli.dev](https://sli.dev)
# https://sli.dev/features/drawing
drawings:
persist: false
# slide transition: https://sli.dev/guide/animations.html#slide-transitions
transition: fade-out
# enable MDC Syntax: https://sli.dev/features/mdc
mdc: true
# make slide text selectable
selectable: true
# take snapshot for each slide in the overview
overviewSnapshots: true
hideInToc: true
layout: intro
---
# Introduction à <span class="highlight">l'accessibilité numérique</span>
<div class="abs-br m-6">
<a href="https://www.nardu.in" rel="noreferer noopener">Nico,</a> Décembre 2024.<br>licence&nbsp;: <a href="https://creativecommons.org/licenses/by-nc/4.0/" rel="noreferer noopener">CC BY-NC</a>
</div>
<!--
The last comment block of each slide will be treated as slide notes. It will be visible and editable in Presenter Mode along with the slide. [Read more in the docs](https://sli.dev/guide/syntax.html#notes)
-->
---
hideInToc: true
layout: bullets
---
# Sommaire
<Toc maxDepth="1"></Toc>
---
layout: title-image
image: https://cover.sli.dev
---
# l'Accessibilité Numérique
Pourquoi, pour qui, comment ?
---
layout: quote
level: 2
hideInToc: true
---
> ## “&nbsp;La force du Web réside dans son universalité. L'accès de tous, quel que soit le handicap, en est un aspect essentiel.&nbsp;
Tim Berners-Lee, Directeur du W3C et inventeur du World Wide Web
<!-- Accès universel (accessible) dès la création de l'outil -->
---
layout: fact
hideInToc: true
---
# 1 personne sur 5 est handicapée
La majorité des handicaps sont invisibles.
<!-- certains sont temporaires, certains arrivent avec l'âge -->
---
layout: quote
hideInToc: true
---
# “&nbsp;Laccessibilité numérique est un droit fondamental. Cest la possibilité pour toutes et tous dutiliser les outils informatiques, quelle que soit leur façon dy accéder.&nbsp;
Access 42
---
## hideInToc: true
## L'accessibilité du Web englobe tous les handicaps qui affectent l'accès au Web, notamment&nbsp;:
- auditifs
- cognitifs
- neurologiques
- physiques
- psychologiques
- oraux
- visuels
---
## layout: center
# Exemples de technologies d'assistance
<div grid="~ cols-2 gap-4">
<Youtube id="nw6-eDJXWzY" />
<Youtube id="N9Q8oF0Lx2M" />
<Youtube id="SlxIEPEC_Qc" />
<Youtube id="LHUyDhutx80" />
</div>
---
# Bonnes pratiques en bref
- [HTML sémantique](https://developer.mozilla.org/fr/docs/Glossary/Semantics)
- structure du contenu ([titres](https://developer.mozilla.org/fr/docs/Web/HTML/Element/Heading_Elements))
- contrastes des couleurs ([outil](https://coolors.co/contrast-checker))
- taille et unités des polices
- formulaire
- intitulés
- aide à la saisie
- messages derreur
- animations/mouvement (carousel, vidéo, scroll, etc.)
- écrire simplement et clairement ([FALC](https://www.culture.gouv.fr/Thematiques/developpement-culturel/Culture-et-handicap/Facile-a-lire-et-a-comprendre-FALC-une-methode-utile))
- simplifier l'interface utilisateur
---
# Éléments sémantiques
````md magic-move {lines: true}
```html
<body>
<div class="header">
<div class="nav">
<a href="#">Accueil</a>
<a href="#">À propos</a>
<a href="#">Contact</a>
</div>
</div>
<div class="main">
<h1>Titre de la page</h1>
<h2>Titre de la section</h2>
<p>Contenu de la page</p>
</div>
<div class="footer">
<p>Pied de page</p>
</div>
</body>
```
```html
<body>
<header>
<nav>
<ul>
<li><a href="#">Accueil</a></li>
<li><a href="#">À propos</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<main>
<h1>Titre de la page</h1>
<section>
<h2>Titre de la section</h2>
<p>Contenu de la page</p>
</section>
</main>
<footer>
<p>Pied de page</p>
</footer>
</body>
```
````
---
## layout: two-cols-header
## Structure du contenu
::left::
```md {all|2|3|4|none}{lines: false}
Erroné
└── h1 Titre principal
├── h2 Titre secondaire
├── h4 Titre niveau 4
│ └── h5 Titre niveau 5
├── h2 Titre secondaire
│ ├── h2 Titre secondaire
│ ├── h3 Titre tertiaire
│ │ ├── h4 Titre niveau 4
│ │ │ └── h6 Titre niveau 6
│ └── h3 Titre tertiaire
└── h1 Titre principal
```
::right::
```md {none|all}{lines: false}
Correct
└── h1 Titre principal
├── h2 Titre secondaire
├── h2 Titre secondaire
│ └── h3 Titre tertiaire
├── h2 Titre secondaire
│ ├── h3 Titre tertiaire
│ ├── h3 Titre tertiaire
│ │ ├── h4 Titre niveau 4
│ │ │ └── h5 Titre niveau 5
│ └── h3 Titre tertiaire
└── h2 Titre secondaire
```
<!-- [HeadingsMap](https://addons.mozilla.org/fr/firefox/addon/headingsmap/) -->
---
layout: center
hideInToc: true
---
# les Formulaires
C'est si simple de faire n'importe quoi 🤪
---
## layout: two-cols
<div class="form">
<h2>Mauvais exemple&nbsp;:</h2>
<form class="nul">
<input type="text" placeholder="nom*">
<input type="text" placeholder="email*">
<button>Envoyer</button>
</form>
</div>
::right::
<div class="form">
<h2>Bon exemple&nbsp;:</h2>
<form class="cool">
<div v-click role="group" aria-labelledby="error-summary-title">
<h3 id="error-summary-title" tabindex="-1">
Il y a 2 erreurs de saisie dans le formulaire.
</h3>
<ol>
<li class="error">
<a href="#input-name">Veuillez renseigner un nom.</a>
</li>
<li class="error">
<a href="#input-email">L'email renseigné n'est pas valide.</a>
</li>
</ol>
</div>
<label for="name">Nom (obligatorie)</label>
<input id="name" type="text" required>
<label for="email">Email (obligatoire)</label>
<input id="email" type="email" aria-describedby="email-description" required>
<p id="email-description">Format attendu: nom@email.fr</p>
<button>Envoyer</button>
</form>
</div>
<div class="absolute bottom-10">
<a href="https://briefs.video/videos/what-happened-to-text-inputs/" rel="noreferer noopener">Qu'est-il arrivé au champ texte&nbsp;? <small>Vidéo en anglais.</small></a>
</div>
---
layout: image-right
image: https://cover.sli.dev
---
# Code
Use code snippets and get the highlighting directly, and even types hover!
```ts {all|5|7|7-8|10|all} twoslash
// TwoSlash enables TypeScript hover information
// and errors in markdown code blocks
// More at https://shiki.style/packages/twoslash
import { computed, ref } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
doubled.value = 2
```
<arrow v-click="[4, 5]" x1="350" y1="310" x2="195" y2="334" color="#953" width="2" arrowSize="1" />
<!-- This allow you to embed external code blocks -->
<!-- Footer -->
[Learn more](https://sli.dev/features/line-highlighting)
<!-- Inline style -->
<style>
.footnotes-sep {
@apply mt-5 opacity-10;
}
.footnotes {
@apply text-sm opacity-75;
}
.footnote-backref {
display: none;
}
</style>
<!--
Notes can also sync with clicks
[click] This will be highlighted after the first click
[click] Highlighted with `count = ref(0)`
[click:3] Last click (skip two clicks)
-->
---
## level: 2
# Shiki Magic Move
Powered by [shiki-magic-move](https://shiki-magic-move.netlify.app/), Slidev supports animations across multiple code snippets.
Add multiple code blocks and wrap them with <code>````md magic-move</code> (four backticks) to enable the magic move. For example:
````md magic-move {lines: true}
```ts {*|2|*}
// step 1
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
```
```ts {*|1-2|3-4|3-4,8}
// step 2
export default {
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
}
}
```
```ts
// step 3
export default {
data: () => ({
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
})
}
```
Non-code blocks are ignored.
```vue
<!-- step 4 -->
<script setup>
const author = {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
</script>
```
````
---
# Components
<div grid="~ cols-2 gap-4">
<div>
You can use Vue components directly inside your slides.
We have provided a few built-in components like `<Tweet/>` and `<Youtube/>` that you can use directly. And adding your custom components is also super easy.
```html
<Counter :count="10" />
```
<!-- ./components/Counter.vue -->
<Counter :count="10" m="t-4" />
Check out [the guides](https://sli.dev/builtin/components.html) for more.
</div>
<div>
```html
<Tweet id="1390115482657726468" />
```
<Tweet id="1390115482657726468" scale="0.65" />
</div>
</div>
<!--
Presenter note with **bold**, *italic*, and ~~striked~~ text.
Also, HTML elements are valid:
<div class="flex w-full">
<span style="flex-grow: 1;">Left content</span>
<span>Right content</span>
</div>
-->
---
## class: px-20
# Themes
Slidev comes with powerful theming support. Themes can provide styles, layouts, components, or even configurations for tools. Switching between themes by just **one edit** in your frontmatter:
<div grid="~ cols-2 gap-2" m="t-2">
```yaml
---
theme: default
---
```
```yaml
---
theme: seriph
---
```
<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-default/01.png?raw=true" alt="">
<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-seriph/01.png?raw=true" alt="">
</div>
Read more about [How to use a theme](https://sli.dev/guide/theme-addon#use-theme) and
check out the [Awesome Themes Gallery](https://sli.dev/resources/theme-gallery).
---
# Clicks Animations
You can add `v-click` to elements to add a click animation.
<div v-click>
This shows up when you click the slide:
```html
<div v-click>This shows up when you click the slide.</div>
```
</div>
<br>
<v-click>
The <span v-mark.red="3"><code>v-mark</code> directive</span>
also allows you to add
<span v-mark.circle.orange="4">inline marks</span>
, powered by [Rough Notation](https://roughnotation.com/):
```html
<span v-mark.underline.orange>inline markers</span>
```
</v-click>
<div mt-20 v-click>
[Learn more](https://sli.dev/guide/animations#click-animation)
</div>
---
# Monaco Editor
Slidev provides built-in Monaco Editor support.
Add `{monaco}` to the code block to turn it into an editor:
```ts {monaco}
import { ref } from 'vue'
import { emptyArray } from './external'
const arr = ref(emptyArray(10))
```
Use `{monaco-run}` to create an editor that can execute the code directly in the slide:
```ts {monaco-run}
import { version } from 'vue'
import { emptyArray, sayHello } from './external'
sayHello()
console.log(`vue ${version}`)
console.log(
emptyArray<number>(10).reduce(
(fib) => [...fib, fib.at(-1)! + fib.at(-2)!],
[1, 1]
)
)
```
---
layout: center
class: text-center
---
# Learn More
[Documentation](https://sli.dev) · [GitHub](https://github.com/slidevjs/slidev) · [Showcases](https://sli.dev/resources/showcases)
<PoweredBySlidev mt-10 />

5
layouts/bullets.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<div class="slidev-layout bullets">
<slot />
</div>
</template>

7
layouts/cover.vue Normal file
View File

@ -0,0 +1,7 @@
<template>
<div class="slidev-layout cover">
<div class="my-auto w-full">
<slot />
</div>
</div>
</template>

14
layouts/intro.vue Normal file
View File

@ -0,0 +1,14 @@
<template>
<div class="slidev-layout place-content-center intro">
<slot />
</div>
</template>
<style scoped>
.intro {
block-size: 100%;
:deep(h1) {
font-size: var(--size-6);
}
}
</style>

5
layouts/quote.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<div class="slidev-layout h-full place-content-center">
<slot />
</div>
</template>

32
layouts/title-image.vue Normal file
View File

@ -0,0 +1,32 @@
<script setup lang="ts">
import { imageSrc } from '../utils/imageHelper'
const props = defineProps({
image: {
type: String,
required: true
}
})
const image = imageSrc(props.image)
</script>
<template>
<div class="slidev-layout h-full title">
<div class="grid grid-cols-2 h-full">
<div class="place-self-center">
<slot />
</div>
<div class="image"></div>
</div>
</div>
</template>
<style scoped>
.image {
block-size: 100%;
background-image: v-bind(image);
background-size: cover;
background-position: center;
}
</style>

36
package.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "slidev-theme-narduin",
"version": "0.0.0",
"type": "module",
"keywords": [
"slidev-theme",
"slidev"
],
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"build": "slidev build example.md",
"dev": "slidev example.md",
"export": "slidev export example.md",
"screenshot": "slidev export example.md --format png"
},
"dependencies": {
"@slidev/types": "^0.50.0-beta.10",
"@unocss/reset": "^0.65.1"
},
"devDependencies": {
"@slidev/cli": "^0.50.0-beta.10",
"prettier": "3.4.2"
},
"slidev": {
"colorSchema": "light",
"defaults": {
"canvasWidth": 1280,
"fonts": {
"mono": "Monaspace Neon,monospace",
"local": "system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto, Oxygen,Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif,Monaspace Neon"
}
}
}
}

11
setup/shiki.ts Normal file
View File

@ -0,0 +1,11 @@
import type { ShikiSetupReturn } from '@slidev/types'
import { defineShikiSetup } from '@slidev/types'
export default defineShikiSetup((): ShikiSetupReturn => {
return {
themes: {
dark: 'vitesse-dark',
light: 'vitesse-light'
}
}
})

226
styles/base.css Normal file
View File

@ -0,0 +1,226 @@
/* BASE */
::placeholder {
color: var(--color-dark);
opacity: 0.8;
}
::selection,
::target-text {
color: var(--color-light-blue);
background-color: var(--color-dark-blue);
}
::target-text {
color: var(--color-soft-blue);
background-color: var(--color-blue);
}
::marker {
color: var(--color-brique);
}
body {
font-size: var(--size-0);
line-height: 1.5;
color: var(--color-dark);
background-color: var(--color-light-white);
accent-color: var(--color-brique);
}
:is(h1, h2, h3, h4, .h2, .h3, .h4) {
font-weight: bold;
}
:where(h1, h2, h3, h4, .h2, .h3, .h4) + * {
margin-block-start: var(--space-s);
}
:is(h1) {
max-inline-size: 20ch;
font-size: var(--size-5);
color: var(--color-dark-blue);
}
h2,
.h2 {
font-size: var(--size-3);
color: var(--color-dark-blue);
}
h3,
.h3 {
max-inline-size: initial;
font-size: var(--size-2);
letter-spacing: 0.05rem;
}
h4,
.h4 {
font-size: var(--size-2);
color: var(--color-dark);
}
h5,
.h5 {
font-size: var(--size-1);
color: var(--color-darkBlue);
}
a {
font-weight: 500;
color: var(--color-blue);
text-decoration: underline;
}
/* a:visited {
color: currentColor;
} */
a:hover,
a:focus {
text-decoration: none;
}
hr {
margin-block: var(--space-m-l);
block-size: 4px;
background-color: var(--color-dark);
}
hr.small {
margin-block: var(--space-xs);
block-size: 2px;
}
ul:not([role='list']),
ol:not([role='list']) {
padding-inline-start: 1rem;
}
ul:not([role='list']) > li + li,
ol:not([role='list']) > li + li {
margin-block-start: var(--space-xs);
}
.sr-only {
clip: rect(0 0 0 0);
clip-path: inset(50%);
block-size: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
inline-size: 1px;
}
.clean-button {
appearance: none;
-webkit-appearance: none;
cursor: pointer;
border: none;
background: none;
}
.btn {
padding: var(--space-2xs) var(--space-xs);
margin-block: var(--space-s);
display: inline-block;
font-size: var(--size-0);
font-weight: bold;
text-decoration: none;
border: 2px solid var(--color-blue);
border-radius: var(--radius-small);
color: var(--color-white);
background-color: var(--color-blue);
transition-property: color, background-color;
transition-duration: 0.3s;
transition-timing-function: ease;
}
.btn:hover,
.btn:focus {
color: var(--color-blue);
background-color: var(--color-white);
}
button[disabled] {
cursor: not-allowed;
color: var(--color-grey-dark);
border-color: var(--color-grey);
background-color: var(--color-white);
}
.highlight {
color: var(--color-blue);
}
/* clean style link */
.clean-link {
text-decoration: none;
font-weight: inherit;
color: currentColor;
}
.clean-link:hover {
text-decoration: none;
}
/* nice hover link */
.nice-link {
position: relative;
display: inline-block;
text-align: center;
text-decoration: none;
}
.nice-link:hover {
text-decoration: none;
}
.nice-link::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
inline-size: 100%;
block-size: 2px;
text-decoration: none;
transform: scaleX(0);
opacity: 1;
transform-origin: 100% 50%;
background-color: var(--color-brique);
}
.nice-link:hover::after {
transform: scaleX(1);
transform-origin: 0% 50%;
}
@media (prefers-reduced-motion: no-preference) {
.nice-link::after {
transition: transform 0.4s cubic-bezier(0.77, 0, 0.175, 1);
}
}
/* blockquote */
blockquote {
margin: var(--space-s) 0;
padding: var(--space-s);
font-weight: normal;
line-height: 1.4;
border-left: 3px solid var(--color-blue);
border-radius: 3px;
background-color: var(--color-soft-blue);
}
blockquote cite {
font-weight: normal;
font-style: normal;
font-size: var(--size-0);
line-height: 1.2;
}
.wrapper {
/* GRID WRAPPER */
display: grid;
grid-template-columns: var(--grid-wrapper);
--_content-padding: var(--content-padding, var(--space-s));
column-gap: var(--_content-padding);
}
/* set content inside wrapper column */
:where(.wrapper, .slidev-layout) > * {
grid-column: wrapper;
}
/* set full width content to full grid */
:where(.wrapper, .slidev-layout) > .full-width {
/* calculate inline padding based on available space minus content space to align full-width content with wrapper content */
padding-inline: max(
calc((100vw - var(--content-width)) / 2),
var(--_content-padding)
);
grid-column: full;
}

5
styles/index.ts Normal file
View File

@ -0,0 +1,5 @@
import '@unocss/reset/normalize.css'
import './reset.css'
import './variables.css'
import './base.css'
import './layouts.css'

8
styles/layouts.css Normal file
View File

@ -0,0 +1,8 @@
.slidev-layout {
@apply: grid-wrapper;
padding-block: var(--space-m-l);
}
.bullets :where(ul, ol, dl) {
list-style-type: initial;
}

188
styles/reset.css Normal file
View File

@ -0,0 +1,188 @@
/* RESET */
:root {
--font-tnum: 'tnum' on;
}
* {
/* Remove default margin on everything */
margin: 0;
/* Remove default padding on everything */
padding: 0;
/* Calc `em` based line height, bigger line height for smaller font size and smaller line height for bigger font size: https://kittygiraudel.com/2020/05/18/using-calc-to-figure-out-optimal-line-height/ */
line-height: calc(0.25rem + 1em + 0.25rem);
}
/* Use a more-intuitive box-sizing model on everything */
*,
::before,
::after {
box-sizing: border-box;
}
/* Remove border and set sensible defaults for backgrounds, on all elements except fieldset progress and meter */
*:where(:not(fieldset, progress, meter)) {
border-width: 0;
border-style: solid;
background-origin: border-box;
background-repeat: no-repeat;
}
@supports (font-variant-numeric: tabular-nums) {
html {
--font-tnum: '____';
font-variant-numeric: tabular-nums;
}
}
html {
/* Allow percentage-based heights in the application */
block-size: 100%;
/* Making sure text size is only controlled by font-size */
-webkit-text-size-adjust: none;
/* Improve text rendering */
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-feature-settings: var(--font-tnum);
}
/* Smooth scrolling for users that don't prefer reduced motion */
@media (prefers-reduced-motion: no-preference) {
html:focus-within {
scroll-behavior: smooth;
}
}
body {
overflow-x: hidden;
font-weight: normal;
/* Allow percentage-based heights in the application */
min-block-size: 100%;
/* https://www.sarasoueidan.com/blog/safari-fluid-typography-bug-fix/ */
-webkit-marquee-increment: 0vw;
}
/* Improve media defaults */
:where(img, svg, video, canvas, audio, iframe, embed, object) {
display: block;
}
:where(img, svg, video) {
block-size: auto;
max-inline-size: 100%;
}
:where(details) {
cursor: pointer;
}
/* Remove stroke and set fill colour to the inherited font colour */
:where(svg) {
stroke: none;
fill: currentColor;
}
/* Set a size for SVG's without a width attribute */
:where(svg):where(:not([width])) {
inline-size: 5rem;
}
/* Remove built-in form typography styles */
:where(input, button, textarea, select),
:where(input[type='file'])::-webkit-file-upload-button {
color: inherit;
font: inherit;
font-size: inherit;
letter-spacing: inherit;
}
/* Change textarea resize to vertical only and block only if the browser supports that */
:where(textarea) {
resize: vertical;
}
@supports (resize: block) {
:where(textarea) {
resize: block;
}
}
/* Avoid text overflows */
:where(h1, h2, h3) {
line-height: 1.1;
}
:where(p, h1, h2, h3, h4, h5, h6) {
overflow-wrap: break-word;
}
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
:where(ul, ol)[role='list'] {
list-style: none;
}
/* More readable underline style for anchor tags without a class. This could be set on anchor tags globally, but it can cause conflicts. */
a:not([class]) {
text-decoration-skip-ink: auto;
}
/* Make it clear that interactive elements are interactive */
:where(
a[href],
area,
button,
input,
label[for],
select,
summary,
textarea,
[tabindex]:not([tabindex*='-'])
) {
cursor: pointer;
touch-action: manipulation;
}
:where(input[type='file']) {
cursor: auto;
}
:where(input[type='file'])::-webkit-file-upload-button,
:where(input[type='file'])::file-selector-button {
cursor: pointer;
}
/* Animate focus outline */
@media (prefers-reduced-motion: no-preference) {
:focus-visible {
transition: outline-offset 145ms cubic-bezier(0.25, 0, 0.4, 1);
}
:where(:not(:active)):focus-visible {
transition-duration: 0.25s;
}
}
:where(:not(:active)):focus-visible {
outline-offset: 2px;
}
/* Make sure users can't select button text */
:where(
button,
button[type],
input[type='button'],
input[type='submit'],
input[type='reset']
),
:where(input[type='file'])::-webkit-file-upload-button,
:where(input[type='file'])::file-selector-button {
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
user-select: none;
text-align: center;
}
/* Disabled cursor for disabled buttons */
:where(
button,
button[type],
input[type='button'],
input[type='submit'],
input[type='reset']
)[disabled] {
cursor: not-allowed;
}
/* END RESET */

95
styles/variables.css Normal file
View File

@ -0,0 +1,95 @@
/* VARIABLES */
:root {
/* font sizes
https://utopia.fyi/type/calculator?c=320,18,1.2,1040,20,1.25,5,2,&s=0.75%7C0.5%7C0.25,1.5%7C2%7C3%7C4%7C6,m-xl&g=s,l,xl,12
*/
--size--1: clamp(0.94rem, calc(0.91rem + 0.14vw), 1rem);
--size-0: clamp(1.13rem, calc(1.07rem + 0.28vw), 1.25rem);
--size-1: clamp(1.35rem, calc(1.26rem + 0.47vw), 1.56rem);
--size-2: clamp(1.62rem, calc(1.47rem + 0.74vw), 1.95rem);
--size-3: clamp(1.94rem, calc(1.72rem + 1.11vw), 2.44rem);
--size-4: clamp(2.33rem, calc(2.01rem + 1.6vw), 3.05rem);
--size-5: clamp(2.8rem, calc(2.35rem + 2.26vw), 3.82rem);
--size-6: clamp(3.36rem, calc(2.73rem + 3.13vw), 4.77rem);
--size-7: clamp(4.03rem, calc(3.17rem + 4.29vw), 5.96rem);
--size-8: clamp(4.84rem, calc(3.68rem + 5.81vw), 7.45rem);
/* spaces
https://utopia.fyi/space/calculator?c=320,18,1.2,1040,20,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,m-xl&g=s,l,xl,12
*/
--space-3xs: clamp(0.31rem, calc(0.31rem + 0vw), 0.31rem);
--space-2xs: clamp(0.56rem, calc(0.53rem + 0.14vw), 0.63rem);
--space-xs: clamp(0.88rem, calc(0.85rem + 0.14vw), 0.94rem);
--space-s: clamp(1.13rem, calc(1.07rem + 0.28vw), 1.25rem);
--space-m: clamp(1.69rem, calc(1.6rem + 0.42vw), 1.88rem);
--space-l: clamp(2.25rem, calc(2.14rem + 0.56vw), 2.5rem);
--space-xl: clamp(3.38rem, calc(3.21rem + 0.83vw), 3.75rem);
--space-2xl: clamp(4.5rem, calc(4.28rem + 1.11vw), 5rem);
--space-3xl: clamp(6.75rem, calc(6.42rem + 1.67vw), 7.5rem);
/* One-up pairs */
--space-3xs-2xs: clamp(0.31rem, calc(0.17rem + 0.69vw), 0.63rem);
--space-2xs-xs: clamp(0.56rem, calc(0.4rem + 0.83vw), 0.94rem);
--space-xs-s: clamp(0.88rem, calc(0.71rem + 0.83vw), 1.25rem);
--space-s-m: clamp(1.13rem, calc(0.79rem + 1.67vw), 1.88rem);
--space-m-l: clamp(1.69rem, calc(1.33rem + 1.81vw), 2.5rem);
--space-l-xl: clamp(2.25rem, calc(1.58rem + 3.33vw), 3.75rem);
--space-xl-2xl: clamp(3.38rem, calc(2.65rem + 3.61vw), 5rem);
--space-2xl-3xl: clamp(4.5rem, calc(3.17rem + 6.67vw), 7.5rem);
/* multi steps */
--space-3xs-s: clamp(0.31rem, calc(-0.1rem + 2.08vw), 1.25rem);
--space-2xs-s: clamp(0.56rem, calc(0.26rem + 1.53vw), 1.25rem);
--space-2xs-m: clamp(0.56rem, calc(-0.02rem + 2.92vw), 1.88rem);
--space-xs-m: clamp(0.88rem, calc(0.43rem + 2.22vw), 1.88rem);
--space-xs-l: clamp(0.88rem, calc(0.15rem + 3.61vw), 2.5rem);
--space-s-l: clamp(1.13rem, calc(0.51rem + 3.06vw), 2.5rem);
--space-s-xl: clamp(1.13rem, calc(-0.04rem + 5.83vw), 3.75rem);
--space-m-xl: clamp(1.69rem, calc(0.77rem + 4.58vw), 3.75rem);
--space-l-2xl: clamp(2.25rem, calc(1.03rem + 6.11vw), 5rem);
--space-l-3xl: clamp(2.25rem, calc(-0.08rem + 11.67vw), 7.5rem);
/* colors */
--color-dark: hsl(239, 57%, 15%);
--color-grey: hsl(211, 12%, 35%);
--color-light-grey: hsl(0, 0%, 94%);
--color-blue: hsl(253, 98%, 41%);
--color-dark-blue: hsl(218, 60%, 21%);
--color-light-blue: hsl(194, 54%, 89%);
--color-blend-blue: hsl(253, 100%, 32%);
--color-soft-blue: hsl(210, 73%, 94%);
--color-violet: hsl(248, 73%, 52%);
--color-brique: hsl(358, 54%, 54%);
--color-white: hsl(0, 0%, 100%);
--color-light-white: hsl(240, 50%, 98%);
--color-black: hsl(0, 0%, 0%);
/* shadows */
--shadow-color: 0deg 0% 80%;
--shadow-elevation-medium: 0px 0.7px 0.7px hsl(var(--shadow-color) / 0.28),
0px 1.5px 1.6px -0.7px hsl(var(--shadow-color) / 0.26),
0px 2.9px 3px -1.5px hsl(var(--shadow-color) / 0.24),
0px 6px 6.3px -2.2px hsl(var(--shadow-color) / 0.22),
0px 11.8px 12.4px -3px hsl(var(--shadow-color) / 0.2);
--shadow-elevation-high: 0px 0.5px 0.5px hsl(var(--shadow-color) / 0.18),
0px 1.4px 1.5px -0.3px hsl(var(--shadow-color) / 0.18),
0px 2.3px 2.4px -0.7px hsl(var(--shadow-color) / 0.17),
0px 3.4px 3.6px -1px hsl(var(--shadow-color) / 0.16),
0px 5.1px 5.4px -1.3px hsl(var(--shadow-color) / 0.16),
0px 7.5px 7.9px -1.7px hsl(var(--shadow-color) / 0.15),
0px 10.8px 11.3px -2px hsl(var(--shadow-color) / 0.15),
-0.1px 15.4px 16.2px -2.3px hsl(var(--shadow-color) / 0.14),
-0.1px 21.3px 22.4px -2.7px hsl(var(--shadow-color) / 0.13),
-0.1px 28.9px 30.3px -3px hsl(var(--shadow-color) / 0.13);
/* radius */
--radius: 20px;
--radius-small: 10px;
/* grid */
--content-width: 75rem;
--grid-wrapper: [full-start] 1fr [wrapper-start]
minmax(0, var(--content-width)) [wrapper-end] 1fr [full-end];
--_content-padding: var(--content-padding, var(--space-s));
}

21
uno.config.ts Normal file
View File

@ -0,0 +1,21 @@
import { defineConfig } from 'unocss'
export default defineConfig({
shortcuts: {
// custom the default background
'bg-main': 'bg-white text-[#181818] dark:(bg-[#121212] text-[#ddd])'
},
rules: [
[
'grid-wrapper',
{
display: 'grid',
'--grid-wrapper':
'[full-start] 1fr [wrapper-start] minmax(0, var(--content-width)) [wrapper-end] 1fr [full-end]',
'grid-template-columns': 'var(--grid-wrapper)',
'--_content-padding': 'var(--content-padding, var(--space-s))',
'column-gap': 'var(--_content-padding)'
}
]
]
})

3
utils/imageHelper.ts Normal file
View File

@ -0,0 +1,3 @@
export function imageSrc(src: string) {
return src.startsWith('http') ? `url(${src})` : `/images/${src}`
}