{
  "name": "Rangée de tuiles sous énoncé",
  "family": "layout",
  "ref": "ref-22-yellow-proposal-bento",
  "intent": "Ouvrir un écran par une rangée de trois tuiles de largeurs très inégales — une grande visuelle, deux brèves dont UNE SEULE est un aplat d'accent — puis laisser un énoncé prendre toute la parole en dessous, dans le seul très grand corps du bloc. Deux lois tiennent la composition : la grande tuile et le COUPLE de brèves se partagent la largeur presque à parts égales, ce qui interdit à la rangée de se lire comme « une image et deux annexes » ; et le marqueur de marque n'est pas calé sur la marge droite mais centré sur l'AXE de la tuile d'accent, base posée sur la baseline de la dernière ligne. C'est ce second ancrage qui rattache le marqueur à l'accent au lieu d'en faire un objet de coin.",
  "when_to_use": "Quand un écran doit dire une chose forte ET montrer trois entrées de rangs différents sans les hiérarchiser par la taille du texte : une couverture de section, une ouverture de proposition commerciale, un hero de page produit. Vaut particulièrement lorsque l'un des trois blocs est un VISUEL et les deux autres du texte court — la répartition 0,49 / 0,24 / 0,25 est faite pour ce cas et pour lui seul. Vaut aussi comme démonstration du geste « accent unique dit deux fois » : la tuile jaune est à la fois la seule colorée et la plus large des deux brèves.",
  "avoid_when": "Avec trois tuiles de MÊME nature — trois brèves, trois KPI : les largeurs inégales n'ont alors aucun motif et se lisent comme un défaut de calage (prendre `card-12-inverted-kpi-row`, qui traite exactement ce cas). Avec deux aplats d'accent : la rangée perd son point d'entrée, et le marqueur n'a plus d'axe unique à viser. Et sous ~1100 px de largeur, où trois colonnes dont une à 24 % ne portent plus trois lignes de texte — au repli, on empile les brèves sous le visuel et le marqueur revient en fin d'énoncé.",
  "media": [
    "slide",
    "web"
  ],
  "tags": [
    "bento",
    "tuile",
    "rangee",
    "enonce",
    "titre",
    "accent",
    "marqueur",
    "asterisque",
    "media",
    "breve",
    "proposition",
    "couverture",
    "hero"
  ],
  "vars": [
    {
      "name": "--vl-to-block",
      "role": "la largeur du bloc — toutes les cotes en découlent, aucune n'est écrite en pixels ailleurs",
      "default": "1448px"
    },
    {
      "name": "--vl-to-w1",
      "role": "la part de la tuile visuelle ; avec w2 + w3 + gouttière elle doit rester à moins de 2 % de la moitié, sinon la rangée bascule en « image + annexes »",
      "default": "0.489"
    },
    {
      "name": "--vl-to-w2",
      "role": "la part de la brève neutre",
      "default": "0.2376"
    },
    {
      "name": "--vl-to-w3",
      "role": "la part de la brève d'ACCENT — 5,8 % plus large que la neutre : la hiérarchie dite une seconde fois, par la largeur",
      "default": "0.2514"
    },
    {
      "name": "--vl-to-gap",
      "role": "la gouttière unique de la rangée",
      "default": "0.01105"
    },
    {
      "name": "--vl-to-row",
      "role": "la hauteur commune des trois tuiles",
      "default": "0.2597"
    },
    {
      "name": "--vl-to-mark",
      "role": "le côté du marqueur de marque ; il dicte aussi son retrait, puisqu'il est centré sur l'axe de la troisième colonne",
      "default": "0.1050"
    }
  ],
  "slots": [
    {
      "name": "media",
      "selector": ".vl-to__tile--media",
      "role": "le visuel de la rangée — image, vidéo ou objet reconstruit ; le pattern porte sa place, pas son dessin"
    },
    {
      "name": "numero",
      "selector": ".vl-to__num",
      "role": "le rang de la brève, en micro-libellé"
    },
    {
      "name": "titre",
      "selector": ".vl-to__h",
      "role": "le titre de la brève, sur deux lignes écrites"
    },
    {
      "name": "corps",
      "selector": ".vl-to__p",
      "role": "l'explication de la brève, collée au plancher de la tuile et coupée à trois lignes"
    },
    {
      "name": "enonce",
      "selector": ".vl-to__say",
      "role": "la phrase qui porte l'écran, sur deux lignes et dans le seul très grand corps du bloc"
    },
    {
      "name": "marque",
      "selector": ".vl-to__mark",
      "role": "le marqueur de marque, centré sur l'axe de la tuile d'accent — **OPTIONNEL** : retiré, l'énoncé garde toute la largeur et le bloc perd son ancre de droite (cf. notes)"
    }
  ],
  "geometry": {
    "root": ".vl-tiles-over",
    "frame": [
      1448,
      668
    ],
    "ratios": {
      "colonnes_over_block": [
        0.489,
        0.2376,
        0.2514
      ],
      "gouttiere_over_block": 0.01105,
      "hauteur_rangee_over_block": 0.2597,
      "marque_over_block": 0.105,
      "accent_sur_neutre": 1.058,
      "ecart_visuel_vs_couple": 0.011,
      "rayon_over_block": 0.0221,
      "interligne_enonce": 0.86,
      "interligne_titre_tuile": 1.24
    },
    "type_px": {
      "enonce": 135,
      "titre_tuile": 33,
      "corps": 18,
      "numero": 18
    },
    "pad_ratio": {
      "top": 0.0214,
      "x": 0.0276,
      "bottom": 0.0504
    }
  },
  "benchmarks": [
    {
      "name": "TROIS TUILES DE MÊME HAUTEUR — la rangée est une bande, pas trois objets posés côte à côte",
      "measure": "(() => { const h = [...document.querySelectorAll('.vl-to__tile')].map((e) => e.getBoundingClientRect().height); return (Math.max(...h) - Math.min(...h)) / W; })()",
      "max": 0.001
    },
    {
      "name": "QUASI-ÉQUILIBRE — la tuile visuelle et le COUPLE de brèves (gouttière comprise) se partagent la largeur à moins de 2 % près : au-delà, la rangée se lit « une image et deux annexes »",
      "measure": "(() => { const t = [...document.querySelectorAll('.vl-to__tile')].map((e) => e.getBoundingClientRect()); return Math.abs(t[0].width - (t[2].right - t[1].left)) / W; })()",
      "max": 0.02
    },
    {
      "name": "L'ACCENT EST AUSSI LE PLUS LARGE — la brève colorée dépasse la neutre de 3 à 10 % : la même hiérarchie dite deux fois, par la couleur ET par la largeur",
      "measure": "box('.vl-to__tile--accent').w / box('.vl-to__tile--brief:not(.vl-to__tile--accent)').w",
      "min": 1.03,
      "max": 1.1
    },
    {
      "name": "UN SEUL APLAT D'ACCENT — deux et la rangée n'a plus de point d'entrée, ni le marqueur d'axe à viser",
      "measure": "(() => { const a = cs('.vl-to__tile--accent', 'backgroundColor'); return [...document.querySelectorAll('.vl-to__tile')].filter((e) => getComputedStyle(e).backgroundColor === a).length; })()",
      "expect": 1,
      "tol": 0
    },
    {
      "name": "MARQUEUR SUR L'AXE DE L'ACCENT — s'il est là, son centre tombe sur celui de la troisième colonne, pas ailleurs",
      "measure": "(() => { if (!document.querySelector('.vl-to__mark')) return 0; const m = box('.vl-to__mark'), t = box('.vl-to__tile--accent'); return Math.abs((m.left + m.right) / 2 - (t.left + t.right) / 2) / W; })()",
      "max": 0.004
    },
    {
      "name": "ET DONC PAS COLLÉ À LA MARGE — il reste au moins 5 % de la largeur entre son bord droit et celui du bloc : un marqueur aligné sur la marge redevient un objet de coin",
      "measure": "(() => { if (!document.querySelector('.vl-to__mark')) return 1; return (box('.vl-tiles-over').right - box('.vl-to__mark').right) / W; })()",
      "min": 0.05
    },
    {
      "name": "BASE DU MARQUEUR SUR LA DERNIÈRE LIGNE — il ne descend jamais sous la boîte de l'énoncé, et n'en remonte pas de plus de 2 %",
      "measure": "(() => { if (!document.querySelector('.vl-to__mark')) return 0.01; return (box('.vl-to__say').bottom - box('.vl-to__mark').bottom) / W; })()",
      "min": 0,
      "max": 0.02
    },
    {
      "name": "INTERLIGNE DE L'ÉNONCÉ SOUS 1 — c'est ce qui fait lire deux lignes comme UNE masse ; au-dessus, ce sont deux phrases empilées",
      "measure": "num('.vl-to__say', 'lineHeight') / num('.vl-to__say', 'fontSize')",
      "max": 1
    },
    {
      "name": "SAUT DE HIÉRARCHIE — l'énoncé fait au moins 3,2 fois le titre d'une brève : entre les deux, aucune taille intermédiaire n'existe",
      "measure": "num('.vl-to__say', 'fontSize') / num('.vl-to__h', 'fontSize')",
      "min": 3.2
    },
    {
      "name": "PLANCHER DE CORPS — l'explication d'une brève ne descend pas sous 0,0120 de la largeur du bloc (18 px sur 1448) : la source, elle, tombe à ~15 px une fois remise à l'échelle",
      "measure": "num('.vl-to__p', 'fontSize') / W",
      "min": 0.012
    },
    {
      "name": "LES DEUX BRÈVES PARTENT DE LA MÊME HAUTEUR — leurs paragraphes sont collés au plancher ET coupés au même nombre de lignes ; sans la coupe, la plus étroite en fait une de plus et le rail se casse",
      "measure": "(() => { const p = [...document.querySelectorAll('.vl-to__p')].map((e) => e.getBoundingClientRect().top); return (Math.max(...p) - Math.min(...p)) / W; })()",
      "max": 0.004
    },
    {
      "name": "AUCUNE OMBRE — sur un fond plus CLAIR qu'elles, les tuiles ne se détachent que par leur aplat et leur rayon ; une ombre y fabriquerait une troisième couche",
      "measure": "[...document.querySelectorAll('.vl-to__tile')].filter((e) => getComputedStyle(e).boxShadow !== 'none').length",
      "expect": 0,
      "tol": 0
    },
    {
      "name": "RAYON EN LONGUEUR — le même rayon en pixels sur trois tuiles de largeurs DIFFÉRENTES ; en pourcentage, il donnerait trois arcs elliptiques",
      "measure": "(() => { const r = [...document.querySelectorAll('.vl-to__tile')].map((e) => parseFloat(getComputedStyle(e).borderTopLeftRadius)); return (Math.max(...r) - Math.min(...r)) / Math.max(...r); })()",
      "max": 0.003
    }
  ],
  "notes": "**Ce que ce pattern ajoute à `card-12-inverted-kpi-row`.** Les deux emploient le même geste — accentuer UNE carte d'une rangée par le fond ET par une colonne plus large. Mais `card-12` traite trois objets de MÊME nature (trois indicateurs), où l'inégalité de largeur est la seule chose qui hiérarchise ; ici les trois tuiles sont de natures différentes (un visuel, deux brèves), et l'inégalité de largeur sert d'abord à faire tenir un visuel à côté de deux textes. C'est pour ça que le benchmark central n'est pas le même : là-bas on mesure l'écart entre colonnes, ici on mesure le QUASI-ÉQUILIBRE entre la tuile visuelle et le couple de brèves.\n\n**Le marqueur est le vrai apport, et il est contre-intuitif.** Le réflexe est de le caler sur la marge droite, en face du titre. Mesuré sur la source, il ne l'est pas : son centre tombe à 1342 px sur 1600, soit exactement l'axe de la tuile d'accent, à 182 px de la marge. L'effet est net dès qu'on compare les deux : calé sur la marge, il ferme la slide et n'appartient à rien ; calé sur l'axe, il tire une verticale invisible depuis la seule tuile colorée, et l'accent unique se prolonge dans la zone de titre au lieu de s'arrêter à la rangée. Le second benchmark de retrait (≥ 5 % du bloc) existe pour interdire le retour au réflexe.\n\n**L'interligne sous 1 a une contrepartie qu'il faut payer explicitement.** À `line-height: 0.86`, le demi-interligne devient négatif (−36 px pour un corps de 134) : la boîte du titre est plus courte que ses glyphes, et un bloc calé en bas laisse ses descendantes mordre la marge de page. La compensation de 31 px sur le `margin-bottom` de l'énoncé n'est pas un réglage à l'œil — c'est la moitié de l'excédent, et elle se recalcule si le corps ou l'interligne changent.\n\n**La coupe du paragraphe est une hauteur maximale, pas un `line-clamp`.** Le clamp ajouterait des points de suspension que la source n'a pas ; la hauteur maximale coupe net, comme un texte de gabarit tronqué. Sans coupe du tout, la brève la plus étroite passe à quatre lignes et les deux paragraphes cessent de partir de la même hauteur — c'est la seule chose que cette rangée demande à ses brèves, et c'est mesuré.\n\n**Le marqueur est OPTIONNEL, et ce qu'on perd en le retirant est nommé.** Le bloc reste valide sans lui : l'énoncé garde la même position, la même compensation d'interligne, et les trois benchmarks qui le concernent se neutralisent quand il est absent (ils testent une loi conditionnelle — « s'il est là, il vise l'axe » — et non sa présence). Ce qui disparaît est réel : sans lui, la zone d'énoncé n'a plus d'ancre à droite, et l'accent unique s'arrête à la rangée au lieu de se prolonger sous elle. Deux cas où le retirer est le bon geste : quand l'énoncé est plus long et réclame la largeur, et quand le bloc est posé dans une page qui porte déjà la marque ailleurs (un hero sous une barre de navigation). Le retrait tient en une chose — supprimer le `div.vl-to__mark` ; la règle CSS peut rester, elle n'est plus appelée.\n\n**Origine.** Reversé le 24/08/2026 depuis une slide de proposition commerciale relevée à la pipette (`assets/refs/ref-22-yellow-proposal-bento.png`, 586 px de large, donc ×2,7304 pour une slide 1600×900). Les corps de la source tombent à ~15 px une fois remis à l'échelle, sous le plancher du corpus : ils sont remontés à 20, et c'est le seul écart au relevé.",
  "id": "layout-19-tiles-over-claim"
}