/* =====================================================================
   LE HAUT DU PORTAIL — CE QU'ON DIT, ET CE QU'ON MONTRE
   =====================================================================

   Avant : tout était centré — l'étiquette, le titre, le paragraphe, les
   deux boutons — sur un fond noir vide relevé d'une lueur rouge. Trois
   défauts, et le troisième est le plus grave.

   1. Centrer quatre blocs l'un sous l'autre ne compose pas une page :
      cela empile. Le regard n'a aucun point d'entrée, et un paragraphe
      centré sur trois lignes se lit mal — l'œil cherche le début de
      chaque ligne à un endroit différent.

   2. La lueur radiale sous un titre est le fond par défaut de toutes
      les pages d'outil depuis dix ans. Il ne dit rien de personne.

   3. Un outil de menuiserie ne montrait ni profilé, ni coupe, ni plan.
      Rien du métier. Le visiteur devait croire sur parole.

   Ce fichier répond aux trois. Le texte passe à gauche, aligné, sur une
   largeur qui se lit. Et à droite on montre — pas une image de banque
   d'images, mais le dessin que l'application produit elle-même : une
   baie au trait, ses cotes, puis la barre de 5,80 m qui se remplit et
   laisse sa chute. C'est le seul dessin que le menuisier reconnaisse
   sans qu'on le lui explique : il l'a déjà sur ses feuilles.

   Tout est en SVG dans la page et animé en CSS. Rien à charger, rien à
   exécuter : le dessin est là au premier affichage, même si les scripts
   tardent sur une connexion de chantier.
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. LA COMPOSITION
   ---------------------------------------------------------------------
   En dessous de 980 px on garde l'empilement centré : sur un téléphone
   deux colonnes ne tiennent pas, et le dessin passe sous les boutons
   plutôt que de repousser l'appel à l'action hors de l'écran.
   --------------------------------------------------------------------- */

.portal-hero { padding: clamp(34px, 6vw, 68px) 0 clamp(30px, 5vw, 56px); }

.hero-montrer { margin-top: clamp(26px, 5vw, 44px); }
.hero-plan { width: 100%; height: auto; display: block; overflow: visible; }

@media (min-width: 980px) {
  .portal-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.04fr);
    gap: clamp(30px, 4.4vw, 66px);
    align-items: center;
    text-align: left;
  }
  .hero-dire { max-width: 33rem; }
  .hero-montrer { margin-top: 0; }

  /* Les blocs de texte étaient centrés par .portal-hero. Alignés à
     gauche, ils partagent enfin un même bord — c'est ce bord qui tient
     la colonne debout. */
  .portal-hero .portal-hero-sub { margin-left: 0; margin-right: 0; }
  .portal-hero .portal-hero-cta { justify-content: flex-start; }
}

/* Le paragraphe se lit à 62 caractères environ. Au-delà, l'œil perd la
   ligne suivante en revenant à la marge. */
.portal-hero .portal-hero-sub { max-width: 34rem; }


/* ---------------------------------------------------------------------
   2. LE DESSIN
   ---------------------------------------------------------------------
   Les couleurs viennent du vocabulaire : le trait suit le texte doux,
   la cote suit le rouge qui coupe, le verre garde son bleu de matière —
   c'est une matière, pas un rôle d'interface.
   --------------------------------------------------------------------- */

.hp-trait { stroke: var(--texte-doux); stroke-width: 1.5; }
.hp-trait rect, .hp-trait path { vector-effect: non-scaling-stroke; }
.hp-verre rect { fill: color-mix(in srgb, #4E7E96 42%, transparent); }
.hp-geste { stroke: var(--texte-doux); stroke-width: 1.4;
            stroke-linecap: round; stroke-linejoin: round; opacity: .75; }
.hp-cote  { stroke: var(--role-couper); stroke-width: 1.2; }

.hp-chiffre text {
  fill: var(--role-couper); font-family: var(--police-chiffre, ui-monospace, monospace);
  font-size: 13px; font-weight: 700; text-anchor: middle;
}
/* Le chiffre est posé SUR la ligne de cote : sans pastille, le trait le
   barre. C'est la convention du dessin technique, pas une décoration. */
.hp-fond { fill: var(--fond); }

.hp-legende {
  fill: var(--texte-doux); font-family: var(--police-chiffre, ui-monospace, monospace);
  font-size: 10px; font-weight: 700; letter-spacing: .12em;
}
.hp-legende-chute { fill: var(--role-attente); text-anchor: end; }

.hp-lit   { fill: none; stroke: var(--filet); stroke-width: 1; }
.hp-seg   { fill: color-mix(in srgb, var(--role-couper) 78%, transparent); }
.hp-s2    { fill: color-mix(in srgb, var(--role-couper) 62%, transparent); }
.hp-s3    { fill: color-mix(in srgb, var(--role-couper) 70%, transparent); }
.hp-s4    { fill: color-mix(in srgb, var(--role-couper) 54%, transparent); }
/* La chute n'est pas une perte : elle est en laiton, la couleur de ce
   qui attend — elle repartira au stock de chutes. */
.hp-chute { fill: color-mix(in srgb, var(--role-attente) 34%, transparent);
            stroke: var(--role-attente-fil); stroke-width: 1; }


/* ---------------------------------------------------------------------
   3. L'ANIMATION
   ---------------------------------------------------------------------
   Elle se joue UNE FOIS, à l'arrivée, en quatre temps qui suivent
   l'ordre réel du métier : on trace, on cote, on range, on compte la
   chute. Pas de boucle : une page qui s'agite en permanence pendant
   qu'on lit fatigue, et donne l'impression d'une vitrine plutôt que
   d'un outil.

   pathLength="1" sur chaque forme normalise sa longueur : le tracé
   s'anime avec dasharray:1 quelle que soit la taille du trait, sans
   qu'on ait à mesurer quoi que ce soit en JavaScript.
   --------------------------------------------------------------------- */

@keyframes hp-tracer  { to { stroke-dashoffset: 0; } }
@keyframes hp-paraitre { from { opacity: 0; } to { opacity: 1; } }
@keyframes hp-pousser  { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.hp-t { stroke-dasharray: 1; stroke-dashoffset: 1;
        animation: hp-tracer .9s ease forwards; }
.hp-t1 { animation-delay: .10s; }
.hp-t2 { animation-delay: .30s; }
.hp-t3 { animation-delay: .55s; }
.hp-t4 { animation-delay: .70s; }
.hp-t5 { animation-delay: .82s; }

.hp-verre rect { opacity: 0; animation: hp-paraitre .7s ease 1.15s forwards; }
.hp-geste path { stroke-dasharray: 1; stroke-dashoffset: 1;
                 animation: hp-tracer .5s ease 1.45s forwards; }

.hp-cote path { stroke-dasharray: 1; stroke-dashoffset: 1;
                animation: hp-tracer .6s ease forwards; }
.hp-c1 { animation-delay: 1.60s; }
.hp-c2 { animation-delay: 1.80s; }
.hp-chiffre { opacity: 0; animation: hp-paraitre .5s ease 2.05s forwards; }

.hp-legende { opacity: 0; animation: hp-paraitre .5s ease 2.35s forwards; }
.hp-lit     { opacity: 0; animation: hp-paraitre .5s ease 2.35s forwards; }

/* Chaque morceau pousse depuis SA gauche : transform-box ramène
   l'origine à la boîte de la forme, sans quoi elle serait celle du SVG
   entier et les segments glisseraient au lieu de grandir. */
.hp-seg, .hp-chute {
  transform-box: fill-box; transform-origin: left center;
  animation: hp-pousser .34s cubic-bezier(.2,.7,.3,1) forwards;
  transform: scaleX(0);
}
.hp-s1    { animation-delay: 2.55s; }
.hp-s2    { animation-delay: 2.72s; }
.hp-s3    { animation-delay: 2.89s; }
.hp-s4    { animation-delay: 3.06s; }
.hp-chute { animation-delay: 3.28s; }
.hp-legende-chute { animation-delay: 3.55s; }

/* Qui a demandé moins de mouvement voit le dessin fini, tout de suite. */
@media (prefers-reduced-motion: reduce) {
  .hp-t, .hp-geste path, .hp-cote path { stroke-dashoffset: 0; animation: none; }
  .hp-verre rect, .hp-chiffre, .hp-legende, .hp-lit { opacity: 1; animation: none; }
  .hp-seg, .hp-chute { transform: none; animation: none; }
}


/* ---------------------------------------------------------------------
   4. L'ÉCHELLE TYPOGRAPHIQUE
   ---------------------------------------------------------------------
   Mesuré avant de toucher quoi que ce soit :

       titre du hero          22,5 px
       paragraphe             16,8 px
       titre de section (bas)  25,6 px

   Le titre pesait 1,34 fois son propre paragraphe — un titre de hero
   demande trois fois. Et il était plus PETIT qu'un intertitre situé
   plus bas dans la page : la ligne la plus importante du site perdait
   contre une simple étiquette de section. C'est cela, et non le fond
   noir, qui faisait « pas fini ».

   L'échelle est reprise en clamp() : elle grandit avec l'écran sans
   jamais déborder sur un téléphone.
   --------------------------------------------------------------------- */

.portal-hero h2 {
  font-size: clamp(2.05rem, 4.4vw, 3.35rem);
  line-height: 1.04;
  letter-spacing: -.032em;
  margin: 0 0 clamp(14px, 1.8vw, 20px);
  text-wrap: balance;
}

/* Le paragraphe grandit un peu lui aussi, sinon l'écart devient un gouffre
   et la page se lit en deux temps au lieu d'un. */
.portal-hero .portal-hero-sub {
  font-size: clamp(1rem, 1.25vw, 1.09rem);
  line-height: 1.62;
  margin-bottom: clamp(26px, 3vw, 38px);
}

/* L'étiquette repassait sur deux lignes dans une colonne étroite. Elle
   perd un peu de corps et d'interlettrage : c'est une mention, pas un
   titre — elle n'a pas à occuper deux lignes avant la vraie phrase. */
.portal-hero .portal-hero-badge {
  font-size: .69rem;
  letter-spacing: .08em;
  margin-bottom: clamp(18px, 2.4vw, 26px);
}


/* ---------------------------------------------------------------------
   5. LA TABLE À DESSIN
   ---------------------------------------------------------------------
   Le fond restait un vide noir relevé d'une lueur. À la place, la trame
   d'un papier millimétré — le support sur lequel ce métier dessine
   depuis toujours.

   Elle est volontairement à la limite du visible : on ne doit pas la
   remarquer, seulement cesser de trouver le fond vide. Un masque la
   fait disparaître sur les bords pour qu'elle ne coupe pas la page au
   couteau.
   --------------------------------------------------------------------- */

.portal-hero { position: relative; isolation: isolate; }
.portal-hero::before {
  content: "";
  position: absolute;
  inset: -10% -50vw;
  z-index: -1;
  background-image:
    repeating-linear-gradient(to right,  var(--filet) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(to bottom, var(--filet) 0 1px, transparent 1px 46px);
  opacity: .3;
  -webkit-mask-image: radial-gradient(58% 62% at 50% 45%, #000 0%, transparent 78%);
          mask-image: radial-gradient(58% 62% at 50% 45%, #000 0%, transparent 78%);
  pointer-events: none;
}


/* ---------------------------------------------------------------------
   6. LE HERO DÉBORDE DE LA COLONNE
   ---------------------------------------------------------------------
   Le portail vit dans un conteneur de 900 px : la bonne mesure pour lire
   des cartes et des tarifs, trop étroite pour un hero à deux colonnes.
   Le titre s'y brisait en quatre lignes.

   Le hero — et lui seul — déborde donc de part et d'autre. Le débord est
   calculé sur la place réellement disponible et plafonné : sur un écran
   juste assez large il vaut zéro, et il ne peut jamais pousser la page
   hors de l'écran. Le reste du portail garde ses 900 px.
   --------------------------------------------------------------------- */

@media (min-width: 1120px) {
  .portal-hero {
    --debord: clamp(0px, calc((100vw - 900px) / 2 - 28px), 132px);
    margin-left: calc(var(--debord) * -1);
    margin-right: calc(var(--debord) * -1);
    /* Le texte reçoit un peu plus que le dessin : c'est lui qui porte la
       phrase, et une phrase qui se brise perd sa force. */
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  }
}

/* Le corps du titre est repris pour que « Calculez vos coupes chap »
   tienne sur une ligne dans la colonne élargie. Un titre de hero qui se
   casse en quatre morceaux ne se lit plus, il se déchiffre. */
.portal-hero h2 { font-size: clamp(1.92rem, 3.5vw, 2.9rem); }
