/* ==========================================================================
   La page d'un objet
   --------------------------------------------------------------------------
   Structure : ouverture → diptyque → identité → chaîne → transmission.

   Le diptyque est le cœur du dispositif. Sur grand écran, le média occupe la
   moitié gauche et RESTE à l'écran pendant que le texte des moments défile à
   droite ; le média change en fondu à chaque nouveau moment. L'objet est donc
   visible en permanence pendant qu'on lit son histoire.

   Sur mobile, le diptyque est impossible : on bascule sur des scènes plein
   écran, un moment à la fois, média en fond.
   ========================================================================== */

.object-page {
  --object-glow: #E4B678;
  position: relative;
}

/* --------------------------------------------------------------------------
   1. L'ouverture
   -------------------------------------------------------------------------- */

.overture {
  position: relative;
  min-height: 100dvh;
  display: grid;
  align-items: end;
  overflow: hidden;
  background: var(--c-void);
  isolation: isolate;
}

.overture__media {
  position: absolute; inset: 0;
  z-index: 0;
}
.overture__media img,
.overture__media video {
  width: 100%; height: 100%;
  object-fit: cover;
  will-change: transform;
  /* Le média entre par un très lent zoom arrière : la sensation de couvercle
     qu'on soulève, sans animation d'ouverture littérale. */
  animation: overture-in 2400ms var(--e-scene) both;
}
@keyframes overture-in {
  from { transform: scale(1.10); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .overture__media img, .overture__media video { animation: none; }
}

/* Voile de lisibilité + teinte de l'objet. */
.overture::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(
    to top,
    rgba(6, 5, 10, 0.96) 0%,
    rgba(6, 5, 10, 0.72) 26%,
    rgba(6, 5, 10, 0.22) 56%,
    rgba(6, 5, 10, 0.46) 100%);
}
.overture::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background: radial-gradient(90% 60% at 18% 96%, var(--object-glow) 0%, transparent 62%);
  opacity: 0.20;
  mix-blend-mode: soft-light;
}

.overture__inner {
  position: relative; z-index: 2;
  width: var(--w-wide);
  margin-inline: auto;
  padding-block: var(--s-8) var(--s-9);
  animation: rise-in 1200ms var(--e-scene) 300ms both;
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .overture__inner { animation: none; } }

.overture__intent {
  display: inline-flex; align-items: center; gap: var(--s-2);
  margin-bottom: var(--s-5);
  padding: 6px var(--s-3) 6px var(--s-2);
  border-radius: var(--r-pill);
  background: rgba(10, 9, 16, 0.55);
  border: 1px solid var(--c-line-accent);
  backdrop-filter: blur(10px);
  color: var(--c-accent);
  font-size: var(--t-tiny); font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
}

.overture__title {
  font-family: var(--f-display);
  font-variation-settings: var(--vf-display);
  font-weight: 400;
  font-size: var(--t-mega);
  line-height: 0.94;
  letter-spacing: var(--ls-mega);
  color: #FCF9F3;
  max-width: 14ch;
  text-shadow: 0 4px 60px rgba(0, 0, 0, 0.6);
}

@media (max-width: 699px) {
  /* Un peu moins que l'écran entier : laisser dépasser le début de la suite
     dit « il y a autre chose en dessous » mieux qu'un chevron. */
  .overture { min-height: 88dvh; }
  /* 14 caractères sur 390 px découpent le titre en cinq lignes. */
  .overture__title { max-width: 20ch; }
  .overture__inner { padding-block: var(--s-6) var(--s-7); }
  .overture__facts { gap: var(--s-2) var(--s-4); font-size: var(--t-tiny); }
}

.overture__line {
  margin-top: var(--s-5);
  font-family: var(--f-read);
  font-size: clamp(1.1rem, 1rem + 0.6vw, 1.5rem);
  line-height: 1.45;
  color: rgba(250, 246, 238, 0.86);
  max-width: 32rem;
}

.overture__facts {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-3) var(--s-5);
  margin-top: var(--s-6);
  font-size: var(--t-small);
  color: rgba(244, 241, 234, 0.7);
}
.overture__facts .chip {
  background: rgba(10, 9, 16, 0.5);
  border-color: rgba(244, 241, 234, 0.2);
  color: rgba(244, 241, 234, 0.9);
  backdrop-filter: blur(8px);
}

.overture__cue {
  position: absolute; z-index: 3;
  left: 50%; bottom: var(--s-5); translate: -50% 0;
  display: grid; place-items: center; gap: var(--s-2);
  color: rgba(244, 241, 234, 0.5);
  font-size: var(--t-tiny); letter-spacing: 0.14em; text-transform: uppercase;
}
.overture__cue span { animation: bob 2.6s var(--e-scene) infinite; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .overture__cue span { animation: none; } }

/* --------------------------------------------------------------------------
   Barre d'actions
   -------------------------------------------------------------------------- */

.object-bar {
  /* Adossée à la barre du haut, pas à 0 : sinon elle glisse derrière elle et
     disparaît dès le premier défilement. */
  position: sticky; top: var(--topbar-h); z-index: 45;
  background: color-mix(in oklab, var(--c-bg) 92%, transparent);
  backdrop-filter: blur(18px) saturate(1.2);
  border-bottom: 1px solid var(--c-line);
}
.object-bar__inner {
  width: var(--w-wide); margin-inline: auto;
  display: flex; align-items: center; gap: var(--s-2);
  padding-block: var(--s-3);
  overflow-x: auto; scrollbar-width: none;
}
.object-bar__inner::-webkit-scrollbar { display: none; }

/* Sur petit écran, onze boutons dans une barre qui défile horizontalement
   sans le dire est une impasse : on ne garde que l'action principale et un
   bouton « autres actions » qui ouvre la liste complète. */
.object-bar__extra { display: none; }
.object-bar__more { display: inline-flex; }
@media (min-width: 900px) {
  .object-bar__extra { display: inline-flex; }
  .object-bar__more { display: none; }
}

.action-list { display: flex; flex-direction: column; gap: var(--s-1); }
.action-list button,
.action-list a {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%; min-height: var(--touch);
  padding: var(--s-3) var(--s-4);
  border: 0; background: none; cursor: pointer;
  border-radius: var(--r-md);
  font-size: var(--t-body); font-weight: 500;
  color: var(--c-ink); text-decoration: none; text-align: left;
}
.action-list button:hover,
.action-list a:hover { background: var(--c-raised); }
.action-list svg { color: var(--c-accent); flex: none; }
.action-list small { display: block; font-size: var(--t-tiny); color: var(--c-ink-faint); font-weight: 400; }
.object-bar__title {
  display: none;
  flex: 0 1 auto;
  font-family: var(--f-display); font-variation-settings: var(--vf-label);
  font-size: var(--t-small); white-space: nowrap;
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transition: opacity var(--d-mid) var(--e-ui);
}
/* Le titre rappelé dans la barre n'a de sens que s'il y a la place de l'écrire
   en entier ; sur petit écran il volerait la place des actions. */
@media (min-width: 1100px) { .object-bar__title { display: block; } }
.object-bar.is-scrolled .object-bar__title { opacity: 1; }

/* --------------------------------------------------------------------------
   2. Le diptyque
   -------------------------------------------------------------------------- */

.diptych {
  position: relative;
  width: var(--w-wide);
  margin-inline: auto;
  padding-block: var(--s-8) var(--s-9);
}

@media (min-width: 1000px) {
  .diptych {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(3rem, 5vw, 6rem);
    align-items: start;
  }
}

/* --- le panneau média, collant --- */

.diptych__media {
  display: none;
}
@media (min-width: 1000px) {
  .diptych__media {
    display: block;
    position: sticky;
    /* Sous la barre du haut ET sous la barre d'actions. */
    top: calc(var(--topbar-h) + 72px);
    height: calc(100dvh - var(--topbar-h) - 104px);
  }
}

.stage {
  position: relative;
  width: 100%; height: 100%;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--c-surface);
  box-shadow: var(--sh-3), var(--sh-edge), var(--glow-soft);
}
.stage__frame {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity var(--d-slow) var(--e-scene), transform var(--d-scene) var(--e-scene);
  transform: scale(1.04);
}
.stage__frame.is-live { opacity: 1; transform: scale(1); }
.stage__frame img,
.stage__frame video { width: 100%; height: 100%; object-fit: cover; }

.stage__caption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: var(--s-6) var(--s-5) var(--s-4);
  background: linear-gradient(to top, rgba(6, 5, 10, 0.9), transparent);
  font-size: var(--t-tiny);
  color: rgba(244, 241, 234, 0.78);
}

/* Pastilles de progression : où l'on en est dans l'histoire. */
.stage__beads {
  position: absolute; top: var(--s-4); right: var(--s-4); z-index: 2;
  display: flex; flex-direction: column; gap: 6px;
}
.stage__bead {
  width: 4px; height: 16px; border-radius: 2px;
  background: rgba(244, 241, 234, 0.26);
  border: 0; padding: 0; cursor: pointer;
  transition: background-color var(--d-mid) var(--e-ui), height var(--d-mid) var(--e-ui);
}
.stage__bead.is-live { background: var(--c-accent); height: 26px; }

/* --- la colonne de texte --- */

.moments { display: grid; }

.moment-block {
  padding-block: clamp(3rem, 12vh, 8rem);
  min-height: 60vh;
  display: flex; flex-direction: column; justify-content: center;
}
.moment-block:first-child { padding-top: 0; }

.moment-block__when {
  display: flex; align-items: baseline; gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.moment-block__year {
  font-family: var(--f-display);
  font-variation-settings: var(--vf-title);
  font-size: 1.5rem;
  color: var(--c-accent);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.moment-block__kind {
  font-size: var(--t-tiny); text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--c-ink-faint);
}

.moment-block__prompt {
  font-size: var(--t-small); color: var(--c-ink-faint);
  margin-bottom: var(--s-3); font-style: italic;
}
.moment-block__title {
  font-family: var(--f-display);
  font-variation-settings: var(--vf-title);
  font-weight: 400;
  font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.4rem);
  line-height: 1.12;
  letter-spacing: var(--ls-title);
  margin-bottom: var(--s-4);
  text-wrap: balance;
}
.moment-block__text {
  font-family: var(--f-read);
  font-size: var(--t-read);
  line-height: var(--lh-read);
  color: color-mix(in oklab, var(--c-ink) 90%, transparent);
  max-width: 34rem;
}
.moment-block__text p + p { margin-top: 1.15em; }

.moment-block--letter .moment-block__text {
  padding-left: var(--s-5);
  border-left: 2px solid var(--c-accent);
  font-style: italic;
}
.moment-block--passage .moment-block__text {
  color: var(--c-ink-soft);
  font-style: italic;
}

.moment-block__foot {
  display: flex; align-items: center; gap: var(--s-3) var(--s-5);
  flex-wrap: wrap;
  margin-top: var(--s-5);
  font-size: var(--t-tiny);
  color: var(--c-ink-faint);
}

/* Le média du moment, visible en colonne (mobile) ou en vignette (desktop) */
.moment-block__media {
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-top: var(--s-5);
  max-width: 34rem;
}
.moment-block__media img,
.moment-block__media video {
  width: 100%; border-radius: var(--r-md);
  border: 1px solid var(--c-line);
}
@media (min-width: 1000px) {
  /* Sur grand écran, le média du moment est déjà sur la scène collante :
     l'afficher une seconde fois en colonne ferait doublon. */
  .moment-block__media { display: none; }
  .moment-block__media--extra { display: grid; }
  /* Le fond de scène n'existe qu'en version mobile. Sans cette règle il
     retombe en flux et republie l'image en grand au milieu du texte. */
  .scene__bg { display: none; }
  .scene { display: block; }
}

/* Mot scellé */
.sealed-note {
  display: grid; gap: var(--s-3);
  padding: var(--s-5);
  border: 1px dashed var(--c-line-accent);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--c-accent) 6%, transparent);
  max-width: 34rem;
}
.sealed-note__head {
  display: flex; align-items: center; gap: var(--s-3);
  color: var(--c-accent); font-weight: 600; font-size: var(--t-small);
}

/* --------------------------------------------------------------------------
   Mobile : le média au-dessus, le texte en dessous
   --------------------------------------------------------------------------
   Première version : chaque moment occupait tout l'écran, texte posé sur la
   photo. Élégant sur une maquette, intenable en vrai — ces moments font 100 à
   250 mots. Le texte devenait dur à lire sur une image, et il fallait des
   hauteurs minimales énormes : 800 à 1000 px par moment sur un écran de 820,
   soit près de 12 écrans pour six moments, avec de grands vides.

   Le média devient donc un bloc pleine largeur, et le texte se lit en dessous
   sur le fond de la page. C'est le motif de lecture mobile classique, et c'est
   le bon. La mise en scène reste là où elle se justifie : l'ouverture.
   -------------------------------------------------------------------------- */

@media (max-width: 999px) {
  .diptych { padding-block: var(--s-5) var(--s-8); }

  .moment-block {
    min-height: 0;
    padding-block: 0;
    display: block;
  }
  /* Un filet entre les moments : sans le plein écran, il faut un repère qui
     dise « nouveau moment ». */
  .moment-block + .moment-block { margin-top: var(--s-7); }
  .moment-block + .moment-block::before {
    content: "";
    display: block;
    width: 3rem; height: 1px;
    background: var(--c-line-accent);
    margin-bottom: var(--s-6);
  }

  .scene { display: block; }

  /* Le média sort de la gouttière du conteneur pour toucher les bords. */
  .scene__bg {
    display: block;
    margin-inline: calc(50% - 50vw);
    margin-bottom: var(--s-5);
    background: var(--c-surface);
    overflow: hidden;
  }
  .scene__bg img,
  .scene__bg video {
    display: block;
    width: 100%;
    max-height: 62dvh;
    object-fit: cover;
    aspect-ratio: 4 / 3;
  }

  .moment-block__title { font-size: 1.5rem; }
  .moment-block__text { font-size: 1.05rem; }

  /* Le lecteur audio d'un moment reste en ligne, sous le texte. */
  .moment-block__media { margin-top: var(--s-5); }
}

/* --------------------------------------------------------------------------
   3. La galerie de médias
   -------------------------------------------------------------------------- */

.gallery-strip {
  width: var(--w-wide); margin-inline: auto;
  padding-block: var(--s-7);
  border-top: 1px solid var(--c-line);
}
.gallery-strip__rail {
  display: flex; gap: var(--s-3);
  overflow-x: auto; padding-bottom: var(--s-3);
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}
.gallery-strip__item {
  flex: none;
  width: clamp(200px, 34vw, 340px);
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  scroll-snap-align: start;
  cursor: zoom-in;
  position: relative;
  transition: border-color var(--d-fast) var(--e-ui), transform var(--d-mid) var(--e-scene);
}
.gallery-strip__item:hover { border-color: var(--c-line-accent); transform: translateY(-3px); }
.gallery-strip__item img,
.gallery-strip__item video { width: 100%; height: 100%; object-fit: cover; }
.gallery-strip__play {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: rgba(6, 5, 10, 0.35);
  color: #fff;
  pointer-events: none;
}
.gallery-strip__badge {
  position: absolute; top: var(--s-2); left: var(--s-2);
  padding: 2px 8px; border-radius: var(--r-pill);
  background: rgba(6, 5, 10, 0.7);
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--c-accent);
}

.gallery-strip__item--audio {
  display: grid; align-content: center;
  aspect-ratio: auto;
  height: auto;
  min-height: 92px;
  padding: var(--s-4);
  cursor: default;
}

/* --------------------------------------------------------------------------
   Lecteur audio
   -------------------------------------------------------------------------- */

.audio {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  transition: border-color var(--d-fast) var(--e-ui);
}
.audio.is-playing { border-color: var(--c-line-accent); }
.audio--compact { padding: var(--s-2) var(--s-3); gap: var(--s-2); }

.audio__button {
  width: 40px; height: 40px; flex: none;
  border-radius: 50%; border: 0; cursor: pointer;
  display: grid; place-items: center;
  background: var(--c-accent); color: var(--c-accent-ink);
  transition: transform var(--d-fast) var(--e-ui), background-color var(--d-fast) var(--e-ui);
}
.audio--compact .audio__button { width: 32px; height: 32px; }
.audio__button:hover { background: var(--c-accent-hi); transform: scale(1.05); }

.audio__body { min-width: 0; display: grid; gap: 6px; }
.audio__label {
  font-size: var(--t-tiny); color: var(--c-ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.audio__track {
  height: 4px; border-radius: 2px;
  background: color-mix(in oklab, var(--c-ink) 14%, transparent);
  cursor: pointer; overflow: hidden;
}
.audio__track span {
  display: block; height: 100%;
  background: var(--c-accent);
  transform-origin: left; transform: scaleX(0);
  transition: transform 120ms linear;
}
.audio__time {
  font-size: var(--t-tiny); color: var(--c-ink-faint);
  font-variant-numeric: tabular-nums;
}

/* Sur la scène collante, un son n'a rien à montrer : on garde la photo de
   couverture derrière, assombrie, et on pose le lecteur par-dessus. */
.stage__audio {
  position: absolute; inset: auto var(--s-5) var(--s-5) var(--s-5);
  z-index: 3;
}
.stage__frame--audio::after {
  content: "";
  position: absolute; inset: 0;
  background: rgba(6, 5, 10, 0.55);
}

/* Visionneuse */
.lightbox {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(4, 3, 8, 0.95);
  backdrop-filter: blur(8px);
  display: grid; grid-template-rows: auto 1fr auto;
  padding: var(--s-4);
}
.lightbox__stage { display: grid; place-items: center; min-height: 0; }
.lightbox__stage img,
.lightbox__stage video { max-width: 100%; max-height: 100%; border-radius: var(--r-md); }
.lightbox__bar { display: flex; align-items: center; gap: var(--s-3); }
.lightbox__caption { text-align: center; color: var(--c-ink-soft); font-size: var(--t-small); padding-top: var(--s-3); }

/* --------------------------------------------------------------------------
   4. L'identité
   -------------------------------------------------------------------------- */

.identity {
  background: var(--c-void);
  border-block: 1px solid var(--c-line);
  padding-block: var(--s-9);
}
.identity__inner {
  width: var(--w-wide); margin-inline: auto;
  display: grid; gap: var(--s-7);
}
@media (min-width: 900px) { .identity__inner { grid-template-columns: 1fr 1fr; gap: var(--s-9); } }

.specs { display: grid; }
.specs__row {
  display: grid; grid-template-columns: 10rem 1fr; gap: var(--s-4);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--c-line);
  font-size: var(--t-small);
}
.specs__row:last-child { border-bottom: 0; }
.specs__key { color: var(--c-ink-faint); }

.marks { display: grid; gap: 0; }
.marks__item {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s-4);
  align-items: baseline;
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--c-line);
  font-size: var(--t-small);
  line-height: 1.55;
}
.marks__item:last-child { border-bottom: 0; }
.marks__num {
  font-family: var(--f-display); font-variation-settings: var(--vf-label);
  color: var(--c-accent); font-variant-numeric: tabular-nums;
  min-width: 1.6rem;
}

/* --------------------------------------------------------------------------
   5. Chaîne de gardiens et destination
   -------------------------------------------------------------------------- */

.chain { width: var(--w-wide); margin-inline: auto; padding-block: var(--s-8); }

.chain__track { display: flex; gap: 0; overflow-x: auto; padding-bottom: var(--s-4); }
.chain__link { flex: none; min-width: min(70vw, 15rem); padding-right: var(--s-5); position: relative; }
.chain__link + .chain__link { padding-left: var(--s-5); }
.chain__link::before {
  content: ""; position: absolute; left: 0; right: 0; top: 26px;
  height: 1px; background: var(--c-line);
}
.chain__link:first-child::before { left: 26px; }
.chain__link:last-child::before  { right: calc(100% - 26px); }
.chain__dot { position: relative; margin-bottom: var(--s-3); width: 52px; }
.chain__dot .avatar { box-shadow: 0 0 0 5px var(--c-bg); }
.chain__name { font-weight: 600; font-size: var(--t-small); }
.chain__role { font-size: var(--t-tiny); color: var(--c-ink-faint); margin-top: 2px; }
.chain__period { font-size: var(--t-tiny); color: var(--c-ink-soft); margin-top: var(--s-2); font-variant-numeric: tabular-nums; }
.chain__link.is-current .chain__name { color: var(--c-accent); }

/* La carte « destinataire » — pour un cadeau ou une transmission */
.destination-card {
  display: grid; gap: var(--s-4);
  padding: var(--s-6);
  border: 1px solid var(--c-line-accent);
  border-radius: var(--r-xl);
  background:
    radial-gradient(120% 100% at 100% 0%, color-mix(in oklab, var(--c-accent) 10%, transparent) 0%, transparent 60%),
    var(--c-surface);
  box-shadow: var(--sh-edge);
}
.destination-card__who {
  font-family: var(--f-display); font-variation-settings: var(--vf-title);
  font-size: clamp(1.5rem, 1.3rem + 1vw, 2.1rem);
  letter-spacing: var(--ls-title);
}
.destination-card__meta { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); font-size: var(--t-small); color: var(--c-ink-soft); }
.countdown {
  display: inline-flex; align-items: baseline; gap: var(--s-2);
  font-family: var(--f-display); font-variation-settings: var(--vf-title);
  font-size: 2.4rem; color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.countdown small { font-family: var(--f-ui); font-size: var(--t-tiny); color: var(--c-ink-faint); text-transform: uppercase; letter-spacing: 0.1em; }

/* --------------------------------------------------------------------------
   6. La porte (repère) — dernière section, volontairement
   -------------------------------------------------------------------------- */

.door { width: var(--w-wide); margin-inline: auto; padding-block: var(--s-7) var(--s-10); }
.door__box {
  display: grid; gap: var(--s-6);
  padding: var(--s-6);
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  background: var(--c-surface);
}
@media (min-width: 780px) { .door__box { grid-template-columns: auto 1fr; align-items: center; gap: var(--s-8); } }
.door__code {
  width: 160px; height: 160px; padding: var(--s-3);
  background: #FFFFFF; border-radius: var(--r-md);
  display: grid; place-items: center; justify-self: start;
}
.door__code img { width: 100%; height: 100%; }
.door__url {
  display: flex; align-items: center; gap: var(--s-2);
  margin-top: var(--s-3);
  padding: var(--s-3);
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-sm);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--t-tiny); color: var(--c-ink-soft);
  overflow-x: auto; white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Objet inaccessible
   -------------------------------------------------------------------------- */

.sealed-page {
  min-height: 82dvh;
  display: grid; place-items: center;
  padding: var(--s-8) var(--s-4);
  text-align: center;
}
.sealed-page__inner { max-width: 30rem; display: grid; gap: var(--s-5); justify-items: center; }
.sealed-page__mark {
  width: 92px; height: 92px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--c-private-soft); color: var(--c-private);
  border: 1px solid color-mix(in oklab, var(--c-private) 35%, transparent);
}
