@font-face{font-family:"LINE Seed Sans TH";src:url(/assets/fonts/LINESeedSansTH_Rg.woff2) format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"LINE Seed Sans TH";src:url(/assets/fonts/LINESeedSansTH_Bd.woff2) format("woff2");font-weight:700;font-display:swap}

/* ---- tokens. Brand palette only: black, white, micemod blue #0067b1 and their tints ---- */
:root{
  --blue:#0067b1;--radius:18px;
  --bg:#000;--surface:#0a0a0a;--fg:#fff;--inv:#000;
  --dim:rgba(255,255,255,.68);--faint:rgba(255,255,255,.56);--ghost:rgba(255,255,255,.42);
  --line:rgba(255,255,255,.12);--line-strong:rgba(255,255,255,.34);
  --inv-dim:rgba(0,0,0,.66);
  --dot:rgba(255,255,255,.14);--held:rgba(0,103,177,.26);
  --glow:radial-gradient(1200px 700px at 50% -10%,rgba(0,103,177,.28),transparent 60%);
  --shadow:0 24px 60px rgba(0,0,0,.45);
  /* mouse drawing */
  --shell-side:#0b0b0b;--shell-a:#2a2a2a;--shell-b:#161616;--shell-c:#0d0d0d;--crest:#ffffff;
  --tile:#f2f2f2;
  --m-stroke:rgba(255,255,255,.4);--m-rim:rgba(255,255,255,.3);--m-ridge:rgba(255,255,255,.28);--wheel:#1d1d1d;
  color-scheme:dark;
}
:root[data-theme="light"]{
  --bg:#fff;--surface:#fff;--fg:#000;--inv:#fff;
  --dim:rgba(0,0,0,.68);--faint:rgba(0,0,0,.56);--ghost:rgba(0,0,0,.36);
  --line:rgba(0,0,0,.12);--line-strong:rgba(0,0,0,.4);
  --inv-dim:rgba(255,255,255,.72);
  --dot:rgba(0,0,0,.12);--held:rgba(0,103,177,.14);
  --glow:none;
  --shadow:0 18px 44px rgba(0,0,0,.08);
  --shell-side:#e3e3e3;--shell-a:#ffffff;--shell-b:#f1f1f1;--shell-c:#e2e2e2;--crest:#ffffff;
  --tile:#f3f3f3;
  --m-stroke:rgba(0,0,0,.55);--m-rim:rgba(0,0,0,.28);--m-ridge:rgba(0,0,0,.3);--wheel:#d6d6d6;
  color-scheme:light;
}

*{box-sizing:border-box}
html{background:var(--bg);color:var(--fg);scrollbar-color:var(--line-strong) var(--bg)}
body{margin:0;font-family:"LINE Seed Sans TH","Noto Sans Thai",system-ui,sans-serif;letter-spacing:-.025em;line-height:1.6;
  background:var(--glow),var(--bg);min-height:100vh;-webkit-font-smoothing:antialiased;transition:background-color .25s,color .25s}
a{color:var(--fg)}
::selection{background:var(--blue);color:#fff}
:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:6px}
.wrap{max-width:1280px;margin:0 auto;padding:0 20px}

/* header */
header.top{display:flex;align-items:center;justify-content:space-between;padding:20px 0}
.logo img{height:28px;width:auto;display:block}
.logo .on-light{display:none}
:root[data-theme="light"] .logo .on-dark{display:none}
:root[data-theme="light"] .logo .on-light{display:block}
.top-right{display:flex;align-items:center;gap:10px}
.lang{display:flex;gap:4px;font-size:14px}
.lang a{color:var(--faint);text-decoration:none;padding:6px 0;width:40px;text-align:center;border-radius:999px;border:1px solid transparent}
.lang a[aria-current]{color:var(--fg);border-color:var(--line)}
button.theme{display:flex;align-items:center;justify-content:center;min-width:124px;gap:8px;font:inherit;font-size:14px;letter-spacing:inherit;color:var(--dim);background:transparent;border:1px solid var(--line);border-radius:999px;padding:5px 12px 5px 9px;cursor:pointer;transition:border-color .15s,color .15s}
button.theme:hover{color:var(--fg);border-color:var(--line-strong)}
button.theme svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6}
button.theme svg path{fill:currentColor;stroke:none}

.hero{padding:6px 0 22px;text-align:center}
.hero h1{font-weight:700;font-size:clamp(28px,3.2vw,40px);line-height:1.15;margin:0 0 8px}
.hero p{color:var(--dim);margin:0 auto;max-width:860px;font-size:15px;min-height:1.6em}

/* ---- before you start: modal checklist, 2 x 2, must be ticked ---- */
dialog.prep{padding:0;border:1px solid var(--line);border-radius:20px;background:var(--surface);color:var(--fg);width:min(680px,calc(100vw - 32px));max-height:calc(100vh - 32px);overflow:auto;box-shadow:0 30px 80px rgba(0,0,0,.5)}
dialog.prep::backdrop{background:rgba(0,0,0,.62);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
dialog.prep[open]{animation:dlg-in .28s cubic-bezier(.2,.8,.2,1)}
dialog.prep[open]::backdrop{animation:fade-in .28s ease-out}
@keyframes dlg-in{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
.prep-box{padding:28px 30px 24px;margin:0}
.prep-box h2{font-weight:400;font-size:28px;line-height:1.2;margin:0 0 6px}
.prep-sub{color:var(--dim);font-size:15px;margin:0 0 22px}
.prep-box ol{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.prep-box li{display:flex;gap:14px;align-items:flex-start;border:1px solid var(--line);border-radius:14px;padding:16px}
.prep-box .pt{display:flex;flex-direction:column;gap:3px;min-width:0}
.prep-box .pt strong{font-size:16px;font-weight:700;line-height:1.35}
.prep-box .pt span{font-size:14px;color:var(--dim);line-height:1.5}
.prep-note{margin:16px 0 0;font-size:13px;color:var(--faint)}
.prep-act{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.ack{display:flex;align-items:center;gap:12px;cursor:pointer;font-size:15px;user-select:none;-webkit-user-select:none}
.ack input{position:absolute;opacity:0;width:1px;height:1px}
.ack .box{width:24px;height:24px;flex:none;border:1.5px solid var(--line-strong);border-radius:7px;display:grid;place-items:center;transition:background .15s,border-color .15s}
.ack .box svg{width:16px;height:16px;fill:none;stroke:#fff;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.6);transition:opacity .15s,transform .15s}
.ack input:checked+.box{background:var(--blue);border-color:var(--blue)}
.ack input:checked+.box svg{opacity:1;transform:none}
.ack input:focus-visible+.box{outline:2px solid var(--blue);outline-offset:3px}
button.go{font:inherit;letter-spacing:inherit;font-size:16px;font-weight:700;color:#fff;background:var(--blue);border:0;border-radius:999px;padding:12px 28px;cursor:pointer;transition:opacity .15s,filter .15s}
button.go:hover:not(:disabled){filter:brightness(1.12)}
button.go:disabled{opacity:.3;cursor:not-allowed}
.ico{flex:none;width:44px;height:44px;border-radius:12px;border:1px solid var(--line);display:grid;place-items:center}
.ico svg{width:30px;height:30px;fill:none;stroke:var(--fg);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.ico .dot{fill:var(--fg);stroke:none}
.ico .pad-i{stroke:var(--faint)}
.ico .cursor{fill:var(--fg);stroke:none}
.ico .wave,.ico .ring{stroke:var(--blue)}
.ico-usb .plug{animation:plug 2.6s cubic-bezier(.5,0,.2,1) infinite}
@keyframes plug{0%,15%{transform:translateY(-5px)}45%,80%{transform:translateY(3px)}100%{transform:translateY(-5px)}}
.ico .wave,.ico .ring{opacity:0;animation:pulse 2.4s ease-out infinite}
.ico .w2,.ico .r2{animation-delay:.3s}
.ico .w3{animation-delay:.6s}
@keyframes pulse{0%{opacity:0}25%{opacity:1}70%,100%{opacity:0}}
.ico .knob-a,.ico .knob-b,.ico .knob-c{fill:var(--surface)}
.ico-sliders .knob-a{animation:knob-a 2.8s cubic-bezier(.5,0,.2,1) infinite}
.ico-sliders .knob-b{animation:knob-b 2.8s cubic-bezier(.5,0,.2,1) infinite}
.ico-sliders .knob-c{animation:knob-a 2.8s cubic-bezier(.5,0,.2,1) infinite .4s}
@keyframes knob-a{0%,15%{transform:translateX(0)}45%,85%{transform:translateX(12px)}100%{transform:translateX(0)}}
@keyframes knob-b{0%,15%{transform:translateX(0)}45%,85%{transform:translateX(-10px)}100%{transform:translateX(0)}}
.ico-chrome .cursor{animation:tap 2.4s ease-in-out infinite;transform-origin:26px 26px}
@keyframes tap{0%,60%,100%{transform:translate(0,0) scale(1)}30%{transform:translate(-3px,-2px) scale(.88)}}
@media (prefers-reduced-motion:reduce){.ico *{animation:none!important;opacity:1!important}dialog.prep[open],dialog.prep[open]::backdrop{animation:none}}

/* ---- test pad ---- */
.pad{position:relative;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);
  box-shadow:var(--shadow);user-select:none;-webkit-user-select:none;cursor:crosshair;overflow:hidden;touch-action:none;transition:background-color .25s}
.touch-note{display:none;padding:18px 32px 0;color:var(--dim);font-size:15px;margin:0}
@media (hover:none){.touch-note{display:block}}

/* status strip: the largest text inside the box, so a phone photo reads it first */
.pad-head{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px 28px;border-bottom:1px solid var(--line);transition:background .2s,color .2s}
.status{display:flex;flex-direction:column;gap:2px;min-width:0}
.status strong{font-weight:400;font-size:clamp(20px,1.9vw,28px);line-height:1.2;display:flex;align-items:center;gap:12px;white-space:nowrap}
.status span{color:var(--dim);font-size:14px;line-height:1.45;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.status[data-state="ok"] strong::before{content:"";width:12px;height:12px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 4px rgba(0,103,177,.26);flex:none}
.pad-head:has(.status[data-state="bad"]){background:var(--fg);color:var(--inv);border-bottom-color:var(--fg)}
.status[data-state="bad"] strong{font-weight:700}
.status[data-state="bad"] span{color:var(--inv-dim)}
.dots{display:flex;gap:6px;list-style:none;margin:0;padding:0;flex:none}
.dots li{width:22px;height:6px;border-radius:3px;background:var(--dot);transition:background .2s}
.dots li.seen{background:var(--fg)}
.dots li.bad{width:36px}
.dots li.off{background:transparent;box-shadow:inset 0 0 0 1px var(--line-strong)}
.pad-head:has(.status[data-state="bad"]) .dots li{background:var(--inv-dim);opacity:.35}
.pad-head:has(.status[data-state="bad"]) .dots li.seen{opacity:.7}
.pad-head:has(.status[data-state="bad"]) .dots li.bad{background:var(--inv);opacity:1}

.pad-inner{display:grid;grid-template-columns:minmax(220px,360px) 1fr;gap:28px;padding:16px 28px;align-items:center}
.pad-inner>*{min-width:0}

/* mouse drawing */
.mouse svg{width:100%;height:auto;display:block;overflow:visible}
.mouse .shell-line path{fill:none;stroke:var(--m-stroke);stroke-width:4;stroke-linejoin:round}
.mouse .shell-side path{fill:url(#shellSide);stroke:url(#shellSide);stroke-width:.8}
.mouse .shell-top path{fill:url(#shellTop);stroke:url(#shellTop);stroke-width:.8}
.mouse .shell-crest{fill:url(#crest)}
.mouse .ridge{stroke:var(--m-ridge);stroke-width:1.2;pointer-events:none}
.mouse .part{fill:transparent;stroke:var(--m-stroke);stroke-width:2.2;stroke-linejoin:round;transition:fill .08s,stroke .2s}
.mouse .part[data-part="1"]{fill:var(--wheel)}
.mouse .part.seen{stroke:var(--fg)}
.mouse .part.bad{fill:var(--fg)}
.mouse .part.down,.mouse .part.roll{fill:var(--blue);stroke:var(--fg)}
.mouse .chev{fill:none;stroke:var(--ghost);stroke-width:5;stroke-linecap:round;stroke-linejoin:round;transition:stroke .08s}
.mouse .chev.on{stroke:var(--blue)}
.mouse text{fill:var(--dim);font-size:15px;font-weight:700;font-family:inherit;letter-spacing:0}
.mouse text.on-part{fill:var(--fg);stroke:var(--surface);stroke-width:3px;paint-order:stroke;pointer-events:none}
.mouse .lead{fill:none;stroke:var(--faint);stroke-width:1}
.mouse .lead-dot{fill:var(--faint)}

/* cards: 2 per row. untested is quiet, tested gets a tick, faulty inverts */
.cards{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px}
.card{border:1px solid var(--line);border-radius:12px;padding:9px 14px;display:flex;flex-direction:column;gap:2px;transition:border-color .15s,background .1s,color .1s}
.card .k{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:clamp(14px,1.15vw,17px);color:var(--faint)}
.card .k span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card .tick{width:18px;height:18px;flex:none;fill:none;stroke:var(--fg);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;opacity:0;transition:opacity .15s}
.card .vals{display:flex;gap:clamp(18px,2.6vw,40px);align-items:baseline}
.card .vals b{opacity:.45;transition:opacity .15s}
.card .vals span{display:flex;align-items:baseline;gap:7px}
.card b{font-size:clamp(26px,2.3vw,36px);font-weight:400;line-height:1.15;font-variant-numeric:tabular-nums}
.card i{font-style:normal;font-size:13px;color:var(--faint)}
.card .note{font-size:12px;color:var(--faint);height:1.3em;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card.seen{border-color:var(--line-strong)}
.card.seen .k{color:var(--fg)}
.card.seen .vals b,.card.seen .tick{opacity:1}
.card.bad{background:var(--fg);border-color:var(--fg);color:var(--inv)}
.card.bad .k,.card.bad i,.card.bad .note{color:var(--inv-dim)}
.card.bad .k span{color:var(--inv);font-weight:700}
.card.bad .dbl b{font-weight:700}
.card.bad .tick{opacity:0}
.card.down{border-color:var(--blue);background:var(--held);color:var(--fg)}
.card.bad.down .k span,.card.bad.down .k,.card.bad.down i,.card.bad.down .note{color:var(--fg)}
.card.off{border-style:dashed;opacity:.55}
.card.off .note{color:var(--dim)}
.card.log{gap:6px}
.log-list{list-style:none;margin:0;padding:0;font-size:12.5px;line-height:1.3;font-variant-numeric:tabular-nums;height:81px;overflow:hidden}
.log-list li{display:flex;justify-content:space-between;gap:10px;padding:2px 6px;margin:0 -6px;border-radius:5px;color:var(--dim)}
.log-list li:first-child{color:var(--fg)}
.log-list li.bad{background:var(--fg);color:var(--inv);font-weight:700}
.log-list li.empty{color:var(--faint)}

/* evidence line: date, browser, rule, optional order number */
.pad-foot{display:flex;align-items:center;gap:10px 22px;padding:10px 28px;border-top:1px solid var(--line);font-size:14px;color:var(--faint)}
.pad-foot .stamp{color:var(--fg);font-variant-numeric:tabular-nums}
.pad-foot .stamp{flex:none}
.pad-foot .meta{display:flex;gap:4px 22px;flex-wrap:wrap;flex:1 1 auto;min-width:0}
.head-right{display:flex;align-items:center;gap:20px;flex:none}
button.reset{display:inline-flex;align-items:center;gap:8px;white-space:nowrap;font:inherit;font-size:15px;letter-spacing:inherit;color:var(--fg);background:transparent;border:1px solid var(--line-strong);border-radius:999px;padding:8px 10px 8px 14px;cursor:pointer;transition:background .15s,border-color .15s,color .15s}
button.reset svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
button.reset kbd{font:inherit;font-size:12px;line-height:1;padding:4px 7px;border-radius:6px;border:1px solid var(--line);color:var(--faint)}
button.reset:hover{background:var(--fg);color:var(--inv);border-color:var(--fg)}
button.reset:hover kbd{border-color:var(--inv-dim);color:var(--inv-dim)}
.pad-head:has(.status[data-state="bad"]) button.reset{color:var(--inv);border-color:var(--inv-dim)}
.pad-head:has(.status[data-state="bad"]) button.reset kbd{color:var(--inv-dim);border-color:var(--inv-dim)}
.pad-head:has(.status[data-state="bad"]) button.reset:hover{background:var(--inv);color:var(--fg)}

/* ---- verdict below the box ---- */
.verdict{margin:28px 0 0;padding:0;display:none}
.verdict.show{display:block}
.verdict h2{font-weight:400;font-size:26px;margin:0 0 8px;line-height:1.3}
.verdict p{color:var(--dim);margin:0 0 12px;max-width:680px}
.verdict ol{color:var(--dim);margin:0 0 20px;padding-left:22px;max-width:680px}
.verdict ol li{margin-bottom:6px}
.verdict .v-block+.v-block{margin-top:28px;padding-top:28px;border-top:1px solid var(--line)}
.cta{display:inline-block;background:var(--blue);color:#fff;text-decoration:none;padding:12px 22px;border-radius:999px;font-weight:700;margin-right:10px;margin-top:4px}
.cta.ghost{background:transparent;color:var(--fg);border:1px solid var(--line);font-weight:400}
.cta:hover{filter:brightness(1.12)}

/* ---- content below the test: heading left, content right ---- */
.content{margin-top:64px}
.sec{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2fr);gap:48px;padding:64px 0;border-top:1px solid var(--line)}
.sec h2{font-weight:400;font-size:clamp(26px,2.4vw,34px);line-height:1.2;margin:0;position:sticky;top:24px;align-self:start;text-wrap:balance}
.body{min-width:0;max-width:780px}
.prose p{color:var(--dim);font-size:17px;margin:0 0 16px}
.prose p:last-child{margin-bottom:0}
.prose strong,.body strong{color:var(--fg);font-weight:700}
.prose table{width:100%;border-collapse:collapse;font-size:15px;margin:8px 0 24px}
.prose td,.prose th{border-top:1px solid var(--line);padding:12px 16px 12px 0;text-align:left;vertical-align:top;color:var(--dim)}
.prose th{color:var(--faint);font-weight:400;font-size:13px;border-top:none;padding-bottom:8px}
.prose td:first-child{color:var(--fg);width:42%}

.steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px}
.steps .n{display:block;font-size:56px;line-height:1;color:var(--ghost);font-variant-numeric:tabular-nums}
.steps h3{font-size:20px;font-weight:700;margin:18px 0 6px}
.steps p{color:var(--dim);margin:0;font-size:15px}

.compare{margin-top:32px;border-top:1px solid var(--line)}
.c-row{display:grid;grid-template-columns:1fr 1fr 1.2fr 1.2fr;gap:16px;padding:14px 0;border-bottom:1px solid var(--line);font-size:15px;color:var(--dim)}
.c-row span:first-child{color:var(--faint)}
.c-head{font-size:13px;padding:12px 0}
.c-head span{color:var(--faint)}
.c-row .c-opt{color:var(--fg)}
.c-head .c-opt{font-weight:700;color:var(--fg)}

.sources{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.sources li{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);gap:6px 24px;padding:12px 0;border-bottom:1px solid var(--line);font-size:14px}
.sources li:last-child{border-bottom:0}
.sources a{color:var(--fg);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--line-strong)}
.sources span{color:var(--dim)}
.fix{list-style:none;margin:0;padding:0;counter-reset:fix}
.fix li{counter-increment:fix;display:grid;grid-template-columns:48px minmax(0,1fr);padding:20px 0;border-top:1px solid var(--line)}
.fix li strong{display:block;font-size:18px;margin-bottom:4px}
.fix li p{margin:0;color:var(--dim);font-size:16px}
.fix li::before{content:counter(fix);color:var(--faint);font-size:18px;line-height:1.6;font-variant-numeric:tabular-nums}

.body .lead{color:var(--dim);font-size:17px;margin:0 0 28px}
.prods{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:16px}
.prod{display:flex;flex-direction:column;text-decoration:none;color:var(--fg)}
.p-img{display:block;aspect-ratio:1;border-radius:14px;overflow:hidden;background:var(--tile);margin-bottom:12px}
.p-img img{width:100%;height:100%;object-fit:contain;display:block;padding:6%;mix-blend-mode:multiply;transition:transform .4s cubic-bezier(.2,.7,.2,1)}
.prod:hover .p-img img{transform:scale(1.04)}
.p-v{font-size:13px;color:var(--faint)}
.p-m{font-size:17px;line-height:1.3}
.p-t{font-size:12.5px;color:var(--dim);margin-top:2px}
.p-cta{font-size:14px;color:var(--dim);margin-top:6px;text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--line-strong)}
.prod:hover .p-cta{color:var(--fg)}
.more{display:inline-flex;align-items:center;gap:8px;margin-top:28px;color:var(--fg);text-decoration:none;border-bottom:1px solid var(--line-strong);padding-bottom:4px}
.more svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transition:transform .2s}
.more:hover svg{transform:translateX(3px)}

.faq details{border-top:1px solid var(--line)}
.faq summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:24px;padding:18px 0;font-size:18px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";width:12px;height:12px;flex:none;background:linear-gradient(currentColor,currentColor) center/12px 1.5px no-repeat,linear-gradient(currentColor,currentColor) center/1.5px 12px no-repeat;transition:transform .2s;color:var(--faint)}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq details p{color:var(--dim);margin:0 0 20px;max-width:640px;font-size:16px}

.ad-slot{margin:0 0 40px} /* AdSense goes here only, phase 2. Never near the test box. */

/* ---- site footer ---- */
.site-foot{border-top:1px solid var(--line);margin-top:40px;padding-top:64px;font-size:14px}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1.3fr .6fr;gap:40px}
.foot-brand p{color:var(--dim);margin:16px 0 20px;max-width:280px}
.site-foot .fh{font-size:14px;font-weight:700;margin:4px 0 14px;line-height:1.4}
.site-foot ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.site-foot ul.plain li{color:var(--dim)}
.site-foot a{color:var(--dim);text-decoration:none}
.site-foot a:hover{color:var(--fg)}
.social{flex-direction:row!important;gap:14px!important}
.social svg{width:20px;height:20px;fill:currentColor;display:block}
.social svg.stroke{fill:none;stroke:currentColor;stroke-width:1.7}
.foot-base{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px 24px;margin-top:56px;padding-top:22px;padding-bottom:40px;border-top:1px solid var(--line);color:var(--faint);font-size:13px}
.foot-base .legal{display:flex;gap:22px;flex-wrap:wrap}
.foot-base a{color:var(--faint)}


/* short laptop screens: keep the whole box in one photo */
@media (min-width:761px) and (max-height:720px){
  .pad-head{padding:10px 24px}
  .status strong{font-size:22px}
  .status span{font-size:13px}
  .pad-inner{padding:12px 24px;grid-template-columns:minmax(200px,320px) 1fr}
  .card{padding:6px 12px}
  .card b{font-size:26px}
  .card .note{min-height:1.1em}
  .pad-foot{padding:8px 24px}
}

/* ---- animated explainer figures (only run while on screen: .play) ---- */
.fig{margin:28px 0;padding:22px 24px 18px;border:1px solid var(--line);border-radius:16px}
.fig svg{width:100%;height:auto;display:block;overflow:visible}
.fig figcaption{margin-top:14px;font-size:14px;color:var(--dim);line-height:1.55}
.fig text{font-family:inherit;letter-spacing:0;font-size:17px;fill:var(--faint)}
.fig .t-strong{fill:var(--fg);font-weight:700}
.fig .t-small{font-size:13px;fill:var(--faint)}
.fig .ln{fill:none;stroke:var(--fg);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.fig .fnt{stroke:var(--line-strong)}
.fig .solid,.fig .pivot{fill:var(--fg)}
.anim *{animation-play-state:paused!important}
.anim.play *{animation-play-state:running!important}

/* html labels around the drawings, so text stays readable at any width */
.fig .legend{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--faint);margin-bottom:10px}
.fig .legend .sw{width:14px;height:14px;border-radius:3px;background:rgba(0,103,177,.16);border:1px dashed var(--blue)}
.fig .b-row{display:grid;grid-template-columns:130px minmax(0,1fr) 80px;align-items:center;gap:16px;padding:8px 0}
.fig .b-row+.b-row{border-top:1px solid var(--line)}
.fig .b-lab{font-weight:700;font-size:15px}
.fig .pair{display:grid;grid-template-columns:1fr 1fr;gap:28px}
.fig .panel{display:flex;flex-direction:column;gap:2px}
.fig .panel strong{font-size:15px}
.fig .panel>span{font-size:13px;color:var(--faint);margin-bottom:8px}
.fig .panel svg+span{margin:8px 0 0;text-align:center}
.fig .f-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}
.fig .f-head strong{font-size:15px}
.fig .f-head span{font-size:13px;color:var(--faint)}
.fig .bad-chip,.fig .bad-chip *{color:var(--inv)!important}
.fig .bad-chip{background:var(--fg);font-weight:700;padding:3px 10px;border-radius:999px}

/* criteria: 80 ms after a press, 20 ms after a release */
.fig.crit .b-row{grid-template-columns:130px minmax(0,1fr) 150px}
.fig .res small{display:block;font-size:12.5px;font-weight:400;color:var(--faint)}
.fig .win2{opacity:0;animation:fig-win 7s ease infinite both}
@keyframes fig-win{0%,4%{opacity:0}12%,92%{opacity:1}100%{opacity:0}}

.fig .legend .trace{width:22px;height:14px;flex:none;border:solid var(--fg);border-width:2px 2px 0 0;border-radius:0}
.fig.crit .legend+.legend{margin-top:-4px}
.fig .dim path{fill:none;stroke:var(--faint);stroke-width:1.4}
.fig .dim text{font-size:13px;fill:var(--dim);font-variant-numeric:tabular-nums}
.fig .win-t{font-size:12px;fill:var(--blue);font-weight:700}
.fig .dim{opacity:0;animation:fig-res 7s ease infinite both}

/* bounce: healthy vs worn */
.fig .win{fill:rgba(0,103,177,.16);stroke:var(--blue);stroke-width:1;stroke-dasharray:3 3}
.fig .draw{stroke-dasharray:1;stroke-dashoffset:1;animation:fig-draw 7s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-draw{0%{stroke-dashoffset:1;opacity:1}28%,92%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
.fig .res{font-size:17px;color:var(--dim);text-align:right;opacity:0;animation:fig-res 7s ease infinite both}
.fig .res-bad{color:var(--fg);font-weight:700}
@keyframes fig-res{0%,28%{opacity:0}34%,92%{opacity:1}100%{opacity:0}}
.fig .hit{fill:none;stroke:var(--fg);stroke-width:2;opacity:0;transform-box:fill-box;transform-origin:center;animation:fig-hit 7s ease-out infinite both}
@keyframes fig-hit{0%,28%{opacity:0;transform:scale(.4)}31%{opacity:1;transform:scale(1.4)}36%,92%{opacity:1;transform:scale(1)}100%{opacity:0}}

/* mechanical leaf bounces, optical shutter does not */
.fig .t-tag{font-size:12px;fill:var(--faint);font-weight:700}
.fig .leaf{transform-box:view-box;transform-origin:40px 72px;animation:fig-leaf 5.2s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-leaf{0%,14%{transform:rotate(0)}24%{transform:rotate(14deg)}27%{transform:rotate(11.5deg)}30%{transform:rotate(14deg)}33%{transform:rotate(12.8deg)}36%,66%{transform:rotate(14deg)}74%{transform:rotate(0)}77%{transform:rotate(1.8deg)}80%,100%{transform:rotate(0)}}
.fig .plunger{animation:fig-plunger 5.2s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-plunger{0%,10%{transform:translateY(0)}24%,66%{transform:translateY(14px)}74%,100%{transform:translateY(0)}}
.fig .spark{fill:none;stroke:var(--blue);stroke-width:2;opacity:0}
.fig .s-no{animation:fig-spark-no 5.2s linear infinite both}
.fig .s-nc{animation:fig-spark-nc 5.2s linear infinite both}
@keyframes fig-spark-no{0%,23%{opacity:0}24%{opacity:1}26%{opacity:0}30%{opacity:1}31.5%{opacity:0}36%{opacity:1}38%,100%{opacity:0}}
@keyframes fig-spark-nc{0%,73%{opacity:0}74%{opacity:1}76%{opacity:0}80%{opacity:1}82%,100%{opacity:0}}
.fig .beam{fill:none;stroke:var(--blue);stroke-width:3;stroke-linecap:round;animation:fig-beam 5.2s linear infinite both}
@keyframes fig-beam{0%,26%{opacity:1}30%,70%{opacity:.12}74%,100%{opacity:1}}
.fig .shutter{animation:fig-shutter 5.2s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-shutter{0%,10%{transform:translateY(0)}28%,70%{transform:translateY(30px)}86%,100%{transform:translateY(0)}}

/* debounce slider 2 ms to 4 ms */
.fig .track{fill:none;stroke:var(--blue);stroke-width:4;stroke-linecap:round;stroke-dasharray:1;stroke-dashoffset:.5;animation:fig-track 7s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-track{0%,15%{stroke-dashoffset:.5}35%,90%{stroke-dashoffset:0}100%{stroke-dashoffset:.5}}
.fig .knob circle{fill:var(--surface);stroke:var(--blue);stroke-width:3}
.fig .knob{animation:fig-knob 7s cubic-bezier(.4,0,.2,1) infinite both}
@keyframes fig-knob{0%,15%{transform:translateX(0)}35%,90%{transform:translateX(110px)}100%{transform:translateX(0)}}

/* wheel reversal: notches appear one by one, one of them goes the wrong way */
.fig .roll{animation:fig-roll .7s linear infinite}
@keyframes fig-roll{from{transform:translateY(0)}to{transform:translateY(14px)}}
.fig .chev{fill:none;stroke:var(--fg);stroke-width:4;stroke-linecap:round;stroke-linejoin:round}
.fig .chev.up{stroke:var(--inv)}
.fig .bad-bg{fill:var(--fg)}
.fig .bad-t{fill:var(--fg);font-weight:700}
.fig .seq{opacity:0;animation:fig-seq 7s ease-out infinite both;animation-delay:calc(var(--i) * .4s)}
@keyframes fig-seq{0%{opacity:0;transform:translateY(-8px)}5%{opacity:1;transform:none}82%{opacity:1}92%,100%{opacity:0}}

/* side button: press, the back arrow gets struck through, page stays */
.fig .side-mouse .mouse{max-width:220px;margin:0 auto;width:100%}
.fig .side-mouse>span{text-align:center;margin-top:8px}
.fig .side-mouse .wheel{fill:var(--wheel)}
.fig .press{animation:fig-press 5s ease infinite both}
@keyframes fig-press{0%,18%{fill:transparent;stroke:var(--m-stroke)}22%,34%{fill:var(--blue);stroke:var(--fg)}40%,100%{fill:transparent;stroke:var(--m-stroke)}}
.fig .slash{fill:none;stroke:var(--blue);stroke-width:3;stroke-linecap:round;stroke-dasharray:1;stroke-dashoffset:1;animation:fig-slash 5s ease infinite both}
@keyframes fig-slash{0%,24%{stroke-dashoffset:1;opacity:1}34%,86%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}

/* step icons */
.step-top{display:flex;align-items:center;justify-content:space-between;gap:12px}
.step-ico{width:52px;height:52px;border:1px solid var(--line);border-radius:14px;display:grid;place-items:center}
.step-ico svg{width:34px;height:34px;overflow:visible}
.step-ico .ln-i{fill:none;stroke:var(--fg);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.step-ico .thin{stroke-width:1.4;stroke:var(--faint)}
.step-ico .solid-i{fill:var(--fg)}
.step-ico .ripple{fill:none;stroke:var(--blue);stroke-width:2;transform-box:fill-box;transform-origin:center;animation:fig-ripple 1.8s ease-out infinite both}
@keyframes fig-ripple{0%{transform:scale(.3);opacity:1}80%,100%{transform:scale(1.5);opacity:0}}
.step-ico .roll-s{animation:fig-roll-s .6s linear infinite}
@keyframes fig-roll-s{from{transform:translateY(0)}to{transform:translateY(7px)}}
.step-ico .flash{fill:var(--fg);opacity:0;animation:fig-flash 2.6s ease-out infinite both}
@keyframes fig-flash{0%,70%{opacity:0}74%{opacity:.85}90%,100%{opacity:0}}

@media (prefers-reduced-motion:reduce){
  .fig *,.step-ico *{animation:none!important}
  .fig .draw,.fig .track,.fig .slash{stroke-dashoffset:0}
  .fig .res,.fig .hit,.fig .seq,.fig .win2,.fig .dim{opacity:1}
  .fig .press{fill:var(--blue)}
  .fig .leaf{transform:rotate(14deg)}
  .step-ico .flash{opacity:0}
}

.crit-block{margin-top:48px;padding-top:36px;border-top:1px solid var(--line)}
.crit-block h3{font-size:20px;font-weight:700;margin:0 0 10px}
.crit-block .fig{margin-bottom:0}

/* tempo guide */
.tempo{display:inline-flex;align-items:center;gap:10px;margin-left:auto;color:var(--dim);flex:none}
.tempo .beat{position:relative;width:10px;height:10px;border-radius:50%;background:var(--blue);flex:none}
.tempo .beat::after{content:"";position:absolute;inset:-1px;border-radius:50%;border:2px solid var(--blue);opacity:0}
.tempo .beat.on{animation:beat-dot .5s ease-out}
.tempo .beat.on::after{animation:beat-ring .5s ease-out}
@keyframes beat-dot{0%{transform:scale(1.5)}100%{transform:scale(1)}}
@keyframes beat-ring{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(3.4)}}
/* both labels share one grid cell: the box is always as wide as the longer one, so swapping never shifts the layout */
.tempo-l{display:grid;white-space:nowrap}
.tempo-l>span{grid-area:1/1;padding:4px 12px;line-height:1.3;border-radius:999px;text-align:center}
.tempo-l .t-norm{padding-left:0;text-align:left}
.tempo-l .t-fast{visibility:hidden;background:var(--fg);color:var(--inv);font-weight:700}
.tempo.fast .t-norm{visibility:hidden}
.tempo.fast .t-fast{visibility:visible}
button.snd{display:grid;place-items:center;width:36px;height:36px;padding:0;border-radius:50%;border:1.5px solid var(--fg);background:transparent;color:var(--fg);cursor:pointer;transition:background .15s,border-color .15s,color .15s}
button.snd svg{width:22px;height:22px;fill:currentColor;stroke:none;overflow:visible}
button.snd svg g{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
button.snd svg .w{display:none}
button.snd[aria-pressed="true"]{background:var(--blue);border-color:var(--blue);color:#fff}
button.snd[aria-pressed="true"] svg .w{display:inline}
button.snd[aria-pressed="true"] svg .x{display:none}
button.snd:hover{filter:brightness(1.15)}
button.snd:focus-visible{outline:2px solid var(--fg);outline-offset:3px}
.prep-snd{margin:8px 0 0;font-size:13px;color:var(--dim)}
.snd-opts{display:inline-flex;align-items:center;gap:10px}
/* muted: the options keep their space (only hidden from sight and from the tab order) so the speaker button never moves */
.snd-opts[hidden]{display:inline-flex;visibility:hidden}
.snd-opts select{-webkit-appearance:none;appearance:none;font:inherit;font-size:13px;letter-spacing:inherit;color:var(--fg);border:1px solid var(--line);border-radius:999px;padding:5px 30px 5px 14px;cursor:pointer;
  background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 11px center/12px}
.snd-opts select:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.snd-opts input[type=range]{width:90px;accent-color:var(--blue);cursor:pointer}
@media (prefers-reduced-motion:reduce){.tempo .beat.on,.tempo .beat.on::after{animation:none}.tempo .beat.on::after{opacity:.5}}

.ns{color:var(--fg);border:1px solid var(--line-strong);border-radius:12px;padding:12px 16px;margin:12px auto 0;max-width:560px}
/* line breaking: Thai only breaks at the spaces between phrases, never inside a word */
:lang(th) body{word-break:keep-all;overflow-wrap:break-word}
.nw{white-space:nowrap}
p,li,figcaption,.status span,.prep-box .pt span{text-wrap:pretty}
h1,h2,h3,.status strong{text-wrap:balance}

/* click feedback: pulse ring on the card, tick pops in the first time a button is confirmed */
.card.pulse{animation:card-pulse .45s cubic-bezier(.2,.8,.2,1)}
@keyframes card-pulse{0%{box-shadow:0 0 0 0 rgba(0,103,177,.55)}100%{box-shadow:0 0 0 12px rgba(0,103,177,0)}}
.card.pop .tick{animation:tick-pop .35s cubic-bezier(.16,1,.3,1)}
@keyframes tick-pop{0%{transform:scale(.2);opacity:0}100%{transform:scale(1);opacity:1}}
.mouse .part.pulse{animation:part-pulse .45s ease-out}
@keyframes part-pulse{0%{stroke-width:6}100%{stroke-width:2.2}}
@media (prefers-reduced-motion:reduce){.card.pulse,.card.pop .tick,.mouse .part.pulse{animation:none}}

/* tablets and small laptops: the test box stacks (mouse above, cards below) so card names have room and are never cut */
@media (max-width:1000px){
  .pad-inner{grid-template-columns:1fr;gap:20px;padding:18px 20px}
  .mouse{max-width:300px;margin:0 auto}
  .card .k span{white-space:normal}
  .pad-head{flex-wrap:wrap}
}
/* no single-word last lines in short labels */
.card .note,.log-list li.empty,.faq summary .q,.status span,.prep-box .pt span{text-wrap:balance}

/* mobile: kept last so it wins over every rule above */
@media (max-width:760px){
  button.theme span{display:none}
  button.theme{padding:6px 8px}
  .pad-head{flex-direction:column;align-items:flex-start;padding:16px}
  .pad-inner{grid-template-columns:1fr;padding:18px 14px;gap:20px}
  .mouse{max-width:240px;margin:0 auto}
  .card{padding:10px 12px}
  .card .vals{gap:14px;flex-wrap:wrap}
  .card b{font-size:26px}
  .card i{font-size:12px}
  .card .k span{white-space:normal}
  .pad-foot{padding:12px 16px;flex-wrap:wrap}
  .tempo{margin-left:0;flex-wrap:wrap;flex:1 1 100%;row-gap:8px}
  .snd-opts{flex:1 1 100%}
  .snd-opts[hidden]{display:none}   /* on phones they sit on their own row; reserving it would leave a blank gap */
  .snd-opts input[type=range]{flex:1}
  .hero p{min-height:0}
  .content{margin-top:56px}
  .sec{grid-template-columns:1fr;gap:20px;padding:44px 0}
  .sec h2{position:static}
  .steps{grid-template-columns:1fr;gap:24px}
  .prods{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot-grid{grid-template-columns:1fr 1fr}
  .foot-brand{grid-column:1/-1}
  .fig{padding:18px 16px 14px}
  .compare{overflow-x:auto}
  .c-row{min-width:600px}
  .sources li{grid-template-columns:1fr}
  .fig .b-row{grid-template-columns:1fr auto;gap:6px 12px}
  .fig .b-row svg{grid-column:1/-1;grid-row:2}
  .fig.crit .b-row{grid-template-columns:auto 1fr}
  .fig.crit .res small{white-space:nowrap}
  .fig .pair{grid-template-columns:1fr;gap:22px}
  .status strong,.status span{white-space:normal}
  .prep-box{padding:22px 18px 18px}
  .prep-box h2{font-size:24px}
  .prep-box ol{grid-template-columns:1fr}
  button.go{width:100%}
  .head-right{width:100%;justify-content:space-between}
  button.reset kbd{display:none}
}
