/* ═══════════════════════════════════════════════════════════════
   LaikaSuite — the hub, as a printed index.

   Everything here derives from packages/design-system/tokens.css. This
   file adds no colour, no radius, no easing and no shadow of its own; it
   composes the ones the identity already owns.

   Three rules govern the whole sheet, and every declaration below obeys
   one of them:

     1  NO ROUND CORNER, ANYWHERE. astralaika.com contains the string
        "border-radius" zero times and so does this file. Elevation is the
        company's hard offset square of ink and never a soft shadow.

     2  COLOUR IS RESERVED FOR IDENTIFICATION. Paper, ink and one cosmic
        red carry the entire page. The fourteen product hues appear in
        exactly two places — the glyph at the head of an entry, and that
        entry's step on the scale — and mean exactly one thing: which
        application this is. Pointing at a row *inks* it; it never tints
        it.

     3  THE VOID IS A MATERIAL. The left column is mostly empty on
        purpose, and what fills it is a readout that only exists when
        something is being pointed at.
   ═══════════════════════════════════════════════════════════════ */

/* Boot guard. The markup carries English defaults so a crawler that runs
   no script still reads a page; a human should not watch them being
   replaced. The head sets data-ready after 2500 ms whatever happens, so a
   script that fails to load costs a delay rather than a blank page.

   No fade: this page's whole argument is that nothing is waited for. */
html:not([data-ready]) body { visibility: hidden; }
@media (prefers-reduced-motion: reduce) {
  html:not([data-ready]) body { visibility: visible; }
}

:root {
  /* The page's one horizontal margin. Everything on the sheet starts on
     it: the bar, the spread and the bulletin all share the value, so the
     left edge of the page is a single unbroken vertical. */
  /* La gouttière d'astralaika.com, à la valeur près. Elle était plus
     étroite de huit pixels à pleine largeur — un écart qui n'avait pas de
     raison écrite, et la marge de gauche est la première mesure qu'un œil
     compare entre deux pages de la même maison. */
  --pad: clamp(20px, 4.5vw, 64px);
  /* Le chiffre de la charte, et celui d'astralaika.com : soixante-huit
     pixels, bordures comprises — la bande de six et le filet de trois sont
     *dans* la mesure, pas en plus. */
  --bar-h: 68px;
  /* Which way a leader is drawn — towards the arrow, which is towards the
     application. In an RTL page that is the other way. */
  --lead-origin: left;

  /* ══ LA BOÎTE DE PEINTURE ═══════════════════════════════════
     Cinq encres, une seule mesure, et c'est un système : elles sont
     déclarées ensemble, numérotées dans l'ordre où la presse les dépose,
     et aucune autre valeur colorée n'est écrite ailleurs dans ce fichier.
     Le repère est la sérigraphie des années soixante-dix — l'arc-en-ciel
     imprimé, une couleur par passe — tenu au niveau du rouge cosmique, qui
     est un rouge *rabattu* : pas un rouge d'écran, un rouge d'encre sur
     papier.

     LA MESURE. #C8321E vaut, en OKLCH, L 0,549 · C 0,190 · h 31°. C'est
     l'étalon : toute encre de la boîte vise cette clarté et cette chroma,
     et ne garde d'elle-même que sa teinte.

     TROIS OBÉISSENT. Le bleu et le magenta n'existaient pas comme couleurs
     de maison : ils sont pris dans la roue des produits — l'azur de Write,
     le fuchsia de Photo — puis rabattus *exactement* sur l'étalon. Les
     valeurs brutes de la roue sont réglées pour se distinguer à seize
     pixels dans un lanceur, ce qui est l'inverse du problème ici : l'azur
     #4B6FFF montait à L 0,599 / C 0,217 et le fuchsia #C21F98 à
     L 0,558 / C 0,223 — les deux plus vifs que le rouge, donc les deux
     auraient crié plus fort que lui dans la même bande.

     DEUX N'OBÉISSENT PAS, et sRGB en est la cause dans les deux cas. Le
     compromis est écrit ici plutôt que deviné plus tard.

       L'OR a fini par obéir, et il a fallu deux allers-retours pour le
       comprendre. #C89B3C est à L 0,714 — 0,165 au-dessus du rouge — et il
       a longtemps été gardé tel quel, avec une exception écrite pour lui :
       seul segment du bandeau à porter de l'encre au lieu du papier, parce
       que le papier n'y mesure que 2,39:1 quand l'encre y monte à 7,24.
       L'exception était juste segment par segment et fausse pour la bande
       entière : cinq affirmations dont une change de couleur de texte en
       cours de route se lisent comme un défaut, quelle que soit la raison.

       Il est donc rabattu comme le bleu et le magenta l'ont été, à la
       clarté de l'étalon : L 0,549, h 83°, chroma au maximum que sRGB
       autorise là — 0,114. #916A00, papier 4,60:1. Il porte enfin le même
       texte que ses quatre voisines.

       CE QUE ÇA COÛTE, ET C'EST ÉCRIT ICI PARCE QUE C'EST RÉEL. Ce fichier
       appelait #916900 « un bronze, pas un or », et il avait raison : à
       cette clarté la couleur est une moutarde sombre, pas l'or clair de la
       charte. La chose demandée — cinq encres, un seul texte — n'était pas
       compatible avec l'or clair, et c'est l'or qui a bougé plutôt que le
       texte, parce qu'un texte isolé se voit et une teinte assombrie ne se
       compare à rien.

       `--gold` de la charte, lui, ne bouge pas : #C89B3C reste ce qu'il est
       partout où la maison l'emploie. La boîte de peinture n'est pas la
       charte, c'est une dérivation mesurée de la charte.

       LE VERT sort par la chroma, et d'un cheveu par la clarté. Il est
       pris sur Calendar (#109E6A, h 161°), la seule vraie encre verte de la
       roue des produits — Sheets est une olive à h 118°. À L 0,549 et
       h 161°, la chroma maximale que sRGB contient est 0,123, soit les deux
       tiers de l'étalon : premier écart, et il est subi.

       Le second est choisi. À la clarté de l'étalon, ce vert donnait
       #008759, qui ne porte ni papier (4,26:1) ni encre (4,07:1) — la pire
       clarté possible, celle qui rate les deux seuils par le milieu. Il est
       donc descendu à L 0,530, soit dix-neuf millièmes sous le rouge :
       #008054, papier 4,65:1. Dix-neuf millièmes ne se voient pas dans une
       bande ; l'illisibilité, si.

     L'ORDRE : 268° → 342° → 31° → 83° → 161°. Ce n'est pas un rangement,
     c'est un parcours — un secteur continu de la roue des teintes, ce qui
     est la définition d'un arc-en-ciel. Le vert ferme la boucle. */
  /* Les cinq encres sont les couleurs de tuiles elles-mêmes, prises telles
     quelles dans `PRODUCTS`. Elles avaient été rabattues en OKLCH sur le
     rouge cosmique pour former une série homogène ; le propriétaire les
     veut brutes, et il a raison sur le fond : ces teintes-là, chacun les
     reconnaît déjà sur les tuiles de la liste. Rabattues, elles devenaient
     cinq couleurs de plus que rien ne rattachait à quoi que ce soit — et
     l'or y perdait son éclat pour devenir une moutarde.

     Le prix est la lisibilité : elles n'ont plus la même clarté, donc le
     texte qui les porte n'a pas partout le même confort. C'est un choix
     assumé, pas un oubli. */
  --press-1: #4b6fff;   /* bleu    — Write   */
  --press-2: #c21f98;   /* magenta — Photo   */
  --press-3: #e23b33;   /* rouge   — Slides  */
  --press-4: #d9a017;   /* jaune   — Vector  */
  --press-5: #3e9c2e;   /* vert    — Toolbox */
  --press-6: #00b8d9;   /* cyan    — Whiteboard */

  /* Il y a eu une seconde série ici : les cinq mêmes teintes éclaircies à
     L 0,66, calculées pour que le bandeau de credo puisse porter du texte
     noir. Elle a été retirée, et c'est un gain plutôt qu'un renoncement.

     La page portait dix encres pour cinq couleurs — une série foncée sur la
     bande du haut, une série claire sur le bandeau du bas — et personne ne
     pouvait voir que c'étaient les mêmes teintes. Deux séries qui se
     ressemblent vaguement ne font pas un système, elles font un doute. Une
     seule série employée aux deux bouts de la première page en fait un.

     Ce que ça coûte est écrit là où ça se paie, sur le bandeau : le texte
     y redevient du papier, et l'or reprend son exception d'encre. */

  /* Cinq aplats francs, et pas un pixel d'interpolation : chaque arrêt est
     doublé, si bien qu'aucune passe ne se fond dans la suivante. Un dégradé
     lisse trahirait les deux registres d'un coup. */
  --press: linear-gradient(to right,
    var(--press-1) 0 16.667%, var(--press-2) 16.667% 33.333%,
    var(--press-3) 33.333% 50%, var(--press-4) 50% 66.667%,
    var(--press-5) 66.667% 83.333%, var(--press-6) 83.333% 100%);

  /* La durée d'une passe, et elle est partagée. Les deux objets encrés de
     la page — la bande d'ouverture et le bandeau de credo — la lisent tous
     les deux, si bien que la passe bleue du haut et la promesse bleue du
     bas se déposent dans la même image. C'est ce qui rend la
     correspondance visible au lieu de la laisser à deviner. Cinq passes en
     haut, cinq promesses en bas, la même horloge : la dernière encre tombe
     en même temps que la dernière chose que la page a à dire. */
  --press-pass: 140ms;
}
[dir="rtl"] {
  --lead-origin: right;
  /* La bande se lit dans le sens de lecture : en écriture droite-à-gauche
     la première passe est celle de droite. */
  --press: linear-gradient(to left,
    var(--press-1) 0 20%, var(--press-2) 20% 40%,
    var(--press-3) 40% 60%, var(--press-4) 60% 80%,
    var(--press-5) 80% 100%);
}

/* The hub is a document, so it gets a document's text selection and a
   document's scroll. Nothing here hijacks either. */
body {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Une ancre suivie sous une barre fixe atterrit sous la barre. Le site de
   l'entreprise règle ça d'une ligne et c'est la même ici. */
html {
  scroll-padding-top: calc(var(--bar-h) + 16px);
}

/* ═══════════════════════════════════════════════════════════════
   THE SHEET — the first screen, and the whole selector
   Three rows: the masthead, the spread, the bulletin. `min-height`
   rather than `height`, so a short window or a long language grows the
   page instead of clipping it.
   ═══════════════════════════════════════════════════════════════ */
.sheet {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  min-height: 100vh;
  min-height: 100dvh;
  /* La place que le bandeau occupait quand il était une rangée de cette
     grille. Il est fixe maintenant, donc hors flux : sans ce retrait la
     première rangée passerait dessous. `box-sizing: border-box` fait que
     le retrait est *dans* les 100dvh — la première page garde donc
     exactement la hauteur qu'elle avait, au pixel. */
  padding-block-start: var(--bar-h);
  /* No sunburst. --field-rays is the company's hero device and the suite
     is allowed exactly one place to draw it, which would be here — but it
     was tried and it lost: at the alpha the company uses it read as a
     starburst wallpaper behind the headline and became the second idea on
     a page whose whole argument is that there is one. The wash underneath
     (the 45° stock hatch and the four warm halos) is the texture this
     sheet gets, and it is quiet enough to stay underneath. */
}

/* ═══ LA BARRE ════════════════════════════════════════════════
   Celle d'astralaika.com, reprise et non imitée. Sa hauteur, sa bande de
   six pixels, son filet de trois, son écart de vingt-deux, sa navigation
   poussée à droite par une marge automatique, sa plaque rouge : les
   valeurs sont celles du site, et la seule substitution est la marque.

   Elle est fixe. C'est *son* comportement au défilement, et le seul que le
   site lui donne — pas d'apparition, pas d'escamotage, pas de rétraction :
   elle est là, tout le temps, et la page passe dessous. Une barre qui se
   cache est une barre qu'il faut aller rechercher.

   Elle ne coûte rien à la première page : ce qu'elle occupait comme rangée
   de grille, elle l'occupe désormais comme retrait de la feuille. */
.bar {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 1000;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  gap: 22px;
  padding-inline: var(--pad);
  /* Un aplat, et rien d'autre : `background: var(--paper)` d'astralaika.com,
     c'est-à-dire #F3EDE0 posé franc.

     Elle a porté `var(--field)` en `background-attachment: fixed`, si bien
     que le lavis de la barre prolongeait exactement celui du corps. L'idée
     se défend et le résultat rate ce qu'une barre doit faire : celle du site
     est un aplat qui *sépare* la page de son en-tête, la nôtre s'y fondait.
     Une barre fixe est un objet posé sur la feuille, pas une découpe dedans. */
  background: var(--ls-sand-50);
  /* La bande d'ouverture n'est plus une bordure mais un retrait : elle est
     peinte par ::before juste en dessous, et elle garde exactement les six
     pixels de la charte. `box-sizing: border-box` les laisse *dans* les
     soixante-huit. */
  padding-block-start: var(--band);
  border-block-end: var(--rule-section) solid var(--border-ink);
}

/* ══ LA BANDE — la boîte de peinture, imprimée ═════════════════
   Les six pixels de rouge qui ouvraient la page en portent maintenant
   cinq. Ils ne coûtent rien : c'est la même bande, à la même hauteur, au
   même endroit — on y fait entrer les encres au lieu d'ajouter un objet.

   Et elle dit quelque chose. Ses cinq passes sont, dans cet ordre exact,
   celles des cinq promesses du bandeau de credo en bas de la première
   page : la bande du haut est la légende de la bande du bas, et la légende
   est complète — une passe, une promesse, aucun reste.

   Elle ne l'a pas toujours été. Le vert est entré dans la boîte avant
   d'avoir quoi que ce soit à nommer, et la cinquième passe est restée
   muette le temps qu'on cherche ce qu'elle disait. Ce qu'elle disait était
   déjà vrai et déjà écrit nulle part : ces applications s'installent.

   Le mouvement dit la même chose une seule fois : `steps(5)`, donc la
   bande ne se dévoile pas, elle se *dépose* — une passe, puis la
   suivante, cinq états nets et aucun entre-deux. C'est une presse, pas
   un balayage, et c'est ce qui tient ensemble la sérigraphie de Patagonia
   et l'affiche soviétique : ni l'une ni l'autre ne fond ses couleurs.
   Elle tourne une fois, à l'ouverture, et ne recommence jamais. */
.bar::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: var(--band);
  background: var(--press);
  /* Décor : en couleurs forcées il garde ses cinq passes plutôt que de
     s'effondrer en un seul aplat système, comme le bandeau et le
     colophon plus bas. */
  forced-color-adjust: none;
}
/* `html[data-ready]`, et ce n'est pas une précaution : `html:not([data-ready])
   body` est en `visibility: hidden` tout en haut de ce fichier. Une
   animation déclenchée à l'analyse du CSS se joue donc pendant que la page
   est encore invisible, et sur un chargement un peu lent elle est finie
   avant d'avoir été vue — ce qui est la définition d'une animation qui ne
   sert à rien. Accrochée à l'attribut, elle part à la seconde où la feuille
   apparaît. */
@media (prefers-reduced-motion: no-preference) {
  html[data-ready] .bar::before {
    animation: press-lay calc(var(--press-pass) * 5) steps(5, jump-start) both;
  }
}
@keyframes press-lay {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
[dir="rtl"] .bar::before { animation-name: press-lay-rtl; }
@keyframes press-lay-rtl {
  from { clip-path: inset(0 0 0 100%); }
  to { clip-path: inset(0 0 0 0); }
}

/* La marque, et c'est celle de la suite. Quarante pixels dans une case de
   quarante, comme le `.logo-slot` du site — et la largeur est *déclarée*
   sur l'image : le fichier fait 180 px de côté, posé sans dimension il
   avait déjà poussé ce bandeau à 189 px de haut et volé 121 px à la
   première page. Une image sans largeur déclarée est une image qui décide
   de la mise en page. */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  color: var(--text);
  text-decoration: none;
}
.brand:hover { color: var(--text); text-decoration: none; }
.logo-slot {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
}
.logo-slot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 0.3s var(--ease-out);
}
.brand:hover .logo-slot img { transform: rotate(-10deg) scale(1.1); }
.brand-name {
  font-size: 18px;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

/* Deux liens, et deux destinations réelles. Le soulignement de trois
   pixels qui s'encre au survol est celui du site. */
.bar-nav {
  display: flex;
  margin-inline-start: auto;
  min-width: 0;
}
.bar-nav a {
  padding: 8px 12px;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  border-block-end: var(--rule-section) solid transparent;
  transition: border-color 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.bar-nav a:hover {
  color: var(--ls-ember-700);
  border-block-end-color: var(--ls-ember-600);
  text-decoration: none;
}
.bar-nav a:focus-visible {
  outline: var(--rule-strong) solid var(--accent);
  outline-offset: 2px;
}

.bar-cta { flex: none; }

/* The knob — astralaika.com's own notched button, kept transparent until
   it is pointed at. The notch belongs here: it is what the company clips
   off its buttons, and a clip-path costs nothing on a control that has no
   shadow to lose. */
.knob {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  padding: 6px 12px;
  color: var(--text-secondary);
  background: none;
  border: var(--rule-strong) solid transparent;
  clip-path: var(--notch);
  cursor: pointer;
  transition: var(--transition-control);
}
.knob:hover {
  color: var(--text);
  border-color: var(--border-ink);
}
.knob:focus-visible {
  outline: var(--rule-strong) solid var(--accent);
  outline-offset: 2px;
}
.knob .ls-icon { flex: none; }
.knob__value { white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════
   THE SPREAD — the poster on the left, the index on the right
   ═══════════════════════════════════════════════════════════════ */
.spread {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(24px, 3.4vw, 68px);
  min-width: 0;
  padding: clamp(20px, 3vh, 44px) var(--pad);
}

/* ═══ THE POSTER ══════════════════════════════════════════════
   Trois rangées : le surtitre, le titre, le relevé — et la quatrième, qui
   n'a rien dedans, est la réserve. L'échelle l'occupait ; elle est partie
   avec le compte qu'elle mesurait, et le vide qu'elle laisse est celui que
   ce parti revendique depuis sa première ligne : « le vide de la colonne
   de gauche n'est pas un manque, c'est le matériau ».

   La dernière rangée est `minmax(0, 1fr)` et jamais `auto` : une rangée
   `auto` laisse la hauteur intrinsèque de ce qu'elle contient remonter
   dans celle de la colonne, et un titre allemand posé sur une figure de
   258 pixels avait alors poussé toute la double page hors de la fenêtre et
   fait passer le bandeau sous la ligne de flottaison. La réserve prend ce
   qui reste, et jamais un pixel de plus. */
.poster {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto minmax(0, 1fr);
  min-width: 0;
}

/* Le surtitre, et c'est le `hero-kicker` du site : PT Mono capitalisé et
   interlettré, précédé de l'étoile à quatre branches, posé au-dessus du
   titre. Le compte y vit maintenant. Il était le plus gros caractère de la
   page, il en est la plus petite ligne ; c'est la seule chose que la
   phase 2 lui fait, et c'est suffisant — il est toujours écrit depuis
   APPS.length, il est toujours juste, il n'est simplement plus l'argument. */
.poster-kicker {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* Le `hero-kicker` du site pose clamp(20px, 4vh, 40px) sous lui ; on en
     posait la moitié, et le surtitre se lisait collé au titre au lieu de le
     préparer. Une ligne de service au-dessus d'une affiche a besoin de son
     silence, sinon elle en fait partie. */
  margin-block-end: clamp(20px, 4vh, 40px);
  color: var(--text-muted);
}
.poster-kicker .ls-star { --form-size: 0.8em; flex: none; color: var(--brand-red); }

.poster-head {
  margin: 0;
  font-size: clamp(2.35rem, 6.2vw, 5.1rem);
  /* 1.14, not the token's 1.02, and the difference is measured rather
     than felt. Anton stacks its accents at about one em above the
     baseline — higher than its own cap height — so at 0.95 the acute of
     CRÉER printed a red wedge through APPLICATIONS, at 1.02 the umlaut of
     ÖFFNEN sat on the digits of 14 ANWENDUNGEN, and at 1.08 it cleared
     them by two pixels at 81px, which is nothing at 36px. A display
     leading is set for the alphabet it is going to carry, and this one
     carries 23 of them: Czech, Polish, Vietnamese and Turkish all stack
     higher than German. The block still reads as one dense mass, which is
     what a poster wants; it simply no longer touches. */
  line-height: 1.14;
  letter-spacing: var(--tracking-display);
  /* A poster is ranged left and ragged right. `balance` evens the lines
     out, which is what a centred deck wants and the opposite of what this
     wants: here the first line should run the full measure. */
  text-wrap: initial;
  /* Hyphenation is not a fallback here, it is the craft: a German or
     Finnish compound is *meant* to break, and a poster that refuses to
     break is a poster that overflows. `lang` is on <html>, so the
     dictionary is the reader's own. */
  hyphens: auto;
  overflow-wrap: break-word;
}
.poster-claim,
.poster-verb { display: block; }
/* La garantie, en encre. C'est l'affirmation de la page, et c'est la seule
   qu'elle fasse au-dessus de la ligne de flottaison. */
.poster-claim { color: var(--text); }
/* The second line in the company's red — its own hero does exactly this,
   and --brand-red is solved per theme so it clears AA on both sheets. */
.poster-verb { color: var(--brand-red); }

/* ═══ THE READOUT ═════════════════════════════════════════════
   The left column is the display for the column beside it. Its height is
   reserved rather than fluid: a block that grew when an entry was pointed
   at would move the whole page under the pointer. */
.readout {
  min-height: clamp(132px, 19vh, 196px);
  margin-block-start: clamp(18px, 3vh, 36px);
  padding-block-start: var(--space-3);
  /* The rule runs the full width of the column, not the width of the text
     under it: a two-pixel rule that stops in the middle of a column is a
     rule that has been cut, and this identity draws rules that close
     sections. The measure is set on the text instead. */
  border-block-start: var(--rule-strong) solid var(--border-ink);
}
.readout-name {
  font-size: var(--display-sm);
  color: var(--text);
}
.readout[data-on="false"] .readout-name { display: none; }
.readout-line {
  max-width: 34ch;
  font-family: var(--font-serif);
  font-size: var(--text-md);
  line-height: var(--leading-loose);
  color: var(--text-secondary);
}

/* L'échelle a été retirée, et avec elle ses quatre-vingts lignes de
   feuille de style. Quatorze pas d'encre cotés « 01 —— 14 » : elle
   mesurait le compte des applications, c'est-à-dire la chose que la
   phase 2 a précisément cessé de vouloir dire. Elle avait été gardée
   parce qu'elle *disait* quelque chose ; dès que le titre a cessé de
   compter, elle ne disait plus qu'une redite — et il lui fallait sa cote
   pour être lue du tout, ce qui est l'aveu d'un objet qui décore. Retirée
   pour de bon plutôt que masquée : l'historique garde tout.

   Ce qu'elle laisse est la dernière rangée vide de la colonne de gauche,
   et c'est la règle numéro trois de ce fichier. */

/* ═══════════════════════════════════════════════════════════════
   THE INDEX — fourteen numbered entries

   A glass plate in a brutalist frame: two pixels of ink, a hard offset
   square of shadow, and the suite's own lensed material inside. No
   clip-path: the notch would take the shadow with it, and a filtered
   wrapper would open a backdrop root and leave the glass nothing to
   refract. The notch stays on the buttons and on the colophon plate,
   which is where the company puts it.
   ═══════════════════════════════════════════════════════════════ */
.register {
  /* The floor is what decides whether fourteen entries are one screen or
     two. 5.2vh puts them at 47px on a 900-tall window and 40px on a
     768-tall one, which is the height at which a 28px plate, a 12.5px
     numeral and an Anton name still sit on one line without touching.
     Below the floor the plate simply grows taller than the viewport and
     the page scrolls, which is honest; it never crushes a row. */
  --row-min: clamp(42px, 5.2vh, 64px);
  display: grid;
  grid-template-rows: repeat(var(--rows, 14), minmax(var(--row-min), 1fr));
  min-width: 0;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  border: var(--rule-strong) solid var(--border-ink);
  box-shadow: var(--shadow-sm), var(--shadow-sheen);
}

.entry {
  /* Repère du liseré ci-dessous, et rien d'autre : la rangée reste une
     grille et aucun de ses enfants n'est sorti du flux. */
  position: relative;
  display: grid;
  grid-template-columns: auto auto minmax(0, auto) minmax(0, 1fr) auto;
  grid-template-areas: "no mark name lead go";
  align-items: center;
  gap: clamp(10px, 1.2vw, 20px);
  min-width: 0;
  padding-inline: clamp(12px, 1.6vw, 26px);
  color: var(--text);
  text-decoration: none;
  border-block-end: var(--rule) solid var(--line);
  transition: background-color var(--duration-fast) var(--ease-out);
}
.entry:last-child { border-block-end: 0; }
.entry:hover {
  /* Ink at five and a half percent — not the product hue. On this page a
     hue names an application and does nothing else. */
  background-color: var(--hover);
  color: var(--text);
  text-decoration: none;
}
.entry:focus-visible {
  outline: var(--rule-strong) solid var(--accent);
  outline-offset: calc(var(--rule-strong) * -1);
}

/* ── LE LISERÉ ────────────────────────────────────────────────
   Huit pixels de rouge cosmique au bord d'attaque de la rangée visée, et
   c'est la matière d'astralaika.com prise telle quelle : le site donne un
   `border-left: 8px solid var(--red)` à ses directives et à son manifeste,
   c'est-à-dire aux blocs qu'il désigne comme ceux qu'on est en train de
   lire. Ni la forme du timbre ni celle de la carte n'ont été reprises —
   cinq substitutions du sélecteur ont déjà été refusées, et la liste
   numérotée reste une liste numérotée. C'est l'encre qui voyage.

   Il est peint par un pseudo-élément et non par une bordure, parce qu'une
   bordure de huit pixels décalerait les quatorze rangées de huit pixels au
   survol de l'une d'elles. `inset-inline-start` le met du côté d'où la
   lecture vient, donc à droite en écriture droite-à-gauche, sans une
   règle de plus. */
.entry::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 0;
  background: var(--ls-ember-600);
  transition: width var(--duration-fast) var(--ease-out);
}
.entry:hover::before,
.entry:focus-visible::before { width: 8px; }

/* ── LE NUMÉRO ────────────────────────────────────────────────
   Il virait au rouge ; il devient une plaque.

   C'est le `.section-tag b` d'astralaika.com à la valeur près — `padding:
   3px 9px`, du papier détouré dans le rouge de la maison, et la graisse
   laissée à 400 parce que le site prend la peine de la ramener là après
   avoir choisi un `<b>`. Le site numérote ses sections exactement comme
   ça, et cette page est un sommaire : c'est le même geste.

   Le retrait est posé en permanence et seul le fond arrive, sinon la
   rangée se réagence sous le pointeur. Chiffres tabulaires, parce qu'une
   colonne de chiffres qui change de largeur selon le chiffre n'est pas une
   colonne — et centrés, parce qu'un chiffre dans une plaque se centre.

   Mesuré : #FBF7EC sur #C8321E donne 4,99:1, ce qui tient AA pour ces
   12,5 px. L'encre est `--ls-ember-600`, c'est-à-dire le `--red`
   d'astralaika.com : le rouge de cette page a une seule source, et ce
   n'est pas la boîte de peinture — celle-ci sert les deux bandes et rien
   d'autre. */
.entry-no {
  grid-area: no;
  padding: 3px 9px;
  font-family: var(--font-mono);
  font-size: var(--text-label);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  text-align: center;
  color: var(--text-faint);
  transition: color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}
.entry:hover .entry-no,
.entry:focus-visible .entry-no {
  color: var(--ls-sand-0);
  background: var(--ls-ember-600);
}

/* The mark, replated.

   The application's own geometry is untouched — it belongs to the
   application — but its *presentation* here is not the tile it wears in a
   dock. A tile is a rounded square carrying a three-stop gradient and a
   specular sheen, and this identity contains no rounded square anywhere.
   So the glyph is knocked out of a flat square of the product's own ink:
   one colour, four right angles, the way a stamp is cut.

   Both the plate and the glyph are solved per theme rather than taken
   from `mid`, because `mid` fails at both ends — Vector's #D9A017 leaves
   paper at 2.0:1 and Packets' #205C93 leaves the dark sheet at 1.4:1.
   Light takes the dark step of the product's ramp with a paper glyph on
   it; dark takes the light step with an ink glyph. Every one of the
   fourteen clears 3.4:1 inside the plate and reads as a square against
   its own sheet. */
.entry-mark {
  grid-area: mark;
  display: block;
  width: clamp(22px, 2.2vw, 28px);
  aspect-ratio: 1;
  /* Aucun fond : la marque porte le sien. La boîte peignait une plaque
     carrée derrière le SVG — un reste de l'époque où l'entrée montrait un
     glyphe monochrome qu'il fallait bien poser sur quelque chose. Depuis
     que la marque est recadrée en disque, ce carré la recarrait aussitôt,
     et le recadrage ne se voyait nulle part. */
}
.entry-mark svg { display: block; width: 100%; height: auto; }

/* The name. A wordmark, so it keeps Anton in all 23 locales — a product
   name is not translated. */
.entry-name {
  grid-area: name;
  font-size: clamp(1.02rem, 1.5vw, 1.5rem);
  line-height: 1;
  white-space: nowrap;
}

/* The leader — the dotted rule of a printed table of contents, and the
   one thing on this page that moves.

   Two background layers on one box: a dashed hairline that is always
   there, and a solid two-pixel rule sized to nothing until the entry is
   pointed at, when it draws from the name towards the arrow. Animating
   `background-size` touches no layout and repaints one strip. */
.entry-lead {
  grid-area: lead;
  align-self: center;
  min-width: var(--space-4);
  height: 2px;
  background-image:
    linear-gradient(var(--ink-solid), var(--ink-solid)),
    repeating-linear-gradient(90deg, var(--border-strong) 0 2px, transparent 2px 7px);
  background-size: 0% 2px, 100% 1px;
  background-position: var(--lead-origin) center, left center;
  background-repeat: no-repeat, repeat-x;
  transition: background-size var(--duration-normal) var(--ease-out);
}
.entry:hover .entry-lead,
.entry:focus-visible .entry-lead { background-size: 100% 2px, 100% 1px; }

.entry-go {
  grid-area: go;
  display: flex;
  color: var(--text-faint);
  transition: color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}
.entry:hover .entry-go,
.entry:focus-visible .entry-go {
  color: var(--brand-red);
  /* --shadow-x is +1 in an LTR page and -1 in an RTL one, so the arrow
     always steps towards the edge it points at. */
  translate: calc(5px * var(--shadow-x)) 0;
}

/* The sentence. It lives in the readout on a wide screen and inside the
   entry on a narrow one, because a phone has no pointer to put on a row
   and therefore no readout to fill. Nothing is truncated either way. */
.entry-line {
  grid-area: line;
  display: none;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

/* ═══ LE BANDEAU DE CREDO ═════════════════════════════════════
   La bande de l'entreprise, qui ferme la première page comme la barre
   l'ouvre — et elle porte désormais les quatre encres de la même boîte de
   peinture, une par promesse. Les encres sont imprimées : elles valent la
   même chose sur les deux feuilles, parce qu'une encre ne sait pas quelle
   heure il est.

   La hauteur ne bouge pas. Le retrait vertical qui était sur la bande est
   passé tel quel sur les segments — `clamp(9px, 1.2vh, 15px)` — et la
   grille répartit la mesure en pistes égales, donc la bande fait ce
   qu'elle faisait : 45 px à 1440×900, comme avant.

   Aucun blanc entre deux passes : `gap: 0`, des arrêts doublés dans le
   dégradé de la bande du haut, et ici quatre fonds jointifs. Deux encres
   qui se touchent sur un bord net, c'est ce que fait une sérigraphie ; un
   fondu trahirait les deux registres d'un coup. */
.bulletin {
  display: grid;
  /* Six pistes égales pour six promesses, une par passe de la bande du
     haut et dans le même ordre. Le compte n'est pas un choix de mise en
     page : chaque passe de couleur porte une affirmation, et l'on n'ajoute
     une encre que lorsqu'il reste quelque chose de vrai à dire. */
  grid-template-columns: repeat(6, minmax(0, 1fr));
  border-block-start: var(--rule-section) solid var(--border-ink);
}
.creed {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: 0;
  padding: clamp(9px, 1.2vh, 15px) var(--space-2);
  text-align: center;
  /* Six promesses au lieu de quatre, dans vingt-trois langues dont
     l'allemand : la place par segment a été divisée d'un tiers pendant que
     les phrases restaient les mêmes. Plutôt que les raccourcir — ce qui
     aurait demandé de retraduire vingt-trois fois et de perdre en
     précision — le corps suit la place disponible et l'interlettrage se
     resserre. `text-wrap: balance` répartit les deux lignes également au
     lieu de laisser un mot seul en dessous, ce qui est la vraie cause de
     l'impression d'encombrement. */
  font-size: clamp(0.62rem, 0.52rem + 0.34vw, 0.78rem);
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-wrap: balance;
  hyphens: auto;
  /* De l'encre, sur les cinq. La bande portait du papier sur trois de ses
     segments et de l'encre sur le quatrième — l'or, seul assez clair pour
     ça — et cette exception se voyait : une bande de quatre promesses dont
     une est écrite dans l'autre sens. C'est l'anomalie qui a fini par
     livrer la bonne règle — puis la règle a changé de sens.

     Le bandeau a porté de l'encre noire sur cinq encres éclaircies. Il porte
     de nouveau du papier sur les cinq encres de la bande du haut, parce que
     l'unité des deux objets vaut plus que l'uniformité du texte : à L 0,549
     ces encres portent le papier à 4,65 / 4,77 / 4,99 / 5,06 et ne portent
     pas le noir, qui plafonne à 3,6. On ne choisit pas la couleur du texte
     puis la couleur du fond ; c'est le fond qui décide.

     Les cinq portent du papier, sans exception, et c'est la dernière règle
     que ce bandeau a apprise. Mesuré, #FBF7EC sur les cinq passes :
       bleu 4,77:1   magenta 5,06:1   rouge 4,99:1
       or   4,60:1   vert    4,65:1
     Le pire est à 4,60, au-dessus du seuil. */
  color: var(--ls-sand-0);
  background: var(--creed-ink);
  /* Décor de fond déclaré par la page : en couleurs forcées il garde ses
     cinq passes plutôt que de s'effondrer en un aplat système. */
  forced-color-adjust: none;
}
.creed:nth-child(1) { --creed-ink: var(--press-1); }
.creed:nth-child(2) { --creed-ink: var(--press-2); }
.creed:nth-child(3) { --creed-ink: var(--press-3); }
/* Plus d'exception. L'or a porté de l'encre quand les quatre autres
   portaient du papier ; c'est la passe qui a été assombrie, pas le texte qui
   a été laissé seul de sa couleur. Voir la boîte de peinture. */
.creed:nth-child(4) { --creed-ink: var(--press-4); }
.creed:nth-child(5) { --creed-ink: var(--press-5); }
.creed:nth-child(6) { --creed-ink: var(--press-6); }

/* ── LA CINQUIÈME PASSE ────────────────────────────────────────
   Elle n'a d'abord porté qu'une étoile, au motif qu'il y avait cinq encres
   pour quatre promesses et qu'en fabriquer une cinquième pour occuper une
   couleur aurait été de la décoration. Le raisonnement tenait ; le rendu
   non. Un caractère isolé sur un aplat de couleur ne se lit pas comme la
   marge d'une presse — il se lit comme une chaîne qui n'est pas arrivée,
   l'état exact qu'une page dont l'argument est de ne pas faire attendre ne
   peut pas se permettre de mimer.

   Il n'y avait rien à fabriquer : l'installation était vraie, vérifiable et
   écrite nulle part, alors que toute la suite en dépend. Elle a été un lien
   vers la rubrique le temps d'un aller-retour, puis ramenée à un segment
   inerte comme ses quatre voisines ; les règles qui l'habillaient en lien
   ont été retirées avec lui plutôt que laissées à traîner. Son encre est la
   cinquième passe claire, posée avec les quatre autres au-dessus. */

.creed .ls-star { --form-size: 0.7em; opacity: 0.75; }

/* Les cinq promesses s'encrent l'une après l'autre, dans l'ordre où on
   les lit, et sur la même horloge que la bande du haut : `--press-pass`
   est partagé, `steps(1, jump-start)` fait tomber chaque promesse d'un
   coup au début de sa passe, si bien que la passe bleue de la barre et la
   promesse bleue du bandeau se déposent dans la même image. C'est là que
   le code se lit : une couleur, une promesse, une passe.

   Rien ne se déplace et rien ne se dimensionne — les quatre boîtes sont à
   leur place dès la première image, seule l'encre arrive. */
@media (prefers-reduced-motion: no-preference) {
  html[data-ready] .creed {
    animation: creed-ink var(--press-pass) steps(1, jump-start)
      calc(var(--i) * var(--press-pass)) both;
  }
}
@keyframes creed-ink {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Sous 1024 la mesure ne tient plus quatre étiquettes de PT Mono
   interlettré sur une ligne : deux pistes, et deux jusqu'en bas. Une seule
   piste a été mesurée et écartée — quatre bandes de couleur empilées
   faisaient 164 px de haut sur un téléphone contre 99 auparavant, et une
   page de portable finissait sur un drapeau. Deux pistes en font 132, ce
   qui est l'ordre de grandeur d'origine.

   Les couleurs suivent les promesses, jamais les cases : le bleu reste sur
   « Instantané » quel que soit le nombre de rangées, parce que c'est le
   rang de l'enfant qui les distribue et non sa position à l'écran. */
@media (max-width: 1023px) {
  /* Six se divisent par deux : trois rangées pleines, aucun trou, et donc
     plus besoin qu'un segment traverse. Cinq ne se divisaient pas, ce qui
     obligeait le dernier à occuper toute la largeur pour ne pas laisser une
     case vide à côté de lui. */
  .bulletin { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════════
   LA RUBRIQUE D'INSTALLATION — la troisième destination

   Le gabarit de section d'astralaika.com, repris et non imité : la mesure
   de 1180 px, l'étiquette monospace à numéro détouré dans le rouge, le
   titre d'affiche, le chapô, puis la grille de cartes à deux pixels
   d'encre et huit pixels de rouge au bord d'attaque.

   Rien n'est dessiné ici. C'est la forme que le site emploie pour trois
   blocs courts qui expliquent quelque chose, et c'est exactement ce que
   cette rubrique est.
   ═══════════════════════════════════════════════════════════════ */
.setup {
  /* PAS de rail de 1180 px centré, et c'est le seul endroit où l'on
     s'écarte du gabarit du site — pour obéir à une règle que cette page a
     écrite avant lui. La gouttière est la première ligne de ce fichier :
     « tout sur la feuille commence dessus, si bien que le bord gauche de la
     page est une seule verticale ininterrompue ». Un rail de 1180 centré
     dans une fenêtre de 1440 démarre son contenu à 194 px, quand la barre,
     l'affiche et le sélecteur démarrent tous à 64. Mesuré : trois
     verticales différentes sur la même feuille de papier, et c'est
     exactement le genre d'écart qui se voit sans qu'on sache le nommer.

     Le site peut se le permettre : ses pages sont d'une seule colonne et
     rien au-dessus d'une section ne donne l'échelle. Ici, le sélecteur est
     juste au-dessus et il donne l'échelle. Le colophon garde son rail
     centré parce que c'est une autre plaque — de l'encre, pas du papier —
     et qu'un changement de support a le droit de changer de mesure.

     Les mesures verticales de `.section` du site, elles, sont reprises
     telles quelles. On tenait
     un tiers plus serré partout — 104 px de respiration au lieu de 150, une
     tête de section à 48 au lieu de 60 — et une section n'est pas plus
     dense pour autant : elle est juste moins finie. */
  padding: clamp(80px, 12vh, 150px) var(--pad);

  /* Le beige plus gris du site — `--paper-2`. La rubrique se détache ainsi
     du papier de la page sans changer de famille : c'est la nuance
     qu'astralaika.com réserve à ce qu'il veut poser en retrait, et non une
     couleur de plus. Une section qui explique un geste n'est pas au même
     plan que celle qui donne accès aux applications. */
  background: var(--ls-sand-100);
}
.setup-head { margin-block-end: clamp(36px, 6vh, 60px); }

/* `.section-tag` du site, y compris son numéro détouré dans le rouge —
   le même objet que la plaque des numéros du sélecteur, à la même mesure.
   Le sommaire numérote ses entrées, la page numérote ses sections. */
.setup-tag {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-block-end: 18px;
  color: var(--text-muted);
}
.setup-tag b {
  padding: 3px 9px;
  font-weight: 400;
  color: var(--ls-sand-0);
  background: var(--ls-ember-600);
}
.setup-title {
  max-width: 22ch;
  /* clamp(32px, 5.4vw, 68px) du site, en rem. Le titre de rubrique montait
     à 54 px là où le site va à 68 : entre une affiche de 82 px au-dessus et
     un corps de 16 en dessous, cinquante-quatre ne creusait pas assez
     l'écart pour que la hiérarchie se voie sans la chercher. */
  font-size: clamp(2rem, 5.4vw, 4.25rem);
  line-height: 1.14;
  letter-spacing: var(--tracking-display);
  text-wrap: initial;
  hyphens: auto;
  overflow-wrap: break-word;
}
.setup-lead {
  max-width: 62ch;
  margin-block-start: 18px;
  font-family: var(--font-serif);
  /* Un cran au-dessus du corps, comme le `.section-sub` du site qui tient
     16,5 px quand ses cartes tiennent 15. Le chapô et les cartes étaient au
     même corps : deux niveaux de lecture écrits à la même taille sont un
     seul niveau. */
  font-size: var(--text-xl);
  line-height: var(--leading-body);
  color: var(--text-secondary);
}

/* ── LES DEUX PAS ─────────────────────────────────────────────
   Avant les gestes, et numérotés, parce que c'est l'ordre qui manquait :
   on n'installe pas depuis cette page, on installe depuis l'application.
   Une liste ordonnée, donc un <ol> — le rang est l'information. */
.setup-steps {
  display: grid;
  gap: var(--space-4);
  margin-block-end: clamp(32px, 5vh, 52px);
  padding: 0;
  list-style: none;
}
.setup-step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-4);
  min-width: 0;
  max-width: 68ch;
}
.setup-step-no {
  min-width: 2.2ch;
  padding: 3px 9px;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--ls-sand-0);
  background: var(--ls-ember-600);
}
.setup-step-body {
  min-width: 0;
  font-family: var(--font-serif);
  font-size: var(--text-md);
  line-height: var(--leading-body);
}

/* ── LES CARTES ───────────────────────────────────────────────
   `.directive` du site, à la valeur près : `border: 2px solid var(--ink)`,
   `border-left: 8px solid var(--red)`, et le décollement de cinq pixels
   avec son ombre portée dure au survol. C'est aussi la matière du liseré
   du sélecteur, et c'est voulu — le rouge au bord d'attaque désigne, sur
   cette page comme sur le site, le bloc qu'on est en train de lire. */
.setup-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: 20px;
}
.setup-card {
  min-width: 0;
  /* `.directive` du site : 26px 24px 28px, le bas plus lourd que le haut.
     Un bloc de texte dont le pied égale la tête a l'air d'avoir glissé. */
  padding: 26px 24px 28px;
  background: var(--surface);
  border: var(--rule-strong) solid var(--border-ink);
  border-inline-start: 8px solid var(--ls-ember-600);
  transition: transform var(--duration-normal) var(--ease-out),
    box-shadow var(--duration-normal) var(--ease-out);
}
@media (hover: hover) {
  .setup-card:hover {
    transform: translateY(-5px);
    box-shadow: var(--shadow-sm);
  }
}
/* ── LA CARTE QUI DIT NON ─────────────────────────────────────
   Identique à « Sur téléphone », au caractère près, et une seule chose
   change : l'or à la place du rouge, sur le liseré et sur l'intitulé — les
   deux seuls endroits où le rouge apparaît dans ces cartes.

   Elle a porté une étoile ajoutée à son intitulé, pour donner à l'or une
   place où il n'aurait pas à être lu. C'était une variation de plus, et une
   variation qui n'a pas de raison se lit comme une erreur : l'œil va sur la
   différence et cherche ce qu'elle signifie. Quand un élément doit
   ressembler à son voisin, on recopie le voisin et on ne change que ce qui
   doit changer.

   L'OR EST #C89B3C, CELUI D'ASTRALAIKA.COM, ET LE PROPRIÉTAIRE A TRANCHÉ
   EN CONNAISSANCE DE CAUSE. Sur la crème de cette carte il mesure 2,39:1,
   donc sous le seuil de lisibilité — il l'a demandé « même s'il se voit
   mal ». C'est l'or de la maison, celui du label « écrire au centre de
   contrôle », et son identité comptait davantage ici que son confort de
   lecture. La mesure est consignée pour que ce soit une décision et non un
   oubli. */
.setup-card--limit { border-inline-start-color: var(--ls-gold, #C89B3C); }
.setup-card--limit .setup-card-tag { color: var(--ls-gold, #C89B3C); }

.setup-card-tag {
  margin-block-end: 14px;
  color: var(--brand-red);
}
.setup-card-body {
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--text-secondary);
}
.setup-card-body + .setup-card-body { margin-block-start: var(--space-3); }

/* La raison, en une phrase, et sous les cartes : quatorze applications
   qui s'installent une par une n'est pas une contrainte, c'est ce qui
   permet de n'installer que celles dont on se sert. */
/* Pleine mesure, et le filet avec. Elle était tenue à 68ch et son filet
   s'arrêtait donc au milieu de la page : c'est précisément ce que ce
   fichier reproche au relevé quelques centaines de lignes plus haut — un
   filet qui s'interrompt en cours de route est un filet coupé, et cette
   identité n'en trace que pour fermer des sections. La phrase tient sur une
   ligne à cette mesure, ce qui est aussi la bonne raison de l'y laisser. */
.setup-note {
  margin-block-start: clamp(24px, 3.4vh, 40px);
  padding-block-start: var(--space-4);
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--text-muted);
  border-block-start: var(--rule) solid var(--border);
}

@media (prefers-reduced-motion: reduce) {
  .setup-card { transition-duration: 1ms; }
}
@media (forced-colors: active) {
  .setup-tag b,
  .setup-step-no { color: Canvas; background: CanvasText; }
  .setup-card { box-shadow: none; }
}
@media print {
  .setup { display: none; }
}

/* ═══════════════════════════════════════════════════════════════
   THE COLOPHON — under the fold, and deliberately minor

   The company's ink footer. It inverts itself in both themes by
   construction rather than by two sets of values: --ink-solid is ink on
   the light sheet and paper on the dark one, and --text-inverse is the
   opposite of both. What has to be restated is the ramp *inside* the
   block, because a plate that inverts its own sheet inverts the ink that
   reads on it — which is the note tokens.css leaves for exactly here.
   ═══════════════════════════════════════════════════════════════ */
.colophon {
  --text-secondary: var(--ls-sand-300);
  --text-muted: #9a9079;
  --text-faint: #6b6352;
  --line: rgb(251 247 236 / 0.16);
  --border: var(--line);
  --brand-red: var(--ls-ember-500);
  padding: clamp(28px, 5vh, 64px) var(--pad) clamp(24px, 4vh, 48px);
  color: var(--text-inverse);
  background: var(--ink-solid);
  /* Les six pixels de rouge qui ouvraient cette plaque sont partis.

     Ils ne disaient rien. La page compte déjà une bande d'encres en haut
     et un bandeau de credo juste au-dessus de ce filet ; un troisième
     rouge, posé entre les deux, n'ajoutait aucune information et coupait
     le bandeau de sa suite. La séparation ne repose pas sur lui : le
     bandeau est en encres saturées et cette plaque est en encre pleine —
     le fond suffit, et il a été regardé plutôt que supposé. */
}
[data-theme="dark"] .colophon {
  --text-secondary: #57503f;
  --text-muted: #69604f;
  --text-faint: #9a8f78;
  --line: rgb(22 19 14 / 0.16);
  --brand-red: var(--ls-ember-600);
}

/* La ligne de marque du pied de page : le `.footer-inner` du site — la
   marque à gauche, les liens poussés à droite, une seule ligne de base qui
   se replie quand la mesure ne suffit plus. Le site met sa case de logo à
   trente-quatre pixels et son nom à quinze dans le pied, contre quarante
   et dix-huit dans la barre ; c'est la même graduation ici, et c'est ce
   qui dit que le pied de page est le rappel et la barre l'annonce. */
.colophon-inner {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
  max-width: 1180px;
  margin-inline: auto;
  margin-block-end: clamp(24px, 4vh, 44px);
  padding-block-end: var(--space-5);
  border-block-end: var(--rule) solid var(--line);
}
/* La plaque s'inverse, donc l'encre de la marque aussi : `--text` n'est
   pas redéfini dans le colophon — seule la rampe atténuée l'est — et une
   marque en `--text` y serait de l'encre sur de l'encre. */
.colophon .brand { color: var(--text-inverse); }
.colophon .brand:hover { color: var(--text-inverse); }
.colophon .logo-slot { width: 34px; height: 34px; }
.colophon .brand-name { font-size: 15px; }

.colophon-links {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 20px;
  min-width: 0;
  margin-inline-start: auto;
}
.colophon-links a {
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 0.2s var(--ease-out);
}
.colophon-links a:hover {
  color: var(--text-inverse);
  text-decoration: none;
}
.colophon-links a:focus-visible {
  outline: var(--rule-strong) solid var(--text-inverse);
  outline-offset: 2px;
}

/* Une colonne, là où il y en avait trois.

   Elles étaient déjà d'inégale largeur — 1,5fr / 1fr / 1fr — parce que
   leurs contenus étaient d'inégale longueur : l'argument, une jauge de
   stockage, une mention d'éditeur. Les deux dernières sont parties (voir
   le balisage : une mesure qui vaut zéro chez presque tout le monde, et
   un éditeur nommé deux fois sur la même plaque), et une grille de trois
   pistes pour un seul enfant n'est plus une grille.

   Reste la mesure de lecture, qui est le vrai sujet : un paragraphe n'a
   pas le droit de courir sur onze cent quatre-vingts pixels. `62ch` le
   tient à la longueur de ligne d'un livre, quelle que soit la largeur de
   la fenêtre — et c'est ce qui remplace, en une déclaration, la piste de
   1,5fr et son repli à 760 px. */
.colophon-grid {
  max-width: 1180px;
  margin-inline: auto;
}
.col { min-width: 0; max-width: 62ch; }
.col-tag {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
  color: var(--text-inverse);
}
.col-tag .ls-star { --form-size: 0.75em; color: var(--ls-ember-500); }
[data-theme="dark"] .col-tag .ls-star { color: var(--ls-ember-600); }
/* L'affirmation, en tête de la colonne large. Elle est courte et c'est
   tout ce qu'on demande à quelqu'un de lire : le paragraphe en dessous
   est là pour celui qui veut vérifier. */
.col-claim {
  margin-block-end: var(--space-2);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  color: var(--text-inverse);
}
.col-body {
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--text-secondary);
}
/* La jauge de stockage est partie, et ses six règles avec elle : il n'y a
   plus qu'un seul bloc dans ce pied de page, et il n'a besoin ni d'un
   chiffre en chasse fixe ni d'un trait de remplissage. */

/* La ligne de colophon : les faits d'édition d'un côté, la plaque de
   l'autre, sur une seule ligne de base. La plaque était le dernier objet
   de la troisième colonne, où elle faisait déborder une colonne par
   ailleurs vide ; ici elle ferme la page, ce qu'un lien de pied de page a
   toujours fait. */
.colophon-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 2vw, 32px);
  max-width: 1180px;
  margin: clamp(28px, 4vh, 52px) auto 0;
  padding-block-start: var(--space-5);
  border-block-start: var(--rule) solid var(--line);
}

/* `.plate` a été retirée. C'était la plaque télégramme du pied de page, et
   elle avait déjà quitté le balisage quand la signature de captainfork.com
   l'a remplacée ; ses vingt lignes sont restées derrière, à styler un
   sélecteur que plus rien ne portait. Du CSS mort est du CSS qu'on
   ressuscite par accident. */

.telemetry {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  color: var(--text-muted);
}
/* Carré, et c'est la règle numéro un de ce fichier — dont l'en-tête
   affirme depuis le début qu'il ne contient pas une seule fois la chaîne
   « border-radius », ce qui était faux d'une occurrence. Trois pixels
   d'encre pleine séparent deux faits ; un rond de trois pixels était la
   seule rondeur de la page, et une charte qui souffre une exception n'en
   est plus une. */
.telemetry-dot {
  width: 3px;
  height: 3px;
  background: currentColor;
  opacity: 0.6;
}

/* ═══════════════════════════════════════════════════════════════
   NARROW — one column, and the sentence comes back into the row

   Not a smaller version of the wide layout: a different arrangement of
   the same parts. There is no pointer on a phone, so there is no readout
   to fill; the sentence therefore belongs in the entry, where it can be
   read without one. The leader goes, because it has no void left to
   cross.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 899px) {
  .spread { grid-template-columns: minmax(0, 1fr); }

  .poster {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: var(--space-4);
  }
  /* No pointer, so no readout: the sentence moves into the entry instead,
     where it can be read without one. */
  .readout { display: none; }

  .register {
    grid-template-rows: repeat(var(--rows, 14), auto);
  }
  .entry {
    grid-template-areas:
      "no mark name go"
      "no mark line line";
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    row-gap: 3px;
    padding-block: clamp(9px, 1.4vh, 14px);
  }
  .entry-lead { display: none; }
  .entry-line { display: block; }
  .entry-name { white-space: normal; }
}

/* Les deux points de bascule de la barre sont ceux d'astralaika.com : la
   navigation part à 1100, la plaque à 780. Ici les deux liens ne
   disparaissent pas dans le vide — le sélecteur est la rangée suivante et
   le colophon est la fin de la page, tous deux à portée de défilement. Un
   menu plein écran pour deux entrées serait un tiroir pour deux
   chaussettes. */
@media (max-width: 1100px) {
  .bar-nav { display: none; }
  #langBtn { margin-inline-start: auto; }
}
@media (max-width: 780px) {
  .bar-cta { display: none; }
}
@media (max-width: 599px) {
  .knob { padding: 6px 8px; }
}

/* ═══════════════════════════════════════════════════════════════
   REDUCED MOTION
   The durations already collapse to 1 ms in tokens.css. What is left to
   say is that the leaders are *there*, not drawn: launcher.js reads the
   same query and does not schedule the entrance at all.
   ═══════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .entry-lead,
  .entry-go,
  .entry-no,
  .entry::before { transition-duration: 1ms; }
}

/* ═══════════════════════════════════════════════════════════════
   FORCED COLOURS
   The glass, the red bulletin and the ink colophon are all decorative
   substrates; the OS palette replaces them and the construction has to
   survive that. What must not survive is a hairline drawn in a colour the
   system has just repainted.
   ═══════════════════════════════════════════════════════════════ */
@media (forced-colors: active) {
  .register { border-color: CanvasText; box-shadow: none; }
  .bulletin, .colophon { forced-color-adjust: none; }
  .entry-lead { background-image: none; border-block-start: 1px solid CanvasText; }
  /* La plaque du numéro et le liseré s'effondrent en aplats système : ils
     resteraient sinon peints en rouge par-dessus une palette imposée. */
  .entry:hover .entry-no,
  .entry:focus-visible .entry-no { color: Canvas; background: Highlight; }
  .entry::before { background: Highlight; }
}

/* ═══════════════════════════════════════════════════════════════
   PRINT — the index is the one thing worth printing
   ═══════════════════════════════════════════════════════════════ */
@media print {
  #langBtn, .bar-cta, .bar-nav, .colophon { display: none; }
  /* Une barre fixe s'imprime sur chaque feuille. Elle redevient un
     en-tête, une fois, en haut de la première. */
  .bar { position: static; }
  .sheet { min-height: 0; padding-block-start: 0; }
  .register { background: none; box-shadow: none; backdrop-filter: none; }
  .spread { grid-template-columns: minmax(0, 1fr); }
}

/* Le bouton de langue, repris d'astralaika.com.
   Un rectangle d'encre de deux pixels qui s'inverse au survol : le site de
   l'entreprise en fait sa seule commande visible, et la suite EST le site.
   Il porte « FR ▾ » — le code court dit dans quelle langue on se trouve,
   ce qu'un globe ne dit pas. */
#langBtn {
  padding: 7px 12px;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--text);
  background: var(--surface);
  border: 2px solid var(--ink-solid);
  transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out);
}
#langBtn:hover,
#langBtn[aria-expanded="true"] {
  color: var(--surface);
  background: var(--ink-solid);
}

/* La signature de l'éditeur, sur le modèle de captainfork.com.
   Discrète par construction : la marque à vingt pixels, une ligne en
   teinte atténuée, et rien qui réclame le regard avant le produit. Elle
   s'éclaire au survol, ce qui suffit à dire qu'elle est cliquable. */
.signature {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--text-muted);
  font-size: var(--text-xs);
  text-decoration: none;
  transition: color 200ms var(--ease-out);
}
.signature img { display: block; flex: none; }
.signature:hover { color: var(--text-inverse); text-decoration: none; }

/* Les liens du pied portent la diagonale de départ, comme les rangées du
   sélecteur : ces quatorze noms mènent chacun à un sous-domaine, et sans
   ce signe ils se lisent comme des ancres de la page courante. Elle est
   plus discrète qu'en pleine liste — un pied de page annonce, il n'insiste
   pas — et elle ne se retourne pas en écriture droite-à-gauche, une
   diagonale montante disant « ailleurs » et non « à droite ». */
.colophon-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.colophon-link__go {
  display: inline-flex;
  --form-size: 0.72em;
  opacity: 0.55;
  transition: opacity var(--duration-fast) var(--ease-out);
}
.colophon-link:hover .colophon-link__go,
.colophon-link:focus-visible .colophon-link__go { opacity: 1; }
