/* ==========================================================================
   AXI-x Torus v0.1 — the score.                     (extension; not SNX core)
   torus.js writes numbers; everything visible about a torus is here.
   A torus (.tr) is a container; its drum (.tr-strip) is a grid F + 2 faces
   wide in HALF microcolumns, inside a window (.tr-scroller) one face wide.
   The pair is the torus's own (container query, Manifest's thresholds); the
   rows are the page's. --roll, in microcolumns, is the only moving part.
   ========================================================================== */
@property --roll{syntax:'<number>';inherits:true;initial-value:0}

.tr{position:relative;container:torus / inline-size;min-width:0;z-index:2;--tr-rows:6;height:calc(var(--snx-row)*var(--tr-rows))}
@media (max-width:639px){.tr{--tr-rows:5}}

/* the window: one face wide, the page's rows tall */
.tr-scroller{position:absolute;inset:0;border:1px solid var(--snx-ink);background:var(--snx-chalk);overflow:clip}
.tr[data-roll-mode=scroll] .tr-scroller{overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:var(--snx-ink-40) transparent;cursor:ew-resize}
.tr[data-roll-mode=scroll] .tr-scroller:focus-visible{outline:2px solid var(--snx-signal);outline-offset:-2px}

/* the drum: pair by the torus's own width (pocket edition below 270px) */
.tr-strip{
  position:relative;display:grid;height:100%;
  --snx-base:3;--snx-over:2;--snx-union:6;--snx-sliver-a:2;--snx-sliver-b:3;
  --tr-h:calc(50cqw/var(--snx-union));                 /* one half microcolumn */
  grid-template-columns:repeat(var(--tr-cols,72),var(--tr-h));
  width:calc(var(--tr-cols,72)*var(--tr-h));
  grid-template-rows:repeat(var(--tr-rows,6),1fr);grid-auto-rows:0;
  translate:calc(-1*(var(--snx-union) + var(--roll,0))*2*var(--tr-h)) 0;
}
@container torus (min-width:270px){.tr-strip{--snx-base:5;--snx-over:3;--snx-union:15;--snx-sliver-a:5;--snx-sliver-b:9}}
@container torus (min-width:540px){.tr-strip{--snx-base:7;--snx-over:5;--snx-union:35;--snx-sliver-a:14;--snx-sliver-b:20}}
.tr[data-roll-mode=scroll] .tr-strip{translate:none}

/* pieces: placed in half microcolumns; the engine's own rules paint them */
.tr-strip > .tr-p{grid-column:var(--u,1)/span var(--uw,2);grid-row:var(--r,1)/span var(--rs,1);min-width:0}
/* slivers roll (law 6): a full microcolumn at 7×5, a thin centred bar below it */
.tr-sliver{z-index:1;pointer-events:none;background:var(--snx-signal);mix-blend-mode:multiply;opacity:.85;width:5px;justify-self:center}
@container torus (min-width:540px){.tr-sliver{width:auto;justify-self:stretch}}
/* seams: every coincidence of the two grids, shown on request */
.tr-seam{z-index:7;pointer-events:none;width:0;justify-self:start;border-left:1px dashed var(--snx-ai-deep);opacity:0;transition:opacity 200ms ease}
.tr.tr-seams .tr-seam{opacity:1}
/* snap stops every half face: a face-aligned roll and a seam-centred one */
.tr-snap{scroll-snap-align:start;width:0;justify-self:start;visibility:hidden;pointer-events:none}
/* both grids, revealed on request (the engine's gridlines, keyed to the window) */
.tr-strip::before{content:'';position:absolute;inset:0;z-index:7;pointer-events:none;opacity:0;transition:opacity 200ms ease;
  background-image:linear-gradient(to right,var(--snx-ink-18) 0 1px,transparent 1px),linear-gradient(to right,rgba(27,42,155,.28) 0 1px,transparent 1px);
  background-size:calc(100cqw/var(--snx-base)) 100%,calc(100cqw/var(--snx-over)) 100%}
.tr.tr-lines .tr-strip::before{opacity:1}

/* the corner label: entirely from what the script wrote */
.tr::after{
  content:attr(data-pair) ' · ' attr(data-faces) ' faces · roll ' attr(data-roll) ' · face ' attr(data-face) ' · seam ' attr(data-seam);
  position:absolute;left:5px;top:4px;z-index:8;pointer-events:none;white-space:nowrap;
  font-family:var(--snx-mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--snx-ink-60);
}
.tr[data-plane="-1"]::after{color:rgba(19,22,40,.55)}

/* plane −1 (law 7): behind a window cut in the sheet, muted, rolled by the page's scroll */
.snx-window.tr-win{overflow:clip;padding:0}
.snx-window.tr-win::after{z-index:1}
.tr-win > .tr{position:absolute;inset:0;height:auto;z-index:0;isolation:isolate}
.tr[data-plane="-1"] .tr-scroller{border:0;background:var(--snx-paper-dim)}
.tr[data-plane="-1"] .tr-strip{filter:saturate(.78) brightness(.95)}
.tr[data-roll-mode=view] .tr-strip{animation:tr-roll linear both;animation-timeline:view();animation-range:entry 0% exit 100%}
@keyframes tr-roll{from{--roll:0}to{--roll:calc(var(--snx-union)/2)}}
@media (prefers-reduced-motion:reduce){
  .tr[data-roll-mode=view] .tr-strip{animation:none;--roll:calc(var(--snx-union)/2)}
  .tr-seam,.tr-strip::before{transition:none}
}
