/* =====================================================================
   SKILL-VISION Estimator — motion & interaction layer.
   Loaded last by index.html and module/recruiting.html, so it refines the
   transitions declared in style.css / recruiting.css.
   Rules: 150–250ms, ease-out only. Animate transform, opacity and colour,
   never layout properties, so nothing shifts. No shadows (design law):
   focus is an outline ring. Print and the PDF render are never animated.
   ===================================================================== */

:root{
  --dur-fast:150ms;--dur:200ms;--dur-slow:250ms;
  --ease-out:cubic-bezier(.16,1,.3,1);
  --press:.98;
  /* instructions.md presets */
  --page-in:160ms;--ease-page-in:cubic-bezier(.2,0,0,1);
  --page-out:120ms;--ease-page-out:cubic-bezier(.4,0,1,1);
  /* SNAPPY_TAB_SPRING {stiffness:600,damping:35,mass:.5}: x(t)=1-4e^(-30t)+3e^(-40t), 99% at 200ms */
  --spring-dur:300ms;
  --spring:linear(0,.048 3.3%,.153 6.7%,.277 10%,.401 13.3%,.513 16.7%,.611 20%,.693 23.3%,.759 26.7%,.813 30%,.856 33.3%,.915 40%,.951 46.7%,.972 53.3%,.984 60%,.991 66.7%,.996 76.7%,.998 86.7%,1);
}
/* Theme-aware helpers: estimator tokens by default, shell tokens on body.sv-shell. */
body{--focus:var(--primary);--skel:var(--muted);--skel-card:var(--card);--skel-border:var(--border)}
body.sv-shell{--focus:var(--sv-accent);--skel:var(--sv-surface-2);--skel-card:var(--sv-surface);--skel-border:var(--sv-border)}
/* cream-on-cream is too faint: light placeholders use the next neutral step */
body.light-theme,:root[data-theme="light"] body.sv-shell{--skel:var(--neutral-200)}

/* ---- buttons & clickable controls: hover colour, press scale, focus ring ---- */
.sv-btn,.sv-icon-btn,.btn,.btn-p,.btn-s,.btn-sh,.btn-chip,.lbtn,.edit-banner button,
.mail-opt,.theme-toggle,.sel-opt,.ni,.mail-open{
  transition-property:background-color,border-color,color,opacity,transform,outline-color;
  transition-duration:var(--dur-fast);transition-timing-function:var(--ease-out);
  outline:2px solid transparent;outline-offset:2px;
  -webkit-tap-highlight-color:transparent;
}
.sv-btn:active:not(:disabled),.sv-icon-btn:active:not(:disabled),.btn:active:not(:disabled),
.btn-p:active:not(:disabled),.btn-s:active:not(:disabled),.btn-sh:active:not(:disabled),
.btn-chip:active,.lbtn:active,.edit-banner button:active,.mail-opt:active:not(:disabled),
.theme-toggle:active,.sel-opt:active,.ni:active,.mail-open:active{transform:scale(var(--press))}
.sv-btn:focus-visible,.sv-icon-btn:focus-visible,.btn:focus-visible,.btn-p:focus-visible,.btn-s:focus-visible,
.btn-sh:focus-visible,.btn-chip:focus-visible,.lbtn:focus-visible,.edit-banner button:focus-visible,
.mail-opt:focus-visible,.theme-toggle:focus-visible,.sel-opt:focus-visible,.ni:focus-visible,.mail-open:focus-visible{outline-color:var(--focus)}
/* hover states the base styles did not have */
.btn-chip:hover{border-color:var(--primary);color:var(--foreground)}
.btn-b:hover,.btn-rd:hover,.btn-am:hover{opacity:.88}
.edit-banner button:hover{background:var(--muted)}
.theme-toggle:hover{border-color:var(--primary);color:var(--foreground)}
.sv-btn:disabled,.btn:disabled,.btn-p:disabled,.btn-s:disabled,.btn-sh:disabled{cursor:not-allowed;opacity:.6}

/* ---- inputs: hover border, focus border + soft ring (outline, not shadow) ---- */
.igrp input,.igrp select,.igrp textarea,.fg input,.fg select,.fg textarea,.ri,.search-bar,.cod-inp,.ah-inp,
.lf input,.sv-login-card input,.sv-modal input,.sv-modal select{
  transition-property:border-color,background-color,outline-color;
  transition-duration:var(--dur-fast);transition-timing-function:var(--ease-out);
  outline:3px solid transparent;outline-offset:0;
}
.igrp input:hover,.igrp select:hover,.igrp textarea:hover,.fg input:hover,.fg select:hover,.fg textarea:hover,
.ri:hover,.search-bar:hover,.ah-inp:hover{border-color:var(--border-strong)}
.sv-login-card input:hover,.sv-modal input:hover,.sv-modal select:hover{border-color:var(--sv-text-3)}
.igrp input:focus,.igrp select:focus,.igrp textarea:focus,.fg input:focus,.fg select:focus,.fg textarea:focus,
.ri:focus,.search-bar:focus,.ah-inp:focus,.lf input:focus,.sv-login-card input:focus,.sv-modal input:focus,.sv-modal select:focus{
  border-color:var(--focus);outline:3px solid color-mix(in srgb,var(--focus) 25%,transparent);outline-offset:0;
}
.cod-inp:focus{outline:3px solid color-mix(in srgb,var(--inverse-highlight) 25%,transparent)}
.sc-chk-inline:focus-visible,.mail-dl input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* ---- cards: quiet border response on hover / while editing inside ---- */
.ic,.sel-card,.card,.kpi,.uc,.cm,.sv-feature,.sol-c{transition:border-color var(--dur) var(--ease-out),opacity var(--dur) var(--ease-out)}
.ic:hover,.sel-card:hover,.card:hover,.uc:hover,.cm:hover,.ic:focus-within,.sel-card:focus-within{border-color:var(--border-strong)}
.sv-feature:hover{border-color:color-mix(in srgb,var(--sv-accent) 40%,var(--sv-border))}
.sel-rd,.sel-dot{transition:border-color var(--dur-fast) var(--ease-out),background-color var(--dur-fast) var(--ease-out),transform var(--dur-fast) var(--ease-out)}
.sel-opt:not([class*="act-"]) .sel-dot{transform:scale(0)}
td{transition:background-color var(--dur-fast) var(--ease-out)}
/* recent-quotes rows on the dashboard */
.dash-row{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px;margin:0 -8px;border-bottom:1px solid var(--border);border-radius:10px;font-size:12px;cursor:pointer;transition:background-color var(--dur-fast) var(--ease-out)}
.dash-row:hover{background:var(--primary-soft)}
.dash-row:last-child{border-bottom:none}
.dash-row-name{font-weight:600;color:var(--foreground)}
.dash-row-meta{color:var(--muted-foreground)}
.dash-row-sum{text-align:right;font-weight:600;color:var(--primary-ink)}
.dash-row-sum small{display:block;font-size:10px}

/* ---- screens & pages (instructions.md FAST_PAGE_VARIANTS, js/motion.js presence) ----
   enter 160ms [.2,0,0,1] from opacity 0 · scale .985 · y 4px; exit 120ms [.4,0,1,1] to y -4px.
   The leaving view keeps its box until the next one enters, so the container never collapses. */
.sv-screen.on,#screen-prev,#app,.page.on{animation:sv-view-in var(--page-in) var(--ease-page-in) both}
.sv-screen.is-leaving,#screen-prev.is-leaving,#app.is-leaving,.page.is-leaving{animation:sv-view-out var(--page-out) var(--ease-page-out) forwards;pointer-events:none}
@keyframes sv-view-in{from{opacity:0;transform:translateY(4px) scale(.985)}}
@keyframes sv-view-out{to{opacity:0;transform:translateY(-4px) scale(.985)}}

/* ---- sliding active-item pill (layoutId="activeTab"), admin sidebar ----
   one element per nav, moved with transform only; the spring has no overshoot. */
.sb-nav{position:relative}
.nav-pill{position:absolute;top:0;left:0;border-radius:16px;background:var(--primary);pointer-events:none;will-change:transform}
.nav-pill.is-ready{transition:transform var(--spring-dur) var(--spring)}
.sb-nav .ni{position:relative;z-index:1}
.sb-nav .ni.on,.sb-nav .ni.on:hover{background:transparent}

/* ---- micro-stagger (STAGGER_CARD_VARIANTS): 30ms per item, 180ms ease-out, y 6px ----
   only real content animates (placeholders stay put); capped at 10 steps. */
.stagger>:not(.skel):not([aria-hidden]){animation:sv-card-in 180ms ease-out calc(var(--i,0)*30ms) both}
.stagger>:nth-child(2){--i:1}.stagger>:nth-child(3){--i:2}.stagger>:nth-child(4){--i:3}
.stagger>:nth-child(5){--i:4}.stagger>:nth-child(6){--i:5}.stagger>:nth-child(7){--i:6}
.stagger>:nth-child(8){--i:7}.stagger>:nth-child(9){--i:8}.stagger>:nth-child(n+10){--i:9}
@keyframes sv-card-in{from{opacity:0;transform:translateY(6px)}}

/* ---- modals: overlay fades, panel scales up from .98; exit animates where supported ---- */
/* estimator dialogs are anchored near the top: content arriving later only grows them downward */
.modal-ov{align-items:flex-start;padding-top:min(10vh,96px)}
.modal{max-height:calc(100vh - 2*min(10vh,96px))}
.modal-ov,.sv-modal-ov{opacity:0;transition:opacity var(--dur) var(--ease-out),display var(--dur) allow-discrete}
.modal-ov.on,.sv-modal-ov.on{opacity:1}
.modal,.sv-modal{opacity:0;transform:translateY(8px) scale(var(--press));transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out)}
.modal-ov.on .modal,.sv-modal-ov.on .sv-modal{opacity:1;transform:none}
@starting-style{
  .modal-ov.on,.sv-modal-ov.on{opacity:0}
  .modal-ov.on .modal,.sv-modal-ov.on .sv-modal{opacity:0;transform:translateY(8px) scale(var(--press))}
}

/* ---- toasts & loaders ---- */
.notif{opacity:0;transition:transform var(--dur-slow) var(--ease-out),opacity var(--dur-slow) var(--ease-out)}
.notif.show{opacity:1}
#sv-toast{opacity:0;transition:transform var(--dur-slow) var(--ease-out),opacity var(--dur-slow) var(--ease-out)}
#sv-toast.on{opacity:1}
#app-loader,body.sv-embedded #app-loader{transition:opacity var(--dur) var(--ease-out),visibility var(--dur)}
body{transition:background-color var(--dur-slow) var(--ease-out),color var(--dur-slow) var(--ease-out)}

/* live figures keep their width while the numbers change */
.sol-pm,.sel-prev,.rie-val,.ah-sub,.rm-val,.kv,.mpv-total-v,.sc-n{font-variant-numeric:tabular-nums}
/* switching admin pages never moves the content sideways */
.content{scrollbar-gutter:stable}
/* refreshing data that is already on screen: dim only if the request is slow */
#prev-tbody{transition:opacity var(--dur-fast) var(--ease-out)}
#prev-tbody.is-refreshing{opacity:.6;transition:opacity var(--dur) var(--ease-out) var(--dur-fast)}
/* clickable rows are keyboard-focusable */
.dash-row:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.prev-row-link:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}

/* =====================================================================
   SKELETONS — placeholders with the size of the content they stand for,
   so swapping in the real data causes no layout shift.
   ===================================================================== */
.skel{display:block;background:var(--skel);border-radius:10px;animation:sv-pulse 2s cubic-bezier(.4,0,.6,1) infinite}
@keyframes sv-pulse{50%{opacity:.5}}
.skel-line{height:12px;width:100%}
.skel-line.w-40{width:40%}.skel-line.w-60{width:60%}.skel-line.w-80{width:80%}
.skel-line.lg{height:20px}
.skel-line+.skel-line{margin-top:8px}
.skel-box{height:56px}
.skel-kpi{height:96px;border-radius:12px}
.skel-row{height:44px;border-radius:10px}
.skel-row+.skel-row{margin-top:8px}
.skel-uc{height:64px}
.skel-uc+.skel-uc{margin-top:8px}
td .skel-line{height:14px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* full-page placeholder of the quote form (shell frame + estimator boot) */
.skel-page{max-width:1800px;margin:0 auto;padding:24px clamp(16px,3vw,48px);display:flex;flex-direction:column;gap:24px}
.skel-page .skel-logo{width:144px;height:48px;margin:0 auto}
.skel-page .skel-title{width:min(420px,80%);height:28px;margin:0 auto}
.skel-page .skel-sub{width:min(560px,90%);height:14px;margin:-12px auto 8px}
.skel-card{background:var(--skel-card);border:1px solid var(--skel-border);border-radius:24px;padding:24px}
.skel-card .skel-h{width:200px;height:18px;margin-bottom:24px}
.skel-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.skel-field{height:68px}
.skel-opt{height:72px;border-radius:16px}
.skel-opt+.skel-opt{margin-top:8px}
/* shell boot: what shows while the session is checked */
.sv-boot-nav{display:flex;align-items:center;justify-content:space-between;padding:16px clamp(16px,5vw,64px);border-bottom:1px solid var(--sv-border)}
.sv-boot-nav .skel:first-child{width:120px;height:24px}
.sv-boot-nav .skel:last-child{width:96px;height:36px;border-radius:16px}
.sv-boot-hero{max-width:640px;margin:0 auto;padding:96px 16px;display:flex;flex-direction:column;align-items:center;gap:16px}
.sv-boot-hero .skel:nth-child(1){width:160px;height:24px}
.sv-boot-hero .skel:nth-child(2){width:100%;height:48px}
.sv-boot-hero .skel:nth-child(3){width:80%;height:16px}
.sv-boot-hero .skel:nth-child(4){width:200px;height:52px;border-radius:16px;margin-top:16px}
@media(max-width:640px){.skel-grid{grid-template-columns:1fr}}

/* ---- accessibility, print, PDF capture ---- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:1ms !important;animation-iteration-count:1 !important;transition-duration:1ms !important;transition-delay:0ms !important}
  .sv-btn:active,.sv-icon-btn:active,.btn:active,.btn-p:active,.btn-s:active,.btn-sh:active,.btn-chip:active,.lbtn:active,
  .edit-banner button:active,.mail-opt:active,.theme-toggle:active,.sel-opt:active,.ni:active,.mail-open:active{transform:none}
  .nav-pill.is-ready{transition:none}
}
#pdf-doc,#pdf-doc *{animation:none !important;transition:none !important}
@media print{*,*::before,*::after{animation:none !important;transition:none !important}}
