/* ==========================================================================
   APEX OPS: THEATRE LAYER
   Loads after apex.css and overrides it. Everything here is additive:
   delete the two tags in the layout and the site returns to the base build.

   Motion language, in order of importance:
     1  APERTURE  the page opens like a lens, not like a web page
     2  LOCK-ON   the cursor acquires a card; the card confirms the acquisition
     3  DEPTH     photography sits behind glass and moves against the tilt
     4  CUT       sections change like a shot change, not a fade
     5  PACE      every duration in the base build is cut by roughly 40%

   Nothing here invents an operational claim, and every effect is off under
   prefers-reduced-motion and on touch.
   ========================================================================== */

:root{
  --ease-out:cubic-bezier(.16,1,.3,1);      /* arrivals: fast in, long settle */
  --ease-cut:cubic-bezier(.7,0,.18,1);      /* wipes and curtains */
  --t-fast:.22s;
  --t-mid:.42s;
  --t-slow:.62s;
  --lift:-13px;                             /* how far a card rises */
  --tilt:7;                                 /* degrees at the card corner */
}

/* --------------------------------------------------------------------------
   1  PACE. The base build reveals at .95s with delays up to .5s, which reads
   as slow on a fast connection. Same grammar, shorter.
   -------------------------------------------------------------------------- */
.seen[data-r]{
  animation-duration:var(--t-slow);
  animation-delay:calc(var(--d,0s) * .58);
  animation-timing-function:var(--ease-out);
}
.seen[data-r="mask"]{animation-duration:.7s}
.seen[data-r="wide"]{animation-duration:.78s}

@keyframes rRise{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}
@keyframes rMask{from{opacity:0;clip-path:inset(0 0 102% 0)}to{opacity:1;clip-path:inset(0 0 -14% 0)}}
@keyframes rWide{from{opacity:0;transform:scale(1.045)}to{opacity:1;transform:none}}

/* curtain: quicker, and it leaves a crimson trailing edge as it lifts */
.curtain{transition-duration:.4s}
.curtain::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--red);
}
.curtain img{animation:curtainMark 1.2s var(--ease-out) infinite alternate}
@keyframes curtainMark{from{opacity:.55}to{opacity:1}}

/* hover feedback, everywhere, sharpened */
.btn{transition:color var(--t-mid) var(--ease-out),transform var(--t-fast) var(--ease-out)}
.btn::before{transition:transform .38s var(--ease-out)}
.tlink::after{transition:transform .3s var(--ease-out)}
.tile img{transition:transform .62s var(--ease-out),filter .62s var(--ease-out)}
.sector{transition:flex .5s var(--ease-out)}
.sector img{transition:filter .6s var(--ease-out),transform .6s var(--ease-out)}
.drop{transition:opacity .2s var(--ease-out),transform .2s var(--ease-out),visibility .2s}
.drawer{transition:clip-path .46s var(--ease-cut)}
.drawer.on a{animation-duration:.42s;animation-delay:calc(.045s * var(--i))}

/* --------------------------------------------------------------------------
   2  APERTURE. Two bars pull back off the opening shot once the curtain has
   lifted. Injected by the script, so they never appear without JavaScript.
   -------------------------------------------------------------------------- */
.tx-bar{
  position:fixed;left:0;right:0;z-index:960;pointer-events:none;
  background:var(--void);height:8.5vh;
  transition:height 1s var(--ease-out) .12s;
}
.tx-bar.t{top:0}
.tx-bar.b{bottom:0}
.tx-bar::after{
  content:"";position:absolute;left:0;right:0;height:1px;background:rgba(210,16,30,.7);
  opacity:1;transition:opacity .9s linear .3s;
}
.tx-bar.t::after{bottom:0}
.tx-bar.b::after{top:0}
html.tx-open .tx-bar{height:0}
html.tx-open .tx-bar::after{opacity:0}
@media(max-width:700px){.tx-bar{height:5vh}}

/* the base build settles the shot with a 2.6s CSS animation and then hands
   over to script, which shows as a jump. One driver instead: the loop. */
.tx .plate-media img,.tx .plate-media video{
  animation:none;transform:scale(1.16);will-change:transform;
}

/* the mark's own geometry, drawn large behind the opening type and drifting
   at a different rate to the photograph. No new asset, real depth. */
.tx-sigil{
  position:absolute;z-index:-1;pointer-events:none;
  right:-6%;top:50%;width:min(86vh,880px);aspect-ratio:1;
  opacity:0;transform:translateY(-50%);
  transition:opacity 1.6s var(--ease-out) .5s;
}
html.tx-open .tx-sigil{opacity:1}
.tx-sigil svg{width:100%;height:100%;display:block}
.tx-sigil path{fill:none;stroke:rgba(244,246,249,.075);stroke-width:1}
.tx-sigil .s-red{stroke:rgba(210,16,30,.28)}
@media(max-width:900px){.tx-sigil{display:none}}

/* falling snow across every opening shot. Only rendered when the plate
   carries data-snow, so the page is correct until the loop is delivered. */
.tx-snow{
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  width:100%;height:100%;object-fit:cover;
  mix-blend-mode:screen;opacity:.42;
}

/* a crimson ridge line drawn along the foot of the opening shot */
.tx-ridge{
  position:absolute;left:0;right:0;bottom:0;height:1px;z-index:2;
  background:linear-gradient(to right,transparent,var(--red) 22%,var(--red) 78%,transparent);
  transform:scaleX(0);transform-origin:center;
  transition:transform 1.2s var(--ease-cut) .35s;
}
html.tx-open .tx-ridge{transform:scaleX(1)}

/* --------------------------------------------------------------------------
   3  DEPTH. The grid holds one vanishing point; cards tilt within it. The
   photograph moves against the tilt, which is what sells the glass.
   -------------------------------------------------------------------------- */
.tiles,.sectors,.values{perspective:1500px;perspective-origin:50% 42%}

.tile,.sector,.value{
  transition:transform .5s var(--ease-out),box-shadow .5s var(--ease-out),opacity .5s;
  transform:translate3d(0,0,0);
}
.tile.tx-lit,.sector.tx-lit,.value.tx-lit{will-change:transform}

.tile.tx-lit{
  transform:translate3d(0,var(--lift),0)
            rotateX(calc(var(--my,0) * -1 * var(--tilt) * 1deg))
            rotateY(calc(var(--mx,0) * var(--tilt) * 1deg));
  box-shadow:0 34px 70px -34px rgba(0,0,0,.95),0 0 0 1px rgba(210,16,30,.4);
  z-index:2;
}
.value.tx-lit{
  transform:translate3d(0,-6px,0)
            rotateX(calc(var(--my,0) * -4deg))
            rotateY(calc(var(--mx,0) * 4deg));
}
.sector.tx-lit{
  transform:rotateX(calc(var(--my,0) * -3deg)) rotateY(calc(var(--mx,0) * 3deg));
  z-index:2;
}

/* the rest of the row steps back while one card is held */
.tiles.tx-hold .tile:not(.tx-lit),
.sectors.tx-hold .sector:not(.tx-lit){opacity:.72}

/* photography counter-parallax: the image lags the tilt, the copy leads it */
.tile.tx-lit img{
  transform:scale(1.1) translate3d(calc(var(--mx,0) * -18px),calc(var(--my,0) * -14px),0);
  filter:grayscale(0) brightness(.76) contrast(1.04);
}
.sector.tx-lit img{
  transform:scale(1.07) translate3d(calc(var(--mx,0) * -12px),calc(var(--my,0) * -9px),0);
}
/* the wrapper is a span so that `.values div` cannot reach it, which means
   `.sector span` and `.values span` can. Reset what they would otherwise
   inherit onto a layout element. */
.tile > .tx-body,.sector > .tx-body,.value > .tx-body,
.tile > .tx-glass,.sector > .tx-glass,.value > .tx-glass{
  max-width:none;font-size:inherit;color:inherit;margin:0;
}
.tx-body{
  display:block;
  transition:transform .5s var(--ease-out);
  transform:translate3d(0,0,0);
}
.tile.tx-lit .tx-body{transform:translate3d(calc(var(--mx,0) * 9px),calc(var(--my,0) * 7px),0)}
.sector.tx-lit .tx-body{transform:translate3d(calc(var(--mx,0) * 6px),calc(var(--my,0) * 5px),0)}

/* --------------------------------------------------------------------------
   4  LOCK-ON. The glass plate over each card: one specular band that tracks
   the pointer, one edge rule, four brackets that snap in on acquisition.
   -------------------------------------------------------------------------- */
.tx-glass{
  display:block;
  position:absolute;inset:0;z-index:4;pointer-events:none;
  opacity:0;transition:opacity .3s var(--ease-out);
}
.tx-lit > .tx-glass{opacity:1}
.tx-glass::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(460px circle at var(--px,50%) var(--py,50%),
             rgba(244,246,249,.085),rgba(244,246,249,.02) 42%,transparent 66%);
}
.tx-glass::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;background:var(--red);
  transform:scaleX(0);transform-origin:left;
  transition:transform .42s var(--ease-cut);
}
.tx-lit > .tx-glass::after{transform:scaleX(1)}

.tx-glass i{
  position:absolute;width:15px;height:15px;
  border:1px solid var(--red);
  opacity:0;transform:scale(.55);
  transition:opacity .2s var(--ease-out),transform .24s var(--ease-out);
}
.tx-glass i:nth-child(1){top:12px;left:12px;border-right:0;border-bottom:0}
.tx-glass i:nth-child(2){top:12px;right:12px;border-left:0;border-bottom:0;transition-delay:.03s}
.tx-glass i:nth-child(3){bottom:12px;left:12px;border-right:0;border-top:0;transition-delay:.06s}
.tx-glass i:nth-child(4){bottom:12px;right:12px;border-left:0;border-top:0;transition-delay:.09s}
.tx-lit > .tx-glass i{opacity:1;transform:none}

/* the reticle hands over to the card: the ring collapses to a point */
html.tx-lock .cur-ring{
  width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  border-color:var(--red);border-width:1px;
}
html.tx-lock .cur-ring::before,html.tx-lock .cur-ring::after{opacity:0}

/* --------------------------------------------------------------------------
   5  CUT. Full-bleed sections do not fade in. A crimson rule wipes the edge,
   the section is revealed behind it. Three per page at most.
   -------------------------------------------------------------------------- */
.tx-cut{
  position:absolute;left:0;right:0;top:0;height:1px;z-index:6;
  background:var(--red);transform:scaleX(0);transform-origin:left;
  pointer-events:none;
}
.tx-cut.on{animation:txWipe .72s var(--ease-cut) forwards}
@keyframes txWipe{
  0%{transform:scaleX(0);transform-origin:left}
  55%{transform:scaleX(1);transform-origin:left}
  56%{transform:scaleX(1);transform-origin:right}
  100%{transform:scaleX(0);transform-origin:right}
}

/* --------------------------------------------------------------------------
   6  TYPE. Display lines rise word by word behind a mask instead of the whole
   block clipping at once. Applied by the script to [data-r="mask"].
   -------------------------------------------------------------------------- */
.tx-split{opacity:1;animation:none!important;clip-path:none!important}
.tx-w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.tx-w > i{
  display:inline-block;font-style:inherit;font-weight:inherit;
  transform:translateY(108%);
}
.tx-split.seen .tx-w > i{
  animation:txWord .78s var(--ease-out) forwards;
  animation-delay:calc(var(--d,0s) * .58 + var(--i,0) * .042s);
}
@keyframes txWord{from{transform:translateY(108%)}to{transform:translateY(0)}}

/* --------------------------------------------------------------------------
   7  NAVIGATION. Out of the way on the way down, back on the way up.
   -------------------------------------------------------------------------- */
.nav{transition:background .3s var(--ease-out),backdrop-filter .3s,border-color .3s,
                padding .3s var(--ease-out),transform .42s var(--ease-out)}
html.tx-hide-nav .nav{transform:translateY(-103%)}

/* --------------------------------------------------------------------------
   8  SCROLL DEPTH. Held photography breathes as the copy passes it.
   -------------------------------------------------------------------------- */
.tx .duo-media img{height:116%;position:relative;top:-8%;will-change:transform}
.tx .close-band img{height:126%;top:-13%;will-change:transform}

/* buttons pull very slightly toward the pointer */
.btn.tx-mag{transform:translate3d(var(--bx,0px),calc(var(--by,0px) - 2px),0)}

/* --------------------------------------------------------------------------
   9  GUARDS. Touch, reduced motion, and print get none of it.
   -------------------------------------------------------------------------- */
@media(hover:none),(pointer:coarse){
  .tx-glass,.tx-sigil{display:none}
  .tile.tx-lit,.sector.tx-lit,.value.tx-lit{transform:none;box-shadow:none}
  .tiles,.sectors,.values{perspective:none}
}

@media(prefers-reduced-motion:reduce){
  .tx-bar,.tx-sigil,.tx-snow,.tx-ridge,.tx-glass,.tx-cut{display:none!important}
  .tile,.sector,.value{transform:none!important;box-shadow:none!important}
  .tiles.tx-hold .tile:not(.tx-lit),.sectors.tx-hold .sector:not(.tx-lit){opacity:1}
  .tx-w > i,.tx-split.seen .tx-w > i{transform:none!important;animation:none!important}
  .curtain img{animation:none}
  html.tx-hide-nav .nav{transform:none}
  .tx .duo-media img,.tx .close-band img{height:100%;top:0;transform:none!important}
  .tx .plate-media img,.tx .plate-media video{transform:none!important;animation:none!important}
  .btn.tx-mag{transform:none!important}
}

@media print{.tx-bar,.tx-sigil,.tx-snow,.tx-glass,.tx-cut,.tx-ridge{display:none}}

/* --------------------------------------------------------------------------
   10  SURFACE. The base build is flat black, which reads as empty rather than
   as material. Three things fix that, in this order of importance:

     a  a 2x2 carbon twill across the page, fixed to the viewport at 5%
     b  alternating section planes, so the page reads as stacked sheets
     c  a soft light that follows the pointer, so the black is lit, not dead

   Every value is a token. If it is too much, lower --tex-a and --spot-a
   before you change anything else.
   -------------------------------------------------------------------------- */
:root{
  --tex:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg stroke='%23ffffff' stroke-width='.65' stroke-opacity='.6' fill='none'%3E%3Cpath d='M0 4 L4 0 M0 2 L2 0 M2 4 L4 2'/%3E%3Cpath d='M4 0 L8 4 M4 2 L6 4 M6 0 L8 2'/%3E%3Cpath d='M0 4 L4 8 M0 6 L2 8 M2 4 L4 6'/%3E%3Cpath d='M4 8 L8 4 M4 6 L6 4 M6 8 L8 6'/%3E%3C/g%3E%3C/svg%3E");
  --tex-size:8px;
  --tex-a:.05;          /* page weave. .03 is barely there, .09 is loud */
  --tex-card-a:.075;    /* weave inside a card on acquisition */
  --plane:rgba(18,22,30,.5);   /* the lifted section tint, cool graphite */
  --plane-edge:rgba(244,246,249,.07);
  --spot-a:.1;          /* the light that follows the pointer */
}

/* a. the weave. Fixed to the viewport, so it behaves like a screen texture
   rather than a wallpaper sliding under the content. */
.tx body::after{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--tex);
  background-size:var(--tex-size) var(--tex-size);
  opacity:var(--tex-a);
}

/* b. planes. Alternate sections carry a translucent tint, so the weave stays
   continuous underneath and the sections still read as separate sheets. */
.tx .block,.tx .block-tight{position:relative;isolation:isolate}
.tx .tx-plane{background:var(--plane)}
.tx .block::before,.tx .block-tight::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:-1;
  background:linear-gradient(to right,transparent,var(--plane-edge) 16%,
             var(--plane-edge) 84%,transparent);
}
.tx .block::after,.tx .block-tight::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(120% 58% at 50% 0%,rgba(244,246,249,.04),transparent 68%);
}

/* panels get a single raking highlight rather than a flat fill */
.tx .tile,.tx form,.tx .facet{
  background-image:linear-gradient(157deg,rgba(244,246,249,.028) 0%,
                   rgba(244,246,249,.006) 38%,transparent 62%);
}

/* c. the light. One translated element, never a repainted gradient. */
.tx-spot{
  position:fixed;top:0;left:0;width:820px;height:820px;margin:-410px 0 0 -410px;
  z-index:-1;pointer-events:none;opacity:0;
  background:radial-gradient(circle,rgba(176,192,214,.1) 0%,
             rgba(176,192,214,.03) 40%,transparent 68%);
  transition:opacity .6s var(--ease-out);
  will-change:transform;
}
.tx-spot.live{opacity:1}

/* the weave returns inside a card on acquisition, strongest at the pointer */
.tx-glass b{
  position:absolute;inset:0;display:block;
  background-image:var(--tex);
  background-size:var(--tex-size) var(--tex-size);
  opacity:var(--tex-card-a);
  -webkit-mask-image:radial-gradient(320px circle at var(--px,50%) var(--py,50%),
                     #000 0%,rgba(0,0,0,.45) 45%,transparent 72%);
  mask-image:radial-gradient(320px circle at var(--px,50%) var(--py,50%),
             #000 0%,rgba(0,0,0,.45) 45%,transparent 72%);
}

@media(hover:none),(pointer:coarse){
  .tx-spot{display:none}
  .tx-glass b{display:none}
}
@media(prefers-reduced-motion:reduce){
  .tx-spot{display:none!important}
}
@media print{.tx body::after,.tx-spot{display:none}}
