/* HORNFILLER components: the 3D tetrahedron (.t3-*) and the notes pictures/demos (.nv-*).
   Colours only from style.css custom properties, so light/dark just work. */

/* ---------- 3D tetrahedron ---------- */
.t3 { width: 100%; height: auto; display: block; margin: 0 auto; overflow: visible; cursor: grab;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.t3.turning { cursor: grabbing; }
.t3:focus { outline: none; }
.t3:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }

.t3-face { cursor: pointer; outline: none; }
.t3.turning .t3-face { cursor: grabbing; }
.t3-fill { stroke: none; fill: transparent; transition: fill-opacity .2s; }
.t3-inset { fill: none; stroke: none; pointer-events: none; }
.t3-face[data-face="0"] .t3-fill { --t3c: var(--tri0); }
.t3-face[data-face="1"] .t3-fill { --t3c: var(--tri1); }
.t3-face[data-face="2"] .t3-fill { --t3c: var(--tri2); }
.t3-face[data-face="3"] .t3-fill { --t3c: var(--tri3); }
.t3-face.s-known .t3-fill { fill: var(--t3c); fill-opacity: calc(var(--tri-op) * 1.6); }
.t3-face.s-known.is-back .t3-fill { fill-opacity: var(--tri-op); }
.t3-face.s-chosen .t3-fill { fill: var(--accent); fill-opacity: .3; }
.t3-face.s-chosen .t3-inset { stroke: var(--accent); stroke-width: 1.8; stroke-linejoin: round; }
.t3-face.s-missing .t3-fill { fill: transparent; }
.t3-face.s-missing .t3-inset { stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 4; stroke-linejoin: round; animation: t3March 1.4s linear infinite; }
.t3-face.s-locked .t3-fill { fill: var(--locked); fill-opacity: .12; }
.t3-face.s-locked .t3-inset { stroke: var(--locked); stroke-width: 1.4; stroke-dasharray: 2 3; }
.t3-face.s-new .t3-fill { fill: var(--ok); fill-opacity: .42; }
.t3-face.s-new .t3-inset { stroke: var(--ok); stroke-width: 1.8; }
.t3-face.pop { transform-box: fill-box; transform-origin: center; animation: t3Pop .55s cubic-bezier(.3, 1.7, .5, 1) both; }
.t3-face.hov .t3-fill { fill-opacity: .34; }
.t3-face.hl .t3-fill, .t3-face:focus-visible .t3-fill { fill: var(--hi); fill-opacity: .45; }
.t3-face.hl .t3-inset, .t3-face:focus-visible .t3-inset { stroke: var(--hi); stroke-width: 2.4; stroke-dasharray: none; }
@keyframes t3March { to { stroke-dashoffset: -18; } }
@keyframes t3Pop { 0% { opacity: 0; transform: scale(.15); } 100% { opacity: 1; transform: scale(1); } }

.t3-lock { pointer-events: none; }
.t3-lock path { fill: none; stroke: var(--locked); stroke-width: 1.6; }
.t3-lock rect { fill: var(--paper); stroke: var(--locked); stroke-width: 1.6; }

.t3-edge { pointer-events: none; }
.t3-line { fill: none; stroke-width: 2.6; stroke-linecap: round; }
.t3-ah { stroke: none; }
.t3-edge.k-given .t3-line { stroke: var(--k-given); } .t3-edge.k-given .t3-ah { fill: var(--k-given); }
.t3-edge.k-composite .t3-line { stroke: var(--k-composite); } .t3-edge.k-composite .t3-ah { fill: var(--k-composite); }
.t3-edge.k-solved .t3-line { stroke: var(--k-solved); } .t3-edge.k-solved .t3-ah { fill: var(--k-solved); }
.t3-edge.k-identity .t3-line { stroke: var(--k-identity); stroke-dasharray: 6 5; stroke-width: 2.2; } .t3-edge.k-identity .t3-ah { fill: var(--k-identity); }
.t3-edge.is-back { opacity: .42; }

.t3-labels, .t3-dots { pointer-events: none; }
.t3-elabel { font-family: var(--font-math); font-style: italic; fill: var(--ink); paint-order: stroke; stroke: var(--halo); stroke-width: 6px; stroke-linejoin: round; }
.t3-elabel .sub { font-size: 70%; }
.t3-elabel.k-composite { fill: var(--k-composite); }
.t3-elabel.k-solved { fill: var(--k-solved); }
.t3-elabel.k-identity { fill: var(--k-identity); font-family: var(--font-up); font-style: normal; }
.t3-elabel.k-identity .sub { font-family: var(--font-math); font-style: italic; }
.t3-vdot { fill: var(--dot); stroke: var(--paper); stroke-width: 2.5; }
.t3-vlabel { fill: var(--dot-ink); font-family: var(--font-math); font-style: italic; font-weight: 700; }
.t3-vlabel .sub { font-size: 70%; }
.t3-idx { fill: var(--muted); font: 11px var(--font-up); paint-order: stroke; stroke: var(--halo); stroke-width: 3px; }

/* ---------- notes diagrams (same language as the board, smaller) ---------- */
.nv-svg { display: block; width: 100%; height: auto; overflow: visible; user-select: none; -webkit-user-select: none; }
.nv-diagram { margin: 10px auto; max-height: 240px; }
.nv-fill { stroke: none; fill-opacity: var(--tri-op); pointer-events: none; }
.nv-fill.tc0 { fill: var(--tri0); } .nv-fill.tc1 { fill: var(--tri1); } .nv-fill.tc2 { fill: var(--tri2); } .nv-fill.tc3 { fill: var(--tri3); }
/* a solid: a gradient on each face, lit by a glow inside the body */
.nv-grad { stroke: none; pointer-events: none; }
.nv-fill.fresh { animation: nvTri 1s ease-out both; }
.nv-ghost { fill: var(--accent); fill-opacity: .05; stroke: var(--muted); stroke-width: 2; stroke-dasharray: 7 6; stroke-linejoin: round; pointer-events: none; }
.nv-line { fill: none; stroke-width: 3.8; stroke-linecap: round; }
.nv-ah { stroke: none; }
.nv-arrow { pointer-events: none; }
.nv-arrow.k-given .nv-line { stroke: var(--k-given); } .nv-arrow.k-given .nv-ah { fill: var(--k-given); }
.nv-arrow.k-composite .nv-line { stroke: var(--k-composite); } .nv-arrow.k-composite .nv-ah { fill: var(--k-composite); }
.nv-arrow.k-solved .nv-line { stroke: var(--k-solved); } .nv-arrow.k-solved .nv-ah { fill: var(--k-solved); }
.nv-arrow.k-identity .nv-line { stroke: var(--k-identity); stroke-dasharray: 8 6; stroke-width: 2.8; } .nv-arrow.k-identity .nv-ah { fill: var(--k-identity); }
.nv-arrow.hi .nv-line { stroke: var(--hi); stroke-width: 6; } .nv-arrow.hi .nv-ah { fill: var(--hi); }
.nv-arrow.thin .nv-line { stroke-width: 2.2; }
.nv-arrow.want .nv-line { stroke: var(--accent); stroke-dasharray: 3 9; stroke-width: 3; animation: nvMarch 1.2s linear infinite; }
.nv-arrow.want .nv-ah { fill: var(--accent); opacity: .7; }
.nv-alabel.want { fill: var(--accent); }
.nv-alabel.nope { fill: var(--warn); }
.nv-arrow.nope .nv-line { stroke: var(--warn); } .nv-arrow.nope .nv-ah { fill: var(--warn); }
.nv-arrow.fresh .nv-line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: nvDraw .5s ease-out forwards; }
.nv-arrow.fresh .nv-ah { animation: nvFade .2s ease-out .4s both; }
.nv-alabel { font-family: var(--font-math); font-style: italic; fill: var(--ink); paint-order: stroke; stroke: var(--halo); stroke-width: 8px; stroke-linejoin: round; pointer-events: none; }
.nv-alabel .sub { font-size: 70%; }
.nv-alabel.k-composite { fill: var(--k-composite); }
.nv-alabel.k-solved { fill: var(--k-solved); }
.nv-alabel.k-identity { fill: var(--k-identity); font-family: var(--font-up); font-style: normal; }
.nv-alabel.k-identity .sub { font-family: var(--font-math); font-style: italic; }
.nv-alabel.hi { font-weight: 700; }
.nv-alabel.fresh { transform-box: fill-box; transform-origin: center; animation: nvPop .4s cubic-bezier(.3, 1.6, .5, 1) .35s both; }
.nv-vdot { fill: var(--dot); stroke: var(--paper); stroke-width: 3; }
.nv-vring { fill: none; stroke: transparent; stroke-width: 2.5; }
.nv-vlabel { fill: var(--dot-ink); font-family: var(--font-math); font-style: italic; font-weight: 700; pointer-events: none; }
.nv-vlabel .sub { font-size: 70%; }
.nv-dot.small .nv-vdot { transform: scale(.82); }
.nv-dot.sel .nv-vdot { fill: var(--accent); }
.nv-dot.sel .nv-vlabel { fill: var(--accent-ink); }
.nv-dot.sel .nv-vring { stroke: var(--accent); }
.nv-dot.hi .nv-vring { stroke: var(--hi); stroke-width: 5; }
.nv-dot.pulse .nv-vring { stroke: var(--accent); stroke-dasharray: 4 4; transform-box: fill-box; transform-origin: center; animation: nvRing 1.3s ease-in-out infinite; }
.nv-dot.copy .nv-vdot { fill: var(--paper); stroke: var(--dot); stroke-width: 2.5; }
.nv-dot.copy .nv-vlabel { fill: var(--ink); }
.nv-dot.copy.sel .nv-vdot { fill: var(--accent); stroke: var(--accent); }
.nv-dot.copy.sel .nv-vlabel { fill: var(--accent-ink); }
.nv-band .nv-line { stroke: var(--accent); stroke-width: 3.2; stroke-dasharray: 10 6; }
.nv-band .nv-ah { fill: var(--accent); }
.nv-band.back { opacity: .5; }
.nv-mapline { fill: none; stroke: var(--accent); stroke-width: 3.4; stroke-dasharray: 9 7; stroke-linecap: round; pointer-events: none; }
.nv-mapline.fresh { animation: nvFade .35s ease-out both; }
.nv-tag { font: 26px var(--font-up); fill: var(--muted); }

@keyframes nvDraw { to { stroke-dashoffset: 0; } }
@keyframes nvFade { from { opacity: 0; } }
@keyframes nvPop { from { opacity: 0; transform: scale(.4); } }
@keyframes nvTri { 0% { fill-opacity: 0; } 35% { fill-opacity: 0; } 60% { fill-opacity: .55; fill: var(--hi); } 100% { fill-opacity: var(--tri-op); } }
@keyframes nvMarch { to { stroke-dashoffset: -24; } }
@keyframes nvRing { 50% { transform: scale(1.22); opacity: .45; } }

/* ---------- demos ---------- */
.nv-demo { margin: 14px 0; padding: 8px 10px 10px; border: 1px solid var(--line); background: var(--paper); max-width: 560px; }
.nv-demo .nv-svg { max-height: 200px; margin: 0 auto; }
.nv-demo-horn-fill .nv-svg, .nv-demo-split-vertex .nv-svg { touch-action: none; cursor: pointer; }
.nv-demo.won { animation: nvWon .8s ease-out; }
@keyframes nvWon { 0% { box-shadow: 0 0 0 0 var(--ok); border-color: var(--ok); } 100% { box-shadow: 0 0 0 9px transparent; } }
.nv-cap { margin: 6px 0 0; font-size: 15px; line-height: 1.4; color: var(--ink-soft); min-height: 2.8em; }
.nv-cap sub, .nv-cap sup { font-size: .72em; line-height: 0; }
.nv-ctrl { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: 6px; }
.nv-ctrl:empty { display: none; }
.nv-ctrl .linklike { font-size: 15px; min-height: 32px; }
.nv-map { font-family: var(--font-up); min-width: 44px; justify-content: center; }
.nv-map[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.nv-t3 { max-width: 240px; margin: 0 auto; }
.nv-demo-missing { color: var(--muted); font-size: 14px; font-style: italic; margin: 8px 0; }

@media (prefers-reduced-motion: reduce) {
  .t3-face.s-missing .t3-inset, .nv-arrow.want .nv-line, .nv-dot.pulse .nv-vring { animation: none; }
  .t3-face.pop, .nv-fill.fresh, .nv-arrow.fresh .nv-line, .nv-alabel.fresh, .nv-demo.won { animation: none; }
  .nv-arrow.fresh .nv-line { stroke-dasharray: none; stroke-dashoffset: 0; }
}
@media (max-width: 520px) {
  .nv-demo { padding: 6px 8px 8px; }
  .nv-cap { font-size: 14px; }
}
