/* objet-code · la fenêtre « an object as code » (7 octobre 2026). Posée sur une section claire (Craie #F7F6F3).
   Le HTML vient de tools/code_html.py : figure.rb-objet-code > .oc-fenetre > .oc-barre + .oc-corps (.oc-vue + .oc-code).
   Tout en rem ; aucune police extérieure (monospace du système pour le code). */

/* Une section claire pour poser la fenêtre (démo, ou toute page qui n'en a pas déjà une). */
.oc-scene { background: #F7F6F3; color: #121117; padding: clamp(3rem, 7vw, 6rem) 0; }
.oc-scene .oc-scene-t { margin: 0 0 0.5rem; font-size: clamp(1.5rem, 3vw, 2.25rem); font-weight: 300; letter-spacing: -.02em; line-height: 1.15; color: #121117; }
.oc-scene .oc-scene-p { margin: 0 0 2rem; max-width: 40rem; color: #4A4752; }

.rb-objet-code { margin: 0; color: #121117; }
.rb-objet-code figcaption { margin-top: 0.875rem; font-size: 0.8125rem; line-height: 1.5; color: #5F5C68; }

.oc-fenetre {
  background: #FFFFFF; border: 1px solid rgba(18, 17, 23, .12); border-radius: 1rem; overflow: hidden;
  box-shadow: 0 0.0625rem 0.125rem rgba(18, 17, 23, .04), 0 1.25rem 2.5rem -1.5rem rgba(18, 17, 23, .14);
}

/* La barre : trois points gris, le nom du fichier au centre. */
.oc-barre {
  height: 2.5rem; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 0 0.875rem;
  border-bottom: 1px solid rgba(18, 17, 23, .08); background: #FCFCFB;
}
.oc-points { display: flex; gap: 0.4375rem; }
.oc-points span { width: 0.6875rem; height: 0.6875rem; border-radius: 50%; background: rgba(18, 17, 23, .13); }
.oc-titre {
  grid-column: 2; font: 500 0.8125rem/1 "Inter", system-ui, -apple-system, "Segoe UI", sans-serif; letter-spacing: -.005em;
  color: #4A4752; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60vw;
}

/* Le corps : la vue 3D puis le code, côte à côte à partir de 900 px. */
.oc-corps { display: grid; grid-template-columns: minmax(0, 1fr); }
.oc-vue { position: relative; height: 20rem; min-width: 0; overflow: hidden; background: #FFFFFF; touch-action: pan-y;
  /* une trame de points discrète derrière la 3D, comme les vues des cartes (Tanguy, 7 oct.) */
  background-image: radial-gradient(rgba(18, 17, 23, .075) 1px, transparent 1.2px); background-size: 1.25rem 1.25rem; background-position: center; }
.oc-code { height: 18rem; min-width: 0; border-top: 1px solid rgba(18, 17, 23, .08); }
@media (min-width: 900px) {
  .oc-corps { grid-template-columns: minmax(0, 55fr) minmax(0, 45fr); height: 34rem; }
  .oc-vue, .oc-code { height: auto; }
  .oc-code { border-top: 0; border-left: 1px solid rgba(18, 17, 23, .08); }
}

.oc-vue canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; outline: none; }
.oc-vue[data-dragging] canvas { cursor: grabbing; }
.oc-vue canvas { opacity: 0; transition: opacity .6s ease; }
.oc-vue[data-state="ready"] canvas { opacity: 1; }

.oc-etat {
  position: absolute; inset: 0; margin: 0; display: grid; place-items: center; padding: 1rem; text-align: center;
  font-size: 0.8125rem; color: #5F5C68;
}
.oc-etat[hidden] { display: none; }
.oc-vue[data-state="fallback"] { display: grid; place-items: center; background: #FAFAF9; }
.oc-vue[data-state="fallback"] .oc-etat { position: static; }

/* L'interrupteur « Assembled | Exploded » : pastille de verre clair, curseur Encre qui glisse en s'étirant
   (d'après RubberSegment : le bord qui part en premier est rapide, l'autre le rattrape). */
.oc-seg {
  position: absolute; top: 0.875rem; left: 0.875rem; z-index: 2; display: inline-flex; padding: 0.1875rem; border-radius: 62.4375rem;
  background: rgba(255, 255, 255, .62); -webkit-backdrop-filter: blur(0.75rem) saturate(1.2); backdrop-filter: blur(0.75rem) saturate(1.2);
  box-shadow: inset 0 0 0 1px rgba(18, 17, 23, .1), 0 0.0625rem 0.125rem rgba(18, 17, 23, .06);
}
.oc-seg-curseur {
  position: absolute; top: 0.1875rem; bottom: 0.1875rem; left: 0.1875rem; right: 50%; border-radius: 62.4375rem; background: #121117;
  box-shadow: 0 0.0625rem 0.1875rem rgba(18, 17, 23, .22);
  transition: left .42s cubic-bezier(.3, .9, .3, 1), right .42s cubic-bezier(.3, .9, .3, 1);
}
.oc-seg[data-dir="r"] .oc-seg-curseur { transition: right .3s cubic-bezier(.25, .9, .3, 1), left .52s cubic-bezier(.6, 0, .25, 1) .05s; }
.oc-seg[data-dir="l"] .oc-seg-curseur { transition: left .3s cubic-bezier(.25, .9, .3, 1), right .52s cubic-bezier(.6, 0, .25, 1) .05s; }
.oc-seg-btn {
  position: relative; z-index: 1; margin: 0; border: 0; background: none; cursor: pointer; border-radius: 62.4375rem;
  padding: 0.4375rem 0.8125rem; min-height: 1.875rem;
  font: 500 0.8125rem/1 "Inter", system-ui, -apple-system, "Segoe UI", sans-serif; letter-spacing: -.005em; color: #121117;
  transition: color .3s ease;
}
.oc-seg-btn[aria-pressed="true"] { color: #FFFFFF; }
.oc-seg-btn:disabled { cursor: default; opacity: .55; }
.oc-seg-btn:focus-visible { outline: 2px solid #121117; outline-offset: 2px; }

/* L'étiquette de la pièce survolée. */
.oc-tag {
  position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none; display: grid; gap: 0.1875rem;
  padding: 0.4375rem 0.5625rem; border-radius: 0.5rem; background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: blur(0.5rem); backdrop-filter: blur(0.5rem);
  box-shadow: inset 0 0 0 1px rgba(18, 17, 23, .12), 0 0.25rem 0.75rem -0.25rem rgba(18, 17, 23, .18);
  opacity: 0; transition: opacity .15s ease; white-space: nowrap;
}
.oc-tag.is-on { opacity: 1; }
.oc-tag-nom { font: 500 0.75rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #121117; }
.oc-tag-bloc { font: 400 0.6875rem/1.2 "Inter", system-ui, sans-serif; color: #5F5C68; }

/* La puce du bloc éclairé (en bas à gauche) et l'aide (en bas à droite). */
.oc-puce, .oc-aide {
  position: absolute; bottom: 0.875rem; z-index: 2; margin: 0; font: 400 0.75rem/1 "Inter", system-ui, sans-serif; color: #5F5C68;
  pointer-events: none;
}
.oc-puce {
  left: 0.875rem; padding: 0.375rem 0.5625rem; border-radius: 62.4375rem; background: rgba(255, 255, 255, .7);
  box-shadow: inset 0 0 0 1px rgba(18, 17, 23, .08); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  opacity: 0; transition: opacity .25s ease;
}
.oc-puce.is-on { opacity: 1; }
.oc-aide { right: 0.875rem; transition: opacity .2s ease; }
.oc-aide.is-off { opacity: 0; }
.oc-vue:not([data-state="ready"]) .oc-aide, .oc-vue:not([data-state="ready"]) .oc-puce { display: none; }

/* Le zoom (27 oct.) : + et − l'un sur l'autre, au milieu du bord gauche, dans une pastille de verre clair comme la barre des
   mises en situation ; montré quand la vue est prête. */
.oc-zoom { position: absolute; z-index: 3; left: 0.875rem; top: 50%; display: flex; flex-direction: column; gap: 0.125rem;
  padding: 0.1875rem; border-radius: 999px; background: rgba(255, 255, 255, .86); transform: translateY(-50%);
  -webkit-backdrop-filter: blur(0.75rem); backdrop-filter: blur(0.75rem);
  box-shadow: 0 0.25rem 1rem rgba(29, 29, 31, .12), inset 0 0 0 1px rgba(29, 29, 31, .06); }
.oc-zoom-b { display: grid; place-items: center; width: 1.75rem; height: 1.75rem; margin: 0; padding: 0; border: 0;
  border-radius: 50%; background: none; color: #1D1D1F; cursor: pointer; transition: background-color .2s ease, opacity .2s ease; }
.oc-zoom-b svg { width: 0.875rem; height: 0.875rem; }
.oc-zoom-b:hover:not(:disabled) { background: rgba(29, 29, 31, .06); }
.oc-zoom-b:focus-visible { outline: 2px solid #1D1D1F; outline-offset: 1px; }
.oc-zoom-b:disabled { opacity: .35; cursor: default; }
.oc-vue:not([data-state="ready"]) .oc-zoom { display: none; }

/* Le code. Les sélecteurs passent devant `.bloc pre` de /lab.css. */
.oc-code { position: relative; overflow: auto; overscroll-behavior: contain; background: #FFFFFF; scrollbar-width: thin; scrollbar-color: rgba(18, 17, 23, .18) transparent; }
.oc-code:focus-visible { outline: 2px solid #121117; outline-offset: -2px; }
.rb-objet-code .oc-code pre {
  margin: 0; padding: 0; background: none; border: 0; border-radius: 0; overflow: visible; min-width: 100%; width: max-content;
  font: 400 0.8125rem/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #121117; tab-size: 4;
  font-variant-ligatures: none;
}
.rb-objet-code .oc-code pre:last-child { padding-bottom: 0.875rem; }
.rb-objet-code .oc-code code { font: inherit; color: inherit; background: none; padding: 0; }
.oc-l { display: block; min-height: 1.65em; padding-right: 1.25rem; transition: background-color .25s ease, box-shadow .25s ease; }
.oc-l::before {
  content: attr(data-l); display: inline-block; width: 3ch; margin: 0 1.5ch 0 1.25rem; text-align: right; color: #A3A0AA;
  -webkit-user-select: none; user-select: none;
}
.oc-l:hover { background: rgba(18, 17, 23, .025); }
.oc-l.is-on { background: rgba(18, 17, 23, .06); box-shadow: inset 0.125rem 0 0 #121117; }
.oc-l.is-on::before { color: #121117; }

/* Couleurs syntaxiques : contraste ≥ 4,5:1 sur blanc et sur le fond d'une ligne éclairée. */
.oc-kw { color: #6B3FA0; }
.oc-str { color: #2E6B4F; }
.oc-num, .oc-cst { color: #9A4B16; }
.oc-fn { color: #1F4E8C; }
.oc-com { color: #6B6874; }
.oc-bloc { color: #121117; font-weight: 600; }

/* Le bloc common, replié en une ligne. */
.oc-commun > summary {
  display: block; list-style: none; cursor: pointer; position: sticky; left: 0; width: max-content; min-width: 100%;
  padding: 0.5rem 1.25rem 0.5rem calc(1.25rem + 4.5ch);
  font: 400 0.8125rem/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #5F5C68;
  background: #FAFAF9; border-bottom: 1px solid rgba(18, 17, 23, .06);
}
.oc-commun > summary::-webkit-details-marker { display: none; }
.oc-commun > summary:hover { color: #121117; background: #F4F3F1; }
.oc-commun > summary:focus-visible { outline: 2px solid #121117; outline-offset: -2px; }
.oc-fl { display: inline-block; transition: transform .2s ease; }
.oc-commun[open] .oc-fl { transform: rotate(90deg); }
.oc-commun[open] > summary { border-bottom-color: transparent; }
.oc-commun[open] > pre { border-bottom: 1px solid rgba(18, 17, 23, .06); }
.oc-commun + pre { padding-top: 0.25rem; }

/* La vue partagée (data-split, 26-27 oct., d'après nova3d.xyz) : la poignée (un filet sombre et un bouton rond blanc),
   « Model » et « Code » de part et d'autre en bas, les noms des blocs reliés à leurs pièces, sur un fond clair. */
.oc-poignee { position: absolute; z-index: 3; top: 0; bottom: 0; left: 46%; width: 2.75rem; margin-left: -1.375rem; display: grid;
  place-items: center; cursor: ew-resize; touch-action: none; outline: none; }
.oc-poignee::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; margin-left: -0.5px; background: rgba(29, 29, 31, .4); }
.oc-poignee-bouton { position: relative; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 50%;
  background: #FFFFFF; color: #1D1D1F; box-shadow: 0 0.125rem 0.625rem rgba(29, 29, 31, .18), inset 0 0 0 1px rgba(29, 29, 31, .06);
  transition: transform .2s ease; }
.oc-poignee:hover .oc-poignee-bouton, .oc-poignee[data-glisse] .oc-poignee-bouton { transform: scale(1.08); }
.oc-poignee:focus-visible .oc-poignee-bouton { outline: 2px solid #1D1D1F; outline-offset: 3px; }
.oc-cote { position: absolute; z-index: 2; bottom: 0.875rem; padding: 0.3125rem 0.5rem; border-radius: 0.25rem; pointer-events: none;
  background: rgba(255, 255, 255, .9); box-shadow: inset 0 0 0 1px rgba(29, 29, 31, .06); font: 500 0.6875rem/1 "Inter", system-ui, sans-serif;
  color: #1D1D1F; transition: opacity .2s ease; }
.oc-cote-c { background: #1D1D1F; color: #FFFFFF; box-shadow: none; }
.oc-cote.is-off { opacity: 0; }
.oc-noms { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.oc-nom { position: absolute; left: 0; top: 0; display: inline-flex; align-items: baseline; gap: 0.375rem; padding: 0.25rem 0.5rem;
  border-radius: 0.25rem; background: rgba(255, 255, 255, .92); box-shadow: 0 1px 2px rgba(29, 29, 31, .06), inset 0 0 0 1px rgba(29, 29, 31, .06);
  font: 400 0.6875rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #86868B; white-space: nowrap; opacity: 0;
  transition: opacity .3s ease; }
.oc-nom b { font-weight: 600; }
.oc-nom.is-on { opacity: 1; }
.oc-fils { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.oc-fils polyline { fill: none; stroke: rgba(29, 29, 31, .3); stroke-width: 1; }
.oc-fils circle { fill: #FFFFFF; stroke: #1D1D1F; stroke-width: 1.25; }
.oc-fils > * { opacity: 0; transition: opacity .3s ease; }
.oc-fils > .is-on { opacity: 1; }
/* Le programme qui s'écrit : sous les fonctions communes repliées, seuls les jetons déjà écrits se montrent. */
.oc-code.oc-ecrit > pre .oc-l:not(.vu), .oc-code.oc-ecrit > pre .oc-l > span:not(.vu) { display: none; }

@media (prefers-reduced-motion: reduce) {
  .oc-seg-curseur, .oc-seg[data-dir] .oc-seg-curseur, .oc-seg-btn, .oc-l, .oc-tag, .oc-puce, .oc-fl, .oc-vue canvas,
  .oc-poignee-bouton, .oc-cote, .oc-nom, .oc-fils > * { transition: none; }
}
