:root{--bg:#f5f5f4;--ink:#292524;--muted:#78716c;--accent:#e7e5e4;--line:#e7e5e4}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px Arial,Helvetica,sans-serif;overflow:hidden}button,a{-webkit-tap-highlight-color:transparent}button{font:inherit;color:inherit;cursor:pointer}button:focus-visible,a:focus-visible{outline:2px solid #78716c;outline-offset:5px}button{border:0;background:none}header{height:92px;display:flex;align-items:center;justify-content:space-between;padding:0 42px;position:relative;z-index:3}.brand{display:flex;align-items:center;gap:8px;color:var(--ink);font-size:24px;font-weight:700;letter-spacing:-1px;text-decoration:none}.brand svg{width:25px;height:31px}.brand span{font-size:11px;align-self:flex-start;margin-top:5px}.edition{font-size:10px;letter-spacing:2px;color:var(--muted)}.reset{font-size:13px;display:flex;gap:8px;align-items:center}.intro{position:absolute;top:112px;left:0;width:100%;text-align:center;pointer-events:none}.eyebrow{font-size:10px;letter-spacing:1.9px;display:flex;gap:7px;align-items:center;justify-content:center}.eyebrow i{width:6px;height:6px;border-radius:50%;background:#a8a29e}h1{font-size:clamp(27px,3vw,43px);font-weight:400;letter-spacing:-1.7px;margin:15px 0 9px}.intro p{color:var(--muted);font-size:14px;margin:0}#scene{position:absolute;inset:0;overflow:hidden;pointer-events:none}.mouse{position:absolute;top:0;left:0;width:190px;height:222px;padding:0;pointer-events:auto;transition:transform .95s cubic-bezier(.22,1,.36,1),opacity .65s;will-change:transform;transform-origin:center;mix-blend-mode:multiply}.mouse img{width:190px;height:190px;object-fit:contain;pointer-events:none;transition:transform .25s}.mouse:hover img{transform:translateY(-7px)}.mouse .caption{display:block;white-space:nowrap;font-size:12px;transition:opacity .35s;opacity:0;line-height:1.5}.mouse .caption small{font-size:10px;display:block;color:#78716c}.mouse.featured .caption,.mouse:hover .caption,.mouse:focus-visible .caption{opacity:1}.mouse.featured{z-index:2}.mouse .rank{position:absolute;top:4px;left:20px;font-size:9px;letter-spacing:1px;background:var(--accent);padding:5px 7px;border-radius:20px;opacity:0}.mouse.first .rank{opacity:1}.status{position:absolute;left:0;right:0;bottom:318px;text-align:center;font-size:11px;color:#78716c;pointer-events:none}.status strong{font-weight:400;color:#44403c}.questionnaire{position:absolute;bottom:65px;left:50%;transform:translateX(-50%);width:640px;background:#ffffff;border:1px solid #e7e5e4;box-shadow:0 8px 36px #44403c09,0 2px 4px #44403c04;border-radius:15px;padding:21px 26px 0;z-index:5}.steps{display:flex;gap:5px;margin-bottom:19px}.steps button{height:4px;background:#e7e5e4;flex:1;padding:0;border-radius:5px}.steps button.past{background:#a8a29e}.steps button.current{background:#44403c}.question-head{display:flex;justify-content:space-between;align-items:center}.step-label{color:#78716c;font-size:10px;letter-spacing:1.5px}.help{border:1px solid #d6d3d1;border-radius:50%;width:19px;height:19px;font-size:11px;padding:0;color:#78716c}h2{font-size:24px;letter-spacing:-.6px;font-weight:400;margin:7px 0}.questionnaire p{font-size:12px;color:#78716c;margin:0 0 18px;line-height:1.45}.options{display:flex;gap:8px}.option{position:relative;flex:1;min-height:68px;border:1px solid #e7e5e4;border-radius:8px;padding:12px 9px;text-align:left;transition:background .18s,border-color .18s}.option:hover{background:#fafaf9;border-color:#a8a29e}.option.selected{background:#f5f5f4;border-color:#a8a29e}.option strong{display:block;font-size:13px;font-weight:500}.option small{font-size:10px;color:#78716c;display:block;margin-top:5px}.option.selected:after{content:'✓';position:absolute;right:9px;top:9px;font-size:11px}.question-footer{display:flex;justify-content:space-between;align-items:center;margin-top:19px;padding:13px 0;border-top:1px solid #f5f5f4}.question-footer button{font-size:11px;padding:3px 0}.question-footer button:disabled{opacity:.25;cursor:default}.question-footer span{font-size:10px;color:#a8a29e}.question-footer #next{font-weight:600}footer{position:absolute;bottom:22px;left:42px;right:42px;display:flex;justify-content:space-between;color:#a8a29e;font-size:9px;letter-spacing:1px}footer a{color:inherit;text-decoration:none;letter-spacing:0}footer b{padding:0 8px;font-weight:400}dialog{border:1px solid var(--line);border-radius:18px;padding:32px;width:min(470px,calc(100% - 28px));box-shadow:0 20px 90px #1c191722}dialog::backdrop{background:#2925244d;backdrop-filter:blur(4px)}.close{position:absolute;right:15px;top:10px;font-size:27px;color:#78716c}dialog img{display:block;width:200px;height:200px;object-fit:contain;margin:0 auto}dialog h2{font-size:26px}dialog p{color:#78716c;line-height:1.7;font-size:13px}dialog dl{display:grid;grid-template-columns:1fr 1fr;gap:12px;font-size:13px}dialog dt{color:#78716c}dialog dd{margin:0;text-align:right}dialog a{color:#57534e}.result-actions{min-height:68px;width:100%;display:flex;gap:8px}.result-actions button{border:1px solid var(--line);padding:12px;border-radius:8px;flex:1}.result-actions button:first-child{background:var(--accent);border-color:var(--accent)}@media(min-height:850px){.questionnaire{bottom:85px}.status{bottom:345px}.intro{top:135px}}@media(max-width:700px){header{height:72px;padding:0 20px}.brand{font-size:21px}.edition{display:none}.reset span{display:none}.reset{font-size:20px}.intro{top:89px}h1{letter-spacing:-1px;font-size:29px}.intro p{font-size:12px}.eyebrow{font-size:8px}.questionnaire{width:calc(100% - 28px);bottom:42px;padding:16px 17px 0;border-radius:13px}.questionnaire h2{font-size:22px}.steps{margin-bottom:14px}.questionnaire p{font-size:11px;margin-bottom:13px}.option{padding:11px 8px;min-height:68px}.option strong{font-size:12px}.option small{font-size:9px;line-height:1.5}.question-footer span{max-width:150px;text-align:center;font-size:9px}.status{bottom:298px;font-size:10px}footer{bottom:14px;left:20px;right:20px;font-size:8px}footer>span:first-child{display:none}footer>span:last-child{margin:auto}.mouse .caption{font-size:13px}.mouse .caption small{font-size:11px}.mouse .rank{font-size:10px}}@media(max-height:680px) and (min-width:701px){.intro{top:77px}.intro h1{font-size:30px;margin:8px}.questionnaire{bottom:45px;padding-top:14px}.steps{margin-bottom:10px}.questionnaire h2{font-size:21px}.questionnaire p{margin-bottom:10px}.option{min-height:58px}.question-footer{margin-top:10px}.status{bottom:273px}footer{bottom:14px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{transition:none!important;animation:none!important}}
body:not(.ready) .mouse{transition:none}.mouse .caption{font-size:15px}.mouse .caption small{font-size:12px}.mouse .rank{font-size:11px}

/* Minimal canvas: only products and questionnaire. */
.status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
#description,#selection{display:none}.questionnaire h2{margin-bottom:20px}#question:focus{outline:none}.question-footer #reset{font-size:19px;color:#a8a29e;padding:0 12px}.mouse .caption small:empty{display:none}
/* Larger product renders; keep names at their current type size. */
.mouse img{display:block;width:228px;height:228px;margin:-19px -19px 0}
/* Questionnaire: softer elevation and clearer, centered controls. */
.questionnaire{border:0;box-shadow:0 2px 5px rgba(41,37,36,.025),0 10px 24px rgba(41,37,36,.045),0 28px 64px rgba(41,37,36,.065);padding-top:24px}
.questionnaire .steps{margin-bottom:25px}
.questionnaire .step-label{display:none}
.questionnaire .question-head{position:absolute;right:24px;top:49px}
.questionnaire .help{width:28px;height:28px;font-size:13px}
.questionnaire h2{text-align:center;font-size:25px;line-height:1.3;margin:0 28px 24px}
.questionnaire p{text-align:center;font-size:14px;line-height:1.5}
.questionnaire .option{text-align:center;min-height:80px;padding:15px 10px}
.questionnaire .option strong{font-size:14px}
.questionnaire .option small{font-size:12px;line-height:1.5;margin-top:6px}
.questionnaire .question-footer{padding:14px 0;margin-top:22px}
.questionnaire .question-footer button{min-width:104px;min-height:44px;padding:11px 17px;font-size:14px;border-radius:8px;transition:background .18s}
.questionnaire .question-footer button:not(:disabled):hover{background:#f5f5f4}
.questionnaire .question-footer #back,.questionnaire .question-footer #next{background:#f5f5f4}
.questionnaire .question-footer #reset{min-width:44px;width:44px;padding:8px;font-size:22px}
@media(max-width:700px){.questionnaire{padding-top:20px}.questionnaire .steps{margin-bottom:22px}.questionnaire .question-head{right:15px;top:42px}.questionnaire h2{font-size:22px;margin:0 24px 22px}.questionnaire .option{padding:13px 7px}.questionnaire .option strong{font-size:13px}.questionnaire .option small{font-size:11px}.questionnaire .question-footer{margin-top:18px}}

/* Borderless answer tiles and stronger English typography. */
.questionnaire{padding-top:28px}.questionnaire h2{font-weight:600}.questionnaire .question-head{top:25px}.questionnaire .help{border:0;background:none;color:#78716c;display:flex;align-items:center;justify-content:center}.questionnaire .help[hidden]{display:none}.questionnaire .help svg{width:21px;height:21px;stroke-width:1.75}.questionnaire .option{border:0;background:#f5f5f4}.questionnaire .option:hover{background:#e7e5e4}.questionnaire .option.selected{background:#f5f5f4}.questionnaire .option strong{font-weight:700}.questionnaire .question-footer #reset{width:auto;min-width:70px;font-size:14px;padding:11px 17px}.result-actions button{border:0;background:#f5f5f4;font-weight:600}@media(max-width:700px){.questionnaire .question-head{top:24px}.questionnaire h2{font-size:21px}}

@font-face{font-family:Inter;src:url('assets/InterVariable.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
:root{--bg:#f5f5f4;--ink:#292524;--muted:#78716c;--accent:#e7e5e4;--line:#e7e5e4}
body{font-family:Inter,Arial,sans-serif;font-optical-sizing:auto}button,a{font-family:inherit}
.questionnaire .options{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}.questionnaire .options:has(>.option:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}.questionnaire .option{background:#f5f5f4}.questionnaire .option:hover{background:#e7e5e4}.questionnaire .option.selected{background:#d6d3d1}.questionnaire .option small,.questionnaire .help,.questionnaire .question-footer #reset{color:#78716c}.questionnaire .option strong{font-size:13px}.questionnaire .question-footer button:not(:disabled):hover{background:#e7e5e4}.result-actions{grid-column:1/-1}.result-actions button:first-child{background:#e7e5e4}.questionnaire .question-footer{justify-content:space-between}
@media(max-width:700px){.questionnaire .options{grid-template-columns:repeat(2,minmax(0,1fr))}.questionnaire .option{min-height:72px}.questionnaire .option small{font-size:11px}}
/* Long catalog names stay readable under the larger renders. */
.mouse .caption{width:190px;white-space:normal;text-align:center;line-height:1.25;min-height:32px}
.mouse .caption small{margin-top:3px}
.mouse.featured .caption{font-size:12px;line-height:1.2}
.mouse.featured .caption small{font-size:10px}
.mouse:not(.featured) .caption{opacity:0!important;visibility:hidden}

/* Keep the questionnaire 40px from the viewport bottom. */
.questionnaire{bottom:40px!important}
.weight-control{grid-column:1/-1;padding:4px 8px 3px}.weight-control input[type=range]{display:block;width:100%;height:18px;margin:3px 0 4px;accent-color:#78716c;cursor:pointer}.range-labels{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:4px;color:#a8a29e;font-size:10px;text-align:center;line-height:1.25}.range-labels span.active{color:#44403c;font-weight:700}.range-any{grid-column:1/-1!important}
@media(min-width:701px){.questionnaire{width:760px}}
.questionnaire .options{display:flex;flex-wrap:nowrap;align-items:stretch;gap:8px;overflow:visible}.questionnaire .option{flex:1 1 0;min-width:0}.questionnaire .option small{min-height:30px;max-width:105px;margin-left:auto;margin-right:auto;color:#57534e;display:flex;align-items:flex-start;justify-content:center}.questionnaire .weight-control{flex:1 1 auto;min-width:0}.questionnaire .range-any{flex:0 0 178px!important}
.questionnaire .question-footer{border-top:0;padding:0;margin:0;min-height:0;position:absolute;inset:0;pointer-events:none}.questionnaire .question-footer button{position:absolute;top:20px;pointer-events:auto;background:transparent!important;min-width:36px;width:36px;height:32px;padding:0;color:#78716c;font-size:0}.questionnaire .question-footer button[hidden]{display:none!important}.questionnaire .question-footer #back{left:18px}.questionnaire .question-footer #reset{right:54px}.questionnaire .question-footer #back:before{content:'←';font-size:22px;line-height:1}.questionnaire .question-footer #reset:before{content:'↻';font-size:21px;line-height:1}.questionnaire .question-footer button:hover{background:transparent!important;color:#44403c;border-radius:0}
.questionnaire{padding-bottom:28px}.questionnaire .question-head{top:30px}.questionnaire .question-footer button{width:28px;height:28px;min-width:28px;top:30px}.questionnaire .question-footer #back{left:18px}.questionnaire .question-footer #back:disabled{display:none}.questionnaire .question-footer #reset{font-size:0!important;left:46px;right:auto}.questionnaire .question-footer #back:before{font-size:21px}.questionnaire .question-footer #reset:before{font-size:21px}
.questionnaire .question-footer button:before{content:none!important}.questionnaire .question-footer button img,.questionnaire .help img,.questionnaire .question-footer button svg,.questionnaire .help svg{display:block;width:21px;height:21px;margin:auto}.questionnaire .question-footer button:hover,.questionnaire .help:hover{color:#44403c}
@media(max-width:700px){.questionnaire .options{overflow-x:auto;overflow-y:hidden;padding-bottom:2px;scrollbar-width:none}.questionnaire .options::-webkit-scrollbar{display:none}.questionnaire .option{flex:0 0 122px}.questionnaire .weight-control{flex:0 0 330px}.questionnaire .range-any{flex:0 0 122px!important}.questionnaire .question-head{top:22px}.questionnaire .question-footer button{top:22px}.questionnaire .question-footer #back{left:10px}.questionnaire .question-footer #reset{left:38px}}


/* Back, reset and info sit on the same line as the heading and on the content edges. */
.questionnaire .question-head{right:26px;top:30px}
.questionnaire .question-footer button{min-height:28px;height:28px;top:30px}
.questionnaire .question-footer #back{left:26px}
.questionnaire .question-footer #reset{left:58px}
/* Every answer tile keeps the same height and centres its content, with or without a hint. */
.questionnaire .option{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px}
.questionnaire .option strong{width:100%}
.questionnaire .option small{min-height:0;margin-top:0}
@media(max-width:700px){.questionnaire .question-head{right:17px;top:28px}.questionnaire .question-footer button{top:28px}.questionnaire .question-footer #back{left:17px}.questionnaire .question-footer #reset{left:49px}}

/* One identical 28px box for back, reset and info, all centred on the heading line.
   Earlier layers gave #reset an id-specific padding, which pushed its icon 11px down. */
.questionnaire .help,
.questionnaire .question-footer #back,
.questionnaire .question-footer #reset{width:28px!important;height:28px!important;min-width:28px!important;min-height:28px!important;padding:0!important;margin:0;border:0;display:flex;align-items:center;justify-content:center;line-height:0}
.questionnaire .question-head,
.questionnaire .question-footer #back,
.questionnaire .question-footer #reset{top:30px}
.questionnaire .question-footer #back{left:26px}
.questionnaire .question-footer #reset{left:58px;right:auto}
.questionnaire .question-head{right:26px}
.questionnaire .help svg,.questionnaire .question-footer button svg{display:block;width:21px;height:21px;margin:0}

/* Help modal illustrations. */
dialog img.diagram{display:block;width:100%;height:auto;max-width:100%;margin:2px 0 16px}

/* Match gallery: full-bleed sheets. The centred card is the old detail modal; its neighbours
   fan out to the screen edges, dimmed, and the stack drags like sheets of paper. */
#details.wide{width:100vw;max-width:none;height:100vh;max-height:none;margin:0;padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px}
#details.wide .close{position:fixed;right:24px;top:16px;z-index:3;color:#57534e}
.gallery{--cardw:470px;width:100vw;max-width:100vw;align-self:stretch;min-width:0;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;scrollbar-width:none}
.gallery::-webkit-scrollbar{width:0;height:0}
.gallery-track{display:flex;width:max-content;gap:26px;align-items:stretch;padding-inline:calc((100vw - var(--cardw))/2)}
.card{flex:0 0 var(--cardw);scroll-snap-align:center;scroll-snap-stop:always;box-sizing:border-box;background:#fff;border:1px solid var(--line);border-radius:18px;padding:32px;text-align:left;max-height:calc(100vh - 150px);overflow-x:clip;overflow-y:auto;overscroll-behavior-x:auto;overscroll-behavior-y:contain;opacity:1;transition:transform .5s cubic-bezier(.22,1,.36,1),opacity .4s,box-shadow .4s;cursor:pointer;user-select:none;box-shadow:0 6px 24px rgba(28,25,23,.05)}
.card.active{cursor:default;box-shadow:0 20px 90px rgba(28,25,23,.17)}
.card img{pointer-events:none;mix-blend-mode:multiply}
.card h2{margin:0}
/* Name plus a bare copy button — the strip swallows a text drag as a swipe, so the button is the
   reliable way to lift the model name off the card. */
.title-row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:6px 0 16px}
/* Shown on every card, centred or not — a neighbour's name is just as copyable, and a click on the
   button copies without dragging that card into the middle. */
.copy-name{flex:0 0 auto;margin-left:auto;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--muted);border:0;background:none;border-radius:6px;cursor:pointer;pointer-events:auto;transition:color .2s}
.copy-name svg{width:23px;height:23px}
.copy-name:hover{color:var(--ink)}
/* Confirmation rides up from the bottom of the sheet and leaves on its own — a checkmark swapped
   into the button was easy to miss with the eye still on the name. */
/* The layer is promoted up front, not by .show: adding will-change together with the animation made
   the browser build the layer on the first frames, which is exactly the hitch at the start of the
   rise. JS pins it in whole pixels, so the transform stays a pure px translate3d — no -50%/-100%
   percentage offsets to land the box on a half pixel and resample the text every frame. */
.toast{position:fixed;z-index:10;pointer-events:none;white-space:nowrap;background:var(--ink);color:#fafaf9;font-size:11px;letter-spacing:.2px;padding:5px 12px;border-radius:999px;box-shadow:0 6px 18px rgba(28,25,23,.22);opacity:0;transform:translate3d(0,0,0);will-change:transform,opacity;backface-visibility:hidden}
/* Rise and fade run as two animations so neither curve has to compromise for the other. One shared
   keyframe list forced easing swaps mid-flight, and every swap read as a jolt. */
.toast.show{animation:toast-rise .68s cubic-bezier(.22,.75,.3,1) forwards,toast-fade .68s forwards}
/* A short hop, not a launch: 8px up from the button and it settles. The old 30px of travel meant the
   pill was still climbing while it faded, and drifted well clear of the icon it belonged to. */
@keyframes toast-rise{
  from{transform:translate3d(0,8px,0)}
  to{transform:translate3d(0,-8px,0)}
}
/* Out fast — the fade-out leg is the last ~20% of the run, front-loaded so most of the alpha is gone
   in the first frames of it instead of lingering half-visible. */
@keyframes toast-fade{
  0%{opacity:0;animation-timing-function:cubic-bezier(.2,.8,.4,1)}
  16%{opacity:1}
  80%{opacity:1;animation-timing-function:cubic-bezier(.2,.75,.45,1)}
  100%{opacity:0}
}
/* The centred card is not click-to-centre any more, so its text can be selected and copied. */
.card.active{user-select:text;-webkit-user-select:text;cursor:auto}
.match{margin:0 0 18px}
.match-bar{height:4px;border-radius:4px;background:#f0efee;overflow:hidden;margin-bottom:8px}
.match-bar i{display:block;height:100%;background:#a8a29e;border-radius:4px;transition:width .4s}
.card.active .match-bar i{background:#78716c}
.match span{font-size:12px;color:#78716c}
.match.none{font-size:12px;color:#a8a29e}
.card a{display:inline-block;font-size:12px}
@media(max-width:700px){.gallery{--cardw:calc(100vw - 44px)}.card{padding:22px 20px;max-height:calc(100vh - 130px)}.gallery-track{gap:16px}.card img{width:150px;height:150px}#details.wide .close{right:14px;top:10px}}
/* Hints only wrapped early because of a 105px cap meant for five-across rows. */
.questionnaire .option small{max-width:150px}
/* Shape answers carry a real catalog render as a worked example, on the tile rather than in a modal. */
.questionnaire .options.with-shots .option{min-height:180px;justify-content:center;padding-top:12px;padding-bottom:12px}
.questionnaire .options.with-shots .option:not(:has(.option-shot)){justify-content:center}
/* Catalog renders sit in a lot of whitespace, so the box is scaled into rather than enlarged. */
.questionnaire .option .option-shot{display:block;width:100%;max-width:146px;height:114px;object-fit:contain;margin:0 auto 2px;mix-blend-mode:multiply;pointer-events:none}
@media(max-width:700px){.questionnaire .options.with-shots .option{min-height:152px;padding-top:10px;padding-bottom:10px}.questionnaire .option .option-shot{max-width:104px;height:80px}}

/* ---- Options that would leave nothing to show ----
   Not `disabled`: a disabled button swallows pointer events in Chrome, and the tooltip needs hover.
   The shape tiles clip their render with overflow:hidden, which would also clip the tooltip, so a
   dead tile drops both the clip and the 1.3 upscale that made the clip necessary. */
.questionnaire .option.unavailable{position:relative;overflow:visible;cursor:not-allowed;color:#a8a29e;background:#fafaf9}
.questionnaire .option.unavailable:hover{background:#fafaf9}
.questionnaire .option.unavailable strong{font-weight:500}
.questionnaire .option.unavailable small{color:#c4c1be}
.questionnaire .option.unavailable .option-shot{transform:none;filter:grayscale(1);opacity:.35}
.questionnaire .option.unavailable:hover::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 10px);left:50%;transform:translateX(-50%);width:236px;background:#292524;color:#fafaf9;font-size:11px;font-weight:400;line-height:1.5;letter-spacing:0;text-align:left;padding:10px 12px;border-radius:9px;z-index:20;pointer-events:none;box-shadow:0 10px 30px #1c191733}
.questionnaire .option.unavailable:hover::before{content:'';position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);border:6px solid transparent;border-top-color:#292524;z-index:20;pointer-events:none}
/* Horizontal scrolling clips the tooltip on narrow screens; there the tap writes it under the title. */
@media(max-width:700px){.questionnaire .option.unavailable:hover::after,.questionnaire .option.unavailable:hover::before{display:none}}
/* A tile that leaves one or two models: still clickable, but it says so and explains on hover. */
.questionnaire .option.thin{position:relative;overflow:visible}
.questionnaire .option.thin:hover::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 10px);left:50%;transform:translateX(-50%);width:236px;background:#292524;color:#fafaf9;font-size:11px;font-weight:400;line-height:1.5;letter-spacing:0;text-align:left;padding:10px 12px;border-radius:9px;z-index:20;pointer-events:none;box-shadow:0 10px 30px #1c191733}
.questionnaire .option.thin:hover::before{content:'';position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);border:6px solid transparent;border-top-color:#292524;z-index:20;pointer-events:none}
@media(max-width:700px){.questionnaire .option.thin:hover::after,.questionnaire .option.thin:hover::before{display:none}}



/* ---- Grip tiles.
   Grip is a qualitative choice no label carries — "claw" means nothing to someone who has not met
   the word — so each tile carries a render of the hand on the shell instead.
   The source files are square with wide empty margins above and below the subject, so `cover`
   crops those away; `contain` would fit the whole 1254px square and shrink the hand to nothing. */
.questionnaire .option.has-icon{min-height:186px;justify-content:center;padding-top:14px;padding-bottom:14px;gap:2px}
.questionnaire .grip-icon{display:block;width:100%;height:96px;object-fit:cover;object-position:center;margin:0 auto 5px;pointer-events:none}
.questionnaire .option.unavailable .grip-icon{opacity:.38;filter:grayscale(1)}

@media(max-width:700px){
  .questionnaire .option.has-icon{min-height:154px;padding-top:11px;padding-bottom:11px}
  .questionnaire .grip-icon{height:74px;margin-bottom:4px}
}
/* Mobile header: back/reset/help icons sit in line with the title text (as on desktop) instead of
   floating on a strip above it. The title is padded to clear the icons and wraps within that space
   rather than sliding under them; the icons are pinned to the title's first line. */
@media(max-width:700px){
  .questionnaire h2{margin-top:9px;margin-bottom:20px;font-size:16px;padding-left:54px;padding-right:34px;line-height:1.3}
  .questionnaire .question-head{top:34px!important;right:12px}
  .questionnaire .question-footer button{top:34px!important;height:26px;width:24px!important;min-width:24px!important}
  .questionnaire .question-footer #back{left:8px!important}
  .questionnaire .question-footer #reset{left:30px!important;right:auto!important}
}

/* ---- P3 additions: card links ---- */
/* Gallery is a transparent full-screen dialog; hide the scene behind it so mix-blend-mode nodes
   can never bleed over the cards. Hidden instantly (no fade) so the blurred backdrop has a static
   target and the open stays smooth. The scene can't stay visible-and-blurred: any isolation that
   would stop the bleed also cuts the multiply blend off from the page, leaving white photo boxes. */
body.gallery-open #scene{opacity:.55;pointer-events:none}
/* A closed dialog must stay hidden even if .wide lingers — #details.wide{display:flex} otherwise
   outweighs the UA rule and leaves the closed gallery on screen. */
#details:not([open]){display:none!important}

/* Results screen has a single, black call to action. */
.result-actions #best{background:#292524;color:#fafaf9;border:0;font-weight:600}
.result-actions #best:hover{background:#44403c}

/* Spec grid: label over value, several per row, so the card stays short (no scroll). */
.card .specs{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:14px 18px;margin:16px 0 5px}
/* Keep the spec grid at two columns and shrink the render on narrow screens so the card stays short. */
@media(max-width:700px){.card .specs{grid-template-columns:1fr 1fr;column-gap:14px;row-gap:12px}.card img{width:150px;height:150px}}
.card .spec{display:flex;flex-direction:column;gap:2px;min-width:0}
.card .spec .k{color:#78716c;font-size:12px;letter-spacing:.2px}
.card .spec .v{font-size:14px;line-height:1.3;overflow-wrap:anywhere}
.card .spec-wide{grid-column:1/-1}
.card .spec-wide .v{white-space:nowrap;overflow-wrap:normal}
/* On the narrowest phones the full "wireless · Wired · Bluetooth" line needs a touch less type. */
@media(max-width:360px){.card .spec-wide .v{font-size:13px}}

/* ---- UI tweaks: black match bar, arrows lower, open-animation performance ---- */
/* Match bar fill black (override the .card.active grey too). */
.match-bar i,.card.active .match-bar i{background:#292524}

/* Move the gallery arrows to the bottom of the viewport. */
.gallery-nav{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:4}

/* Performance: animating box-shadow on 12 cards is what made opening the gallery stutter — drop it
   from the card transition (the shadow stays, it just no longer animates). The backdrop blur is
   cheap here because the scene behind is hidden instantly, so it blurs a static background (the
   questionnaire panel) once instead of recomputing every frame. */
.card{transition:transform .5s cubic-bezier(.22,1,.36,1),opacity .4s}
dialog::backdrop{background:#29252442;backdrop-filter:blur(8px)}

/* Flat cards and dialog: no drop shadows, the border carries the edge. */
.card,.card.active,dialog{box-shadow:none}

/* The dimmed background mice are clickable (they jump to that model) — brighten on hover so they
   clearly read as interactive. */
.mouse{cursor:pointer;transition:transform .95s cubic-bezier(.22,1,.36,1),opacity .3s}
.mouse:hover{opacity:1!important}

/* ---- Mobile: the questionnaire is a bottom sheet ---- */
/* Edge to edge and flush with the bottom of the viewport, rounded on the top corners only. Saves
   the ~40px gap plus the side gutters, which is a lot of room on a phone. */
@media(max-width:700px){
  .questionnaire{
    left:0;
    right:0;
    width:100%;
    transform:none;
    bottom:0!important;
    border-radius:16px 16px 0 0;
    padding-bottom:calc(20px + env(safe-area-inset-bottom,0px));
    /* The card shadow only falls downwards, which is the one edge a bottom sheet has off screen.
       A light upward pair lifts the top edge off the scene without turning into a dark band. */
    box-shadow:0 -1px 4px rgba(41,37,36,.04),0 -8px 22px rgba(41,37,36,.07);
  }
}

/* Back and reset sat one hit-area apart, so the two icons visually touched. Push them apart, and
   off the edge of the screen now that the sheet is full-bleed; the title's padding follows. */
.questionnaire .question-footer #reset{left:66px}
@media(max-width:700px){
  .questionnaire .question-footer #back{left:14px!important}
  .questionnaire .question-footer #reset{left:44px!important;right:auto!important}
  .questionnaire .question-head{right:16px!important}
  .questionnaire h2{margin-left:0;margin-right:0;padding-left:72px;padding-right:72px}
}

/* Mobile: let the option row fill the sheet. The row is a horizontal scroller sized for four
   options, so with two or three the boxes were stranded at 122px against a full-width sheet.
   Growing from that basis fills the width when they fit; shrinking down to 104px lets three fill
   it too, while four or more still overflow into the scroll (and the clipped last box is what
   signals that the row scrolls). */
@media(max-width:700px){
  .questionnaire .options > .option{flex:1 1 122px;min-width:104px}
}


/* ---- Mobile: readable captions under the featured shells ---- */
/* The shells are scaled to ~.6 on a phone, which shrank the 13px name to about 8px on screen.
   Dividing the node's scale back out keeps the caption at its intended size whatever the shell
   does; the extra weight and darker weight line hold up against the light background. */
@media(max-width:700px){
  .mouse.featured .caption{font-size:calc(13px / var(--s,1));font-weight:600}
  .mouse.featured .caption small{font-size:calc(11px / var(--s,1));color:#57534e;margin-top:calc(2px / var(--s,1))}
}

/* Hand question: two bare tiles, so the word itself carries the tile. */
.questionnaire .option[data-field="side"] strong{font-size:20px}

/* ---- Gallery: swipe instead of arrows ---- */
/* The arrows are gone, so the strip is the only child of the sheet and centres itself top to
   bottom. The strip is a real scroll container with snap points, so the browser arbitrates the two
   axes itself: sideways pans the strip, up and down scrolls the card under the thumb. Driving it
   from pointer events instead meant the card's own scroller claimed almost every touch first.
   The card must not claim the sideways gesture either: `overflow-y:auto` alone makes the browser
   compute `overflow-x:auto` too, so the card is a horizontal scroller with nowhere to go, and
   `overscroll-behavior:contain` then refuses to hand the swipe up to the strip. `clip` keeps the
   card off the horizontal axis entirely; the x-axis `auto` is the fallback where `clip` is not
   supported, and containment stays on the axis that actually needed it. */
.gallery.dragging{scroll-snap-type:none;cursor:grabbing}
.gallery.dragging .card{user-select:none;-webkit-user-select:none}
/* The shot multiplies against the card's own white background, so isolating the card changes
   nothing on screen but stops every drag frame from re-blending against the whole page. */
.card{isolation:isolate;contain:layout paint}
#details.wide{gap:0}
@media(max-width:700px){.card{max-height:calc(100vh - 96px)}}

/* `100vh` on a phone is the viewport with the browser's address bar counted out — the sheet came
   out taller than what you can actually see, so its centred card sat low and ran off the bottom.
   `dvh` is the height that is really on screen. */
@supports(height:100dvh){
  #details.wide{height:100dvh}
  .card{max-height:calc(100dvh - 150px)}
  @media(max-width:700px){.card{max-height:calc(100dvh - 96px)}}
}
