/* ======================= MM Glass — page cover + theme cover (vg-loader.js) =======================
   Linked from each page's <head> so the cover paints before any script runs (the CSP forbids inline styles: the markup
   is in the HTML, the look is here). The app's own page colour (#F2F2F7 light, #000 dark) with the Ventanal gótico mark
   and «MM GLASS» (2026-11-09, «Entrada C · Cortina de láminas», Isaac; docs/demos/animaciones-m2-ventanal.html). The
   mark waits 250 ms before it shows, so a quick page change never flashes it; the first open of the session
   (html.vgk-first) opens behind the glass-slat curtain. vg-loader.js removes the cover as soon as the page is ready
   (no minimum), with a 200 ms fade. (the in-app waits use the same Ventanal MM: .vgk-mini.)
   - .vgk-page   full-page cover: page start (markup in the HTML) and opening another app from a link (.is-nav: the
                 whole cover waits 250 ms, so a fast step stays instant);
   - .vgk-inline in-app wait (vg-wait.js loadingHtml / vg-loader.js waitHtml): the small coin (28 px, 20 px in .is-sm)
                 with its shine beside the text; appears only after 250 ms, so quick answers never flash it;
   - theme switch: View Transition rules below; .vgk-cover is the fallback layer for browsers without them. */
:root{--vgk-ink:#6b6f7b;--vgk-bg:#F2F2F7;--vgk-glyph:#2B3035;--vgk-shine:rgba(255,255,255,.85)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--vgk-ink:#9c9ea8;--vgk-bg:#000;--vgk-glyph:#DFE8EC;--vgk-shine:rgba(143,163,173,.95)}}
:root[data-theme="dark"]{--vgk-ink:#9c9ea8;--vgk-bg:#000;--vgk-glyph:#DFE8EC;--vgk-shine:rgba(143,163,173,.95)}

.vgk-sr{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;overflow:hidden!important;clip-path:inset(50%)!important;white-space:nowrap!important;border:0!important}

/* ---- full-page cover (2026-11-09, «Entrada C · Cortina de láminas», Isaac): the Ventanal gótico mark (mm-ventanal.svg;
   mm-ventanal-dark.svg on a dark page) is the cover's own ::before and «MM GLASS» (Barlow Condensed 600, loaded by
   entrada-hielo-boot.js) its ::after, so any cover markup paints them before a script runs; .vgk-fx (vg-loader.js) is
   the same box in the same grid cell, with the glass sweep clipped to the panes (mm-ventanal-mask.svg) that keeps
   running while the page loads. First open of the session (html.vgk-first): the page opens behind a curtain of 9 glass
   slats that turn open from the centre (.vgk-curtain, added by vg-loader.js, which marks the cover .is-c), the mark
   grows in behind it and the word opens its spacing. Before the module runs, the same slats are the cover background,
   so nothing changes when the real ones take over. The cover still goes as soon as the page is ready (no minimum). --- */
.vgk-page{--vgk-m:min(108px,30vw);--vgk-word:#2B3035;
  --vgk-slat:linear-gradient(104deg,#15171A 0%,#2B3035 38%,#8FA3AD 47%,#DFE8EC 49%,#4C535B 53%,#2B3035 70%,#15171A 100%);
  position:fixed;inset:0;z-index:2147483000;display:grid;grid-template:minmax(0,1fr)/minmax(0,1fr);place-items:center;background:var(--vgk-bg);pointer-events:none;contain:strict}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .vgk-page{--vgk-word:#ECEFF2}}
:root[data-theme="dark"] .vgk-page{--vgk-word:#ECEFF2}
.vgk-page::before,.vgk-page>.vgk-fx{grid-area:1/1;display:block;width:var(--vgk-m);aspect-ratio:1;margin-bottom:calc(var(--vgk-m) * .5);animation:vgk-rise .36s cubic-bezier(.22,.61,.36,1) .25s both}
.vgk-page::before{content:"";background:url("mm-ventanal.svg") 50% 50%/100% 100% no-repeat}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .vgk-page::before{background-image:url("mm-ventanal-dark.svg")}}
:root[data-theme="dark"] .vgk-page::before{background-image:url("mm-ventanal-dark.svg")}
.vgk-page::after{content:"MM GLASS";grid-area:1/1;margin-top:calc(var(--vgk-m) * .5 + 52px);padding-left:.2em;font:600 24px/26px "Barlow Condensed","Arial Narrow","Roboto Condensed",sans-serif;letter-spacing:.2em;white-space:nowrap;color:var(--vgk-word);animation:vgk-rise .36s cubic-bezier(.22,.61,.36,1) .25s both}
html.vgk-first #vg-boot:not(.is-c)::before,html.vgk-first #vg-boot:not(.is-c)::after,html.vgk-first #vg-boot:not(.is-c)>.vgk-fx{animation-delay:0s}   /* (the curtain open, .is-c, has its own timing) */
.vgk-page.is-nav::before,.vgk-page.is-nav::after,.vgk-page.is-nav>.vgk-fx{animation-delay:0s}   /* the link cover already waits 250 ms as a whole */
.vgk-page>:not(.vgk-fx):not(.vgk-curtain){display:none}   /* an older cover's markup (lens, «Cargando» caption) */
.vgk-fx{position:relative}
.vgk-sweep{position:absolute;inset:0;display:block;overflow:hidden;-webkit-mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat;mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat}
.vgk-sweep::after{content:"";position:absolute;top:-10%;bottom:-10%;left:0;width:34%;background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.85),rgba(255,255,255,0));
  transform:translateX(-120%) skewX(-18deg);animation:vgk-sweep 1.6s cubic-bezier(.45,0,.25,1) .45s infinite}
/* the curtain: before the module runs, its slats are the cover background (the same tile) */
html.vgk-first #vg-boot:not(.is-c){background:var(--vgk-slat) 0 0/calc(100% / 9) 100% repeat-x}
html.vgk-first #vg-boot:not(.is-c)::before,html.vgk-first #vg-boot:not(.is-c)::after,html.vgk-first #vg-boot:not(.is-c)>.vgk-fx{opacity:0;animation:none}
.vgk-curtain{position:absolute;inset:0;display:flex;perspective:900px;animation:vgk-gone 0s .95s both}
.vgk-curtain>i{--vgk-d:1;flex:1;display:block;backface-visibility:hidden;background:var(--vgk-slat);box-shadow:inset 1px 0 0 rgba(236,239,242,.35),inset -1px 0 0 rgba(0,0,0,.5);
  animation:vgk-slat .48s cubic-bezier(.6,0,.3,1) .12s both}
.vgk-curtain>i:nth-child(-n+4){--vgk-d:-1}
.vgk-curtain>i:is(:nth-child(4),:nth-child(6)){animation-delay:.17s}
.vgk-curtain>i:is(:nth-child(3),:nth-child(7)){animation-delay:.22s}
.vgk-curtain>i:is(:nth-child(2),:nth-child(8)){animation-delay:.27s}
.vgk-curtain>i:is(:nth-child(1),:nth-child(9)){animation-delay:.32s}
.vgk-page.is-c::before,.vgk-page.is-c>.vgk-fx{animation:vgk-markin .42s cubic-bezier(.2,.8,.2,1) .26s both}
.vgk-page.is-c::after{animation:vgk-wordin .42s cubic-bezier(.2,.8,.2,1) .82s both}
.vgk-page.is-c .vgk-sweep::after{animation-delay:.8s}
.vgk-page.is-nav{animation:vgk-fade .2s ease-out .25s both}   /* opening another app: nothing at all for a fast step */
.vgk-page.is-out{opacity:0;transform:scale(1.04);transition:opacity .2s cubic-bezier(.4,0,1,1),transform .2s cubic-bezier(.4,0,1,1)}   /* the one fade onto the finished page */
body.vg-intro-on .vgk-page{display:none}   /* (Poncheo's retired intro, while an older app.js could still draw it) */
@keyframes vgk-rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes vgk-markin{from{opacity:0;transform:scale(.88)}to{opacity:1;transform:none}}
@keyframes vgk-wordin{from{opacity:0;letter-spacing:0;padding-left:0}to{opacity:1;letter-spacing:.2em;padding-left:.2em}}
@keyframes vgk-slat{from{transform:rotateY(0deg);opacity:1}to{transform:rotateY(calc(var(--vgk-d) * 88deg));opacity:.2}}
@keyframes vgk-gone{to{visibility:hidden}}
@keyframes vgk-sweep{0%{transform:translateX(-120%) skewX(-18deg)}30%,100%{transform:translateX(320%) skewX(-18deg)}}
@keyframes vgk-shine{0%{transform:translateX(-75%)}55%,100%{transform:translateX(75%)}}

/* ---- moving between screens (2026-11-09, «Transición A · Puertas corredizas», Isaac; vg-doors.js): two glass leaves
   with an aluminium edge and the transom line close over the content, the screen changes behind them and they open
   again, 0.42 s in all. Opaque glass colour (no live blur in the apps, see below); composite-only motion. */
.vgd-doors{--vgd-glass:rgba(223,232,236,.94);--vgd-edge:#B2B9C1;position:fixed;left:0;right:0;top:0;bottom:0;z-index:2147482000;pointer-events:none;overflow:hidden;contain:strict}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .vgd-doors{--vgd-glass:rgba(43,48,53,.95);--vgd-edge:#8c949d}}
:root[data-theme="dark"] .vgd-doors{--vgd-glass:rgba(43,48,53,.95);--vgd-edge:#8c949d}
.vgd-doors>i{position:absolute;top:0;bottom:0;width:50%;display:block;overflow:hidden;background:var(--vgd-glass)}
.vgd-doors>.vgd-l{left:0;border-right:3px solid var(--vgd-edge);transform:translateX(-101%)}
.vgd-doors>.vgd-r{right:0;border-left:3px solid var(--vgd-edge);transform:translateX(101%)}
.vgd-doors>i::before{content:"";position:absolute;left:0;right:0;top:54%;height:2px;background:var(--vgd-edge);opacity:.8}
.vgd-doors>i::after{content:"";position:absolute;top:-20%;bottom:-20%;left:20%;width:26%;background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.5),rgba(255,255,255,0));transform:skewX(-18deg)}

/* ---- in-app wait (vg-wait.js loadingHtml / vg-loader.js waitHtml): the small Ventanal MM with its glass shine beside the
   text, centred in its view; fades in after 250 ms so a quick answer never flashes it. .is-sm: rows and cards. */
.vgk.vgk-inline{display:flex;align-items:center;justify-content:center;gap:10px;min-height:120px;padding:24px 16px;animation:vgk-fade .2s ease-out .25s both}
.vgk.vgk-inline.is-now{animation:none}
.vgk.vgk-inline.is-sm{justify-content:flex-start;gap:8px;min-height:0;padding:6px 0}
.vgk-inline .vgk-wait-text{color:var(--vgk-ink);text-align:start}
@keyframes vgk-fade{from{opacity:0}to{opacity:1}}
.vgk-mini{--vgk-s:28px;position:relative;display:block;flex:none;width:var(--vgk-s);height:var(--vgk-s);overflow:hidden;isolation:isolate;
  background:var(--vgk-glyph);-webkit-mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat;mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat}
/* the glass shine crossing the Ventanal MM (clipped to its panes by the mask): composite-only, endless while waiting */
.vgk-mini::after{content:"";position:absolute;top:-10%;bottom:-10%;left:0;width:45%;background:linear-gradient(90deg,rgba(255,255,255,0),var(--vgk-shine),rgba(255,255,255,0));
  transform:translateX(-120%);animation:vgk-mini-shine 1.4s cubic-bezier(.4,0,.2,1) infinite}
@keyframes vgk-mini-shine{from{transform:translateX(-120%)}to{transform:translateX(260%)}}
.is-sm>.vgk-mini{--vgk-s:20px}
.vgk-mini>*{display:none}   /* an older markup's lens / ring spans */
.vgk-mini::after{display:block}
/* Nómina's own wait (payroll-render.js .rg-load) if an older module draws it without the coin */
.rg-load:not(:has(.vgk-mini)){display:flex;align-items:center;justify-content:center;gap:10px;padding:40px 0;text-align:center}
.rg-load:not(:has(.vgk-mini))::before{content:"";display:block;flex:none;width:28px;height:28px;background:var(--vgk-glyph);-webkit-mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat;mask:url("mm-ventanal-mask.svg") 50% 50%/100% 100% no-repeat}
html.vg-scrolling :is(.vgk-mini,.vgk-sweep)::after{animation-play-state:paused}
html.vg-lite .vgk-mini::after{animation:none;opacity:0}

/* ---- theme switch (vg-loader.js revealTheme) ----------------------------------------------------------------------
   View Transition: the new page, clipped by the growing circle, over the old one; both snapshots stay fully opaque
   (no cross-fade, no blend), the group lasts as long as the circle (850 ms). While it runs: no CSS transitions (and no
   backdrop blurs on touch / lite devices, where the glass is opaque anyway) — a switch-time stylesheet adopted by vg-loader.js (html.vgk-switching / html.vgk-still are markers). */
/* (anchored on html: a rule whose selector is only a pseudo-element is otherwise tried on every element at every style pass) */
html::view-transition-old(root),html::view-transition-new(root){animation:none;mix-blend-mode:normal;opacity:1}
html::view-transition-old(root){z-index:1}
html::view-transition-new(root){z-index:2}
html::view-transition-group(root){animation-duration:.85s}
/* while the switch runs, vg-loader.js adopts a constructed stylesheet (no transitions; touch / lite: no blurs) — not rules here:
   universal selectors in the page's own stylesheets are tried on every element at every style pass */
/* fallback without View Transitions: a plain layer in the new theme's page colour */
.vgk-cover{position:fixed;inset:0;z-index:2147483600;pointer-events:none;contain:strict;will-change:clip-path,opacity;background:#e6e6eb}
.vgk-cover[data-to="dark"]{background:#060708}

/* ---- no live backdrop blur on any screen (22-oct) ------------------------------------------------------------------
   The glass panes are opaque, their colour pre-blended over the page (vg-dash.css, vg-glass-poncheo.css, vg-presence.css,
   stats.css): a blur under them added nothing visible but re-rendered everything behind on every scroll / 3D frame —
   the heaviest GPU work in the apps, and what made laptops with an integrated GPU stutter. This one rule drops whatever
   blur is left (the Workshop's own panels, dialogs' backdrops). Five :not(#id) outrank the apps' own !important rules. */
html:not(#vg0):not(#vg0):not(#vg0):not(#vg0):not(#vg0) *,html:not(#vg0):not(#vg0):not(#vg0):not(#vg0):not(#vg0) *::before,
html:not(#vg0):not(#vg0):not(#vg0):not(#vg0):not(#vg0) *::after,html:not(#vg0):not(#vg0):not(#vg0):not(#vg0):not(#vg0) *::backdrop{-webkit-backdrop-filter:none!important;backdrop-filter:none!important}

/* the lite tier (html.vg-lite, vg-tier.js: a weak or software GPU): the endless decorative pulses stand still (the «En
   vivo» dots, the live chart point, the brand sheen); the dots themselves stay */
html.vg-lite :is(.vgl-head em u,.vgl-toggle u,.vgv-dot u,.hero .brandmark .bm-sheen)::after,html.vg-lite .hero .brandmark .bm-sheen::before,
html.vg-lite .st .sx3-live i,html.vg-lite .st .sx3-lines .dot.on{animation:none!important}
/* …and the search button's typed hint shows whole and still (its typing redrew the header a few times a second) */
html.vg-lite :is(#app,#shared-workshop) .vg-global>button[data-global="open"]::after{animation:none!important;clip-path:none!important}
/* while the page scrolls under the mouse wheel / trackpad (html.vg-scrolling, vg-loader.js) the endless decorations hold
   still: each pulse or typed letter made the compositor draw extra frames in the middle of the scroll (measured: half of
   the frames dropped while scrolling Poncheo on a 165 Hz laptop); they carry on where they were once it stops */
html.vg-scrolling :is(.vgl-head em u,.vgl-toggle u,.vgv-dot u)::after,html.vg-scrolling .st .sx3-live i,html.vg-scrolling .st .sx3-lines .dot.on,
html.vg-scrolling :is(#app,#shared-workshop) .vg-global>button[data-global="open"]::after{animation-play-state:paused!important}

@media (prefers-reduced-motion: reduce){
  .vgk-inline{animation:none!important}
  .vgk-page::before,.vgk-page::after,.vgk-page>.vgk-fx,.vgk-page.is-nav{animation:none!important}
  .vgk-curtain,.vgd-doors{display:none!important}
  html.vgk-first #vg-boot:not(.is-c){background:var(--vgk-bg)}
  html.vgk-first #vg-boot:not(.is-c)::before,html.vgk-first #vg-boot:not(.is-c)::after{opacity:1}
  .vgk-mini::after,.vgk-sweep::after{animation:none!important;opacity:0}
  .vgk-page.is-out{transition:none}
}
