# Classes codées : Yoane Cinema Glass

Contrat aligné sur `css/tokens.css`, `css/base.css`, `css/atoms.css`, `css/molecules.css`, `css/organisms.css`. Préfixe `yc-`. Partie `__`, modificateur `--`, état `.is-*` ou attribut. La spec narrative est dans `DESIGN.md`.

`[data-brand]` ne doit changer que `--yc-accent` et `--yc-accent-hover`. `atoms.css`, chargé après `tokens.css`, réécrit aujourd'hui les douze couleurs sur les deux marques. Voir DESIGN.md, section 16.

## Couleurs

| Variable | Hex | Rôle |
|---|---|---|
| `--yc-bg` | `#05070a` | Toile |
| `--yc-bg-2` | `#09090b` | Bande |
| `--yc-surface-1` | `#0f1114` | Carte opaque |
| `--yc-surface-2` | `#16181c` | Survol, menu |
| `--yc-text-1` | `#fafafa` | Titre, bouton clair |
| `--yc-text-2` | `#a1a1aa` | Corps |
| `--yc-text-3` | `#8a8a93` | Méta. 5.19:1 sur surface 2 |
| `--yc-line` | `#26272b` | Filet 1px |
| `--yc-accent` | `#22d3ee` | Lien, focus, point. Doc4Geeks : `#06b6d4` |
| `--yc-accent-hover` | `#67e8f9` | Survol de l'accent |
| `--yc-wa` | `#25d366` | Bouton WhatsApp, et l'icône `.yc-channel--wa` |
| `--yc-danger` | `#c27c7c` | Erreur de formulaire |
| `--yc-line-hover` | `#3f3f46` | Filet de survol. Hors des douze |

Pas de `.yc-badge--accent`, pas de `.yc-tag--accent`, pas de teinte par catégorie. Le seul dégradé est `.yc-grad-text`.

## Type et socle (`base.css`)

| Classe | Rendu |
|---|---|
| `.yc-skip` | Lien d'évitement, z-index `--yc-z-skip`, visible au focus |
| `.yc-sr` | Texte masqué, lu par l'outil d'assistance |
| `.yc-display` | 800, `clamp(2.6rem, 6vw, 4.75rem)`, approche -0.03em |
| `.yc-h1` | 900. Mobile puis `clamp(2.8rem, 5.1vw, 76px)` dès 768px |
| `.yc-h2` | 800, `clamp(2rem, 4vw, 3rem)`, approche -0.02em |
| `.yc-h3` | 700, 1.25rem |
| `.yc-lead` | 18px, texte 2, max 62ch |
| `.yc-body` | 16px / 1.6, texte 2, max 65ch |
| `.yc-small` | 14px, approche 0.02em |
| `.yc-caption` | 12px, texte 3 |
| `.yc-mono` | JetBrains Mono, 12px, capitales, approche 0.08em, texte 3 |
| `.yc-eyebrow` | Mono 12px, capitales, approche 0.08em, accent |
| `.yc-grad-text` | Blanc vers cyan, `background-clip: text` |
| `.yc-container` | Max 1200px, gouttière 24px, 16px sous 768px |
| `.yc-grid` | 12 colonnes dès 768px. `.yc-col-1` à `.yc-col-12` |
| `.yc-rule` | Filet 1px |
| `.yc-photo-frame` | Rayon 16px, filet, image cover, scrim bas |

Focus global : contour 2px `--yc-accent`, décalage 2px, `--yc-glow-focus`.

## Atomes (`atoms.css`)

### `.yc-btn`

Base : inline-flex, gap 8px, min-height 44px, padding `0 18px`, rayon 12px, 14px / 700, approche 0.02em, transition 160ms. `.yc-btn--md` n'a pas de règle.

| Classe | Rôle |
|---|---|
| `.yc-btn__label` | Libellé, une ligne, graisse héritée |
| `.yc-btn__icon` | 20px. 16 en `--sm`, 24 en `--lg` |
| `.yc-btn__spinner` | Masqué. Visible en `.is-loading` |
| `.yc-btn--primary` | Fond texte 1, texte toile. Survol : fond à 88 % vers la toile, glow noir et accent à 14 %. Actif : 78 % |
| `.yc-btn--wa` | Fond `--yc-wa`, texte `--yc-bg`. Survol : vert à 82 % vers texte 1. Actif : vert à 88 % vers la toile |
| `.yc-btn--outline` | Transparent, filet, texte 2. Survol : surface 2, texte 1, filet `#3f3f46` |
| `.yc-btn--ghost` | Transparent, texte 2. Survol : surface 2, texte 1 |
| `.yc-btn--link` | Padding 0, accent, soulignement à 55 %. Survol : accent survol |
| `.yc-btn--sm` | 36px, padding `0 12px`, 13px |
| `.yc-btn--lg` | 48px, padding `0 22px`, 16px |
| `.yc-btn--icon` | Carré 44px, 36 en sm, 48 en lg |
| `.is-loading` | Pas de pointeur, icône masquée, spinner visible |
| `.is-copied` | Texte 1, filet. État « Lien copié » |
| `[disabled]`, `[aria-disabled="true"]` | Opacité 0.4, pas d'ombre, pas de translation |

Actif : `translateY(1px)`, retiré en reduced-motion. Focus : contour 2px. Le primary au focus remplace l'ombre par un glow accent à 16 %.

```html
<a class="yc-btn yc-btn--wa" href="https://wa.me/">
  <!-- SANITY: siteSettings.whatsappUrl -->
  <svg class="yc-btn__icon yc-icon yc-icon--fill" viewBox="0 0 24 24" aria-hidden="true"></svg>
  <span class="yc-btn__label">Écrire sur WhatsApp</span>
</a>
```

Sanity `yc.button` : `label`, `href`, `variant` `primary|wa|outline|ghost|link`, `size` `sm|md|lg`, `icon`, `iconPosition` `start|end`, `openInNewTab`.

### `.yc-badge`

Base : surface 1, filet, texte 2, rayon 999, 14px / 600, padding `6px 12px`, min-height 32px. `.yc-badge__dot` : 8px, accent, sans halo.

| Classe | Rendu |
|---|---|
| `.yc-badge--open` | Fond transparent, filet accent à 30 %, texte accent. Point animé 3.6s, sauf dans `.yc-hero` |
| `.yc-badge--past` | Même boîte que la base |
| `.yc-badge--online` | Même boîte que la base |

Sanity : `status` `open|past|online`. Libellé ouvert fixe : « Ouvert aux échanges et aux interventions ».

### `.yc-tag`

Surface 1, filet, rayon 8px, padding `4px 8px`, Inter 14px / 500, texte 2, min-height 28px. Pas de modificateur.

### `.yc-link`

Accent, graisse 500, soulignement décalé. Survol et focus : `--yc-accent-hover`, contour 2px au focus. `.yc-link--inline` graisse 400. `.yc-link--external` avec `.yc-link__icon` 16px.

### Champ

| Classe | Rôle |
|---|---|
| `.yc-field` | Colonne, gap 8px |
| `.yc-field-grid` | 1 colonne, 2 dès 720px |
| `.yc-field--wide` | Toute la rangée |
| `.yc-label` | 14px / 500, texte 1, `for` obligatoire |
| `.yc-field__req` | Mono, texte 3. Déclaré dans `molecules.css` |
| `.yc-input`, `.yc-textarea`, `.yc-select` | Surface 1, filet, rayon 12px, min-height 44px, padding `10px 12px`, texte 1 |
| `.yc-textarea` | Min-height 120px |
| `.yc-field__hint` | 14px, texte 2 |
| `.yc-field__error` | 14px, danger, `role="alert"` |
| `.yc-field__success` | 14px, texte 1, coche cyan en `::before` |
| `.is-error`, `[aria-invalid="true"]` | Filet danger |
| `.is-success` | Filet inchangé, message avec coche |
| `:disabled` | Opacité 0.4 |

Survol : filet `#3f3f46`. Focus : contour 2px, le filet reste `--yc-line` hors erreur. Placeholder en texte 3, jamais seul label.

### Choix, interrupteur, puce

| Classe | Rôle |
|---|---|
| `.yc-choice` | Rangée 44px. Input masqué |
| `.yc-choice__face` | 18px, filet, surface 1. Rond si précédé de `.yc-radio` |
| `.yc-choice__icon` | 14px, visible si `.yc-checkbox:checked` |
| `.yc-radio:checked + .yc-choice__face` | Fond accent, anneau intérieur 4px surface 1 |
| `.yc-checkbox:checked + .yc-choice__face` | Fond accent |
| `.yc-switch` | `role="switch"`, `aria-checked` |
| `.yc-switch__track` | 44×24. Off : surface 2. On : accent |
| `.yc-switch__thumb` | 18px. On : toile, `translateX(20px)` |
| `.yc-chip` | Bouton 44px, rayon 8px, surface 1, texte 2 |
| `.yc-chip.is-selected`, `[aria-pressed="true"]` | Filet et texte accent, fond transparent |

Sanity `yc.choice` : `label`, `value`, `checked`.

### `.yc-avatar`

Rond, cover, anneau 1px filet. Défaut 48px. Modificateurs : `--xs` `--24` 24, `--sm` `--32` 32, `--40` 40, `--md` 48, `--56` 56, `--lg` 64, `--72` 72, `--xl` `--96` 96. `.yc-avatar--ring` : anneau 1px accent. `.yc-avatar-group` : chevauchement -8px, anneau 2px surface 1.

### `.yc-icon`

24px, trait 1.5, `currentColor`. `--16`, `--20`, `--24`. `--fill` pour le glyphe WhatsApp. `.is-muted` en texte 3.

### `.yc-divider`

1px `--yc-line`. `.yc-divider--labeled` : texte mono capitales entre deux filets.

### `.yc-tooltip`

Bulle `.yc-tooltip__bubble` dans le flux, affichée au survol et au focus. Surface 2, filet, texte 1, 14px, rayon 8px. `--top` et `--bottom` ne déplacent pas la bulle. `role="tooltip"`.

### `.yc-logo`

| Classe | Rôle |
|---|---|
| `.yc-logo` | Lien, gap 10px, min-height 44px |
| `.yc-logo__mark` | Tuile 32px, surface 2, filet, « YN », trait accent en bas |
| `.yc-logo__word` | 15px / 700 |
| `.yc-logo__suffix` | Texte 2 / 500 |

Survol : filet de tuile `#3f3f46`. Pas de classe `--mark` ni `--word`.

Sanity : `logoMark`, `brandName`, `brandSuffix`.

### Code, touche, spinner, progression

| Classe | Rôle |
|---|---|
| `.yc-code-inline` | Mono, surface 1, filet, rayon 8px |
| `.yc-kbd` | Mono 12px, surface 2, filet, bordure basse 2px |
| `.yc-spinner` | 16px, rotation 700ms, coupée en reduced-motion |
| `.yc-progress` | Piste 4px, filet |
| `.yc-progress__bar` | Accent, largeur `--yc-progress-value` |
| `.yc-progress.is-loading` | Barre à 40 % |
| `.yc-progress-label` | Libellé texte 2, valeur texte 1 |

Outils de planche, à ne pas embarquer sur un site : `.yc-row`, `.yc-row--top`, `.yc-split`, `.yc-stack`, `.yc-state`, `.yc-state-scroll`, `.yc-state-table`, `.yc-atom-note`, `.yc-avatar-board`, `.yc-icon-grid`, `.yc-tip-board`.

## Molécules (`molecules.css`)

| Classe | Anatomie et états |
|---|---|
| `.yc-nav-item` | 14px / 500, texte 2, 44px, rayon 8px. Survol et `aria-current="page"` : texte 1, surface 2. Focus : contour et glow. Actif : toile, translate 1px. `aria-disabled` : opacité 0.4 |
| `.yc-nav-row` | Rangée de liens, gap 4px |
| `.yc-stat` | `.yc-stat__value` 18px / 800, `.yc-stat__label` 15px / 500 texte 2 |
| `.yc-stat-line` | Point 3px entre les stats |
| `.yc-stat-card` | Carte 16px de rayon, min-height 112px. Survol surface 2. Actif : toile |
| `.yc-float` | Verre, ombre 3, `data-rot` à 2, -2, 3 ou -3. `data-depth="0.9"` ou `.is-far` : opacité 0.4 |
| `.yc-float--chip` | `.yc-float__status`, `.yc-float__dot` |
| `.yc-float-stage` | Scène de planche. `__photo`, `__scrim`, `__layer`. Positions `--whatsapp`, `--analytics`, `--terminal`, `--pipeline` dès 800px |
| `.yc-project` | Média 1/1 contain, `.yc-project__kind`, h3, `.yc-project__tags`. Survol : filet hover, image ×1.02 |
| `.yc-article-card` | Même boîte. `time` en mono texte 3 |
| `.yc-article-card--feature` | Deux colonnes dès 800px, image max 440px |
| `.yc-timeline` | Fil 1px `--yc-line` |
| `.yc-timeline-item` | Padding gauche 28px. `__node` texte 3. `.is-current` : nœud accent. `__card` surface 1 |
| `.yc-timeline-item__meta` | Mono 12px, texte 3 |
| `.yc-timeline-item__role`, `__summary` | Pas de règle. Paragraphs 14px texte 2 |
| `.yc-quote` | Filet gauche `--yc-line`. `--accent` : filet gauche accent. Footer 14px |
| `.yc-callout` | Carte, h3 16px |
| `.yc-terminal` | `__bar`, `__dots` (texte 3), `__name`, `__body` mono 13px |
| `.yc-breadcrumb` | `ol`, séparateur « / ». Courant : `aria-current="page"` |
| `.yc-pagination` | Liens 44px. Courant : fond texte 1, texte toile |
| `.yc-toc` | `__title` « Sur cette page ». Courant : `aria-current="true"` ou `.is-current`, filet intérieur accent |
| `.yc-share` | Ghost. `.is-copied` sur le bouton |
| `.yc-follow` | Carte, un bouton outline |
| `.yc-channel` | `__mark`, `__value`. `--wa` : icône en `--yc-wa`. Lien `.yc-link` |
| `.yc-talk` | Carte. `__media` 1/1, `__body`, `__meta`. `--invite` : pas de colonne photo |
| `.yc-mol-grid` | `--2` et `--3` dès 800px |
| `.yc-mol-label` | Légende de planche |

Sanity : `yc.navItem`, `project`, `post`, `experience`, `talk`. Champs détaillés dans DESIGN.md.

## Organismes (`organisms.css`)

Le passage bureau / 390 se fait par `@container ycorg` sur `.yc-org-frame` (1100px, ou 390px avec `--mobile`). Sans ce conteneur, la disposition bureau reste.

| Classe | Rôle |
|---|---|
| `.yc-header` | Sticky, padding 12px |
| `.yc-header__bar` | Verre, 64px, rayon 16px, max 1280px |
| `.yc-header__nav` | Liens. Masquée sous 760px de conteneur |
| `.yc-header__cta` | `.yc-btn--primary` « Me contacter » |
| `.yc-header__burger` | 44px. Visible seulement sous 760px |
| `.yc-header__sheet` | Opaque surface 1. `[hidden]` la ferme |
| `.yc-header.is-scrolled`, `.is-open` | Barre surface 1, plus de flou |
| `.yc-hero--cinema` | 100svh, photo, scrim, halo, copie, flottants |
| `.yc-hero__photo--desktop` | Cover, ancrage 78 % 42 %. Masquée en conteneur étroit |
| `.yc-hero__photo--mobile` | Masquée par défaut. `center 22%` en conteneur étroit |
| `.yc-hero__scrim` | Overlay desktop, puis mobile |
| `.yc-hero__copy` | Z-index hero |
| `.yc-hero__lead` | 18px, texte 2 |
| `.yc-hero__stats` | Reprend `.yc-stat-line`. Chiffre 900, libellé 14px texte 3 |
| `.yc-hero__actions` | WhatsApp puis outline. Colonne en conteneur étroit |
| `.yc-hero__chips` | Masquées au bureau, deux tags au plus en étroit |
| `.yc-hero__floats` | `.yc-float--terminal`, `--analytics`, `--chat` |
| `.yc-hero--page` | H1 en 800. Se combine avec `--split`, `--bleed`, `--medal` |
| `.yc-hero__medal` | 96px |
| `.yc-band`, `.yc-band--alt` | Section. Alt : `--yc-bg-2` |
| `.yc-project-grid` | 1 puis 2 colonnes. `--neutral`, `--accent` (filet haut accent à 30 %), `__tint` masqué, `__media--note` en 16/10 |
| `.yc-article-list` | 1 puis 3 colonnes. `__more` pour le lien « Tous les articles » |
| `.yc-cta-band` | Fond `--yc-bg-2`. `__medal` 88px. Un bouton |
| `.yc-contact-form` | Max 640px. `__types` : légende et `.yc-chip` |
| `.yc-footer` | `__grid` 4 colonnes, `__brand`, `__place`, `__label`, `__legal` |
| `.yc-talk` | Réécrit la molécule : padding de section, média 1376/768. `__copy` sans règle propre. `__facts` mono 12px |
| `.yc-gallery` | 1 puis 2 colonnes. Légende sous l'image |
| `.yc-org-frame`, `--mobile`, `--sheet` | Cadres de planche |
| `.yc-org-scroll`, `.yc-org-kicker` | Coque de planche |

Liens de nav codés : Accueil, À propos, Projets, Blog, Interventions, Contact.

## Templates

Même `.yc-header` et `.yc-footer`. Suite dans DESIGN.md, section 15.

| Gabarit | Organismes |
|---|---|
| Accueil | header, hero cinéma, bandes, grille projets, talk, liste d'articles, bande CTA, footer |
| Page À propos | header, hero page, galerie, timeline, citation, bande CTA, footer |
| Page Projets | header, hero page, grille projets, footer |
| Fiche projet | header, fil d'Ariane, hero page, corps, bande CTA, footer |
| Blog | header, hero page, liste, pagination, suivre, footer |
| Article | header, fil d'Ariane, hero page, sommaire, prose, liste, footer |
| Interventions | header, hero page, deux `.yc-talk`, footer |
| Contact | header, hero page, canaux, formulaire, footer |

## Sanity partagé

```js
{ name: "siteSettings", type: "document", fields: [
  { name: "brandName", type: "string", initialValue: "Yoane" },
  { name: "brandSuffix", type: "string", initialValue: "Ngassam" },
  { name: "dataBrand", type: "string", options: { list: ["yoane", "doc4geeks"] }, initialValue: "yoane" },
  { name: "logoMark", type: "string", initialValue: "YN" },
  { name: "email", type: "string", initialValue: "hello@doc4geeks.com" },
  { name: "linkedin", type: "url" },
  { name: "whatsappUrl", type: "url" },
  { name: "nav", type: "array", of: [{ type: "yc.navItem" }] },
  { name: "contactCta", type: "yc.button" }
]}
```

`yoanengassam.com` et `yoane.doc4geeks.com` : `dataBrand` `yoane`. `doc4geeks.com` : `doc4geeks`.

## Règles d'usage

1. Corps en `--yc-text-2` sur `--yc-bg` (7.87:1). `--yc-text-3` est la méta (5.89:1 sur la toile, 5.19:1 sur surface 2).
2. Accent : lien, focus, sourcil, seconde ligne du titre, point, coche, filet de sommaire courant.
3. `--yc-wa` : fond du bouton WhatsApp, texte `#05070a` (10.17:1). L'icône de canal peut être verte. Le libellé `#fafafa` sur ce vert est à 1.90:1.
4. `--yc-danger` : erreur de formulaire seulement (5.82:1 sur surface 1).
5. Verre : `.yc-header__bar` au repos, et `.yc-float`. `.is-scrolled` et `.is-open` redeviennent opaques.
6. Glow : focus, et survol du bouton principal. Pas de glow de carte.
7. Un bouton plein par intention et par vue. Le blanc « Me contacter » et le vert « Écrire sur WhatsApp » sont deux intentions.
8. Reduced-motion coupe translation, pulsation, spinner, zoom d'image et flou des panneaux lointains.
9. Un h1 par page. Header et footer identiques.
10. Cible 44px pour les actions de page. `--sm` (36px) reste dans les outils denses.
