layout-14-statement-first

Page qui parle avant de se nommer

Inverser l'ordre de lecture d'un hero : la phrase parle en premier dans un petit corps, la navigation lui fait face à la même hauteur, et le nom de marque n'arrive qu'ensuite — mais il prend alors toute la largeur utile, sans qu'AUCUNE taille intermédiaire n'existe entre les deux. C'est ce saut sans palier, et le blanc plus large qui le précède, qui font qu'un nom devient un événement au lieu d'être le plus gros d'une série.

layoutwebslide1140×848px14 benchmarks

Télécharger le .zip

Le fragment RÉEL, dans son propre document, sur le sol de sa charte — pas une image. Ce que vous voyez est exactement ce que vous collerez.

Employer quand

Une page d'accueil ou une couverture dont le message vaut mieux que le nom : studio, agence, maison déjà connue de ceux à qui elle parle. Aussi quand la charte n'a aucun accent coloré — la composition tient entièrement par l'échelle et le blanc, donc elle survit à une palette de trois valeurs.

Éviter quand

Le nom doit être reconnu AVANT le message — page institutionnelle, premier contact avec un public qui ne connaît pas la maison : ici le nom arrive en second, et cet ordre suppose que la phrase se suffit. Écarter aussi quand le nom tient sur deux lignes : le saut d'échelle repose sur un mot unique qui sature la largeur utile, et sur deux lignes le nom cesse d'être un signe pour redevenir un bloc de texte.

Notes

La composition tient sur deux ressorts, et ils se mesurent tous les deux. Le premier est le SAUT D'ÉCHELLE : 27 px puis 204 px, sans rien entre les deux. Ce n'est pas une échelle typographique, c'est son refus — une échelle à raison régulière donnerait quatre ou cinq paliers, et le nom ne serait plus qu'un maximum. Deux assertions le tiennent ensemble : le rapport ≥ 7, et le fait que le troisième corps de la page (la nav) se range SOUS le plus petit des deux autres au lieu de s'intercaler. C'est cette seconde assertion qui attrape la faute qu'on commet vraiment : personne n'ajoute un corps intermédiaire par erreur, tout le monde grossit la nav « pour équilibrer ». Le second est un BLANC ASYMÉTRIQUE : l'intervalle phrase → nom (54 px) est plus large que l'intervalle nom → bande (33 px). Répartis également, les trois blocs se lisent comme une pile ; asymétriques, ils se lisent comme un mouvement. Le blanc de pied n'est d'ailleurs pas posé, il RESTE : la bande est poussée par `margin-top: auto`, donc l'intervalle absorbe tout changement de longueur de phrase sans qu'on recalcule quoi que ce soit. Piège de mesure payé ici : un `h1` est un BLOC, sa boîte fait toujours la largeur utile quoi qu'on écrive dedans. Une assertion « le nom ne franchit pas la marge » écrite sur `getBoundingClientRect()` de l'élément est donc VIDE — elle sort verte sur un nom qui déborde de 1 %. Elle se mesure sur l'ENCRE, par un `Range` sur le contenu ; et c'est cette correction qui a fait tomber le corps de démonstration de 204 à 201 px, le mot de remplissage n'ayant pas la chasse de celui de la source. La bande de pied est `layout-13-image-triptych` dans le slot `strip` — poids inégaux compris, ils font partie de la composition. Elle est ici réduite à trois cellules pleines pour que le fragment reste autonome et que ses assertions portent sur la composition. Le réglage du nom à la largeur utile et le calage de son `®` appartiennent à `title-04-name-fills-measure` : les deux patterns se posent l'un dans l'autre et ne se recouvrent sur rien. La page est UNE couche. Pas de carte posée sur un sol, pas de fond de planche : elle porte son fond, sa marge et sa mise en page. C'est ce qui la distingue de `layout-11-hero-card-on-photo`, la composition jumelle de `ref-07`, qui en a deux parce qu'elle a un sol photographique — et dont l'`avoid_when` refuse explicitement le cas d'ici.

Mots-clés

heroaccueilordre-de-lectureechellewordmarknavbandegroteskneutreblanc

Benchmarks — la géométrie, en assertions vérifiables

Rejouables par node bin/check.mjs layout-14-statement-first : le pattern se prouve, il ne se croit pas.

assertionmesureattendu
L'ORDRE DE LECTURE — phrase, puis nom, puis bande : trois zones qui ne se chevauchent jamais(() => { const s = box('.vl-sf__statement'), m = box('.vl-sf__mark'), t = box('.vl-sf__strip'); return (s.bottom <= m.top + 1 && m.bottom <= t.top + 1) ? 1 : 0; })()1 ± 0
la phrase parle EN PREMIER : elle affleure la marge haute, rien n'est au-dessus d'ellebox('.vl-sf__statement').top / H0.0472 ± 0.004
la nav lui FAIT FACE : même bord haut à moins de 1 % de la hauteur prèsMath.abs(box('.vl-sf__nav').top - box('.vl-sf__statement').top) / H≤ 0.01
et elle est fer à DROITE sur la marge : les deux blocs de tête tiennent les deux bords(W - box('.vl-sf__nav').right) / W0.0351 ± 0.004
les deux blocs de tête ne se croisent jamais : la mesure de la phrase laisse la place à la nav(box('.vl-sf__nav').left - box('.vl-sf__statement').right) / W≥ 0.02
SAUT D'ÉCHELLE : le corps du nom vaut au moins 7 fois celui de la phrasenum('.vl-sf__mark','fontSize') / num('.vl-sf__statement','fontSize')7 → 9
et SANS PALIER : le troisième corps de la page (la nav) est plus PETIT que la phrase, pas entre elle et le nomnum('.vl-sf__nav','fontSize') < num('.vl-sf__statement','fontSize') ? 1 : 01 ± 0
le blanc qui SÉPARE la phrase du nom est plus large que celui qui suit le nom — c'est lui qui fait lever les yeux(box('.vl-sf__mark').top - box('.vl-sf__statement').bottom) / (box('.vl-sf__strip').top - box('.vl-sf__mark').bottom)≥ 1.15
la bande tombe en PIED : son bas affleure la marge basse(H - box('.vl-sf__strip').bottom) / H0.0472 ± 0.004
elle occupe TOUTE la largeur utile — d'une marge à l'autre, jamais une bande centrée plus étroitebox('.vl-sf__strip').w / W0.9298 ± 0.004
et elle pèse près de 45 % de la hauteur : assez pour FERMER la page, pas assez pour la partager en deuxbox('.vl-sf__strip').h / H0.448 ± 0.02
marges ÉGALES sur les quatre côtés — une seule valeur, c'est ce qui fait que la page est la surface(() => { const s = getComputedStyle(document.querySelector('.vl-sf')); const p = ['paddingTop','paddingRight','paddingBottom','paddingLeft'].map((k) => parseFloat(s[k])); return (Math.max(...p) - Math.min(...p)) / W; })()≤ 0.001
rien ne franchit la marge : mesuré sur l'ENCRE du nom (un h1 est un bloc — sa boîte fait la largeur utile quoi qu'on y écrive, donc elle ne prouve rien)(() => { const el = document.querySelector('.vl-sf__mark'); const r = document.createRange(); r.selectNodeContents(el); const ink = r.getBoundingClientRect(); const lim = W - 2 * num('.vl-sf','paddingLeft'); return ink.width / lim; })()0.985 → 1
la phrase reste une ADRESSE et pas un paragraphe : sa mesure est bornée sous les deux tiers de la pagebox('.vl-sf__statement').w / W0.35 → 0.65

Le code

fragment — patterns/layout-14-statement-first.html Télécharger
<!-- layout-14-statement-first — la page qui parle AVANT de se nommer. L'ordre de lecture est
     inversé par rapport au hero courant : d'abord la phrase (haut-gauche, petit corps), la nav
     qui lui fait face à la même hauteur, et le nom de marque seulement ENSUITE — mais il prend
     alors toute la largeur utile. La bande d'images tombe en pied et ferme la page.

     Ce qui fait tenir la composition n'est pas la disposition, c'est le SAUT D'ÉCHELLE : entre
     le corps de la phrase et celui du nom il n'y a AUCUN palier, aucune taille intermédiaire.
     Un sous-titre glissé entre les deux et la page redevient une page ordinaire — le nom cesse
     d'être un événement pour devenir le plus gros d'une série.

     Le second ressort est un blanc : l'intervalle qui sépare la phrase du nom est le plus grand
     de la page, plus grand que celui qui sépare le nom de la bande. C'est lui qui fait qu'on
     LÈVE les yeux du texte avant de recevoir le nom.

     La bande de pied est `layout-13-image-triptych`, posée dans le slot `strip` : ici elle est
     réduite à trois cellules pleines, pour que ce fragment reste autonome et que ses assertions
     portent sur la COMPOSITION et non sur des images. En usage réel on y colle le triptyque.
     Couleurs via --vl-* uniquement, aucune valeur en dur. -->
<div class="vl-sf">

  <div class="vl-sf__top">
    <p class="vl-sf__statement">We partner with startups and visionaries to<br>
      craft brand identities, digital experiences,<br>
      and narratives that resonate.</p>
    <nav class="vl-sf__nav">
      <a href="#">Work</a><a href="#">Index</a><a href="#">About</a><a href="#">Contact</a>
    </nav>
  </div>

  <h1 class="vl-sf__mark">Northbeam<span class="vl-sf__r">&reg;</span></h1>

  <div class="vl-sf__strip">
    <figure class="vl-sf__cell"></figure>
    <figure class="vl-sf__cell"></figure>
    <figure class="vl-sf__cell"></figure>
  </div>

</div>

<style>
/* La page EST la surface : elle porte son fond, sa marge et sa mise en page. Pas de carte
   posée dessus, pas de sol derrière — une couche, et c'est tout ce que la source montre.
   La colonne flex à trois enfants est ce qui rend l'ordre de lecture MESURABLE : haut, nom,
   pied, dans cet ordre, sans qu'aucun positionnement ne puisse les faire se croiser. */
.vl-sf {
  width: 1140px; height: 848px;
  padding: var(--vl-margin);
  background: var(--vl-card);
  color: var(--vl-ink);
  border-radius: var(--vl-radius-card);
  display: flex; flex-direction: column;
  font-family: "Helvetica Neue", Helvetica, Inter, Arial, sans-serif;
}

/* La phrase et la nav partagent la même ligne haute — `flex-start`, pas d'alignement optique
   bricolé. Les deux affleurent la marge : la phrase à gauche, la nav à droite. */
.vl-sf__top { display: flex; justify-content: space-between; align-items: flex-start; gap: 64px; }

/* Le petit corps de la page, et le seul texte à LIRE. Sa mesure est bornée : au-delà d'une
   soixantaine de signes la phrase cesse d'être une adresse et redevient un paragraphe. */
.vl-sf__statement {
  margin: 0; max-width: 700px;
  font-size: 27px; line-height: 1.4; font-weight: 400; letter-spacing: -0.004em;
  color: var(--vl-ink-soft);
}

/* La nav est PLUS PETITE que la phrase, et c'est structurant : le troisième corps de la page
   se range sous le plus petit des deux autres, jamais entre eux. Un corps intermédiaire ferait
   un palier, et le saut d'échelle qui porte toute la composition disparaîtrait. */
.vl-sf__nav {
  display: flex; gap: 17px;
  margin: 5px 0 0;
  font-size: 18px; line-height: 1; font-weight: 400;
}
.vl-sf__nav a { color: var(--vl-ink); text-decoration: none; }

/* Le nom. Sa marge HAUTE est le plus grand blanc de la page — plus grand que celui qui le
   sépare de la bande. C'est cette asymétrie qui fait qu'on lève les yeux de la phrase avant de
   recevoir le nom ; répartie également, la page redevient une pile de trois blocs.
   Le corps ne se choisit pas dans une échelle : il se règle à la largeur utile — c'est le
   travail de `title-04-name-fills-measure`, qui porte aussi le calage du ®.
   201 px et non une valeur ronde : c'est ce qu'il faut pour que « Northbeam® » affleure les
   deux marges d'une page de 1140. `ref-08` écrit un autre mot, de même longueur mais pas de
   même chasse, et y met 204. Changer le mot ou la largeur oblige à recalculer — un h1 est un
   BLOC, sa boîte fait la largeur utile quoi qu'on écrive dedans, donc rien ne signale le
   débord : c'est l'ENCRE qu'il faut mesurer, et un benchmark le fait. */
.vl-sf__mark {
  margin: 54px 0 0;
  font-size: 201px; line-height: 0.92; font-weight: 700;
  letter-spacing: -0.035em; white-space: nowrap;
}
.vl-sf__r {
  font-size: 0.26em; vertical-align: baseline;
  position: relative; top: -1.52em; left: 0.02em;
  letter-spacing: 0;
}

/* `margin-top: auto` : la bande est poussée en PIED, et le blanc qui reste retombe au-dessus
   d'elle. Une hauteur fixe plus un `margin-top` calculé donnerait la même image aujourd'hui et
   dériverait au premier changement de longueur de phrase. */
.vl-sf__strip {
  margin-top: auto;
  display: flex; align-items: stretch; gap: var(--vl-gap-photo);
  height: 380px;
}
/* Trois cellules pleines : ce fragment mesure la composition, pas des photos. Les poids
   inégaux sont conservés parce qu'ils font partie de la composition — c'est `layout-13` qui
   porte leur loi (hauteur commune, gouttière constante, remplissage exact). */
.vl-sf__cell {
  margin: 0; flex: 1 0 0;
  background: var(--vl-ink); opacity: 0.12;
  border-radius: var(--vl-radius-photo);
}
.vl-sf__cell:nth-child(2) { flex-grow: 1.31; opacity: 0.2; }
.vl-sf__cell:nth-child(3) { flex-grow: 1.14; opacity: 0.16; }
</style>
tokens de la charte — systems/ref-08-swiss-studio-hero.json Télécharger
:root {
  --vl-bg: #F6F5F2;
  --vl-board: #F6F5F2;
  --vl-card: #F6F5F2;
  --vl-ink: #111111;
  --vl-ink-soft: #2A2A28;
  --vl-radius-card: 4px;
  --vl-radius-photo: 8px;
  --vl-margin: 40px;
  --vl-gap-photo: 16px;
}
les métadonnées — patterns/layout-14-statement-first.json (télécharger)
{
  "name": "Page qui parle avant de se nommer",
  "family": "layout",
  "ref": "ref-08-swiss-studio-hero",
  "intent": "Inverser l'ordre de lecture d'un hero : la phrase parle en premier dans un petit corps, la navigation lui fait face à la même hauteur, et le nom de marque n'arrive qu'ensuite — mais il prend alors toute la largeur utile, sans qu'AUCUNE taille intermédiaire n'existe entre les deux. C'est ce saut sans palier, et le blanc plus large qui le précède, qui font qu'un nom devient un événement au lieu d'être le plus gros d'une série.",
  "when_to_use": "Une page d'accueil ou une couverture dont le message vaut mieux que le nom : studio, agence, maison déjà connue de ceux à qui elle parle. Aussi quand la charte n'a aucun accent coloré — la composition tient entièrement par l'échelle et le blanc, donc elle survit à une palette de trois valeurs.",
  "avoid_when": "Le nom doit être reconnu AVANT le message — page institutionnelle, premier contact avec un public qui ne connaît pas la maison : ici le nom arrive en second, et cet ordre suppose que la phrase se suffit. Écarter aussi quand le nom tient sur deux lignes : le saut d'échelle repose sur un mot unique qui sature la largeur utile, et sur deux lignes le nom cesse d'être un signe pour redevenir un bloc de texte.",
  "media": [
    "web",
    "slide"
  ],
  "tags": [
    "hero",
    "accueil",
    "ordre-de-lecture",
    "echelle",
    "wordmark",
    "nav",
    "bande",
    "grotesk",
    "neutre",
    "blanc"
  ],
  "vars": [
    {
      "name": "--vl-card",
      "role": "fond de la page — c'est la page elle-même, il n'y a pas de sol derrière",
      "default": "#F6F5F2"
    },
    {
      "name": "--vl-ink",
      "role": "encre du nom et de la nav",
      "default": "#111111"
    },
    {
      "name": "--vl-ink-soft",
      "role": "encre de la phrase — le seul texte à LIRE, donc le seul à ne pas être au maximum du contraste",
      "default": "#2A2A28"
    },
    {
      "name": "--vl-margin",
      "role": "marge de page, égale sur les quatre côtés",
      "default": "40px"
    },
    {
      "name": "--vl-radius-card",
      "role": "rayon de la page",
      "default": "4px"
    },
    {
      "name": "--vl-radius-photo",
      "role": "rayon des cellules de la bande de pied",
      "default": "8px"
    },
    {
      "name": "--vl-gap-photo",
      "role": "gouttière de la bande de pied",
      "default": "16px"
    }
  ],
  "slots": [
    "statement",
    "nav",
    "mark",
    "strip"
  ],
  "geometry": {
    "root": ".vl-sf",
    "frame": [
      1140,
      848
    ],
    "ratios": {
      "margin_over_frame": 0.0351,
      "margin_over_frame_h": 0.0472,
      "statement_measure_over_frame": 0.614,
      "strip_h_over_frame_h": 0.448,
      "strip_w_over_frame": 0.9298,
      "mark_over_statement_size": 7.44
    },
    "type_px": {
      "statement": 27,
      "nav": 18,
      "mark": 201
    },
    "pad_ratio": {
      "top": 0.0351,
      "x": 0.0351,
      "bottom": 0.0351
    }
  },
  "benchmarks": [
    {
      "name": "L'ORDRE DE LECTURE — phrase, puis nom, puis bande : trois zones qui ne se chevauchent jamais",
      "measure": "(() => { const s = box('.vl-sf__statement'), m = box('.vl-sf__mark'), t = box('.vl-sf__strip'); return (s.bottom <= m.top + 1 && m.bottom <= t.top + 1) ? 1 : 0; })()",
      "expect": 1,
      "tol": 0
    },
    {
      "name": "la phrase parle EN PREMIER : elle affleure la marge haute, rien n'est au-dessus d'elle",
      "measure": "box('.vl-sf__statement').top / H",
      "expect": 0.0472,
      "tol": 0.004
    },
    {
      "name": "la nav lui FAIT FACE : même bord haut à moins de 1 % de la hauteur près",
      "measure": "Math.abs(box('.vl-sf__nav').top - box('.vl-sf__statement').top) / H",
      "max": 0.01
    },
    {
      "name": "et elle est fer à DROITE sur la marge : les deux blocs de tête tiennent les deux bords",
      "measure": "(W - box('.vl-sf__nav').right) / W",
      "expect": 0.0351,
      "tol": 0.004
    },
    {
      "name": "les deux blocs de tête ne se croisent jamais : la mesure de la phrase laisse la place à la nav",
      "measure": "(box('.vl-sf__nav').left - box('.vl-sf__statement').right) / W",
      "min": 0.02
    },
    {
      "name": "SAUT D'ÉCHELLE : le corps du nom vaut au moins 7 fois celui de la phrase",
      "measure": "num('.vl-sf__mark','fontSize') / num('.vl-sf__statement','fontSize')",
      "min": 7,
      "max": 9
    },
    {
      "name": "et SANS PALIER : le troisième corps de la page (la nav) est plus PETIT que la phrase, pas entre elle et le nom",
      "measure": "num('.vl-sf__nav','fontSize') < num('.vl-sf__statement','fontSize') ? 1 : 0",
      "expect": 1,
      "tol": 0
    },
    {
      "name": "le blanc qui SÉPARE la phrase du nom est plus large que celui qui suit le nom — c'est lui qui fait lever les yeux",
      "measure": "(box('.vl-sf__mark').top - box('.vl-sf__statement').bottom) / (box('.vl-sf__strip').top - box('.vl-sf__mark').bottom)",
      "min": 1.15
    },
    {
      "name": "la bande tombe en PIED : son bas affleure la marge basse",
      "measure": "(H - box('.vl-sf__strip').bottom) / H",
      "expect": 0.0472,
      "tol": 0.004
    },
    {
      "name": "elle occupe TOUTE la largeur utile — d'une marge à l'autre, jamais une bande centrée plus étroite",
      "measure": "box('.vl-sf__strip').w / W",
      "expect": 0.9298,
      "tol": 0.004
    },
    {
      "name": "et elle pèse près de 45 % de la hauteur : assez pour FERMER la page, pas assez pour la partager en deux",
      "measure": "box('.vl-sf__strip').h / H",
      "expect": 0.448,
      "tol": 0.02
    },
    {
      "name": "marges ÉGALES sur les quatre côtés — une seule valeur, c'est ce qui fait que la page est la surface",
      "measure": "(() => { const s = getComputedStyle(document.querySelector('.vl-sf')); const p = ['paddingTop','paddingRight','paddingBottom','paddingLeft'].map((k) => parseFloat(s[k])); return (Math.max(...p) - Math.min(...p)) / W; })()",
      "max": 0.001
    },
    {
      "name": "rien ne franchit la marge : mesuré sur l'ENCRE du nom (un h1 est un bloc — sa boîte fait la largeur utile quoi qu'on y écrive, donc elle ne prouve rien)",
      "measure": "(() => { const el = document.querySelector('.vl-sf__mark'); const r = document.createRange(); r.selectNodeContents(el); const ink = r.getBoundingClientRect(); const lim = W - 2 * num('.vl-sf','paddingLeft'); return ink.width / lim; })()",
      "min": 0.985,
      "max": 1
    },
    {
      "name": "la phrase reste une ADRESSE et pas un paragraphe : sa mesure est bornée sous les deux tiers de la page",
      "measure": "box('.vl-sf__statement').w / W",
      "min": 0.35,
      "max": 0.65
    }
  ],
  "notes": "La composition tient sur deux ressorts, et ils se mesurent tous les deux.\n\nLe premier est le SAUT D'ÉCHELLE : 27 px puis 204 px, sans rien entre les deux. Ce n'est pas une échelle typographique, c'est son refus — une échelle à raison régulière donnerait quatre ou cinq paliers, et le nom ne serait plus qu'un maximum. Deux assertions le tiennent ensemble : le rapport ≥ 7, et le fait que le troisième corps de la page (la nav) se range SOUS le plus petit des deux autres au lieu de s'intercaler. C'est cette seconde assertion qui attrape la faute qu'on commet vraiment : personne n'ajoute un corps intermédiaire par erreur, tout le monde grossit la nav « pour équilibrer ».\n\nLe second est un BLANC ASYMÉTRIQUE : l'intervalle phrase → nom (54 px) est plus large que l'intervalle nom → bande (33 px). Répartis également, les trois blocs se lisent comme une pile ; asymétriques, ils se lisent comme un mouvement. Le blanc de pied n'est d'ailleurs pas posé, il RESTE : la bande est poussée par `margin-top: auto`, donc l'intervalle absorbe tout changement de longueur de phrase sans qu'on recalcule quoi que ce soit.\n\nPiège de mesure payé ici : un `h1` est un BLOC, sa boîte fait toujours la largeur utile quoi qu'on écrive dedans. Une assertion « le nom ne franchit pas la marge » écrite sur `getBoundingClientRect()` de l'élément est donc VIDE — elle sort verte sur un nom qui déborde de 1 %. Elle se mesure sur l'ENCRE, par un `Range` sur le contenu ; et c'est cette correction qui a fait tomber le corps de démonstration de 204 à 201 px, le mot de remplissage n'ayant pas la chasse de celui de la source.\n\nLa bande de pied est `layout-13-image-triptych` dans le slot `strip` — poids inégaux compris, ils font partie de la composition. Elle est ici réduite à trois cellules pleines pour que le fragment reste autonome et que ses assertions portent sur la composition. Le réglage du nom à la largeur utile et le calage de son `®` appartiennent à `title-04-name-fills-measure` : les deux patterns se posent l'un dans l'autre et ne se recouvrent sur rien.\n\nLa page est UNE couche. Pas de carte posée sur un sol, pas de fond de planche : elle porte son fond, sa marge et sa mise en page. C'est ce qui la distingue de `layout-11-hero-card-on-photo`, la composition jumelle de `ref-07`, qui en a deux parce qu'elle a un sol photographique — et dont l'`avoid_when` refuse explicitement le cas d'ici.",
  "id": "layout-14-statement-first"
}

À côté