/* GerencialTIC motion layer (proposal ui-a).
   Rules: transform/opacity only (no layout shift), one easing family, everything off under
   prefers-reduced-motion. Content is fully visible without JS: hidden states only apply
   when motion.js has set html.m-on. */
:root {
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
  --t-fast: 180ms;
  --t-med: 420ms;
  --header-h: 68px;
}
@media (max-width: 760px) { :root { --header-h: 60px; } }


/* 2. Active section in the nav: a hairline that grows from the left. */
.top nav a { position: relative; padding-block: 6px; transition: color var(--t-fast) var(--ease-soft); }
.top nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; background: #fff;
  transform: scaleX(0); transform-origin: left; transition: transform var(--t-med) var(--ease-out); }
.top nav a:hover::after, .top nav a[aria-current="true"]::after { transform: scaleX(1); }
.top nav a[aria-current="true"] { color: #fff; }
/* Reading progress: 2px line on the bottom edge of the header. */
.top { --p: 0; }
.top::after { content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 100%; background: #fff; opacity: .55;
  transform: scaleX(var(--p)); transform-origin: left; pointer-events: none; }

/* 3. Hover depth: cards rise 2px and the border catches light. Pointer devices only. */
.card, .trust > div { transition: transform var(--t-med) var(--ease-out), border-color var(--t-med) var(--ease-out), box-shadow var(--t-med) var(--ease-out); }
.tile { transition: transform var(--t-med) var(--ease-out), border-color var(--t-med) var(--ease-out), background-color var(--t-med) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .card:hover, .trust > div:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--text) 38%, var(--rule)); box-shadow: 0 14px 30px -18px rgba(0,0,0,.28); }
  .tile:hover { transform: translateY(-2px); border-color: #5a5a5a; background-color: #181818; }
  :root[data-theme="dark"] .tile:hover { background-color: #0c0c0c; }
}
/* Magnetic primary CTA: JS sets --mx/--my (max 5px); press gives a small settle. */
.btn { transition: transform var(--t-fast) var(--ease-out), background-color var(--t-fast), opacity var(--t-fast), color var(--t-fast); }
.btn-primary.mag { transform: translate(var(--mx, 0px), var(--my, 0px)); }
.btn:active { transform: translate(var(--mx, 0px), var(--my, 0px)) scale(.97); }

/* 4. Hero chat: messages arrive one by one, with a typing indicator made of the brand dots. */
/* From first paint (m-demo is set in <head> with m-on) only the first message is visible, so there is no flash.
   Under reduced motion m-demo is only set when the visitor presses Reproducir (gentle mode, m-gentle). */
/* Messages that have not arrived yet take no space, so the stack stays anchored to the bottom like a
   real chat; each arrival settles in with a short rise. The ERP card appears on the lookup step. */
.m-demo .thread.live > :not(.is-shown):not(.typing) { display: none; }
.m-demo .thread.live > .is-shown { animation: msgIn 420ms var(--ease-out) both; }
.m-demo .thread.live.fading > .is-shown { animation: none; opacity: 0; transition: opacity 600ms var(--ease-out); }
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.m-demo .demo > .erp-float { opacity: 0; transform: translateY(10px); transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out); }
.m-demo .demo.erp-shown > .erp-float { opacity: 1; transform: none; }
.m-demo .demo.fading > .erp-float { opacity: 0; transition-duration: 600ms; }
.m-demo .erp-float .handoff { opacity: 0; transition: opacity 420ms var(--ease-out); }
.m-demo .demo.handoff-shown .erp-float .handoff { opacity: 1; }
.typing { display: none; gap: 5px; align-items: center; padding: 12px 15px; border-radius: 16px; pointer-events: none; }
.typing.on { display: inline-flex; animation: msgIn 240ms var(--ease-out) both; }
.typing.in { background: var(--in-bg); border-bottom-left-radius: 4px; align-self: flex-start; }
.typing.out { background: var(--out-bg); border-bottom-right-radius: 4px; align-self: flex-end; }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: dot 1.1s var(--ease-soft) infinite; }
.typing.in i { color: var(--meta); } .typing.out i { color: var(--out-fg); }
.typing i:nth-child(2) { animation-delay: .15s; } .typing i:nth-child(3) { animation-delay: .3s; }
@keyframes dot { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }
/* Product boards: each [data-step] is hidden in place (no layout shift) until motion.js reveals it;
   a value with data-from first flies from its highlighted source (.fly is the clone in flight). */
.m-demo .scene.is-board [data-step]:not(.is-shown) { visibility: hidden; opacity: 0; }
.m-demo .scene.is-board [data-step].is-shown { animation: msgIn 420ms var(--ease-out) both; }
.m-demo .scene.is-board .reveal.pending { visibility: hidden; opacity: 0; }
.m-demo .scene.is-board .reveal { transition: opacity 420ms var(--ease-out); }
.fly { position: absolute; z-index: 3; pointer-events: none; white-space: nowrap; font-size: .86rem; font-weight: 600; color: var(--erp-fg);
  background: color-mix(in srgb, var(--accent) 22%, var(--erp-bg)); border-radius: 4px; padding: 1px 5px; box-shadow: 0 10px 24px -12px rgba(0,0,0,.5); }
/* Custodio map: the unit crawls along the corridor; the stop alert pulses. */
.m-demo .map-ov .u07 { animation: crawl 12s linear infinite; }
@keyframes crawl { from { offset-distance: 30%; } to { offset-distance: 33.6%; } }
.m-demo .map-ov .ring { animation: ring 1.6s var(--ease-out) infinite; transform-box: fill-box; transform-origin: center; }
@keyframes ring { from { transform: scale(.6); opacity: .6; } to { transform: scale(2.2); opacity: 0; } }
.m-paused .map-ov .u07, .m-paused .map-ov .ring { animation-play-state: paused; }
/* Chat-style steps (Custodio's chat móvil) take no space until they arrive, like the hero thread. */
.m-demo .scene.is-board.is-active [data-step].grow:not(.is-shown) { display: none; }   /* inactive scenes keep their full layout, so the stage reserves the tallest final state */
/* Escort route: the dot travels the line while the scenario plays. */
.m-demo .route-dot { animation: route 6s linear infinite; }
@keyframes route { from { offset-distance: 0%; } to { offset-distance: 100%; } }
.m-paused .route-dot { animation-play-state: paused; }
.m-demo .scene.leaving { opacity: 0; transition: opacity 400ms var(--ease-out); }
/* Pause control (WCAG 2.2.2), inline in the demo footer next to the caption. */
.chat-pause { display: inline-flex; align-items: center; gap: 8px; background: var(--erp-bg); color: var(--erp-fg); border: 1px solid var(--erp-line); border-radius: 999px; padding: 7px 14px 7px 11px;
  font: 600 .8rem/1 var(--font); cursor: pointer; transition: border-color var(--t-fast); }
.chat-pause:hover { border-color: var(--text); }
.chat-pause:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.chat-pause svg { width: 12px; height: 12px; fill: currentColor; }

/* 5. Brand dot-grid: a slow band of light sweeps across the dots. Very low contrast on purpose. */
.panel.dots::before { -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.55) 0 35%, #000 50%, rgba(0,0,0,.55) 65% 100%);
  mask-image: linear-gradient(90deg, rgba(0,0,0,.55) 0 35%, #000 50%, rgba(0,0,0,.55) 65% 100%);
  -webkit-mask-size: 300% 100%; mask-size: 300% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0;
  animation: sweep 14s linear infinite; }
@keyframes sweep { to { -webkit-mask-position: 0 0; mask-position: 0 0; } }
.m-paused .panel.dots::before { animation-play-state: paused; }

/* 6. Industry tabs: a pill slides under the active label; the pane cross-fades and its tiles settle in sequence. */
.tabs { position: relative; isolation: isolate; }
.tabs .pill { position: absolute; z-index: -1; left: 0; top: 0; border-radius: 999px; background: var(--text); pointer-events: none;
  transition: transform 460ms var(--ease-out), width 460ms var(--ease-out); }
.tabs.has-pill label { transition: color 260ms var(--ease-soft), border-color 260ms var(--ease-soft); }
.tabs.has-pill label.is-active { color: var(--paper); border-color: transparent; }
/* With the pill present, the static black background on the checked label is replaced by the pill. */
#t1:checked ~ .tabs.has-pill label[for="t1"], #t2:checked ~ .tabs.has-pill label[for="t2"], #t3:checked ~ .tabs.has-pill label[for="t3"], #t4:checked ~ .tabs.has-pill label[for="t4"], #t5:checked ~ .tabs.has-pill label[for="t5"], #t6:checked ~ .tabs.has-pill label[for="t6"], #t7:checked ~ .tabs.has-pill label[for="t7"] { background: transparent; border-color: transparent; }
.m-on .tabpanes > .pane .lead { animation: paneIn 420ms var(--ease-out) backwards; }
.m-on .tabpanes > .pane .tile { animation: tileIn 520ms var(--ease-out) backwards; }
.m-on .tabpanes > .pane .tile:nth-child(2) { animation-delay: 60ms; }
.m-on .tabpanes > .pane .tile:nth-child(3) { animation-delay: 120ms; }
.m-on .tabpanes > .pane .tile:nth-child(4) { animation-delay: 180ms; }
@keyframes paneIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes tileIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* 7. Scroll reveal, limited to groups of peers (cards, steps, rows): they settle in a short stagger
   the first time they enter. Section titles are never hidden. */
.m-on [data-reveal] > * { opacity: 0; transform: translateY(14px); transition: opacity 640ms var(--ease-out), transform 640ms var(--ease-out); transition-delay: calc(var(--i, 0) * 70ms); }
.m-on [data-reveal].is-in > * { opacity: 1; transform: none; }
/* motion.js removes data-reveal once the group has settled, so hover depth works again. */


/* Reduced motion: the page is static and complete. The hero demo shows each scenario's final state
   and does not autoplay; a visible Reproducir button lets the visitor opt in, and then it plays gently:
   crossfades only, no flying values, no moving markers (motion.js sets m-demo + m-gentle on press). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .m-on [data-reveal] > *, .m-on .thread > *, .m-on .demo > .erp-float, .m-on .erp-float .handoff { opacity: 1 !important; transform: none !important; display: revert !important; }
  .btn-primary.mag { transform: none; }
  .typing { display: none; }
  .top::after { display: none; }
  .map-ov .u07, .map-ov .ring, .route-dot { animation: none !important; }
  :root:not(.m-gentle) .thread > *, :root:not(.m-gentle) .demo > .erp-float, :root:not(.m-gentle) .erp-float .handoff { opacity: 1 !important; transform: none !important; display: revert !important; }
  :root:not(.m-gentle) .scene.is-board [data-step], :root:not(.m-gentle) .scene.is-board .reveal { visibility: visible !important; opacity: 1 !important; display: revert !important; }
  .m-gentle .demo-wrap .erp-float, .m-gentle .demo-wrap .handoff, .m-gentle .demo-wrap .reveal, .m-gentle .demo-wrap .scene, .m-gentle .demo-wrap .thread { transition: opacity 320ms ease !important; transform: none !important; }
  .m-gentle .demo-wrap .is-shown { animation: gentleIn 320ms ease both !important; transform: none !important; }
}
@keyframes gentleIn { from { opacity: 0; } to { opacity: 1; } }
