/* ==========================================================================
   TWG Platform — design tokens + motion system (w248, 2026-10-05). Own code.
   Loaded after app.css + shell.css and before a brand's colours; behaviour in
   motion.js (window.TWGMotion). Guide: docs/design/DESIGN-SYSTEM.md
   Rules: motion moves transform + opacity only · every duration is a token ·
   html[data-motion="subtle"] keeps the fades and drops the movement ·
   html[data-motion="off"] and the device's reduce-motion setting stop it all.
   1 tokens · 2 switches · 3 keyframes · 4 shell · 5 content · 6 forms ·
   7 overlays · 8 sign-in · 9 client portal · 10 public home · 11 helpers
   ========================================================================== */

/* ---------- 1. Tokens ----------------------------------------------------- */
:root{
  /* 8-point spacing (4 is the half step) */
  --ds-sp-1:4px;--ds-sp-2:8px;--ds-sp-3:12px;--ds-sp-4:16px;--ds-sp-5:24px;--ds-sp-6:32px;--ds-sp-7:40px;--ds-sp-8:48px;--ds-sp-9:64px;--ds-sp-10:80px;
  /* type scale (1.2 steps from 14) and line heights */
  --ds-tx-xs:12px;--ds-tx-sm:13px;--ds-tx-md:14.5px;--ds-tx-lg:16px;--ds-tx-xl:19px;--ds-tx-2xl:24px;--ds-tx-3xl:30px;--ds-tx-4xl:38px;--ds-tx-5xl:48px;
  --ds-lh-tight:1.15;--ds-lh-body:1.5;
  /* radii and elevation */
  --ds-rad-xs:6px;--ds-rad-sm:8px;--ds-rad-md:12px;--ds-rad-lg:16px;--ds-rad-xl:24px;--ds-rad-pill:999px;
  --ds-el-1:0 1px 2px rgba(11,11,13,.06);--ds-el-2:0 2px 6px rgba(11,11,13,.07),0 10px 24px -12px rgba(11,11,13,.18);
  --ds-el-3:0 6px 14px rgba(11,11,13,.08),0 22px 48px -18px rgba(11,11,13,.3);--ds-el-4:0 28px 70px -20px rgba(11,11,13,.45);
  /* layers */
  --ds-z-sticky:20;--ds-z-drawer:50;--ds-z-menu:60;--ds-z-dialog:80;--ds-z-toast:90;--ds-z-tip:95;
  /* TWG brand: black, gold, platinum (gold on black 9.0:1, deep gold on white 5.4:1) */
  --twg-black:#0b0b0d;--twg-ink:#16171b;--twg-gold:#d4a94e;--twg-gold-2:#f0d99a;--twg-gold-deep:#8a6412;--twg-platinum:#d9dce1;--twg-platinum-2:#f1f2f4;
  /* motion: durations, easings, how far things travel */
  --mo-1:90ms;--mo-2:160ms;--mo-3:240ms;--mo-4:360ms;--mo-5:520ms;
  --mo-out:cubic-bezier(.2,.8,.2,1);--mo-in:cubic-bezier(.4,0,1,1);--mo-io:cubic-bezier(.4,0,.2,1);
  --mo-spring:cubic-bezier(.34,1.4,.64,1);--mo-snap:cubic-bezier(.2,.9,.3,1);
  --mo-move:1;
}
@supports (transition-timing-function:linear(0,1)){:root{
  --mo-spring:linear(0,.092,.293,.511,.713,.876,.996,1.064,1.095,1.099,1.086,1.066,1.044,1.025,1.009,.999,.993,.99,.99,.992,.994,.996,.998,.999,1,1.001,1.001,1.001,1);
  --mo-snap:linear(0,.07,.218,.376,.538,.668,.773,.859,.917,.959,.984,1,1.008,1.011,1.012,1.011,1.009,1.007,1.005,1.004,1.003,1.002,1.001,1,1)}}

/* ---------- 2. Switches --------------------------------------------------- */
html[data-motion="subtle"]{--mo-move:0;--mo-2:100ms;--mo-3:140ms;--mo-4:180ms;--mo-5:220ms;--mo-spring:var(--mo-out);--mo-snap:var(--mo-out)}
html[data-motion="off"] *,html[data-motion="off"] *::before,html[data-motion="off"] *::after{animation-duration:.01ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.01ms!important;transition-delay:0s!important;scroll-behavior:auto!important}
@media (prefers-reduced-motion:reduce){:root{--mo-move:0}
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}

/* ---------- 3. Keyframes (transform + opacity only) ------------------------ */
@keyframes mo-fade{from{opacity:0}}
@keyframes mo-rise{from{opacity:0;transform:translateY(calc(var(--mo-move)*10px))}}
@keyframes mo-pop{from{opacity:0;transform:translateY(calc(var(--mo-move)*-4px)) scale(calc(1 - var(--mo-move)*.03))}}
@keyframes mo-dialog{from{opacity:0;transform:translateY(calc(var(--mo-move)*10px)) scale(calc(1 - var(--mo-move)*.03))}}
@keyframes mo-sheet{from{opacity:.6;transform:translateY(calc(var(--mo-move)*100%))}}
@keyframes mo-drawer-r{from{opacity:.6;transform:translateX(calc(var(--mo-move)*100%))}}
@keyframes mo-toast{from{opacity:0;transform:translateY(calc(var(--mo-move)*-12px)) scale(calc(1 - var(--mo-move)*.04))}}
@keyframes mo-shake{20%{transform:translateX(-5px)}40%{transform:translateX(4px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}
@keyframes mo-sweep{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@keyframes mo-pulse{from{opacity:.55;transform:scale(1)}to{opacity:0;transform:scale(2.4)}}
@keyframes mo-bar{0%{transform:translateX(-100%) scaleX(.35)}60%{transform:translateX(20%) scaleX(.6)}100%{transform:translateX(100%) scaleX(.35)}}

/* ---------- 4. Shell: sidebar, top bar, menus ------------------------------ */
.btn,button,.ib,summary.btn{transition:transform var(--mo-1) var(--mo-out),box-shadow var(--mo-2) var(--mo-out),background-color var(--mo-2) var(--mo-out),border-color var(--mo-2) var(--mo-out),color var(--mo-2) var(--mo-out)}
.btn:active,.ib:active,button.secondary:active,form button[type="submit"]:not(.plain):not(.link):active{transform:scale(.97)}
.side-nav{position:relative}
.side-nav a.nl svg{transition:transform var(--mo-2) var(--mo-out)}
.side-nav a.nl:hover svg{transform:translateX(calc(var(--mo-move)*2px))}
.side-nav a.nl .cnt,.ib .badge{animation:mo-pop var(--mo-5) var(--mo-spring) both}
.mo-navink{position:absolute;left:10px;right:10px;top:0;height:100px;border-radius:9px;background:var(--side-active);transform-origin:0 0;pointer-events:none;opacity:0;z-index:0}
.top{transition:box-shadow var(--mo-3) var(--mo-out)}
.top.mo-scrolled{box-shadow:0 1px 0 var(--line),0 10px 24px -18px rgba(16,24,40,.5)}
.subnav-tabs{position:relative}
.mo-tabs{position:relative}
.mo-ink{position:absolute;left:0;bottom:0;width:100px;height:2px;border-radius:2px 2px 0 0;background:var(--accent);transform-origin:0 50%;pointer-events:none}
@media (max-width:900px){html[data-drawer="open"] .side{transition:transform var(--mo-4) var(--mo-snap)}html[data-drawer="open"] .scrim{animation:mo-fade var(--mo-2) var(--mo-out) both}}
details[open]>.menu,details[open]>.acct-menu,details.subnav-more[open]>:not(summary){animation:mo-pop var(--mo-2) var(--mo-out) both;transform-origin:top right}
details[open]>.acct-menu{transform-origin:top center}
.cm-item,.menu a,.menu button.plain{transition:background-color var(--mo-1) var(--mo-out),transform var(--mo-1) var(--mo-out)}
.cm-item:active{transform:scale(.98)}
.mo-bar{position:fixed;left:0;right:0;top:0;height:3px;z-index:var(--ds-z-tip);pointer-events:none;overflow:hidden}
.mo-bar::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,var(--accent),var(--twg-gold),transparent);animation:mo-bar 1.1s var(--mo-io) infinite}
html[data-motion="off"] .mo-bar::after{animation:none;transform:none;opacity:.7}

/* ---------- 5. Content: cards, tables, pills, boards, empty, loading ------- */
.card{transition:box-shadow var(--mo-3) var(--mo-out),border-color var(--mo-3) var(--mo-out),transform var(--mo-3) var(--mo-out)}
a.card:hover{transform:translateY(calc(var(--mo-move)*-2px))}
a.card:active{transform:scale(.99)}
.stat,.money,[data-count]{font-variant-numeric:tabular-nums}
tbody tr>td{transition:background-color var(--mo-1) linear}
.pill,.st,.badge,.score{transition:background-color var(--mo-2) var(--mo-out),color var(--mo-2) var(--mo-out),border-color var(--mo-2) var(--mo-out)}
.tile[draggable="true"]{transition:transform var(--mo-2) var(--mo-out),box-shadow var(--mo-2) var(--mo-out),border-color var(--mo-2) var(--mo-out),opacity var(--mo-2) var(--mo-out)}
.tile[draggable="true"]:active{cursor:grabbing}
.tile.dragging{opacity:.45;transform:scale(.97) rotate(calc(var(--mo-move)*-1.2deg))}
.col{transition:box-shadow var(--mo-2) var(--mo-out)}
.col.over{box-shadow:inset 0 0 0 2px var(--accent),0 0 0 4px var(--accent-soft)}
.empty:not(.sm){animation:mo-rise var(--mo-4) var(--mo-out) both}
.empty:not(.sm)::before{content:"";display:block;width:56px;height:56px;margin:0 auto 14px;border-radius:16px;background:var(--bg-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b8892b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l7 2.6v5.2c0 4.6-3 8.2-7 10.2-4-2-7-5.6-7-10.2V5.6z'/%3E%3Cpath d='M9 14.5v-2M12 14.5v-5M15 14.5V11'/%3E%3C/svg%3E") center/30px no-repeat;border:1px solid var(--line)}
.mo-skelbox{display:grid;gap:10px;padding:6px 0}
.mo-skel{display:block;position:relative;overflow:hidden;height:12px;border-radius:6px;background:var(--bg-2)}
.mo-skel::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,var(--line-2),transparent);animation:mo-sweep 1.3s linear infinite}
html[data-motion="off"] .mo-skel::after{animation:none;transform:none;opacity:0}
.mo-in{animation:mo-rise var(--mo-3) var(--mo-out) both;animation-delay:calc(var(--mo-i,0)*30ms)}

/* ---------- 6. Forms: focus, floating labels, inline validation ------------ */
input,select,textarea{transition:border-color var(--mo-2) var(--mo-out),box-shadow var(--mo-2) var(--mo-out),background-color var(--mo-2) var(--mo-out)}
input:user-invalid,select:user-invalid,textarea:user-invalid{border-color:var(--bad,#b3261e);box-shadow:0 0 0 3px color-mix(in srgb,var(--bad,#b3261e) 16%,transparent)}
.mo-shake{animation:mo-shake var(--mo-4) var(--mo-io) both}
.mo-err{display:block;margin:6px 0 0;font-size:var(--ds-tx-sm);font-weight:500;color:var(--bad,#b3261e);animation:mo-rise var(--mo-2) var(--mo-out) both}
.mo-fl{position:relative}
.mo-fl>label{position:absolute;left:13px;top:15px;margin:0;z-index:1;pointer-events:none;color:var(--muted);font-weight:500;transform-origin:0 0;transition:transform var(--mo-2) var(--mo-out),color var(--mo-2) var(--mo-out)}
.mo-fl input{padding-top:22px;padding-bottom:6px;min-height:52px}
.mo-fl:focus-within>label,.mo-fl:has(input:not(:placeholder-shown))>label,.mo-fl:has(input:autofill)>label{transform:translateY(-9px) scale(.78)}
.mo-fl:focus-within>label{color:var(--accent)}

/* ---------- 7. Overlays: palette, dialogs, drawers, toasts ----------------- */
.pal-scrim,.hd-scrim{animation:mo-fade var(--mo-2) var(--mo-out) both}
.pal-box{animation:mo-dialog var(--mo-4) var(--mo-snap) both}
.pal-list>*{transition:background-color var(--mo-1) linear}
.hdrawer{animation:mo-drawer-r var(--mo-4) var(--mo-snap) both}
dialog[open]{animation:mo-dialog var(--mo-4) var(--mo-snap) both}
dialog::backdrop{animation:mo-fade var(--mo-2) var(--mo-out) both}
.toasts .flash{animation:mo-toast var(--mo-5) var(--mo-spring) both}
.mo-toasts{position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom));z-index:var(--ds-z-toast);display:flex;flex-direction:column;gap:8px;align-items:center;transform:translateX(-50%);width:max-content;max-width:calc(100vw - 32px);pointer-events:none}
.mo-toast{pointer-events:auto;display:flex;align-items:center;gap:12px;padding:11px 10px 11px 16px;border-radius:var(--ds-rad-md);background:var(--twg-ink);color:#fff;font-size:var(--ds-tx-md);font-weight:500;box-shadow:var(--ds-el-3);border:1px solid rgba(255,255,255,.1);max-width:min(480px,100%)}
.mo-toast.ok{border-color:rgba(78,194,131,.6)}.mo-toast.err,.mo-toast.error{border-color:rgba(240,123,115,.7)}.mo-toast.gold{border-color:var(--twg-gold)}
.mo-toast button{flex:none;width:28px;height:28px;min-height:0;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.12);color:#fff;font-size:16px;line-height:1;cursor:pointer}

/* ---------- 8. Sign-in screens --------------------------------------------- */
.auth-card{animation:mo-dialog var(--mo-5) var(--mo-snap) both}
.auth .auth-card form button[type="submit"]{min-height:48px;border-radius:var(--ds-rad-pill);font-size:var(--ds-tx-lg)}
.auth-card .steps li{transition:color var(--mo-3) var(--mo-out),opacity var(--mo-3) var(--mo-out)}

/* ---------- 9. Client portal: calm, large, clear steps --------------------- */
.pt>.pcard,.pt>.hero,.pt>.need,.pt>.pgrid,.pt>.stand,.pt>.quick{animation:mo-rise var(--mo-4) var(--mo-out) both}
.pt>:nth-child(n+3){animation-delay:40ms}.pt>:nth-child(n+4){animation-delay:80ms}.pt>:nth-child(n+5){animation-delay:120ms}
.pt .status-box .val{font-size:26px;line-height:var(--ds-lh-tight);letter-spacing:-.01em}
.pt .hero .amt{font-variant-numeric:tabular-nums}
.pt .tl li{animation:mo-rise var(--mo-3) var(--mo-out) both}
.pt .tl li:nth-child(2){animation-delay:50ms}.pt .tl li:nth-child(3){animation-delay:100ms}.pt .tl li:nth-child(4){animation-delay:150ms}.pt .tl li:nth-child(n+5){animation-delay:200ms}
.pt .tl li.now::after{content:"";position:absolute;left:-8px;top:3px;width:14px;height:14px;border-radius:50%;background:var(--p-accent,#1558b0);pointer-events:none;animation:mo-pulse 1.8s var(--mo-out) 3 both}
.pt .tl li.done::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 7.2l2.3 2.3 4.7-5'/%3E%3C/svg%3E");background-position:center;background-repeat:no-repeat;background-size:10px}
.pt-tabs a{transition:color var(--mo-2) var(--mo-out),transform var(--mo-1) var(--mo-out)}
.pt-tabs a:active{transform:scale(.94)}
.pt-sheet:target{animation:mo-fade var(--mo-2) var(--mo-out) both}
.pt-sheet:target .panel{animation:mo-sheet var(--mo-5) var(--mo-snap) both}
.pt .stand a,.pt .quick a .ic,.navlist a{transition:transform var(--mo-2) var(--mo-out),border-color var(--mo-2) var(--mo-out),background-color var(--mo-2) var(--mo-out)}
.pt .stand a:hover{transform:translateY(calc(var(--mo-move)*-2px))}
.pt .stand a:active,.pt .quick a:active .ic{transform:scale(.97)}

/* ---------- 10. Public home ------------------------------------------------- */
.sx-btn,.sx-card,.sx-pick,.sx-pillar{transition:transform var(--mo-3) var(--mo-out),box-shadow var(--mo-3) var(--mo-out),border-color var(--mo-3) var(--mo-out),background-color var(--mo-3) var(--mo-out)}
.sx-btn:active{transform:scale(.97)}
.sx-card:hover,.sx-pillar:hover{transform:translateY(calc(var(--mo-move)*-4px))}
.sx-total-n{font-variant-numeric:tabular-nums}

/* ---------- 11. Helpers ------------------------------------------------------ */
@media (pointer:coarse){.btn,.ib,.side-nav a.nl,.subnav-tabs a,.pt-tabs a,.mo-toast button{min-height:44px}.ib{min-width:44px}}
@media (forced-colors:active){.mo-ink,.mo-navink{background:Highlight}}
@media print{.mo-bar,.mo-toasts,.mo-navink{display:none!important}}
