
/* ==========================================================================
   ASA COMPASS : un instrument, pas une page

   Karl a demandé de reprendre l'esprit du calculateur de son site principal :
   « j'aime le style un peu console, ça a quasiment l'air d'un jouet, donc ça
   donne envie de naviguer l'interface et d'aller jouer dedans », avec « du
   relief dans les boutons, dans les fenêtres ».

   Le SYSTÈME est repris ; la MATIÈRE est propre à ce projet. Quatre règles
   suffisent à tenir tout l'appareil :

     1. la lumière vient du haut. Toute surface bombée porte une arête claire
        sur son bord supérieur et une ombre sur son bord inférieur ;
     2. une surface qui reçoit se creuse. Champs, compteurs, zones de saisie
        ont une ombre INTERNE, jamais portée ;
     3. ce qui se presse s'enfonce. Un bouton descend d'un pixel au clic et
        son ombre externe devient interne ;
     4. l'accent est une lampe, pas une couleur. Le laiton n'éclaire que ce
        qui compte, et il diffuse.

   Thème unique et sombre, assumé : une console éclairée par le haut n'a pas
   de version claire, et le sujet le justifie : l'exploration des recoins
   obscurs d'une blockchain. Toutes les couleurs sont posées explicitement,
   la page ne dépend donc d'aucun fond hérité.
   ========================================================================== */
:root{
  color-scheme: dark;

  /* --- la matière : un métal bleu-nuit, éclairé par le haut --- */
  --chassis-haut:#1B2531;
  /* LE RELIEF, monte d un cran le 31 aout 2026.
     Karl trouvait le site trop sobre et a demande du punch. Il a essaye le
     cuivre et le bois sur un temoin, puis a tranche : la palette turquoise et
     argent ne bouge pas, c est la MATIERE qui doit porter. Le fond s assombrit,
     les blocs s eclaircissent, les aretes se marquent, et l ecart entre les
     deux fait tout le relief. Metallique veut dire degrade et reflet, jamais
     aplat : ces variables decrivent un metal eclaire par le haut. */
  --chassis:     #22303F;
  --creux:       #131C26;
  --fond:        #05080C;
  --enfonce:     #070A0F;

  /* --- les arêtes : la lumière rasante sur les bords --- */
  --arete-vive:  rgba(255,255,255,.26);
  --arete:       rgba(255,255,255,.12);
  --arete-basse: rgba(0,0,0,.55);
  --ombre-douce: rgba(0,0,0,.50);

  /* --- l'encre --- */
  --encre:      #E8E4DA;
  --doux:       #A9B2BE;
  --brume:      #6F7A88;
  --filet:      rgba(255,255,255,.20);

  /* --- la lampe : la charte de marque d'ASA Compass ---------------------
     Karl a fourni une charte complete avec le logo. Sa palette est turquoise
     et argent (#00E0B8, #00A88A, #F2F2F2, #808A8D), la ou le site etait en
     laiton dore. Garder le laiton aurait donne un en-tete turquoise pose sur
     un corps dore : deux marques dans une page. L'accent bascule donc, mais
     la MECANIQUE ne change pas, l'accent reste une lampe qui n'eclaire que
     les chiffres et les prix.
     Les noms de variables gardent le mot « laiton » a dessein : toute la
     feuille de style s'y refere, et un renommage massif risquerait plus qu'il
     n'apporterait. La couleur a change, pas le role. */
  --laiton:     #00E0B8;
  --laiton-vif: #5CF2D6;
  --lueur:      rgba(0,224,184,.22);
  --vivant:     #6FB394;
  --argent:     #F2F2F2;
  /* Eclairci de #808A8D quand les blocs ont ete eclaircis : sur le nouveau
     chassis, l ancien gris tombait a 3,80 de rapport de contraste, sous le
     seuil de lisibilite de 4,5. La teinte est conservee, seule la clarte
     monte, ce qui rend le changement invisible a l oeil et sensible a la
     lecture. Il porte la majorite des textes secondaires du site. */
  --argent-gris:#8D989B;
}

*{box-sizing:border-box}
body{
  margin:0;background:var(--fond);color:var(--encre);
  font-family:"Archivo",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
  /* Une lueur haute, comme la lampe au-dessus de l'appareil. */
  background-image:radial-gradient(120% 70% at 50% -18%, rgba(211,160,85,.07), transparent 62%);
  background-attachment:fixed;
}
.enveloppe{max-width:1240px;margin:0 auto;padding:0 24px}
a{color:var(--laiton);text-decoration:none}
a:hover{color:var(--laiton-vif)}
a:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:3px;border-radius:3px}
.mono{font-family:"IBM Plex Mono",ui-monospace,Menlo,monospace}

/* --- le bombé et le creux, les deux gestes de base ------------------- */
.bombe{
  background:linear-gradient(180deg, var(--chassis-haut) 0%, var(--chassis) 46%, var(--creux) 100%);
  border:1px solid var(--arete-basse);
  box-shadow:
    inset 0 1px 0 var(--arete-vive),
    inset 0 -1px 0 rgba(0,0,0,.5),
    0 1px 0 rgba(0,0,0,.6),
    0 18px 34px -20px var(--ombre-douce);
}
.enfonce{
  background:var(--enfonce);
  box-shadow:inset 0 3px 9px rgba(0,0,0,.95), inset 0 -1px 0 var(--arete);
  border:1px solid rgba(0,0,0,.5);
}

/* ---- entête : la façade de l'appareil ---- */
.barre{
  position:sticky;top:0;z-index:10;
  background:linear-gradient(180deg, var(--chassis-haut), var(--chassis));
  border-bottom:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 6px 20px -2px rgba(0,0,0,.85);
}
.barre .enveloppe{display:flex;align-items:center;gap:16px;height:64px}
.marque{
  font-family:"Libre Caslon Display",Georgia,serif;font-size:1.3rem;
  color:var(--encre);white-space:nowrap;letter-spacing:.01em;
  text-shadow:0 1px 0 rgba(0,0,0,.6);
}
.marque:hover{color:var(--laiton)}
.marque .aiguille{color:var(--laiton);text-shadow:0 0 10px var(--lueur)}

/* ---- le bouton : bombé au repos, enfoncé au clic ---- */
.portefeuille{
  margin-left:auto;font:inherit;font-size:.85rem;font-weight:500;
  padding:8px 15px;border-radius:9px;cursor:pointer;color:var(--encre);
  background:linear-gradient(180deg, #26313F 0%, #19212C 100%);
  border:1px solid var(--arete-basse);
  box-shadow:
    inset 0 1px 0 var(--arete-vive),
    0 1px 0 rgba(0,0,0,.55),
    0 3px 7px -3px rgba(0,0,0,.6);
  transition:transform .1s ease, box-shadow .1s ease, color .1s ease;
}
.portefeuille:hover{color:var(--laiton-vif)}
.portefeuille:active{
  transform:translateY(1px);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.9);
}
.portefeuille:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px}
.portefeuille[data-connecte]{
  font-family:"IBM Plex Mono",monospace;color:var(--vivant);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 0 14px -4px rgba(111,179,148,.5), 0 1px 0 rgba(0,0,0,.55);
}

/* ---- la recherche : une fente creusée dans la façade ---- */
.chercher{position:relative;flex:0 1 300px}
.chercher input{
  width:100%;padding:9px 12px 9px 32px;font:inherit;font-size:.9rem;
  color:var(--encre);background:var(--enfonce);
  border:1px solid rgba(0,0,0,.6);border-radius:9px;
  box-shadow:inset 0 3px 8px rgba(0,0,0,.95), inset 0 -1px 0 var(--arete);
}
.chercher input::placeholder{color:var(--brume)}
.chercher input:focus{outline:none;box-shadow:inset 0 3px 8px rgba(0,0,0,.95), 0 0 0 2px var(--lueur)}
.chercher svg{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--brume)}
.resultats{
  position:absolute;top:calc(100% + 8px);left:0;right:0;max-height:60vh;overflow-y:auto;
  background:linear-gradient(180deg, var(--chassis-haut), var(--chassis));
  border:1px solid var(--arete-basse);border-radius:10px;
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 16px 34px -12px rgba(0,0,0,.8);
  display:none;
}
.resultats.ouvert{display:block}
.resultats a{display:flex;justify-content:space-between;gap:12px;padding:10px 13px;
  color:var(--encre);border-bottom:1px solid var(--filet);font-size:.9rem}
.resultats a:last-child{border-bottom:none}
.resultats a:hover{background:rgba(211,160,85,.08);color:var(--laiton-vif)}
.resultats .compte{color:var(--brume);font-size:.8rem;white-space:nowrap}
.resultats .rien{padding:13px;color:var(--brume);font-size:.9rem}

/* ---- accueil ---- */
.hero{padding:74px 0 42px}
h1{
  font-family:"Libre Caslon Display",Georgia,serif;font-weight:400;
  font-size:clamp(2.5rem,6.4vw,4.4rem);line-height:1.04;margin:0 0 20px;
  max-width:16ch;text-wrap:balance;text-shadow:0 2px 0 rgba(0,0,0,.5);
}
.sous-titre{font-size:1.16rem;color:var(--doux);max-width:56ch;margin:0 0 28px;text-wrap:pretty}
.avis{
  display:inline-flex;align-items:center;gap:9px;padding:8px 14px;border-radius:9px;
  background:var(--enfonce);border:1px solid rgba(0,0,0,.5);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.92);
  font-size:.83rem;color:var(--doux);
}
.avis b{color:var(--laiton);font-weight:600;letter-spacing:.06em;font-size:.76rem;
  text-transform:uppercase;text-shadow:0 0 10px var(--lueur)}

/* ---- les compteurs : des fenêtres d'affichage creusées ---- */
.compteurs{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px;padding:34px 0 8px}
.compteurs div{
  padding:16px 18px;border-radius:11px;
  background:var(--enfonce);border:1px solid rgba(0,0,0,.55);
  box-shadow:inset 0 3px 10px rgba(0,0,0,.95), inset 0 -1px 0 var(--arete), 0 1px 0 var(--arete-vive);
}
.compteurs .n{
  display:block;font-family:"Libre Caslon Display",Georgia,serif;
  font-size:2.05rem;line-height:1;color:var(--laiton);
  font-variant-numeric:tabular-nums;margin-bottom:6px;
  text-shadow:0 0 16px var(--lueur);
}
.compteurs .q{display:block;font-size:.82rem;color:var(--brume);line-height:1.35}

.section-titre{display:flex;align-items:baseline;gap:14px;margin:54px 0 18px}
.section-titre h2{
  font-family:"Libre Caslon Display",Georgia,serif;font-weight:400;
  font-size:1.9rem;margin:0;text-shadow:0 2px 0 rgba(0,0,0,.5);
}
.section-titre p{margin:0;color:var(--brume);font-size:.92rem}

/* ---- les cartes de mise en vente ---- */
.cartes{display:grid;grid-template-columns:repeat(auto-fill,minmax(214px,1fr));gap:18px}
.carte{
  border-radius:12px;overflow:hidden;display:flex;flex-direction:column;
  background:linear-gradient(180deg, var(--chassis-haut) 0%, var(--chassis) 55%, var(--creux) 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.6), 0 16px 34px -14px rgba(0,0,0,.75);
  transition:transform .14s ease, box-shadow .14s ease;
}
.carte:hover{
  transform:translateY(-2px);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 20px 32px -18px rgba(0,0,0,.7), 0 0 0 1px rgba(211,160,85,.35);
}
.carte-oeuvre{display:block;aspect-ratio:1;background:var(--enfonce);overflow:hidden;
  box-shadow:inset 0 1px 6px rgba(0,0,0,.7)}
.carte-oeuvre img,.carte-oeuvre video{width:100%;height:100%;object-fit:cover;display:block}
.carte-bas{padding:12px 14px 14px;display:flex;flex-direction:column;gap:5px;flex:1}
.carte-bas h3{font-size:.95rem;font-weight:600;margin:0;line-height:1.28;overflow-wrap:anywhere}
.carte-serie{margin:0;font-size:.78rem;color:var(--brume)}
.carte-pied{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:auto;padding-top:8px}
.carte-prix{
  font-family:"IBM Plex Mono",monospace;font-size:1.02rem;font-weight:500;color:var(--laiton);
  font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:5px;
  text-shadow:0 0 12px var(--lueur);
}
.acheter{
  font:inherit;font-size:.8rem;font-weight:600;padding:6px 14px;border-radius:8px;cursor:pointer;
  color:var(--encre);background:linear-gradient(180deg, #2C3745 0%, #1C2530 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.55), 0 3px 7px -3px rgba(0,0,0,.6);
  transition:transform .1s ease, box-shadow .1s ease, color .1s ease;
}
.acheter:hover:not(:disabled){color:var(--laiton-vif)}
.acheter:active:not(:disabled){transform:translateY(1px);box-shadow:inset 0 3px 8px rgba(0,0,0,.9)}
.acheter:disabled{opacity:.45;cursor:not-allowed}
.carte-tirage{margin:2px 0 0;font-size:.68rem;color:var(--brume)}

/* Le bandeau de démonstration : ces blocs montrent une maquette, pas des faits. */
.maquette > .plaque{background:linear-gradient(180deg, rgba(211,160,85,.10), transparent)}
.maquette > .plaque::before{
  content:"DEMO";order:-1;
  font-family:"IBM Plex Mono",monospace;font-size:.62rem;font-weight:600;letter-spacing:.14em;
  color:var(--laiton);border:1px solid var(--laiton);border-radius:3px;padding:2px 6px;
  align-self:center;
}

/* ---- LE BOÎTIER ------------------------------------------------------
   Ce qui manquait pour que l'interface ressemble à un appareil : le
   calculateur de Window Portal Network n'est pas seulement fait d'éléments
   en relief, il est **enfermé dans un cadre**. C'est le boîtier qui fait
   l'objet ; sans lui, les reliefs flottent sur une page.

   Chaque bloc majeur reçoit donc son propre coffret, avec une plaque de
   titre en haut, la façade, et le contenu fraisé dedans. */
.coffret{
  border-radius:16px;margin-bottom:44px;overflow:hidden;
  background:linear-gradient(180deg, var(--chassis-haut) 0%, var(--chassis) 42%, var(--creux) 100%);
  border:1px solid var(--arete-basse);
  box-shadow:
    inset 0 1px 0 var(--arete-vive),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 1px 0 rgba(0,0,0,.65),
    0 24px 48px -16px rgba(0,0,0,.78);
}
.coffret > .plaque{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding:15px 20px;
  border-bottom:1px solid var(--arete-basse);
  box-shadow:0 1px 0 var(--arete-vive);
  background:linear-gradient(180deg, rgba(255,255,255,.035), transparent);
}
.coffret > .plaque h2{
  font-family:"Libre Caslon Display",Georgia,serif;font-weight:400;
  font-size:1.42rem;margin:0;text-shadow:0 2px 0 rgba(0,0,0,.55);
}
.coffret > .plaque p{margin:0;color:var(--brume);font-size:.85rem}
/* La vis de coin : un détail d'appareil, discret mais qui ancre l'objet. */
.coffret > .plaque::after{
  content:"";margin-left:auto;width:9px;height:9px;border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #39424F, #14191F 70%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18), 0 1px 0 rgba(0,0,0,.6);
  flex:none;align-self:center;
}
.coffret > .dedans{padding:18px 20px 20px}
.coffret > .dedans > :last-child{margin-bottom:0}

/* ---- registre d'activité : un bandeau de listing dans un creux ---- */
.registre{
  border-radius:12px;overflow:hidden;margin-bottom:10px;
  background:var(--creux);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 2px 10px rgba(0,0,0,.7), 0 1px 0 var(--arete-vive);
}
.echange{
  display:grid;grid-template-columns:54px 1fr auto;gap:14px;align-items:center;
  padding:11px 14px;border-bottom:1px solid var(--filet);color:var(--encre);
  transition:background .12s ease;
}
.echange:last-child{border-bottom:none}
.echange:hover{background:rgba(211,160,85,.07);color:var(--encre)}
/* Une vente dont la collection n est pas au catalogue : meme ligne, meme prix,
   mais aucun lien, et elle ne fait pas semblant d en avoir un. */
.echange.sans-page{cursor:default}
.echange.sans-page:hover{background:none}
.echange .hors-catalogue{color:var(--brume);opacity:.8;font-style:italic}
.echange .miniature{
  width:54px;height:54px;border-radius:8px;overflow:hidden;background:var(--enfonce);
  box-shadow:inset 0 1px 4px rgba(0,0,0,.8), 0 1px 0 var(--arete-vive);
}
.echange .miniature img,.echange .miniature video{width:100%;height:100%;object-fit:cover;display:block}
.echange .quoi{min-width:0}
.echange .piece-nom{font-weight:500;font-size:.94rem;line-height:1.3;overflow-wrap:anywhere}
.echange .ligne-detail{font-size:.78rem;color:var(--brume);margin-top:3px}
.echange .ligne-detail .serie{color:var(--laiton)}
/* Le nom de la page quand il differe de celui de la collection : une precision,
   pas une alerte. Discret, mais lisible. */
.echange .ligne-detail .dans-famille{color:var(--brume);font-style:italic}
/* La recherche de piece dans une collection. Meme matiere que le reste :
   un creux dans lequel on tape, et des lignes qui repondent. */
.visuellement-cache{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.cherche-piece{display:block;padding:14px 14px 0}
.cherche-piece input{
  width:100%;box-sizing:border-box;padding:10px 13px;border-radius:9px;
  background:var(--enfonce);color:var(--encre);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 2px 8px rgba(0,0,0,.65), 0 1px 0 var(--arete-vive);
  font:inherit;font-size:.9rem;
}
.cherche-piece input:focus{outline:none;border-color:var(--laiton);box-shadow:inset 0 2px 8px rgba(0,0,0,.65), 0 0 0 3px var(--lueur)}
.compte-pieces{margin:10px 14px 0;font-size:.78rem;color:var(--brume)}
.pieces-liste{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:8px;padding:12px 14px}
.piece-ligne{
  display:block;padding:9px 11px;border-radius:8px;color:var(--encre);
  background:linear-gradient(180deg,#1B2531 0%,#141B24 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive);
  font-size:.84rem;line-height:1.3;overflow-wrap:anywhere;
}
.piece-ligne:hover,.piece-ligne:focus-visible{border-color:var(--laiton);color:var(--encre)}
.piece-ligne .asa{display:block;font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--brume);margin-top:3px}
.plus-pieces{
  display:block;margin:0 14px 16px;padding:9px 16px;border-radius:9px;cursor:pointer;
  background:linear-gradient(180deg,#26313F 0%,#19212C 100%);
  border:1px solid var(--arete-basse);box-shadow:inset 0 1px 0 var(--arete-vive);
  color:var(--encre);font:inherit;font-size:.84rem;
}
.plus-pieces:hover{border-color:var(--laiton)}
.echange .ligne-detail .marche{
  color:var(--doux);border:1px solid var(--filet);border-radius:3px;
  padding:1px 6px;font-size:.94em;background:rgba(0,0,0,.3);
}
.echange .valeur{text-align:right;white-space:nowrap}
.echange .prix{
  font-family:"IBM Plex Mono",monospace;font-size:1rem;font-weight:500;
  font-variant-numeric:tabular-nums;color:var(--laiton);
  text-shadow:0 0 12px var(--lueur);
  display:inline-flex;align-items:center;gap:5px;
}
/* Le symbole prend la couleur du texte qui le porte : laiton sur les prix,
   et il suivra tout changement d'accent sans retouche. */
.algo{
  width:.78em;height:.78em;flex:none;
  filter:drop-shadow(0 0 6px var(--lueur));
}
.compteurs .n .algo{width:.62em;height:.62em;margin-left:.14em;vertical-align:baseline}
.echange .quand{font-size:.73rem;color:var(--brume);margin-top:2px;display:block}
.plus{
  display:inline-block;margin:20px 0 0;font-size:.88rem;font-weight:500;
  padding:9px 16px;border-radius:9px;color:var(--encre);
  background:linear-gradient(180deg, #26313F 0%, #19212C 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.55), 0 3px 7px -3px rgba(0,0,0,.6);
  transition:transform .1s ease, box-shadow .1s ease, color .1s ease;
}
.plus:hover{color:var(--laiton-vif)}
.plus:active{transform:translateY(1px);box-shadow:inset 0 3px 8px rgba(0,0,0,.9)}

/* ---- le sélecteur de période du palmarès ----------------------------------
   Karl a demandé de pouvoir trier les plus grosses ventes par tranche de
   temps. Les onglets suivent la règle 3 du système : ce qui est choisi est
   ENFONCÉ, ce qui ne l'est pas reste bombé. L'état se lit donc au relief seul,
   sans dépendre de la couleur.
   -------------------------------------------------------------------------- */
.periodes{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 14px}
.periode{
  font-family:"IBM Plex Mono",monospace;font-size:.72rem;letter-spacing:.06em;
  padding:6px 11px;border-radius:8px;cursor:pointer;color:var(--doux);
  background:linear-gradient(180deg,#26313F 0%,#19212C 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.55);
  transition:color .12s ease, box-shadow .12s ease, transform .1s ease;
}
.periode:hover{color:var(--laiton-vif)}
.periode:active{transform:translateY(1px)}
.periode[aria-selected="true"]{
  color:var(--laiton);text-shadow:0 0 12px var(--lueur);
  background:var(--enfonce);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.95), 0 1px 0 var(--arete-vive);
}
.periode:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px}
.periode .n{opacity:.5;margin-left:5px;font-size:.92em}
/* La barre de tri est secondaire par rapport à celle des périodes : elle
   choisit un ordre, pas un contenu. D'où sa taille réduite et sa marge. */
/* La roulette de classement. Elle ne paraît que dans l'onglet « All » : trier
   une chronologie par mois reviendrait à la défaire. */
.roulette{display:inline-flex;align-items:center;gap:9px;margin:0 0 20px}
.roulette > span{
  font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brume);
}
.roulette select{
  font:inherit;font-size:.83rem;cursor:pointer;color:var(--encre);
  padding:8px 30px 8px 12px;border-radius:8px;appearance:none;
  background:linear-gradient(180deg,#26313F 0%,#19212C 100%)
    no-repeat right 11px center/9px 6px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6' fill='none' stroke='%23A9B2BE' stroke-width='1.6'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E"),
    linear-gradient(180deg,#26313F 0%,#19212C 100%);
  background-repeat:no-repeat,no-repeat;
  background-position:right 11px center,0 0;
  background-size:9px 6px,100% 100%;
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.55);
}
.roulette select:hover{color:var(--laiton-vif)}
.roulette select:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px}
/* LES COLLECTIONS DORMANTES, atténuées et non cachées.
   Karl : « comme un peu fantômes ». Elles restent lisibles et cliquables : ce
   n'est pas une punition, c'est une hiérarchie. L'atténuation se lève au
   survol, pour que rien ne soit hors d'atteinte. */
/* L'ÉTOILE DES FAVORIS, posée sur la mosaïque.
   Karl : « une petite étoile embarquée par-dessus la mosaïque des quatre, en
   haut à droite, juste les contours d'une petite étoile, que si on coche
   l'intérieur devient golden. »

   Pas de cadre, pas de fond : le seul dessin est le contour. Une ombre portée
   le détache d'une image claire sans qu'il faille poser une pastille sombre
   derrière, ce qui alourdissait la première version. */
.tuile{position:relative}
.etoile{
  position:absolute;top:7px;right:7px;z-index:3;
  width:22px;height:22px;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:none;border:0;
  transition:transform .12s ease;
}
.etoile svg{
  width:16px;height:16px;fill:none;
  stroke:#FFFFFF;stroke-width:1.5;stroke-linejoin:round;
  /* L'ombre remplace le fond : lisible sur une œuvre claire comme sur une
     œuvre sombre, sans rien poser par-dessus l'image. */
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.9));
  transition:fill .14s ease, stroke .14s ease;
}
.etoile:hover{transform:scale(1.12)}
.etoile[aria-pressed="true"] svg{
  fill:var(--laiton);stroke:var(--laiton-vif);
  filter:drop-shadow(0 0 7px var(--lueur)) drop-shadow(0 1px 2px rgba(0,0,0,.85));
}
.etoile:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px;border-radius:4px}

.tuile.dormante{opacity:.42;filter:saturate(.55);transition:opacity .15s ease, filter .15s ease}
.tuile.dormante:hover, .tuile.dormante:focus-visible{opacity:1;filter:none}

/* CE QUI PORTE L'ATTRIBUT « hidden » EST CACHÉ, SANS EXCEPTION.

   Le navigateur cache un élément « hidden » par une simple règle display:none
   de sa feuille par défaut, que N'IMPORTE QUELLE règle display de la page
   surcharge. Poser display:grid sur une classe qu'on masque ensuite par
   « hidden » rend donc l'attribut muet, et le code qui bascule paraît ne rien
   faire alors qu'il fait exactement ce qu'on lui demande.

   Karl l'a vu sur l'onglet 2022 de l'index : « on dirait qu'il ne fonctionne
   pas, il ne trie rien ». Il ne triait rien en effet, mais pas pour la raison
   qu'on croyait. Le bouton basculait bien, seulement les vues par année portent
   display:grid pour leur chronologie latérale, si bien qu'elles restaient
   TOUTES affichées, empilées sous la grille complète. Mesuré dans Chrome :
   4 444 vignettes visibles au chargement pour 2 222 collections.

   Le défaut s'était déjà présenté six fois, et six fois on avait ajouté la
   règle jumelle pour une classe précise. Cette règle-ci les remplace toutes et
   ferme le motif : aucune classe future ne pourra le rouvrir. Le point
   d'exclamation est nécessaire, c'est lui qui bat une règle plus précise ;
   rien dans ces pages ne pose de display en ligne qu'il pourrait contrarier. */
[hidden]{display:none !important}

/* LA CHRONOLOGIE LATÉRALE, dans les vues par année.
   Elle reste collée pendant qu'on défile et marque le mois où l'on se trouve.
   Sur un écran étroit elle disparaît : une colonne fixe y volerait la moitié
   de la largeur, et la page se parcourt très bien sans elle. */
.avec-chronologie{display:grid;grid-template-columns:44px 1fr;gap:18px;align-items:start}

/* LA COLONNE ALPHABETIQUE (K-14), batie sur la meme ossature que la
   chronologie : meme largeur, meme filet, meme position collante. C est la
   demande de Karl, « le meme mecanisme, la barre a gauche », et deux colonnes
   qui se ressemblent sans se ressembler tout a fait seraient pires que deux
   colonnes franchement differentes. */
/* DEUX PISTES, MAIS SEULEMENT QUAND LA COLONNE EST LA.

   Un element masque ne prend aucune cellule dans une grille. La colonne
   alphabetique etant cachee hors des tris alphabetiques, la grille des tuiles
   se retrouvait placee dans la premiere piste, celle de quarante-quatre
   pixels : mille six cents collections empilees sur une seule colonne.
   Karl l a vu tout de suite, et ma verification ne l avait pas attrape parce
   qu elle cherchait la PRESENCE des elements, pas leur largeur.

   On place donc chaque enfant dans sa piste explicitement, et la zone repasse a
   une seule colonne quand la barre est absente. */
.avec-alphabet{display:grid;grid-template-columns:44px 1fr;gap:18px;align-items:start}
.avec-alphabet > .alphabet{grid-column:1}
.avec-alphabet > .colonne-tout{grid-column:2;min-width:0}
.avec-alphabet.sans-colonne{grid-template-columns:1fr}
.avec-alphabet.sans-colonne > .colonne-tout{grid-column:1}
.alphabet{
  position:sticky;top:74px;display:flex;flex-direction:column;gap:2px;
  padding:9px 0;
}
.alphabet[hidden]{display:none}
.alphabet::before{
  content:"";position:absolute;left:50%;top:14px;bottom:14px;width:1px;
  background:linear-gradient(180deg,transparent,var(--filet) 12%,var(--filet) 88%,transparent);
  transform:translateX(-.5px);
}
.lettre{
  position:relative;z-index:2;cursor:pointer;
  width:22px;height:19px;margin:0 auto;padding:0;border:0;border-radius:5px;
  font-family:"IBM Plex Mono",monospace;font-size:.66rem;font-weight:600;
  color:var(--brume);background:var(--fond);
  transition:color .14s,background .14s;
}
.lettre:hover,.lettre:focus-visible{color:var(--turquoise)}
.lettre.ici{color:#04211C;background:var(--turquoise)}
/* Une lettre sans collection reste a sa place, en retrait : l alphabet doit
   garder sa forme complete, exactement comme les mois vides de la
   chronologie. Elle ne se clique pas, puisqu il n y a nulle part ou aller. */
.lettre.vide{opacity:.28;pointer-events:none}
@media (max-width:900px){
  .avec-alphabet{grid-template-columns:1fr}
  /* Sur telephone, la colonne passe a l horizontale plutot que de manger la
     largeur : elle reste utile et ne coute plus rien a la grille. */
  .alphabet{
    position:static;flex-direction:row;flex-wrap:wrap;justify-content:center;
    gap:3px;margin-bottom:14px;
  }
  .alphabet::before{display:none}
}
.chronologie{
  position:sticky;top:74px;display:flex;flex-direction:column;gap:7px;
  padding:9px 0;
}
/* Le filet qui relie les jalons : c'est lui qui fait la « ligne ». */
.chronologie::before{
  content:"";position:absolute;left:50%;top:14px;bottom:14px;width:1px;
  background:linear-gradient(180deg,transparent,var(--filet) 12%,var(--filet) 88%,transparent);
  transform:translateX(-.5px);
}
.jalon{position:relative;display:flex;align-items:center;justify-content:center;height:26px}
.jalon .pastille{
  display:flex;align-items:center;justify-content:center;
  border-radius:50%;position:relative;z-index:2;
  font-family:"IBM Plex Mono",monospace;font-weight:600;
  color:var(--brume);background:var(--fond);
  box-shadow:0 0 0 1px var(--arete-basse);
  transition:width .12s ease,height .12s ease,color .12s ease,background .12s ease,box-shadow .12s ease;
}
/* Toutes les pastilles ont la même taille : Karl a écarté la variation par
   densité, qui « brise le design ». Un mois sans collection est simplement
   plus pâle, sans changer la ligne. */
.jalon .pastille{
  width:30px;height:30px;
  /* « Comme d'un verre un peu plus sombre » : la pastille est un disque de
     verre teinté sur lequel la constellation est gravée. */
  background:rgba(6,10,15,.72);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 0 0 1px var(--arete-basse);
  /* LE PREFIXE N EST PAS DECORATIF : Safari ne connait backdrop-filter sans lui
     qu a partir de sa version 18, et Karl regarde ses pages sur un iPhone. Sans
     cette ligne le flou ne se fait pas du tout chez lui. */
  -webkit-backdrop-filter:blur(2px);
  backdrop-filter:blur(2px);
}
.jalon.vide .pastille{opacity:.38}

.constel{width:22px;height:22px;display:block;overflow:visible}
/* LE TRACÉ QUI SE DESSINE.
   Karl : « la ligne de la constellation se dessine en néon ». Le trait est
   masqué par un pointillé dont le vide fait toute sa longueur ; en ramenant le
   décalage à zéro, il se révèle d'un bout à l'autre. 60 unités couvrent le plus
   long des douze tracés. */
.constel .trait{
  fill:none;stroke:var(--laiton);stroke-width:1.1;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:60;stroke-dashoffset:60;
  opacity:0;
  transition:stroke-dashoffset .75s ease-out, opacity .25s ease;
}
.constel .etoile-c{
  fill:var(--brume);
  transition:fill .3s ease, filter .3s ease;
}

/* Au repos, seules les étoiles se voient : une carte du ciel sans les lignes,
   que l'arrivée sur le mois vient relier. */
.jalon:hover .constel .trait,
.jalon.ici .constel .trait{stroke-dashoffset:0;opacity:1}
.jalon:hover .constel .etoile-c,
.jalon.ici .constel .etoile-c{
  fill:var(--laiton-vif);
  filter:drop-shadow(0 0 3px var(--lueur));
}
/* Le néon du mois où l'on se trouve : plus vif que le simple survol. */
.jalon.ici .constel .trait{
  stroke:var(--laiton-vif);
  filter:drop-shadow(0 0 4px var(--laiton)) drop-shadow(0 0 9px var(--lueur));
}
.jalon.ici .pastille{
  background:rgba(0,224,184,.10);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 0 0 1px rgba(0,224,184,.45),
             0 0 16px -4px var(--lueur);
}

/* Le nom du mois apparaît en fondu quand on arrive dessus, sans qu'il faille
   survoler : c'est ce que Karl a demandé, et cela dit où l'on est sans geste. */
.jalon.ici .etiquette{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .constel .trait{transition:opacity .2s ease}
  .jalon:hover .constel .trait, .jalon.ici .constel .trait{stroke-dashoffset:0}
}

.jalon:hover .pastille{color:var(--laiton-vif);box-shadow:0 0 0 1px var(--laiton)}
/* Le mois où l'on se trouve : allumé, pour répondre au « montrer où on est
   constamment » de Karl. */
.jalon.ici .pastille{
  color:#04211C;background:linear-gradient(180deg,var(--laiton-vif),var(--laiton));
  box-shadow:0 0 12px -2px var(--lueur);
}

/* L'étiquette, écrite au survol comme Karl l'a demandé. */
.jalon .etiquette{
  position:absolute;left:calc(100% + 10px);white-space:nowrap;z-index:5;
  font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.06em;
  color:var(--encre);background:var(--chassis);
  padding:5px 9px;border-radius:7px;
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 6px 16px -8px rgba(0,0,0,.9);
  opacity:0;transform:translateX(-4px);pointer-events:none;
  transition:opacity .12s ease, transform .12s ease;
}
.jalon .etiquette b{color:var(--laiton);font-weight:500;margin-left:3px}
.jalon:hover .etiquette, .jalon:focus-visible .etiquette{opacity:1;transform:none}
.jalon:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px;border-radius:50%}

@media (max-width:820px){
  .avec-chronologie{grid-template-columns:1fr}
  .chronologie{display:none}
}

.reglages-index{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-bottom:20px}
.reglages-index .roulette{margin:0}

/* L'interrupteur, dans la matière du reste : creusé au repos, allumé quand il
   est actif. */
.bascule{display:inline-flex;align-items:center;gap:9px;cursor:pointer;user-select:none}
.bascule input{position:absolute;opacity:0;width:0;height:0}
.bascule .glissiere{
  position:relative;width:34px;height:19px;border-radius:10px;flex:none;
  background:var(--enfonce);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 2px 5px rgba(0,0,0,.75);
  transition:background .14s ease, box-shadow .14s ease;
}
.bascule .glissiere::after{
  content:"";position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;
  background:linear-gradient(180deg,#4A5666,#333D4A);
  box-shadow:0 1px 2px rgba(0,0,0,.6);
  transition:transform .14s ease, background .14s ease;
}
.bascule input:checked + .glissiere{
  background:rgba(0,224,184,.22);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 0 12px -4px var(--lueur);
}
.bascule input:checked + .glissiere::after{
  transform:translateX(15px);
  background:linear-gradient(180deg,var(--laiton-vif),var(--laiton));
}
.bascule input:focus-visible + .glissiere{outline:2px solid var(--laiton-vif);outline-offset:2px}
.bascule-texte{
  font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brume);
}
.bascule-texte b{color:var(--doux);font-weight:500}
.vue-index{margin-bottom:40px}
.palmares-vide{color:var(--brume);font-size:.85rem;padding:14px 2px;margin:0}

/* LA DATE DE FRAPPE SUR LA MINIATURE.
   Karl : « peut-être même sur la miniature, de façon très discrète, en
   abréviation de date ». Elle se pose en surimpression dans le coin de
   l'image, sur un fond sombre translucide pour rester lisible quelle que soit
   l'œuvre. C'est la donnée qui fait la valeur de ce catalogue, mais elle ne
   doit pas manger l'œuvre : d'où la petite taille et l'opacité réduite, qui
   remonte au survol pour qui veut la lire. */
.piece{position:relative}
.piece[data-frappe]:not([data-frappe=""])::after{
  content:attr(data-frappe);
  position:absolute;top:7px;right:7px;
  font-family:"IBM Plex Mono",monospace;font-size:.6rem;letter-spacing:.04em;
  color:var(--argent);background:rgba(4,8,12,.72);
  padding:2px 6px;border-radius:5px;
  border:1px solid rgba(255,255,255,.08);
  opacity:.62;transition:opacity .12s ease;
  pointer-events:none;
}
.piece:hover[data-frappe]::after{opacity:1}

/* La marque des collections dont une pièce a bougé dans les cinq dernières
   années. Discrète : elle informe, elle ne décore pas, et son absence ne dit
   rien de mal sur une collection. */
.tuile .detail .vive{
  color:var(--vivant);
  font-family:"IBM Plex Mono",monospace;font-size:.63rem;letter-spacing:.1em;
  text-transform:uppercase;
}
.tuile .detail .vive::before{
  content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
  background:var(--vivant);margin-right:5px;vertical-align:middle;
  box-shadow:0 0 6px rgba(111,179,148,.8);
}

/* La vignette d'une pièce dont l'image n'est pas encore extraite. Surface
   creusée portant le numéro de l'actif, jamais un cadre vide : c'est la règle
   que Karl a posée pour les mosaïques, appliquée ici aux lignes de vente. */
.sans-image{
  display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;border-radius:8px;
  background:var(--enfonce);
  box-shadow:inset 0 2px 7px rgba(0,0,0,.8), 0 1px 0 var(--arete-vive);
}
.sans-image i{
  font-style:normal;font-family:"IBM Plex Mono",monospace;
  font-size:.56rem;letter-spacing:.02em;color:var(--brume);
  padding:0 3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
@media (pointer:coarse){
  /* 14px donne 45 points de haut, mesures : le seuil tactile de 44 est
     franchi. A 13px on retombait a 43, soit un point trop court. */
  .periode{padding:14px 14px}
}

/* ---- répartition par marché : des voyants ---- */
.marches{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:14px;margin-bottom:54px}
.marches div{
  padding:18px 20px;border-radius:11px;
  background:var(--enfonce);border:1px solid rgba(0,0,0,.55);
  box-shadow:inset 0 3px 10px rgba(0,0,0,.95), 0 1px 0 var(--arete-vive);
}
.marches .part{
  display:block;font-family:"Libre Caslon Display",Georgia,serif;font-size:1.95rem;
  line-height:1;color:var(--laiton);font-variant-numeric:tabular-nums;margin-bottom:6px;
  text-shadow:0 0 16px var(--lueur);
}
.marches .qui{display:block;font-size:.93rem;font-weight:500}
.marches .combien{display:block;font-size:.77rem;color:var(--brume);margin-top:3px}

/* ---- LA CONSOLE MENSUELLE ------------------------------------------
   Chaque mois est un tiroir de l'appareil : une façade avec son nom gravé,
   qu'on ouvre pour voir ce qu'il contient. */
.console > .dedans{display:flex;flex-direction:column;gap:14px}
.mois{
  border-radius:12px;overflow:hidden;
  background:linear-gradient(180deg, #1F2937 0%, #172029 50%, #0F151C 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.6), 0 10px 22px -16px var(--ombre-douce);
}
.mois-tete{
  display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:13px 18px;cursor:pointer;list-style:none;
  border-bottom:1px solid transparent;
  transition:background .12s ease;
}
.mois[open] > .mois-tete{border-bottom-color:var(--arete-basse);box-shadow:0 1px 0 var(--arete-vive)}
.mois-tete::-webkit-details-marker{display:none}
.mois-tete:hover{background:rgba(211,160,85,.06)}
.mois-nom{
  font-family:"Libre Caslon Display",Georgia,serif;font-size:1.32rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--encre);
  text-shadow:0 2px 0 rgba(0,0,0,.6);
}
.mois-compte{
  font-family:"IBM Plex Mono",monospace;font-size:.76rem;color:var(--brume);
}
/* Le témoin d'ouverture, à droite : une diode qui s'allume. */
.mois-tete::after{
  content:"";margin-left:auto;width:8px;height:8px;border-radius:50%;
  background:#2A323C;box-shadow:inset 0 1px 2px rgba(0,0,0,.8);
  align-self:center;flex:none;transition:background .15s ease, box-shadow .15s ease;
}
.mois[open] > .mois-tete::after{
  background:var(--laiton);
  box-shadow:0 0 10px var(--lueur), inset 0 1px 0 rgba(255,255,255,.35);
}
.mois-dedans{padding:16px 18px 18px}
.mois.vide{opacity:.5}
.mois.vide .mois-tete{cursor:default}
.mois.vide .mois-compte{font-style:italic}

/* ---- tuiles et pièces : des cartouches bombés ---- */
.grille{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:20px}
.tuile,.ancien,.piece{
  border-radius:12px;overflow:hidden;color:var(--encre);display:block;
  background:linear-gradient(180deg, var(--chassis-haut) 0%, var(--chassis) 55%, var(--creux) 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.6), 0 14px 26px -18px var(--ombre-douce);
  transition:transform .14s ease, box-shadow .14s ease;
}
.tuile{display:flex;flex-direction:column}
.tuile:hover,.ancien:hover,.piece:hover{
  transform:translateY(-2px);color:var(--encre);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.6),
             0 20px 32px -18px rgba(0,0,0,.7), 0 0 0 1px rgba(211,160,85,.35);
}
.tuile:active,.ancien:active,.piece:active{transform:translateY(0)}
.mosaique{display:grid;grid-template-columns:repeat(2,1fr);gap:2px;background:rgba(0,0,0,.55);aspect-ratio:1}
.mosaique span{background:var(--enfonce);overflow:hidden;display:block}
/* Une case sans image reste une surface creusée, jamais un trou blanc. */
.mosaique .sourde{
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,.022) 0 6px, transparent 6px 12px),
    var(--enfonce);
  box-shadow:inset 0 1px 5px rgba(0,0,0,.7);
}
.mosaique img,.mosaique video{width:100%;height:100%;object-fit:cover;display:block}
.tuile .texte{padding:13px 15px 15px}
.tuile h3{font-size:1rem;font-weight:600;margin:0 0 6px;line-height:1.3;overflow-wrap:anywhere}
.tuile .detail{display:flex;gap:10px;font-size:.77rem;color:var(--brume);flex-wrap:wrap}

/* ---- page de collection ---- */
.fil{padding:26px 0 0;font-size:.86rem;color:var(--brume)}
.tete-collection{padding:14px 0 30px}
.tete-collection h1{font-size:clamp(2rem,4.6vw,3.1rem);margin:0 0 16px;max-width:22ch}
.faits{display:flex;flex-wrap:wrap;gap:9px}
.fait{
  font-family:"IBM Plex Mono",monospace;font-size:.75rem;color:var(--doux);
  border-radius:7px;padding:5px 11px;
  background:var(--enfonce);border:1px solid rgba(0,0,0,.5);
  box-shadow:inset 0 1px 4px rgba(0,0,0,.7), 0 1px 0 var(--arete-vive);
}
.fait.vif{color:var(--vivant);text-shadow:0 0 10px rgba(111,179,148,.45)}
.pieces{display:grid;grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:18px}
.piece .cadre{aspect-ratio:1;background:var(--enfonce);overflow:hidden;
  box-shadow:inset 0 1px 6px rgba(0,0,0,.7)}
.piece img,.piece video{width:100%;height:100%;object-fit:cover;display:block}
.piece .nom{padding:10px 12px 3px;font-size:.83rem;line-height:1.35;overflow-wrap:anywhere}
.piece .meta{padding:0 12px 11px;font-size:.71rem;color:var(--brume)}

/* Deux blocs côte à côte : les prix records n'ont plus besoin de toute la
   largeur, Karl l'a signalé. */
.deux-colonnes{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:20px;align-items:start}

/* ---- les degrés de rareté : une jauge, pas une étiquette ---- */
.degres{display:flex;flex-direction:column;gap:9px}
.degre{display:grid;grid-template-columns:minmax(84px,auto) 1fr auto;gap:12px;align-items:center}
.degre-nom{font-size:.88rem;color:var(--encre)}
.degre-barre{
  height:11px;border-radius:6px;overflow:hidden;
  background:var(--enfonce);box-shadow:inset 0 1px 4px rgba(0,0,0,.8);
}
.degre-barre span{
  display:block;height:100%;
  background:linear-gradient(90deg, var(--laiton), var(--laiton-vif));
  box-shadow:0 0 10px var(--lueur);
}
.degre-n{
  font-family:"IBM Plex Mono",monospace;font-size:.8rem;color:var(--brume);
  font-variant-numeric:tabular-nums;
}

/* ---- anciens mints ---- */
.anciens{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:16px}
.ancien .cadre{aspect-ratio:1;background:var(--enfonce);box-shadow:inset 0 1px 6px rgba(0,0,0,.7)}
.ancien img,.ancien video{width:100%;height:100%;object-fit:cover;display:block}
.ancien .nom{padding:9px 11px 3px;font-size:.82rem;line-height:1.3;overflow-wrap:anywhere}
.ancien .date{padding:0 11px 10px;font-size:.71rem;color:var(--laiton);font-family:"IBM Plex Mono",monospace}

.vide{color:var(--brume);max-width:56ch}
footer{
  margin-top:20px;padding:36px 0 56px;color:var(--brume);font-size:.88rem;
  background:linear-gradient(180deg, transparent, rgba(0,0,0,.35));
  border-top:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive);
}
footer p{max-width:62ch}
footer a{color:var(--laiton)}

@media (max-width:560px){
  .enveloppe{padding:0 16px}
  .hero{padding:46px 0 30px}
  .barre .enveloppe{height:auto;padding-top:10px;padding-bottom:10px;flex-wrap:wrap;gap:10px}
  .chercher{flex:1 1 100%}
  .portefeuille{margin-left:0;order:-1}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}


/* ==========================================================================
   L'EN-TÊTE : une barre d'abord, une voûte ensuite

   Relevé fait sur les pages réelles de Magic Eden, Blur, OpenSea et Tensor,
   après que Karl a demandé « une plateforme qui a l'air extrêmement
   professionnel » en renvoyant à Solana et Ethereum.

   Ce qu'elles ont toutes : une barre très mince, la recherche large et
   centrale, et le contenu qui commence sans attendre. Blur ajoute la chasse
   fixe en capitales espacées, qui donne l'air d'un terminal plutôt que d'une
   brochure : c'est exactement le registre que Karl cherche depuis le début
   avec son « style console ».

   La voûte est la seule liberté prise, et elle est tenue courte, environ deux
   cents pixels, sur l'accueil uniquement.
   ========================================================================== */
.entete{position:relative;z-index:20}

/* --- la barre ----------------------------------------------------------- */
.bande{
  position:sticky;top:0;z-index:30;
  background:linear-gradient(180deg, #131A23 0%, #0E141B 100%);
  border-bottom:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 2px 14px -6px rgba(0,0,0,.9);
}
.bande .enveloppe{display:flex;align-items:center;gap:14px;height:56px}

.bande .compacte{display:flex;align-items:center;gap:9px;flex:none}
.bande .compacte img{width:25px;height:25px;display:block;
  filter:drop-shadow(0 0 8px rgba(0,224,184,.4));}
.bande .compacte span{
  font-family:"Cinzel",Georgia,serif;font-weight:600;
  font-size:.9rem;letter-spacing:.1em;color:var(--argent);white-space:nowrap;}
.bande .compacte span i{font-style:normal;color:var(--laiton)}
.bande .compacte:hover span{color:#fff}

.bande nav{display:flex;align-items:center;gap:2px;flex:none}
.bande nav a{
  font-family:"IBM Plex Mono",monospace;
  font-size:.74rem;font-weight:500;letter-spacing:.11em;text-transform:uppercase;
  padding:7px 11px;border-radius:6px;color:var(--doux);white-space:nowrap;
  transition:color .12s ease, background .12s ease;}
.bande nav a:hover{color:var(--laiton-vif);background:rgba(0,224,184,.08)}
.bande nav a[aria-current="page"]{
  color:var(--laiton);background:var(--enfonce);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.95), 0 1px 0 var(--arete-vive);}

/* La recherche est l'élément le plus large de la barre, comme partout dans ce
   marché : c'est par elle qu'on entre dans un catalogue de cent mille pièces. */
.bande .chercher{flex:1 1 auto;max-width:none;min-width:150px}

.bande .portefeuille{
  flex:none;margin:0;order:0;
  font-family:"IBM Plex Mono",monospace;
  font-size:.73rem;letter-spacing:.09em;text-transform:uppercase;font-weight:600;
  padding:9px 15px;color:#04211C;
  background:linear-gradient(180deg, var(--laiton-vif) 0%, var(--laiton) 100%);
  border:1px solid rgba(0,0,0,.5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45), 0 1px 0 rgba(0,0,0,.6),
             0 0 18px -6px rgba(0,224,184,.7);}
.bande .portefeuille:hover{color:#04211C;filter:brightness(1.08)}
.bande .portefeuille[data-connecte]{
  color:var(--laiton);
  background:linear-gradient(180deg,#26313F 0%,#19212C 100%);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 0 16px -5px var(--lueur);}

/* --- les deux menus de la barre ----------------------------------------
   Karl, après avoir essayé le site avec son portefeuille : « un onglet de
   profil, et quand on ouvre l'onglet on peut aller dans les réglages de son
   compte, help, contact. Et à côté un onglet plus financier qui par défaut
   montre les fonds en ALGO, avec un onglet déroulable qui affiche aussi les
   autres ASA. »

   Le défaut qu'ils corrigent : le bouton affichait l'adresse et déconnectait
   au clic, sans le dire. Karl s'est déconnecté sans le vouloir. La
   déconnexion est désormais une ligne nommée dans le tiroir de profil, jamais
   un effet de bord.
   ---------------------------------------------------------------------- */
.menu{position:relative;flex:none}
.menu .tirette{
  display:flex;align-items:center;gap:7px;cursor:pointer;
  /* Karl : « il y a juste le haut de algo qui tombe sur une deuxième ligne ».
     Un nom NFD n'a pas de longueur bornée, et le laisser se couper produit un
     bouton qui grandit et fait sauter toute la barre. Il tient donc sur une
     ligne, quitte à finir en points de suspension. */
  white-space:nowrap;max-width:220px;
  font-family:"IBM Plex Mono",monospace;font-size:.74rem;font-weight:500;
  padding:7px 11px;border-radius:8px;color:var(--encre);
  background:linear-gradient(180deg,#26313F 0%,#19212C 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 1px 0 rgba(0,0,0,.55);
  transition:color .12s ease, box-shadow .12s ease;
}
.menu .tirette:hover{color:var(--laiton-vif)}
.menu .tirette[aria-expanded="true"]{
  color:var(--laiton);background:var(--enfonce);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.95), 0 1px 0 var(--arete-vive);
}
.menu .tirette:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:2px}
.menu .somme{color:var(--laiton);text-shadow:0 0 10px var(--lueur);font-variant-numeric:tabular-nums}
.menu .chevron{opacity:.55;transition:transform .15s ease}
.menu .tirette[aria-expanded="true"] .chevron{transform:rotate(180deg)}
/* Le nom lui-même : il rétrécit avant l'avatar et le chevron, qui eux gardent
   leur taille. Sans min-width nulle, un élément de grille flexible refuse de
   descendre sous la largeur de son contenu. */
.menu .tirette > span{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;
}
.menu .frimousse{
  width:22px;height:22px;border-radius:50%;object-fit:cover;flex:none;
  background:var(--enfonce);box-shadow:0 0 0 1px var(--arete-basse);
}

.menu .tiroir{
  position:absolute;top:calc(100% + 8px);right:0;z-index:60;
  /* Karl trouvait le tiroir « un peu trop large pour rien » : 186 px suffisent
     aux libellés les plus longs, icône comprise. */
  min-width:186px;padding:7px;border-radius:11px;
  background:linear-gradient(180deg, var(--chassis-haut) 0%, var(--chassis) 100%);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 18px 38px -14px rgba(0,0,0,.9);
}
.menu .tiroir a, .menu .tiroir button{
  display:flex;align-items:center;gap:9px;width:100%;text-align:left;cursor:pointer;
  font:inherit;font-size:.83rem;padding:9px 11px;border-radius:7px;
  color:var(--doux);background:none;
  /* Une bordure transparente dès le repos : sans elle, celle qui paraît au
     survol décalerait le texte d'un pixel, ce qui se voit. */
  border:1px solid transparent;
  transition:color .12s ease, background .12s ease, border-color .12s ease;
}
.menu .tiroir svg{
  width:15px;height:15px;flex:none;fill:none;
  stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;
  opacity:.75;
}
.menu .tiroir a:hover{color:var(--laiton-vif);background:rgba(0,224,184,.08)}

/* LA DÉCONNEXION, en rouge dès le repos.
   Karl : « les Disconnect, j'aimerais qu'ils soient par défaut en rouge, avec
   son encadré aussi. Quand on glisse le curseur, peut-être qu'il pourrait
   juste y avoir un encadré qui s'ajoute. »
   C'est la seule ligne du menu qui défait quelque chose, et il l'a découvert
   en se déconnectant sans le vouloir : elle doit se voir AVANT d'être cliquée,
   pas après. */
.menu .tiroir #deco{
  color:#FF8B7A;
  margin-top:7px;
  border-color:rgba(255,120,100,.32);
  background:rgba(255,120,100,.06);
}
.menu .tiroir #deco svg{opacity:.9}
.menu .tiroir #deco:hover{
  color:#FFB3A6;
  border-color:rgba(255,120,100,.85);
  background:rgba(255,120,100,.13);
}
.menu .tiroir-titre{
  font-family:"IBM Plex Mono",monospace;font-size:.63rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brume);margin:4px 0 7px;padding:0 11px;
}
.menu .tiroir-vide{color:var(--brume);font-size:.79rem;margin:0;padding:5px 11px 9px}
.menu .jeton{
  /* L'alignement sur la ligne de base plaçait le nombre au bas du LOGO et non
     du texte : la ligne de base d'une boîte flex se prend sur son premier
     élément, et le nom vit dans un b qui commence par une image de quinze
     pixels. Karl l'avait vu : la quantité des jetons ne tombait pas en face du
     nom de la monnaie. Centrer règle le cas sans toucher à la structure. */
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:7px 11px;border-radius:7px;font-size:.82rem;
}
.menu .jeton:hover{background:rgba(255,255,255,.04)}
.menu .jeton b{display:flex;align-items:center;gap:7px;font-weight:500;color:var(--encre)}
.menu .logo-jeton{width:15px;height:15px;flex:none}
.menu svg.logo-jeton{color:var(--argent-gris)}
.menu img.logo-jeton.rond{
  border-radius:50%;object-fit:cover;
  /* Le repli vit SOUS l'image, en CSS. Une version précédente le mettait dans
     un attribut onerror dont les apostrophes refermaient la chaîne : le script
     entier cassait, et le bouton de connexion ne répondait plus. Une règle de
     style ne peut pas casser un script. */
  background:linear-gradient(180deg,var(--laiton-vif),var(--laiton));
}
/* La pastille tient lieu de logo tant que l'image manque : mieux vaut une
   marque lisible qu'un carré vide ou qu'aucun repère du tout. */
.menu .logo-jeton.pastille{
  display:flex;align-items:center;justify-content:center;border-radius:50%;
  font-family:"IBM Plex Mono",monospace;font-size:.42rem;font-weight:600;
  letter-spacing:-.02em;color:#04211C;
  background:linear-gradient(180deg,var(--laiton-vif),var(--laiton));
}
.menu .jeton span,.menu .jeton .chiffres{
  font-family:"IBM Plex Mono",monospace;color:var(--laiton);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
/* Trois informations sur une meme ligne, empilees a droite : le solde, sa
   valeur, et la variation du jour. Alignees a droite pour que les chiffres se
   lisent en colonne d une monnaie a l autre. */
.menu .jeton .chiffres{
  display:flex;flex-direction:column;align-items:flex-end;gap:1px;line-height:1.35;
}
.menu .jeton .chiffres em{font-style:normal;color:var(--laiton)}
.menu .jeton .chiffres u{
  text-decoration:none;font-size:.72rem;color:var(--argent-gris);
}
.menu .jeton .chiffres u:empty{display:none}
/* La couleur ne porte jamais seule l information : une fleche accompagne
   toujours le pourcentage, pour qui distingue mal le rouge du vert. */
.menu .jeton .var{
  font-style:normal;font-size:.68rem;letter-spacing:.01em;
}
.menu .jeton .var.hausse{color:#3FD9A4}
.menu .jeton .var.baisse{color:#FF6B6B}

/* Le bouton qui remplace le solde quand la monnaie n est pas encore acceptee.
   Il porte la couleur d action du site, comme le bouton de mise en vente, mais
   en plus discret : c est une invitation dans un tiroir, pas un appel a
   l action en facade. */
.menu .jeton-a-accepter{align-items:center}
.accepter-actif{
  cursor:pointer;padding:5px 13px;border-radius:7px;font:inherit;font-size:.74rem;
  font-weight:600;color:#04211C;border:1px solid rgba(0,224,184,.5);
  background:linear-gradient(180deg,var(--turquoise),#00B896);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3);
  transition:opacity .16s;white-space:nowrap;
}
.accepter-actif:hover:not(:disabled){opacity:.9}
.accepter-actif:disabled{opacity:.55;cursor:default}

/* --- L ENVOI D UN ACTIF (K-09) --------------------------------------------
   Le bouton vit au bout de la ligne, dans la liste des jetons. Il reste
   discret : envoyer est une action rare, et un appel a l action sur chaque
   ligne transformerait un inventaire en tableau de bord de trading, ce que
   Karl ne veut pas. */
.registre-envoyable{position:relative}
.registre-envoyable .echange{padding-right:86px}
.envoyer-actif{
  position:absolute;right:14px;transform:translateY(-46px);
  cursor:pointer;padding:5px 12px;border-radius:7px;font:inherit;font-size:.72rem;
  color:var(--argent);background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.12);
  transition:color .16s,border-color .16s;
}
.envoyer-actif:hover,.envoyer-actif:focus-visible{
  color:var(--encre);border-color:rgba(0,224,184,.4);
}
.champ-envoi{margin-top:18px}
.champ-envoi label{
  display:block;margin-bottom:6px;font-size:.76rem;color:var(--argent-gris);
}
.champ-envoi input{
  width:100%;padding:10px 12px;border-radius:9px;font:inherit;font-size:.86rem;
  color:var(--encre);background:rgba(0,0,0,.34);
  border:1px solid rgba(255,255,255,.10);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.9);
  font-family:"IBM Plex Mono",monospace;
}
.champ-envoi input:focus{outline:none;border-color:rgba(0,224,184,.45)}
.ligne-montant{display:flex;gap:8px}
.ligne-montant button{
  flex:none;cursor:pointer;padding:0 14px;border-radius:9px;font:inherit;
  font-size:.74rem;color:var(--argent);background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.12);
}
/* L etat de chaque champ se dit sous lui, au moment ou il est verifie, plutot
   qu au moment ou l on tente d envoyer : un refus au dernier geste est un
   refus qu on aurait pu eviter. */
.etat-envoi{
  margin:6px 0 0;min-height:1.1em;font-size:.75rem;line-height:1.45;
  color:var(--argent-gris);
}
.etat-envoi.bon{color:var(--turquoise)}
.etat-envoi.mauvais{color:#FF8080}
.etat-envoi b{color:var(--encre)}
.pied-envoi{display:flex;justify-content:flex-end;gap:10px;margin-top:20px;align-items:center}
.fenetre-fermer.secondaire{
  font-size:.8rem;line-height:1.4;padding:8px 14px;border-radius:9px;
}

/* COPIER SON ADRESSE D UN CLIC.

   Karl : « dans le portfolio, la partie ou il y a l adresse de portefeuille
   qui est cliquable, j aimerais mieux que cliquer dessus effectue un copier. »

   C est le bon geste : sur SA PROPRE adresse, on ne veut presque jamais aller
   voir un explorateur, on veut la coller ailleurs. Une adresse Algorand fait
   cinquante-huit caracteres et ne se retient pas ; celle qui est affichee est
   d ailleurs abregee, donc meme la selectionner a la souris ne donnerait pas
   la bonne chose. C est l adresse ENTIERE qui part au presse-papiers.

   L acces a l explorateur ne disparait pas pour autant : il passe dans une
   fleche voisine, minuscule mais distincte. Retirer en silence un chemin qui
   existait serait une perte deguisee en amelioration. */
.adresse-copiable{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  /* 44 points de haut, la cible tactile confortable, et une marge negative
     qui rend a la ligne la hauteur que ce rembourrage lui prend : mesure faite
     dans Chrome, 42 pixels sans cela. */
  padding:7px 10px;margin:-8px 0;min-height:44px;
  font:inherit;color:inherit;font-family:"IBM Plex Mono",monospace;
  background:none;border:1px solid transparent;border-radius:8px;
  transition:border-color .18s,background .18s;
}
.adresse-copiable:hover,.adresse-copiable:focus-visible{
  border-color:rgba(255,255,255,.14);background:rgba(255,255,255,.04);
}
.adresse-copiable svg{width:13px;height:13px;flex:none;opacity:.6}
/* Le texte doit etre un bloc en ligne, sinon la largeur qu on fige avant de
   dire « Copied » n a aucun effet et toute la ligne saute. Mesure faite :
   112 pixels avant, 92 pendant, sans cette regle. */
.adresse-copiable .texte-adresse{display:inline-block;text-align:center;white-space:nowrap}
.adresse-copiable:hover svg{opacity:1}
/* Le mot qui confirme prend la place du reste sans faire sauter la ligne :
   un texte qui change de largeur deplacerait tout ce qui suit. */
.adresse-copiable.copiee{border-color:rgba(0,224,184,.45);color:var(--turquoise)}
.vers-explorateur.fleche{
  display:inline-flex;align-items:center;justify-content:center;
  padding:7px 8px;margin:-8px 0;min-height:44px;min-width:30px;
  opacity:.55;transition:opacity .18s;
}
.vers-explorateur.fleche:hover,.vers-explorateur.fleche:focus-visible{opacity:1}
.vers-explorateur.fleche svg{width:12px;height:12px}

/* Un lien vers l explorateur ne doit pas deguiser le nom en bouton : il se
   signale au survol, et pas avant. */
.vers-explorateur{
  color:inherit;text-decoration:none;
  border-bottom:1px solid transparent;transition:border-color .18s;
}
.vers-explorateur:hover,.vers-explorateur:focus-visible{
  border-bottom-color:currentColor;
}

/* --- LE MENU DES FILTRES (K-11) -----------------------------------------
   Karl ne veut pas lire « Show adult » sur sa page d accueil. Les filtres se
   rangent donc derriere un bouton, qui signale qu un filtre est actif sans
   dire lequel : le nommer ramenerait en facade le mot qu on vient d en
   retirer. */
.filtres{position:relative}
.filtres-bouton{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  padding:7px 13px;border-radius:9px;font:inherit;font-size:.78rem;
  color:var(--argent);background:rgba(255,255,255,.03);
  border:1px solid rgba(255,255,255,.10);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 1px 2px rgba(0,0,0,.35);
  transition:border-color .18s,color .18s;
}
.filtres-bouton:hover,.filtres-bouton:focus-visible{
  color:var(--encre);border-color:rgba(0,224,184,.35);
}
.filtres-bouton.actif{color:var(--encre);border-color:rgba(0,224,184,.45)}
.filtres-bouton svg{
  width:14px;height:14px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.5;stroke-linecap:round;
}
/* La pastille dit qu un reglage a ete touche, rien de plus. */
.filtres-pastille{
  width:6px;height:6px;border-radius:50%;background:var(--turquoise);
  box-shadow:0 0 6px rgba(0,224,184,.8);
}
.filtres-panneau{
  position:absolute;top:calc(100% + 8px);right:0;z-index:40;min-width:224px;
  padding:12px;border-radius:12px;
  background:linear-gradient(180deg,rgba(12,26,24,.98),rgba(8,18,17,.98));
  border:1px solid rgba(255,255,255,.10);
  box-shadow:0 18px 40px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.06);
}
.filtre + .filtre{margin-top:13px;padding-top:13px;border-top:1px solid rgba(255,255,255,.07)}
.filtre-nom{
  margin:0 0 7px;font-size:.74rem;color:var(--argent-gris);letter-spacing:.02em;
}
.filtre-nom b{color:var(--laiton);font-weight:500}
/* TROIS CRANS, tous marques. Karl avait trouve lui-meme, sur un autre de ses
   sites, qu un reglage dont seules les positions du milieu se voient laisse
   croire qu on est au bout alors qu on ne l est pas. */
.crans{
  display:grid;grid-template-columns:repeat(3,1fr);gap:2px;padding:2px;
  border-radius:8px;background:rgba(0,0,0,.30);
  border:1px solid rgba(255,255,255,.07);
}
.cran{position:relative;cursor:pointer}
.cran input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.cran span{
  display:block;padding:5px 4px;text-align:center;border-radius:6px;
  font-size:.7rem;letter-spacing:.02em;color:var(--argent-gris);
  transition:background .16s,color .16s;
}
.cran input:checked + span{
  color:#04211C;font-weight:600;
  background:linear-gradient(180deg,var(--turquoise),#00B896);
}
.cran input:focus-visible + span{outline:2px solid var(--turquoise);outline-offset:1px}
.cran:hover input:not(:checked) + span{color:var(--encre)}
/* Une combinaison de filtres peut ne rien laisser passer. Le dire, plutot que
   de laisser une grille vide dont on ne sait pas si elle est vide ou cassee. */
.filtres-vide{
  margin:44px 0;text-align:center;color:var(--argent-gris);font-size:.85rem;
}
/* Les cases des protocoles (K-51) : une par protocole trouve dans la donnee. */
.cases{display:flex;flex-direction:column;gap:4px}
.case{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:.78rem;color:var(--argent-gris)}
.case input{accent-color:var(--turquoise);width:14px;height:14px;margin:0;cursor:pointer}
.case input:checked + span{color:var(--encre)}
.case b{color:var(--laiton);font-weight:500}
/* L annonce de ce que les filtres masquent : visible, sous les reglages. */
.filtres-annonce{margin:6px 0 14px;font-size:.82rem;color:var(--argent-gris)}
.filtres-annonce b{color:var(--encre);font-weight:600}
.filtres-annonce .pourquoi{color:var(--brume);cursor:help;border-bottom:1px dotted currentColor}
button.lien{background:none;border:0;padding:0;font:inherit;color:var(--laiton);cursor:pointer;text-decoration:underline}
button.lien:hover{color:var(--laiton-vif)}

/* --- LE BOUTON DE MISE EN VENTE (K-12) -----------------------------------
   Karl : « un gros bouton evident, peut-etre d une belle couleur ». C est le
   SEUL aplat de couleur pleine de toute la barre : au milieu du logo, des
   liens, de la recherche et des trois menus, un second le rendrait invisible.
   Il garde la matiere du site, degrade et arete de lumiere, plutot qu un aplat
   qui jurerait avec tout le reste. */
.lister{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;flex:none;
  padding:9px 16px;border-radius:9px;font:inherit;font-size:.8rem;font-weight:600;
  color:#04211C;border:1px solid rgba(0,224,184,.5);
  background:linear-gradient(180deg,var(--turquoise),#00B896);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 3px 10px -2px rgba(0,224,184,.45);
  transition:transform .14s,box-shadow .14s;
}
.lister:hover,.lister:focus-visible{
  transform:translateY(-1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 6px 16px -3px rgba(0,224,184,.6);
}
.lister:active{transform:translateY(0)}
.lister svg{
  width:13px;height:13px;flex:none;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round;
}
/* La barre s enroule sous 900 pixels : le bouton doit rester sur la premiere
   ligne avec le logo, pas descendre avec la navigation. Un appel a l action
   qu il faut aller chercher plus bas cesse d en etre un. */
@media (max-width:900px){
  .lister{order:-1;margin-left:auto}
  .lister span{display:none}
}

.fenetre-lister{position:fixed;inset:0;z-index:210;display:flex;
  align-items:center;justify-content:center;padding:24px}
.fenetre-lister[hidden]{display:none}
/* Deux surfaces cliquables cote a cote, chacune avec son icone et sa courte
   explication dessous, comme Karl l a decrit. Elles sont grisees tant que le
   marche n est pas ouvert, mais restent lisibles : elles servent a montrer ce
   qui vient. */
.choix-lister{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:20px}
@media (max-width:560px){.choix-lister{grid-template-columns:1fr}}
.choix{
  display:flex;flex-direction:column;gap:8px;padding:20px 18px;border-radius:12px;
  background:rgba(255,255,255,.025);border:1px solid rgba(255,255,255,.09);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06);
}
.choix[aria-disabled="true"]{opacity:.62}
.choix svg{
  width:28px;height:28px;fill:none;stroke:var(--turquoise);stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;
}
.choix b{font-size:.92rem;color:var(--encre);font-weight:600}
.choix span{font-size:.78rem;color:var(--argent-gris);line-height:1.5}
.avis-lister{
  margin:18px 0 0;padding:12px 14px;border-radius:9px;font-size:.79rem;
  line-height:1.55;color:var(--doux);
  background:rgba(255,224,120,.06);border:1px solid rgba(255,224,120,.18);
}
.avis-lister b{color:var(--encre)}

/* --- LE SOMMAIRE DE LA PAGE READ ME --------------------------------------
   Onze sections sur une seule page se parcourent mal sans point d entree. Le
   sommaire reste en haut plutot que de coller au defilement : Karl a pose que
   le defilement suit le geste, et une barre qui poursuit le lecteur sur une
   page de lecture le derange plus qu elle ne l aide. */
.sommaire{
  display:flex;flex-wrap:wrap;gap:8px;margin:0 0 28px;
}
.sommaire a{
  padding:6px 12px;border-radius:8px;font-size:.76rem;text-decoration:none;
  color:var(--argent);background:rgba(255,255,255,.03);
  border:1px solid rgba(255,255,255,.09);
  transition:color .16s,border-color .16s;
}
.sommaire a:hover,.sommaire a:focus-visible{
  color:var(--encre);border-color:rgba(0,224,184,.35);
}

/* --- LES ONGLETS DU PORTFOLIO (K-08) -------------------------------------
   Karl : « je voulais des onglets qui te permettent de naviguer ». Ils ont la
   meme matiere que le reste du site, creuses au repos et allumes quand ils
   portent la vue courante. */
.onglets-profil{
  display:flex;gap:4px;flex-wrap:wrap;margin:26px 0 0;padding:4px;
  border-radius:11px;background:rgba(0,0,0,.28);
  border:1px solid rgba(255,255,255,.07);
}
.onglets-profil[hidden]{display:none}
.onglets-profil button{
  display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  padding:8px 15px;border:0;border-radius:8px;font:inherit;font-size:.79rem;
  color:var(--argent-gris);background:none;
  transition:color .16s,background .16s;
}
.onglets-profil button:hover{color:var(--encre)}
.onglets-profil button[aria-selected="true"]{
  color:var(--encre);background:rgba(255,255,255,.055);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 1px 2px rgba(0,0,0,.35);
}
/* La pastille dit combien il y a a voir, et ne parait que quand il y a
   quelque chose : un zero entre parentheses est une facon de dire qu on n a
   rien, en prenant la place de quelque chose. */
.pastille-onglet{
  font-style:normal;font-size:.66rem;padding:1px 6px;border-radius:99px;
  font-family:"IBM Plex Mono",monospace;
  color:#04211C;background:var(--turquoise);
}
.pastille-onglet[hidden]{display:none}
.vue-profil[hidden]{display:none}

/* Le logo d un actif dans les listes, avec son repli en lettres. */
.logo-actif{width:30px;height:30px;flex:none;border-radius:7px;object-fit:cover}
.logo-actif.rond{border-radius:50%}
.logo-actif.pastille-lettres{
  display:flex;align-items:center;justify-content:center;
  font-family:"IBM Plex Mono",monospace;font-size:.7rem;font-weight:600;
  color:#04211C;background:linear-gradient(180deg,var(--laiton-vif),var(--laiton));
}
/* La cible d une ancre ne doit pas se glisser sous la barre du haut. */
.coffret[id]{scroll-margin-top:88px}

/* --- LE PORTFOLIO EN MOSAIQUE (K-05) -------------------------------------
   Cinq par rangee, comme Karl l a demande. La disposition sur telephone est
   volontairement conservatrice : il a dit « ce que tu veux pour le telephone,
   on va y revenir plus tard », donc deux colonnes a 375 points, ce qui garde
   les vignettes lisibles, en attendant qu il tranche devant le resultat. */
.roulette-avoirs{margin:0 0 18px}
.mosaique-avoirs{
  display:grid;grid-template-columns:repeat(5,1fr);gap:16px;
}
@media (max-width:1000px){.mosaique-avoirs{grid-template-columns:repeat(3,1fr)}}
@media (max-width:620px){.mosaique-avoirs{grid-template-columns:repeat(2,1fr)}}

.carte-avoir{
  display:flex;flex-direction:column;gap:0;cursor:pointer;text-align:left;
  padding:0;border-radius:12px;overflow:hidden;font:inherit;
  background:rgba(255,255,255,.025);
  border:1px solid rgba(255,255,255,.09);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 2px 6px rgba(0,0,0,.35);
  transition:transform .16s,border-color .16s,box-shadow .16s;
}
.carte-avoir:hover,.carte-avoir:focus-visible{
  transform:translateY(-2px);border-color:rgba(0,224,184,.38);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 8px 20px rgba(0,0,0,.45);
}
.carte-image{
  display:block;aspect-ratio:1;overflow:hidden;
  background:linear-gradient(160deg,rgba(0,224,184,.07),rgba(0,0,0,.32));
}
.carte-image img{width:100%;height:100%;object-fit:cover;display:block}
/* Quand aucune image ne repond, les initiales de la collection tiennent lieu
   de repere : un cadre vide ne dit rien, deux lettres disent laquelle. */
.carte-image.sans-image{
  display:flex;align-items:center;justify-content:center;
  font-family:"IBM Plex Mono",monospace;font-size:1.6rem;font-weight:600;
  color:var(--turquoise);letter-spacing:.04em;
}
.carte-nom{
  display:block;padding:10px 11px 2px;font-size:.8rem;color:var(--encre);
  /* Le nom tient sur deux lignes au plus : au-dela, les cartes d une meme
     rangee cessent d avoir la meme hauteur et la grille se deforme. */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.3;
}
.carte-compte{
  display:block;padding:3px 11px 11px;font-size:.72rem;color:var(--laiton);
  font-family:"IBM Plex Mono",monospace;
}

/* --- LA FENETRE DES PIECES DETENUES --------------------------------------- */
body.fenetre-ouverte{overflow:hidden}
.fenetre-avoirs{position:fixed;inset:0;z-index:200;display:flex;
  align-items:center;justify-content:center;padding:24px}
.fenetre-avoirs[hidden]{display:none}
.fenetre-fond{position:absolute;inset:0;background:rgba(2,10,9,.82);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.fenetre-boite{
  position:relative;width:min(760px,100%);max-height:82vh;overflow:auto;
  padding:20px;border-radius:16px;
  background:linear-gradient(180deg,rgba(12,26,24,.99),rgba(8,18,17,.99));
  border:1px solid rgba(255,255,255,.11);
  box-shadow:0 28px 64px rgba(0,0,0,.6);
}
.fenetre-tete{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.fenetre-tete h3{margin:0;font-size:1.05rem;color:var(--encre)}
.fenetre-tete p{margin:3px 0 0;font-size:.76rem;color:var(--argent-gris)}
.fenetre-fermer{
  cursor:pointer;font-size:1.4rem;line-height:1;padding:2px 8px;border-radius:8px;
  color:var(--argent-gris);background:none;border:1px solid rgba(255,255,255,.10);
}
.fenetre-fermer:hover,.fenetre-fermer:focus-visible{color:var(--encre)}
.fenetre-grille{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));
  gap:11px;margin-top:18px;
}
.fenetre-piece{display:block;border-radius:9px;overflow:hidden;text-decoration:none;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
.fenetre-piece:hover{border-color:rgba(0,224,184,.4)}
.fenetre-piece img{width:100%;aspect-ratio:1;object-fit:cover;display:block}
.fenetre-piece span{
  display:block;padding:5px 7px;font-size:.64rem;color:var(--argent-gris);
  font-family:"IBM Plex Mono",monospace;
}
/* LE BOUTON D ENVOI D UNE PIECE, dans la fenetre des pieces detenues.

   Il se pose SUR la vignette plutot qu a cote : la grille tient des vignettes
   carrees serrees, et une colonne de boutons la disloquerait. Au repos il
   reste discret, et il se revele au survol comme au foyer clavier, pour que
   la navigation sans souris y ait acces aussi. Sur un ecran tactile, ou le
   survol n existe pas, il reste visible en permanence. */
.fenetre-piece-boite{position:relative;display:block}
.envoyer-piece{
  position:absolute;right:6px;bottom:6px;cursor:pointer;
  padding:4px 9px;border-radius:6px;font:inherit;font-size:.64rem;
  color:var(--encre);background:rgba(9,13,19,.86);
  border:1px solid rgba(255,255,255,.16);
  opacity:0;transition:opacity .16s,border-color .16s;
}
.fenetre-piece-boite:hover .envoyer-piece,
.envoyer-piece:focus-visible{opacity:1;border-color:rgba(0,224,184,.5)}
@media (hover:none){.envoyer-piece{opacity:1}}

/* LA CASE QUI ARRETE LE CLIC MACHINAL, sur l envoi d une piece.
   Un jeton se rachete, une piece de 2021 ne se rachete pas. La cible fait
   44 points de haut, la taille a laquelle Karl verifie ses pages. */
.jurer{
  display:flex;align-items:center;gap:10px;margin-top:16px;
  min-height:44px;font-size:.8rem;color:var(--argent);cursor:pointer;
}
.jurer input{width:18px;height:18px;accent-color:var(--turquoise);cursor:pointer}

/* L apercu de la piece qu on envoie : on regarde ce qui part. */
.apercu-envoi{margin-top:16px;text-align:center}
.apercu-envoi img{
  width:132px;height:132px;object-fit:cover;border-radius:10px;
  border:1px solid rgba(255,255,255,.10);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 10px 24px -12px rgba(0,0,0,.8);
}

.fenetre-pied{margin:18px 0 0;text-align:center;font-size:.8rem}
.fenetre-pied a{color:var(--turquoise);text-decoration:none}
.fenetre-pied a:hover{text-decoration:underline}
/* L icone qui dit de quel tiroir il s agit. Deux tirettes voisines montrant
   toutes deux ALGO et XDB doivent se distinguer avant d etre lues : celle des
   soldes porte un portefeuille, celle des prix le symbole de la monnaie. */
.menu .icone-tirette{
  width:14px;height:14px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;
  color:var(--argent-gris);
}
.menu .tirette:hover .icone-tirette{color:var(--turquoise)}

/* Le symbole de la monnaie dans la tirette, a la place du mot. */
.menu .tirette .somme .logo-jeton{
  width:11px;height:11px;vertical-align:-1px;margin-left:3px;
}

/* --- la bannière du portefeuille ----------------------------------------
   Karl voulait « une bannière, mais une bannière fonctionnelle » : l'avatar du
   NFD, le nom .algo, et dessous le nombre de pièces détenues. La bannière du
   NFD sert de fond quand le visiteur en a une, comme sur les pages de profil
   des grandes places de marché.
   ---------------------------------------------------------------------- */
.banniere-profil{position:relative;overflow:hidden;border-bottom:1px solid var(--arete-basse)}
.banniere-profil .fond{
  position:absolute;inset:0;background-size:cover;background-position:center;
  /* Assombrie et désaturée : c'est un fond, pas une image à regarder, et le
     texte doit rester lisible quelle que soit la bannière du visiteur. */
  filter:brightness(.34) saturate(.8);
}
.banniere-profil::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg, rgba(6,10,15,.55) 0%, rgba(9,13,19,.86) 100%);
}
.banniere-profil > .enveloppe{
  position:relative;z-index:2;
  display:flex;align-items:flex-end;justify-content:space-between;gap:20px;
  padding-top:30px;padding-bottom:26px;flex-wrap:wrap;
}
.banniere-profil .qui{display:flex;align-items:center;gap:16px;min-width:0}
.banniere-profil .frimousse-grande{
  width:72px;height:72px;border-radius:14px;object-fit:cover;flex:none;
  background:var(--enfonce);
  border:1px solid var(--arete-basse);
  box-shadow:inset 0 1px 0 var(--arete-vive), 0 6px 18px -6px rgba(0,0,0,.9),
             0 0 24px -8px rgba(0,224,184,.5);
}
.banniere-profil h1{
  font-family:"Cinzel",Georgia,serif;font-weight:600;
  font-size:clamp(1.35rem,3.4vw,2rem);letter-spacing:.04em;
  margin:0;line-height:1.15;overflow-wrap:anywhere;color:var(--encre);
}
.banniere-profil .compte{
  font-family:"IBM Plex Mono",monospace;font-size:.79rem;
  color:var(--doux);margin:6px 0 0;
}
.banniere-profil .compte b{color:var(--laiton);font-weight:500;text-shadow:0 0 10px var(--lueur)}
@media (max-width:640px){
  .banniere-profil > .enveloppe{align-items:flex-start;flex-direction:column}
  .banniere-profil .frimousse-grande{width:58px;height:58px}
}

/* --- la voûte, sur l'accueil seulement ---------------------------------- */
.voute{
  position:relative;overflow:hidden;
  min-height:clamp(178px,25vh,224px);
  display:flex;align-items:center;justify-content:center;
  background:
    radial-gradient(ellipse 62% 78% at 50% 46%, rgba(0,224,184,.11), transparent 70%),
    linear-gradient(180deg, #05080C 0%, #070B11 58%, var(--fond) 100%);
  border-bottom:1px solid var(--arete-basse);}
/* Le ciel est peint dans un canevas : quelques kilo-octets de code plutôt
   qu'un fichier vidéo, et il réagit au curseur, ce qu'une vidéo ne peut pas. */
.voute canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.voute .dedans{position:relative;text-align:center;padding:22px 24px}

.voute .rose{display:block;margin:0 auto;width:clamp(76px,9vw,104px);line-height:0}
.voute .rose img{
  width:100%;height:auto;display:block;
  filter:drop-shadow(0 0 26px rgba(0,224,184,.36)) drop-shadow(0 3px 6px rgba(0,0,0,.9));
  will-change:transform;   /* aucune transition : la rotation colle au geste */
  /* LE CENTRE DE ROTATION, TROUVÉ PAR LA SYMÉTRIE.
     Karl a vu la rose osciller, et il a eu raison DEUX FOIS : la première
     quand il l'a signalé, la seconde quand il a insisté après que j'eus conclu
     à tort que le centre par défaut était le bon.

     Mes deux premières mesures étaient mauvaises parce qu'elles mesuraient la
     BOÎTE et non la FIGURE : la boîte englobante et les axes les plus larges
     sont tous deux faussés par les pointes, qui n'ont pas la même longueur
     selon la direction.

     LA BONNE MESURE : le centre d'une figure à symétrie de rotation est le
     point autour duquel l'image tournée se superpose le mieux à elle-même. En
     balayant les centres candidats et en comparant chaque fois l'image à sa
     rotation de 90 degrés, l'écart tombe de 21,72 au centre géométrique à 8,63
     au centre réel, soit deux fois et demie mieux.

     Le centre tombe à 49,67 % / 47,83 %, c'est-à-dire vingt-sept pixels plus
     haut que le milieu de l'image. */
  transform-origin:49.67% 47.83%;}
.voute .rose:focus-visible{outline:2px solid var(--laiton-vif);outline-offset:8px;border-radius:50%}

.voute .nom{
  font-family:"Cinzel",Georgia,serif;font-weight:600;
  font-size:clamp(1.5rem,3.6vw,2.3rem);letter-spacing:.15em;
  margin:13px 0 0;line-height:1;
  background:linear-gradient(180deg,#FFFFFF 0%,var(--argent) 40%,var(--argent-gris) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 16px rgba(0,224,184,.28)) drop-shadow(0 2px 2px rgba(0,0,0,.9));}
.voute .devise{
  font-family:"IBM Plex Mono",monospace;
  margin:9px 0 0;font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--argent-gris);}

@media (max-width:900px){
  .bande .enveloppe{height:auto;padding-top:8px;padding-bottom:8px;flex-wrap:wrap;gap:8px}
  .bande nav{order:3;width:100%;justify-content:center;flex-wrap:wrap}
  .bande .chercher{order:2;flex:1 1 160px}
  .voute{min-height:158px}
}
