/*! 98.css v0.1.20 - https://github.com/jdan/98.css */@font-face{font-family:"Pixelated MS Sans Serif";font-style:normal;font-weight:400;src:url(ms_sans_serif.woff) format("woff");src:url(ms_sans_serif.woff2) format("woff2")}@font-face{font-family:"Pixelated MS Sans Serif";font-style:normal;font-weight:700;src:url(ms_sans_serif_bold.woff) format("woff");src:url(ms_sans_serif_bold.woff2) format("woff2")}body{color:#222;font-family:Arial;font-size:12px}.title-bar,.window,button,input,label,option,select,table,textarea,ul.tree-view{-webkit-font-smoothing:none;font-family:"Pixelated MS Sans Serif",Arial;font-size:11px}h1{font-size:5rem}h2{font-size:2.5rem}h3{font-size:2rem}h4{font-size:1.5rem}u{border-bottom:.5px solid #222;text-decoration:none}button,input[type=reset],input[type=submit]{border:none;border-radius:0;box-sizing:border-box;color:transparent;min-height:23px;min-width:75px;padding:0 12px;text-shadow:0 0 #222}.vertical-bar,button,input[type=reset],input[type=submit]{background:silver;box-shadow:inset -1px -1px #0a0a0a,inset 1px 1px #fff,inset -2px -2px grey,inset 2px 2px #dfdfdf}.vertical-bar{height:20px;width:4px}button:not(:disabled):active,input[type=reset]:not(:disabled):active,input[type=submit]:not(:disabled):active{box-shadow:inset -1px -1px #fff,inset 1px 1px #0a0a0a,inset -2px -2px #dfdfdf,inset 2px 2px grey;text-shadow:1px 1px #222}@media (not(hover)){button:not(:disabled):hover,input[type=reset]:not(:disabled):hover,input[type=submit]:not(:disabled):hover{box-shadow:inset -1px -1px #fff,inset 1px 1px #0a0a0a,inset -2px -2px #dfdfdf,inset 2px 2px grey}}button:focus,input[type=reset]:focus,input[type=submit]:focus{outline:1px dotted #000;outline-offset:-4px}button::-moz-focus-inner,input[type=reset]::-moz-focus-inner,input[type=submit]::-moz-focus-inner{border:0}:disabled,:disabled+label,input[readonly],input[readonly]+label{color:grey}:disabled+label,button:disabled,input[type=reset]:disabled,input[type=submit]:disabled{text-shadow:1px 1px 0 #fff}.window{background:silver;box-shadow:inset -1px -1px #0a0a0a,inset 1px 1px #dfdfdf,inset -2px -2px grey,inset 2px 2px #fff;padding:3px}.title-bar{align-items:center;background:linear-gradient(90deg,navy,#1084d0);display:flex;justify-content:space-between;padding:3px 2px 3px 3px}.title-bar.inactive{background:linear-gradient(90deg,grey,#b5b5b5)}.title-bar-text{color:#fff;font-weight:700;letter-spacing:0;margin-right:24px}.title-bar-controls{display:flex}.title-bar-controls button{display:block;min-height:14px;min-width:16px;padding:0}.title-bar-controls button:active{padding:0}.title-bar-controls button:focus{outline:none}.title-bar-controls button[aria-label=Minimize]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='6' height='2' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23000' d='M0 0h6v2H0z'/%3E%3C/svg%3E");background-position:bottom 3px left 4px;background-repeat:no-repeat}.title-bar-controls button[aria-label=Maximize]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='9' height='9' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 0H0v9h9V0zM8 2H1v6h7V2z' fill='%23000'/%3E%3C/svg%3E");background-position:top 2px left 3px;background-repeat:no-repeat}.title-bar-controls button[aria-label=Restore]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='9' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23000' d='M2 0h6v2H2zM7 2h1v4H7zM2 2h1v1H2zM6 5h1v1H6zM0 3h6v2H0zM5 5h1v4H5zM0 5h1v4H0zM1 8h4v1H1z'/%3E%3C/svg%3E");background-position:top 2px left 3px;background-repeat:no-repeat}.title-bar-controls button[aria-label=Help]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='6' height='9' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23000' d='M0 1h2v2H0zM1 0h4v1H1zM4 1h2v2H4zM3 3h2v1H3zM2 4h2v2H2zM2 7h2v2H2z'/%3E%3C/svg%3E");background-position:top 2px left 5px;background-repeat:no-repeat}.title-bar-controls button[aria-label=Close]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0h2v1h1v1h2V1h1V0h2v1H7v1H6v1H5v1h1v1h1v1h1v1H6V6H5V5H3v1H2v1H0V6h1V5h1V4h1V3H2V2H1V1H0V0z' fill='%23000'/%3E%3C/svg%3E");background-position:top 3px left 4px;background-repeat:no-repeat;margin-left:2px}.status-bar{gap:1px;display:flex;margin:0 1px}.status-bar-field{box-shadow:inset -1px -1px #dfdfdf,inset 1px 1px grey;flex-grow:1;margin:0;padding:2px 3px}.window-body{margin:8px}fieldset{border-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='5' height='5' fill='gray' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0h5v5H0V2h2v1h1V2H0' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0h4v4H0V1h1v2h2V1H0'/%3E%3C/svg%3E") 2;margin:0;padding:10px;padding-block-start:8px}legend{background:silver}.field-row{align-items:center;display:flex}[class^=field-row]+[class^=field-row]{margin-top:6px}.field-row>*+*{margin-left:6px}.field-row-stacked{display:flex;flex-direction:column}.field-row-stacked *+*{margin-top:6px}label{align-items:center;display:inline-flex}input[type=checkbox],input[type=radio]{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:0;border:none;margin:0;opacity:0;position:fixed}input[type=checkbox]+label,input[type=radio]+label{line-height:13px}input[type=radio]+label{margin-left:18px;position:relative}input[type=radio]+label:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 0H4v1H2v1H1v2H0v4h1v2h1V8H1V4h1V2h2V1h4v1h2V1H8V0z' fill='gray'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 1H4v1H2v2H1v4h1v1h1V8H2V4h1V3h1V2h4v1h2V2H8V1z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 3h1v1H9V3zm1 5V4h1v4h-1zm-2 2V9h1V8h1v2H8zm-4 0v1h4v-1H4zm0 0V9H2v1h2z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 2h-1v2h1v4h-1v2H8v1H4v-1H2v1h2v1h4v-1h2v-1h1V8h1V4h-1V2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2h4v1h1v1h1v4H9v1H8v1H4V9H3V8H2V4h1V3h1V2z' fill='%23fff'/%3E%3C/svg%3E");content:"";display:inline-block;height:12px;left:-18px;margin-right:6px;position:absolute;top:0;width:12px}input[type=radio]:active+label:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 0H4v1H2v1H1v2H0v4h1v2h1V8H1V4h1V2h2V1h4v1h2V1H8V0z' fill='gray'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 1H4v1H2v2H1v4h1v1h1V8H2V4h1V3h1V2h4v1h2V2H8V1z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 3h1v1H9V3zm1 5V4h1v4h-1zm-2 2V9h1V8h1v2H8zm-4 0v1h4v-1H4zm0 0V9H2v1h2z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 2h-1v2h1v4h-1v2H8v1H4v-1H2v1h2v1h4v-1h2v-1h1V8h1V4h-1V2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2h4v1h1v1h1v4H9v1H8v1H4V9H3V8H2V4h1V3h1V2z' fill='silver'/%3E%3C/svg%3E")}input[type=radio]:checked+label:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='4' height='4' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0H1v1H0v2h1v1h2V3h1V1H3V0z' fill='%23000'/%3E%3C/svg%3E");content:"";display:block;height:4px;left:-14px;position:absolute;top:4px;width:4px}input[type=checkbox]:focus+label,input[type=radio]:focus+label{outline:1px dotted #000}input[type=radio][disabled]+label:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 0H4v1H2v1H1v2H0v4h1v2h1V8H1V4h1V2h2V1h4v1h2V1H8V0z' fill='gray'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 1H4v1H2v2H1v4h1v1h1V8H2V4h1V3h1V2h4v1h2V2H8V1z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 3h1v1H9V3zm1 5V4h1v4h-1zm-2 2V9h1V8h1v2H8zm-4 0v1h4v-1H4zm0 0V9H2v1h2z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 2h-1v2h1v4h-1v2H8v1H4v-1H2v1h2v1h4v-1h2v-1h1V8h1V4h-1V2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2h4v1h1v1h1v4H9v1H8v1H4V9H3V8H2V4h1V3h1V2z' fill='silver'/%3E%3C/svg%3E")}input[type=radio][disabled]:checked+label:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='4' height='4' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0H1v1H0v2h1v1h2V3h1V1H3V0z' fill='gray'/%3E%3C/svg%3E")}input[type=checkbox]+label{margin-left:19px;position:relative}input[type=checkbox]+label:before{background:#fff;box-shadow:inset -1px -1px #fff,inset 1px 1px grey,inset -2px -2px #dfdfdf,inset 2px 2px #0a0a0a;content:"";display:inline-block;height:13px;left:-19px;margin-right:6px;position:absolute;width:13px}input[type=checkbox]:active+label:before{background:silver}input[type=checkbox]:checked+label:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='7' height='7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 0H6v1H5v1H4v1H3v1H2V3H1V2H0v3h1v1h1v1h1V6h1V5h1V4h1V3h1V0z' fill='%23000'/%3E%3C/svg%3E");content:"";display:block;height:7px;left:-16px;position:absolute;top:3px;width:7px}input[type=checkbox][disabled]+label:before{background:silver}input[type=checkbox][disabled]:checked+label:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='7' height='7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 0H6v1H5v1H4v1H3v1H2V3H1V2H0v3h1v1h1v1h1V6h1V5h1V4h1V3h1V0z' fill='gray'/%3E%3C/svg%3E")}input[type=email],input[type=number],input[type=password],input[type=text]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:0}input[type=email],input[type=number],input[type=password],input[type=text],select{background-color:#fff;box-shadow:inset -1px -1px #fff,inset 1px 1px grey,inset -2px -2px #dfdfdf,inset 2px 2px #0a0a0a;box-sizing:border-box;padding:3px 4px}select,textarea{border:none}textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-radius:0;box-shadow:inset -1px -1px #fff,inset 1px 1px grey,inset -2px -2px #dfdfdf,inset 2px 2px #0a0a0a;box-sizing:border-box;padding:3px 4px}input[type=email],input[type=password],input[type=text],select{height:21px}input[type=number]{height:22px}input[type=email],input[type=number],input[type=password],input[type=text]{line-height:2}input[type=email]:disabled,input[type=email]:read-only,input[type=number]:disabled,input[type=number]:read-only,input[type=password]:disabled,input[type=password]:read-only,input[type=text]:disabled,input[type=text]:read-only,textarea:disabled{background-color:silver}select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0v16h1V1h14V0z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1v14h1V2h12V1H2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H0v-1h15V0h1v17z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1h-1v14H1v1h14V1z' fill='gray'/%3E%3Cpath fill='silver' d='M2 2h12v13H2z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 6H4v1h1v1h1v1h1v1h1V9h1V8h1V7h1V6z' fill='%23000'/%3E%3C/svg%3E");background-position:top 2px right 2px;background-repeat:no-repeat;border-radius:0;padding-right:32px;position:relative}input[type=email]:focus,input[type=number]:focus,input[type=password]:focus,input[type=text]:focus,select:focus,textarea:focus{outline:none}input[type=range]{-webkit-appearance:none;background:transparent;width:100%}input[type=range]:focus{outline:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='21' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0v16h2v2h2v2h1v-1H3v-2H1V1h9V0z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1 1v15h1v1h1v1h1v1h2v-1h1v-1h1v-1h1V1z' fill='%23C0C7C8'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 1h1v15H8v2H6v2H5v-1h2v-2h2z' fill='%2387888F'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10 0h1v16H9v2H7v2H5v1h1v-2h2v-2h2z' fill='%23000'/%3E%3C/svg%3E");border:none;box-shadow:none;height:21px;transform:translateY(-8px);width:11px}input[type=range].has-box-indicator::-webkit-slider-thumb{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='21' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0v20h1V1h9V0z' fill='%23fff'/%3E%3Cpath fill='%23C0C7C8' d='M1 1h8v18H1z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 1h1v19H1v-1h8z' fill='%2387888F'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10 0h1v21H0v-1h10z' fill='%23000'/%3E%3C/svg%3E");transform:translateY(-10px)}input[type=range]::-moz-range-thumb{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='21' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0v16h2v2h2v2h1v-1H3v-2H1V1h9V0z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1 1v15h1v1h1v1h1v1h2v-1h1v-1h1v-1h1V1z' fill='%23C0C7C8'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 1h1v15H8v2H6v2H5v-1h2v-2h2z' fill='%2387888F'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10 0h1v16H9v2H7v2H5v1h1v-2h2v-2h2z' fill='%23000'/%3E%3C/svg%3E");border:0;border-radius:0;height:21px;transform:translateY(2px);width:11px}input[type=range].has-box-indicator::-moz-range-thumb{background:url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='21' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0v20h1V1h9V0z' fill='%23fff'/%3E%3Cpath fill='%23C0C7C8' d='M1 1h8v18H1z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 1h1v19H1v-1h8z' fill='%2387888F'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10 0h1v21H0v-1h10z' fill='%23000'/%3E%3C/svg%3E");transform:translateY(0)}input[type=range]::-webkit-slider-runnable-track{background:#000;border-bottom:1px solid grey;border-right:1px solid grey;box-shadow:1px 0 0 #fff,1px 1px 0 #fff,0 1px 0 #fff,-1px 0 0 #a9a9a9,-1px -1px 0 #a9a9a9,0 -1px 0 #a9a9a9,-1px 1px 0 #fff,1px -1px #a9a9a9;box-sizing:border-box;height:2px;width:100%}input[type=range]::-moz-range-track{background:#000;border-bottom:1px solid grey;border-right:1px solid grey;box-shadow:1px 0 0 #fff,1px 1px 0 #fff,0 1px 0 #fff,-1px 0 0 #a9a9a9,-1px -1px 0 #a9a9a9,0 -1px 0 #a9a9a9,-1px 1px 0 #fff,1px -1px #a9a9a9;box-sizing:border-box;height:2px;width:100%}.is-vertical{display:inline-block;height:150px;transform:translateY(50%);width:4px}.is-vertical>input[type=range]{height:4px;margin:0 16px 0 10px;transform:rotate(270deg) translateX(calc(-50% + 8px));transform-origin:left;width:150px}.is-vertical>input[type=range]::-webkit-slider-runnable-track{border-bottom:1px solid grey;border-left:1px solid grey;border-right:0;box-shadow:-1px 0 0 #fff,-1px 1px 0 #fff,0 1px 0 #fff,1px 0 0 #a9a9a9,1px -1px 0 #a9a9a9,0 -1px 0 #a9a9a9,1px 1px 0 #fff,-1px -1px #a9a9a9}.is-vertical>input[type=range]::-moz-range-track{border-bottom:1px solid grey;border-left:1px solid grey;border-right:0;box-shadow:-1px 0 0 #fff,-1px 1px 0 #fff,0 1px 0 #fff,1px 0 0 #a9a9a9,1px -1px 0 #a9a9a9,0 -1px 0 #a9a9a9,1px 1px 0 #fff,-1px -1px #a9a9a9}.is-vertical>input[type=range]::-webkit-slider-thumb{transform:translateY(-8px) scaleX(-1)}.is-vertical>input[type=range].has-box-indicator::-webkit-slider-thumb{transform:translateY(-10px) scaleX(-1)}.is-vertical>input[type=range]::-moz-range-thumb{transform:translateY(2px) scaleX(-1)}.is-vertical>input[type=range].has-box-indicator::-moz-range-thumb{transform:translateY(0) scaleX(-1)}select:focus{background-color:navy;color:#fff}select:focus option{background-color:#fff;color:#000}select:active{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0h16v17H0V0zm1 16h14V1H1v15z' fill='gray'/%3E%3Cpath fill='silver' d='M1 1h14v15H1z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 7H5v1h1v1h1v1h1v1h1v-1h1V9h1V8h1V7z' fill='%23000'/%3E%3C/svg%3E")}a{color:#00f}a:focus{outline:1px dotted #00f}ul.tree-view{background:#fff;box-shadow:inset -1px -1px #fff,inset 1px 1px grey,inset -2px -2px #dfdfdf,inset 2px 2px #0a0a0a;display:block;margin:0;padding:6px}ul.tree-view li{list-style-type:none}ul.tree-view a{color:#000;text-decoration:none}ul.tree-view a:focus{background-color:navy;color:#fff}ul.tree-view li,ul.tree-view ul{margin-top:3px}ul.tree-view ul{border-left:1px dotted grey;margin-left:16px;padding-left:16px}ul.tree-view ul>li{position:relative}ul.tree-view ul>li:before{border-bottom:1px dotted grey;content:"";display:block;left:-16px;position:absolute;top:6px;width:12px}ul.tree-view ul>li:last-child:after{background:#fff;bottom:0;content:"";display:block;left:-20px;position:absolute;top:7px;width:8px}ul.tree-view details{margin-top:0}ul.tree-view details[open] summary{margin-bottom:0}ul.tree-view ul details>summary:before{margin-left:-22px;position:relative;z-index:1}ul.tree-view details>summary:before{background-color:#fff;border:1px solid grey;content:"+";display:block;float:left;height:9px;line-height:8px;margin-right:5px;padding-left:1px;text-align:center;width:8px}ul.tree-view details[open]>summary:before{content:"-"}ul.tree-view details>summary::-webkit-details-marker,ul.tree-view details>summary::marker{content:""}pre{background:#fff;box-shadow:inset -1px -1px #fff,inset 1px 1px grey,inset -2px -2px #dfdfdf,inset 2px 2px #0a0a0a;display:block;margin:0;padding:12px 8px}code,code *{font-family:monospace}summary:focus{outline:1px dotted #000}::-webkit-scrollbar{width:16px}::-webkit-scrollbar:horizontal{height:17px}::-webkit-scrollbar-corner{background:#dfdfdf}::-webkit-scrollbar-track{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='2' height='2' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1 0H0v1h1v1h1V1H1V0z' fill='silver'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 0H1v1H0v1h1V1h1V0z' fill='%23fff'/%3E%3C/svg%3E")}::-webkit-scrollbar-thumb{background-color:#dfdfdf;box-shadow:inset -1px -1px #0a0a0a,inset 1px 1px #fff,inset -2px -2px grey,inset 2px 2px #dfdfdf}::-webkit-scrollbar-button:horizontal:end:increment,::-webkit-scrollbar-button:horizontal:start:decrement,::-webkit-scrollbar-button:vertical:end:increment,::-webkit-scrollbar-button:vertical:start:decrement{display:block}::-webkit-scrollbar-button:vertical:start{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0v16h1V1h14V0z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1v14h1V2h12V1H2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H0v-1h15V0h1v17z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1h-1v14H1v1h14V1z' fill='gray'/%3E%3Cpath fill='silver' d='M2 2h12v13H2z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 6H7v1H6v1H5v1H4v1h7V9h-1V8H9V7H8V6z' fill='%23000'/%3E%3C/svg%3E");height:17px}::-webkit-scrollbar-button:vertical:end{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0v16h1V1h14V0z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1v14h1V2h12V1H2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H0v-1h15V0h1v17z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1h-1v14H1v1h14V1z' fill='gray'/%3E%3Cpath fill='silver' d='M2 2h12v13H2z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 6H4v1h1v1h1v1h1v1h1V9h1V8h1V7h1V6z' fill='%23000'/%3E%3C/svg%3E");height:17px}::-webkit-scrollbar-button:horizontal:start{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0v16h1V1h14V0z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1v14h1V2h12V1H2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H0v-1h15V0h1v17z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1h-1v14H1v1h14V1z' fill='gray'/%3E%3Cpath fill='silver' d='M2 2h12v13H2z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 4H8v1H7v1H6v1H5v1h1v1h1v1h1v1h1V4z' fill='%23000'/%3E%3C/svg%3E");width:16px}::-webkit-scrollbar-button:horizontal:end{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0v16h1V1h14V0z' fill='%23DFDFDF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1v14h1V2h12V1H2z' fill='%23fff'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H0v-1h15V0h1v17z' fill='%23000'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1h-1v14H1v1h14V1z' fill='gray'/%3E%3Cpath fill='silver' d='M2 2h12v13H2z'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 4H6v7h1v-1h1V9h1V8h1V7H9V6H8V5H7V4z' fill='%23000'/%3E%3C/svg%3E");width:16px}.window[role=tabpanel]{position:relative;z-index:2}menu[role=tablist]{display:flex;list-style-type:none;margin:0 0 -2px;padding-left:3px;position:relative;text-indent:0}menu[role=tablist]>li{border-top-left-radius:3px;border-top-right-radius:3px;box-shadow:inset -1px 0 #0a0a0a,inset 1px 1px #dfdfdf,inset -2px 0 grey,inset 2px 2px #fff;z-index:1}menu[role=tablist]>li[aria-selected=true]{background-color:silver;margin-left:-3px;margin-top:-2px;padding-bottom:2px;position:relative;z-index:8}menu[role=tablist]>li>a{color:#222;display:block;margin:6px;text-decoration:none}menu[role=tablist]>li[aria-selected=true]>a:focus{outline:none}menu[role=tablist]>li>a:focus{outline:1px dotted #222}menu[role=tablist].multirows>li{flex-grow:1;text-align:center}.sunken-panel{border:2px groove transparent;border-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='5' height='5' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='gray' d='M0 0h4v1H0z'/%3E%3Cpath fill='gray' d='M0 0h1v4H0z'/%3E%3Cpath fill='%230a0a0a' d='M1 1h2v1H1z'/%3E%3Cpath fill='%230a0a0a' d='M1 1h1v2H1z'/%3E%3Cpath fill='%23fff' d='M0 4h5v1H0z'/%3E%3Cpath fill='%23fff' d='M4 0h1v5H4z'/%3E%3Cpath fill='%23dfdfdf' d='M3 1h1v3H3z'/%3E%3Cpath fill='%23dfdfdf' d='M1 3h3v1H1z'/%3E%3C/svg%3E") 2;box-sizing:border-box;overflow:auto}.sunken-panel,table{background-color:#fff}table{border-collapse:collapse;position:relative;text-align:left;white-space:nowrap}table>thead>tr>*{background:silver;box-shadow:inset -1px -1px #0a0a0a,inset 1px 1px #fff,inset -2px -2px grey,inset 2px 2px #dfdfdf;box-sizing:border-box;font-weight:400;height:17px;padding:0 6px;position:sticky;top:0}table.interactive>tbody>tr{cursor:pointer}table>tbody>tr.highlighted{background-color:navy;color:#fff}table>tbody>tr>*{height:14px;padding:0 6px}
/*# sourceMappingURL=98.css.map */

/* ===========================================================================
   VECTOR RACER ADDITIONS
   ===========================================================================

   This file is a deliberate fork of 98.css v0.1.20. Everything above this line
   is upstream and unmodified — 98.upstream.css beside it is the pristine copy,
   so `diff 98.upstream.css 98.css` shows exactly what the project added.

   The rule for this project is that ALL styling lives here. There is no second
   stylesheet: anything the app needs that 98.css does not provide is added
   below, in the library's own idiom — silver surfaces, 1px inset highlights,
   no border radii, no transitions.

   Merging a new upstream release means replacing everything above the line and
   keeping this block.

   Contents:
     1. desktop        the teal background every window sits on
     2. screens        window sizing and per-screen layout
     3. player grid    one row per car
     4. board          the canvas, its frame, and the standings rail
     5. dialogs        the modal and the identity picker
     6. helpers
     7. icons          the Win98 bitmaps in title bars, menu and message boxes
     8. lobby + leaderboard   the online room card and the results window
   =========================================================================== */

/* --- 1. desktop ---------------------------------------------------------- */

/* No interface scale.

   There was a zoom here that stepped the whole interface up on a large screen.
   It went wrong in two ways at once. 98.css sets a bitmap font, and a
   fractional zoom resampled every glyph onto a half-pixel grid, so the text and
   the 1px bevels went soft. And at 2x the layout was measured in one coordinate
   space and painted in another, which pushed the standings rail and the dock
   off-screen entirely and left the board as the only thing you could see.

   Native size it is. That is what the library was drawn for. */

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  color-scheme: light;
}

body {
  background: #008080;                  /* the default Windows 98 desktop */
  -webkit-font-smoothing: none;
  font-family: "Pixelated MS Sans Serif", Arial;
  font-size: 11px;
  -webkit-tap-highlight-color: transparent;
}

[hidden] { display: none !important; }

/* Every screen is a window sitting on the desktop. */
.screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right))
           max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
}

.screen > .window {
  width: 100%;
  max-width: 460px;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.screen > .window > .window-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.loadbar {
  height: 20px;
  width: 220px;
  padding: 2px;
  background: silver;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
.loadfill {
  height: 100%;
  background: repeating-linear-gradient(
    to right,
    navy 0px, navy 8px,
    transparent 8px, transparent 10px
  );
  animation: loadgrow 2.5s steps(12) infinite;
}
@keyframes loadgrow {
  0%   { width: 0; }
  100% { width: 100%; }
}

/* Title bars carry the window name and nothing else — there are no minimize,
   maximize or close controls in this app, so 98.css's .title-bar-controls
   rules simply go unused. Every screen leaves by a button in its own body. */
.title-bar-text { user-select: none; }

/* --- 2. screens ---------------------------------------------------------- */

.window-body > * + * { margin-top: 8px; }

fieldset { min-width: 0; }
legend { padding: 0 3px; }

.row { display: flex; align-items: center; gap: 6px; }
.row + .row { margin-top: 6px; }
.grow { flex: 1 1 auto; min-width: 0; }
.right { margin-left: auto; }

.hint { margin: 4px 0 0; line-height: 1.35; }
.hint.dim { color: grey; }
/* A hint that has become a complaint. Maroon rather than pure red: the
   palette this interface is drawn from has one, and a #FF0000 message on
   silver is a colour Windows kept for the error dialog's icon. */
.hint.bad { color: #800000; }

/* The menu strip: a raised silver column down the middle of the desktop,
   with the title in a blue band across the top of it — the same gradient a
   window's title bar uses, because that is where a Windows title lives. */
#menu { padding: 0; }
.menustrip {
  width: 300px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 3px 3px 16px;
  background: silver;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff,
              inset -2px -2px grey, inset 2px 2px #dfdfdf;
}
.menubanner {
  background: linear-gradient(90deg, navy, #1084d0);
  color: #fff;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: .04em;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.menustrip button {
  margin: 0 13px;
  min-height: 40px;
  font-size: 12px;
  font-weight: 700;
}

.bigbtn {
  font-weight: 700;
  font-size: 12px;
  min-height: 34px;
  padding: 0 22px;
}
#menu .bigbtn { align-self: center; min-width: 170px; }

#setup > .window { max-width: 560px; }
#settings > .window { max-width: 620px; }
#display > .window { max-width: 680px; }
/* The failure screen is a message box, so it is sized like one rather than
   stretched to the width of a settings panel. */
#netfail > .window { max-width: 380px; }

/* --- 3. player grid ------------------------------------------------------ */

#playerRows, #netPlayers {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
  /* Every cell in this list is a seat-sized box, so the Add player button
     fills one the way a car does instead of sitting a third as tall in a row
     of its own. `auto` is the upper bound, not the lower: if a row ever needs
     more than --seat-h it takes it, and the button stretches with it. */
  --seat-h: 90px;
  grid-auto-rows: minmax(var(--seat-h), auto);
  gap: 10px;
  align-content: start;
  padding: 2px;
}

.prow {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto auto auto;
  align-items: center;
  gap: 3px 8px;
  padding: 6px;
  background: silver;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff,
              inset -2px -2px grey, inset 2px 2px #dfdfdf;
}
/* Being dragged reads as a pressed button. */
.prow.dragging {
  box-shadow: inset -1px -1px #fff, inset 1px 1px #0a0a0a,
              inset -2px -2px #dfdfdf, inset 2px 2px grey;
}
/* The car spans both rows of the grid cell and sits centred against them. It
   was left to auto-place, which parked it against the name on the top row with
   the kind select hanging below it. (There was a `.picon` rule here doing this
   for a class the markup stopped using.) */
/* Two-button either-or (the Human/CPU pair): the pressed one is the answer. */
.seg { display: flex; gap: 2px; }
.seg button.on {
  box-shadow: inset -1px -1px #fff, inset 1px 1px #0a0a0a,
              inset -2px -2px #dfdfdf, inset 2px 2px grey;
  font-weight: 700;
}

/* The car tile is still a button — pressing it opens the garage on that
   seat — but it wears no bevel: the model stands on the panel itself, the
   way an icon sits on a toolbar, not inside a second frame. */
.prow .pcar {
  grid-row: 1 / 4;
  align-self: center;
  padding: 0;
  margin-right: 2px;
  min-width: 0;
  min-height: 0;
  line-height: 0;
  background: none;
  box-shadow: none;
}
.prow .pcar:not(:disabled):active { box-shadow: none; }
.prow .pname { grid-column: 2; grid-row: 1; align-self: end; }
/* The kind pair runs the width of the row under the name; Remove sits up on
   the name's line at the right. Stacking them this way is what lets a seat fit
   in half the panel, so eight of them still lay out two across. */
.prow .pkind { grid-column: 2 / 4; grid-row: 2; align-self: start; }

/* Human / CPU: two buttons, and the pressed one is the answer — the same way
   every other either-or in this interface shows its choice.

   Sized up from the 23px 98.css default. These are the controls a row is
   actually for, they sit beside a 34px car tile, and at the default height they
   read as an afterthought next to it. The icons stay 16px — they are bitmaps
   and scaling one is the thing that would look wrong.

   An icon needs its own room: `button.iconline` puts it 10px in and 16px wide,
   so the label cannot start before 26px without touching it. */
.prow .pkind button {
  min-width: 0;
  min-height: 30px;
  font-size: 13px;
  padding: 0 14px 0 34px;
}

/* Remove carries no icon. It is the one destructive control on the row, and a
   picture beside the word only made it louder than the two choices above it. */
.prow .premove {
  min-width: 0;
  min-height: 30px;
  font-size: 13px;
  padding: 0 14px;
}

/* Remove sits at the right end of its own row, spanning both lines, because it
   acts on the row rather than on anything in it. */
/* Under the pair it belongs with, not up on the name's line: removing a car is
   the last thing on the row, and it should read after the choice about it. */
.prow .premove {
  grid-column: 2 / 4;
  grid-row: 3;
  justify-self: start;
}

/* The empty box the grid grows into. A sunken well rather than a raised row:
   there is no car in it yet, so it should not look like one. */
/* The place the grid grows into: an ordinary button occupying the cell the next
   car will fill. It was a sunken box around a button, which read as a separate
   panel under the list rather than as the end of it. */
/* Fills its cell like any other seat — the row track above gives it the
   height, `stretch` makes the button take all of it. */
.padd {
  align-self: stretch;
  font-size: 13px;
}

/* The car tile on the grid is the same drawing as the car on the board, just
   smaller — so what you pick in the garage is what you see lining up. */
.pcar canvas { display: block; }
.pname { font-weight: 700; }

/* --- 4. board ------------------------------------------------------------ */

#game { padding: 0; }
#game > .window {
  box-sizing: border-box;
  max-width: none;
  width: 100%;
  height: 100%;
  padding: max(3px, env(safe-area-inset-top, 0px))
           max(3px, env(safe-area-inset-right, 0px))
           max(3px, env(safe-area-inset-bottom, 0px))
           max(3px, env(safe-area-inset-left, 0px));
}

/* Flex, not a named grid.
   -----------------------
   The board used to be a grid with template areas, and the rail could vanish
   entirely: any item that failed to claim its area got auto-placed outside the
   overflow:hidden body and was simply never seen. Flex has no such failure —
   the rail is a sibling with its own size, and if anything goes wrong it is
   visibly wrong rather than absent. */
#game > .window > .window-body {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
}
#game > .window > .window-body > * { margin-top: 0; }

#stage {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  background: #fff;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
#cv {
  display: block;
  position: absolute;
  inset: 2px;              /* sized by the inset alone - see sizeCanvas() */
  touch-action: none;
}

/* #pfToast is the profile screen's copy of this balloon — see section 9. */
#toast, #pfToast {
  position: absolute;
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  background: #ffffe1;                  /* the Windows tooltip yellow */
  border: 1px solid #000;
  padding: 3px 6px;
  max-width: 90%;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  /* An icon and the text sit on one line, the way a balloon tip did. The icon
     is 16px and must not be squeezed by a long message, hence `.icon`'s
     flex: 0 0 auto. */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
#toast.show, #pfToast.show { opacity: 1; }

/* Standings. Never allowed to collapse: a fixed share on a phone, a fixed
   column on a desktop. */
#rail { flex: 0 0 auto; display: flex; flex-direction: column; min-height: 0; }
.railbox { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; margin: 0; }
#chipwrap { flex: 1 1 auto; min-height: 68px; }

#chipwrap { overflow: auto; }
#chips { display: flex; gap: 2px; overflow-x: auto; padding: 2px; }
.chip {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  min-height: 28px;
  background: silver;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff,
              inset -2px -2px grey, inset 2px 2px #dfdfdf;
  white-space: nowrap;
}
/* Whose turn it is, in the only way Windows highlights a row. */
.chip.active { background: navy; color: #fff; }
.chip.out { color: grey; }
.chip u { border-bottom: none; font-weight: 700; min-width: 30px; }
.chip .who { display: flex; align-items: center; gap: 4px; }
.chip em { font-style: normal; font-size: 13px; }
/* A mark is a bitmap by the time it gets here, already quantised to the
   sixteen Windows colours — so the browser must not smooth it back out on a
   display with more device pixels than CSS ones. */
.chip .swatch {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey;
}


#dock { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
/* The move button. Narrower than full width and a little taller than the rest,
   because it is the one control pressed in a hurry and it should not read as
   just another button in the row. */
#btnConfirm {
  flex: 0 1 auto;
  min-width: 150px;
  max-width: 260px;
  min-height: 34px;
  font-weight: 700;
  font-size: 13px;
  margin-left: auto;
}

/* --- 5. dialogs ---------------------------------------------------------- */

#modal {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, .35);
}

#modalCard { width: 100%; max-width: 360px; }

.mbtns { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.mbody p { margin: 0 0 6px; }
.mbody ol { margin: 6px 0 0; padding-left: 20px; }

/* The patch-notes archive, inside that same dialog. A sunken white panel is
   what Windows put a body of text in, and it is the one structure here that
   is allowed to scroll — the height is capped against the viewport so the
   OK button below it is never pushed off a phone. One release is shorter
   than the cap and the panel simply does not scroll. */
.nscroll { max-height: min(46vh, 320px); padding: 6px 8px; }
.nrel + .nrel { border-top: 1px solid #dfdfdf; margin-top: 8px; padding-top: 8px; }
.nver { margin: 0 0 4px; }
/* The date sits off the version rather than beside it: at 11px a single
   space between bold "0.9.1" and "30 August" reads as "0.9.130". */
.nver .dim { color: grey; margin-left: 7px; }

/* --- 6. helpers ---------------------------------------------------------- */

.preview {
  background: #fff;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
  padding: 2px;
}
.preview canvas { display: block; width: 100%; height: 150px; }

.facts { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px; }
.facts b { text-align: right; }
.facts b { font-weight: 700; }

/* Wide windows: the grid screen gets its circuit alongside and the board gets
   a standings rail. Below this everything stacks, as it would have on a
   640x480 display. */
@media (min-width: 900px) and (min-height: 520px) {
  /* A fixed height, not a fitted one. Adding or removing a car used to grow
     and shrink the whole window under the pointer — the button you were about
     to press moved. The window is a fixed box now and the seat list scrolls
     inside it, which is what every other Windows list does.

     The size is the wide layout's: tall enough for the circuit panel beside it
     and for a full eight-car grid without scrolling. `max-height: 100%` on
     .screen > .window still wins on a short display. */
  #setup > .window { max-width: 880px; height: 560px; }
  .setupcols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 268px;
    gap: 10px;
    align-items: start;
    min-height: 0;
    flex: 1 1 auto;
  }
  .setupcols > fieldset { min-height: 0; display: flex; flex-direction: column; }
  /* The seat list fills the height the window reserves for it, so the room a
     car would go into is inside the Players panel rather than bare window
     below it. The circuit panel keeps to its contents. */
  #localPanel, #onlinePanel { align-self: stretch; }
  #playerRows, #netPlayers { --cols: 2; }

  /* Board on the left, standings down the right, controls under the board. */
  #game > .window > .window-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 250px;
    grid-template-rows: minmax(0, 1fr) auto auto;
    gap: 6px;
  }
  #stage { grid-column: 1; grid-row: 1; }
  #dock  { grid-column: 1; grid-row: 2; }
  #rail  { grid-column: 2; grid-row: 1 / 3; min-width: 0; }

  #chips {
    gap: 4px;
    flex-direction: column;
    overflow-x: hidden;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
  }
  .chip { width: 100%; }
  #chipwrap { min-height: 0; }
  input.picon { --iconsz: 48px; }
}

/* --- the garage: one car, yours ------------------------------------------ */

#garage > .window { max-width: 620px; }
.garagecols { display: flex; flex-direction: column; gap: 8px; }
.garageside, .garagepick { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

/* The Windows 98 Color dialog, reduced to the one control that told the
   truth: the 8-bit palette, all 240 colours in 15 rows of 16, greys first and
   then the wheel. Whatever a colour field could have found is one of these.

   The cells are 15px, not the 22px they were. Two hundred and forty swatches
   at 22px is a 367px wall that dwarfed everything else on the screen and read
   as the subject of it; the colour of a car is one of its three choices, not
   the whole dialog. 15px is still a comfortable target and the grid now sits
   inside a column beside the car it paints. */
#gcBasics { display: grid; grid-template-columns: repeat(16, 15px); gap: 1px; }
.swatchbtn {
  min-width: 0; min-height: 0; padding: 2px;
  width: 15px; height: 15px; display: block;
}
.swatchbtn span { display: block; width: 100%; height: 100%; }
.swatchbtn.on {
  box-shadow: inset -1px -1px #fff, inset 1px 1px #0a0a0a,
              inset -2px -2px #dfdfdf, inset 2px 2px grey;
}

/* Body and Trim: two toolbar buttons above the grid, each carrying a swatch
   of its colour. The pressed one is the colour the grid edits — the Color
   dialog's Basic/Custom choice, reduced to the two colours a car has. */
.targets { display: flex; gap: 4px; margin-bottom: 6px; }
.targets button {
  min-width: 0; padding: 3px 10px;
  display: flex; align-items: center; gap: 6px;
}
.targets button.on {
  box-shadow: inset -1px -1px #fff, inset 1px 1px #0a0a0a,
              inset -2px -2px #dfdfdf, inset 2px 2px grey;
}
.targets .swatch {
  width: 16px; height: 16px; flex: 0 0 auto;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey;
}

/* The car preview fills its box edge to edge — the teal is the ground, and a
   band of white beside it read as a bug rather than as a mount. Tall enough
   for the prerendered model at a size worth looking at. */
.carprev canvas { display: block; width: 100%; height: 148px; }
#gcSummary { margin: 4px 0 0; text-align: center; }

/* Model and Livery: two list boxes, a picture against a name, which is what
   STYLE.md says a data list is and what 98.css already draws. The grids they
   replaced were thumbnails and nothing else — twenty-seven navy cars three
   dozen pixels wide, told apart by squinting, chosen by position. A name is
   the difference between picking "the fourth one along" and picking Hazard.

   The pictures are white cars with black trim, built once and cached: the
   list is a catalogue, and the colours belong to the preview. */
.cartable { background: #fff; }
.cartable table { width: 100%; }
.cartable tbody tr { cursor: pointer; }
.cartable tbody td { height: auto; padding: 0 8px; }
.cartable tbody td.carpic { width: 1%; padding: 1px 0 1px 2px; }
.cartable canvas { display: block; }
.cartable tbody tr:hover { background: #dfdfdf; }
.cartable tbody tr.highlighted,
.cartable tbody tr.highlighted:hover { background: navy; color: #fff; }
/* A model that exists and is not on offer, drawn the way Windows drew any
   unavailable command: the label in grey with a white shadow a pixel down
   and right — the engraved look 98.css gives a :disabled button — and the
   picture greyed, which is what a disabled bitmap was.

   Greying is two steps, because either alone was too polite to read as
   "no". The car is first flattened to a pale grey — all colour gone, the
   range squeezed towards white so the darkest panel lands near the silver
   of a disabled control — and then half its pixels are knocked out on a 2x2
   checker of window white. Windows greyed a bitmap by exactly that stipple;
   doing it to a car that is still navy only made it a dotted navy car, so
   the wash goes first. What is left is a silhouette you can still tell from
   its neighbours and could not mistake for something you may click. No
   hover, and no pointer, because there is nothing to click. */
.cartable tbody tr.locked { cursor: default; color: grey; text-shadow: 1px 1px 0 #fff; }
.cartable tbody tr.locked:hover { background: transparent; }
.cartable tbody tr.locked td.carpic { position: relative; }
.cartable tbody tr.locked td.carpic canvas {
  filter: grayscale(1) brightness(1.6) contrast(0.35);
}
.cartable tbody tr.locked td.carpic:after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='2' height='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M0 0h1v1H0zM1 1h1v1H1z'/%3E%3C/svg%3E");
}
/* The panel is what the arrow keys talk to, so it is what shows the focus —
   the dotted rectangle Windows drew inside a focused list. */
.cartable:focus { outline: 1px dotted #000; outline-offset: -3px; }
.cartable:focus-visible { outline: 1px dotted #000; outline-offset: -3px; }
/* The livery list scrolls: twenty-seven patterns never fitted a box, and
   telling them apart by squinting is what the names are for. */
#gcLiveryBox { max-height: 294px; }

/* The model list is in two columns — Explorer's own List view, which is what
   Windows did with a set of named things too long for one column and too few
   to page. Fifteen models are eight rows instead of fifteen, and no name is
   given up for the height, which a grid of bare tiles would have been: half
   the fleet is now a joke you cannot read off a silhouette, and nobody
   guesses Zángana from a wedge.

   The flow is down one column and then across, which is the order the arrow
   keys walk in. `column-count: 2` does that in one line but balances to half
   the content and rounds the split down, which clipped the bottom row; a
   grid filled column-first is exact. It needs the row count, and ui/garage.js
   sets it from the length of CAR_MODELS — the one number the stylesheet has
   no way to work out. */
/* Ten models were five rows and 180px; fifteen are eight, at 36px each, and
   260px cut the eighth off with no scrollbar to reach it — a model you can
   only get to with the arrow keys is a model most people never find. The
   bound is the height of the rows there are, so the list still never
   scrolls; the livery box under it is what gives up the 36px, and it was
   already scrolling. Past about twenty models this stops working and the
   list has to start scrolling in 98.css's own bar. */
#gcModelBox { max-height: 300px; }
#gcModelBox table { display: block; }
#gcModels {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
}
#gcModels tr {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
}
#gcModels td { display: block; }
/* "Der Beste 640C" is the longest name and fits; anything longer is cut
   rather than allowed to widen its column past its neighbour. */
#gcModels td:last-child { overflow: hidden; text-overflow: ellipsis; }

/* The driver's own name is the one thing in this dialog they type, so it is
   not set at the same size as the read-only colour numbers beside it. */
#prefName {
  font-size: 16px;
  padding: 4px 6px;
  min-height: 26px;
}

/* Two columns: the car and what paints it on the left, the two catalogues on
   the right. The left one is exactly as wide as the palette, which is the one
   control here with a size of its own. */
@media (min-width: 900px) and (min-height: 520px) {
  .garagecols { flex-direction: row; align-items: flex-start; }
  .garagecols > .garageside { flex: 0 0 275px; }
  .garagecols > .garagepick { flex: 1 1 auto; min-width: 0; }
}

/* --- 7. icons ------------------------------------------------------------

   Real Windows 98 icons, copied out of assets/icons/png into web/icons/98/
   under names that say the size, because only web/ is served (the API mounts
   it at /, and serve_web.py serves it directly) and only what is listed in
   sw.js SHELL survives offline. Copy what a screen uses; do not vendor the
   whole pack.

   These are bitmaps drawn at one size, the same as the marks in the chips: a
   16px icon is shown at 16px and a 32px icon at 32px, never scaled between
   them, because resampling a 16-colour icon is what turns its 1px highlights
   into grey mush. `image-rendering: pixelated` keeps them hard on a display
   with more device pixels than CSS ones. */

.icon {
  image-rendering: pixelated;
  flex: 0 0 auto;
  display: block;
}
.icon-16 { width: 16px; height: 16px; }
.icon-32 { width: 32px; height: 32px; }

/* A title bar icon is the window's own name in picture form, not a control:
   it sits at the left, where Windows put it, and nothing about it is
   clickable. The "no minimize, maximize or close" rule is untouched.

   Upstream sets `justify-content: space-between` so a title bar can push its
   controls to the right edge. This app has no controls, so with an icon added
   that rule would fling the text across to the far side instead. The icon and
   the name are one group at the left. */
.title-bar { justify-content: flex-start; gap: 3px; }

/* Pick a title bar icon that survives the navy behind it. The plain `users`
   icon has a head of black hair that reads as a hole in the gradient at 16px;
   `users_green` is the same figures drawn light, and stays legible. This is
   why the icons were chosen against the real title bar rather than on a page
   of white. */

/* The three menu buttons are 40px tall, which is room for a 32px icon beside
   the label. Left-aligned rather than centred, so the icons line up down the
   strip instead of drifting with the width of each word. */
.menustrip button {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  padding: 0 16px;
}

/* Back is not a destination, so it does not get a destination's button. The
   strip's items are 40px tall with room for a 32px icon; Back is the same
   small plain button every window on every other screen leaves by, so the
   strips and the windows agree about what going back looks like. */
.menustrip button.menuback {
  /* Left, on the same 13px inset as the items above it, so the strip has one
     left edge rather than a centred button hanging under a stack of
     left-aligned ones. It is where a window's Back sits too. */
  align-self: flex-start;
  display: inline-flex;
  justify-content: center;
  gap: 0;
  min-height: 23px;
  min-width: 96px;
  margin: 6px 0 0 13px;
  padding: 0 12px;
  font-weight: 400;
  font-size: 11px;
}

/* A message box is an icon on the left and the text beside it, with the
   buttons underneath — the shape every Win98 dialog had. The row is there
   whether or not a dialog passes an icon, so the text lands in the same place
   either way. */
.mrow { display: flex; align-items: flex-start; gap: 12px; }
.mrow > .mbody { flex: 1 1 auto; min-width: 0; }

/* The leaderboard. 98.css already draws a <table> with a sticky silver header;
   the panel only bounds it so a long history scrolls inside its own frame. */
#board > .window { max-width: 560px; }
.boardpanel { max-height: 190px; }
.boardpanel table { width: 100%; }

/* The mode screen: the same silver strip as the main menu, because it is the
   same kind of choice — a short list of ways in, one press each. */
#mode { padding: 0; }
.modenote { margin: 2px 13px 4px; }

/* An icon in front of text that is already there.

   A background rather than an <img>, because these land on nodes whose text is
   read back — a table cell, a status line, a button showing a room code. An
   element that grew an extra child would still look right and would quietly
   stop `node.textContent` being the string that was put in it.

   The URLs are relative to this file, in web/vendor/98/, the same as the
   fonts above. `image-rendering` applies to a background too, and these are
   16-colour bitmaps shown at their own size like every other icon here. */
.iconline {
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 16px 16px;
  image-rendering: pixelated;
  padding-left: 21px;
  min-height: 16px;
}
.ic-error    { background-image: url("../../icons/98/msg_error-16.png"); }
.ic-warning  { background-image: url("../../icons/98/msg_warning-16.png"); }
.ic-question { background-image: url("../../icons/98/msg_question-16.png"); }
.ic-info     { background-image: url("../../icons/98/msg_information-16.png"); }
.ic-done     { background-image: url("../../icons/98/check-16.png"); }
.ic-waiting  { background-image: url("../../icons/98/hourglass-16.png"); }
.ic-copy     { background-image: url("../../icons/98/copy-16.png"); }
.ic-human    { background-image: url("../../icons/98/users-16.png"); }
.ic-cpu      { background-image: url("../../icons/98/computer_2-16.png"); }
/* The way through to the Track settings window — the same globe that
   window wears in its title bar, so the button and its destination match. */
.ic-track    { background-image: url("../../icons/98/globe_map-16.png"); }
.ic-refereed { background-image: url("../../icons/98/certificate-16.png"); }
.ic-local    { background-image: url("../../icons/98/computer-16.png"); }

/* A button centres its label by default, which strands the icon at the far
   left of a wide control with the text floating in the middle. Left-align the
   label so the two read as one thing — a toolbar button, which is what a
   button with an icon on it is. */
button.iconline {
  padding-left: 31px;
  background-position: left 10px center;
  text-align: left;
}

/* The host key rides on the name, not on the row: a row spans the whole panel,
   so a background on it puts the key out at the far edge with nothing to
   attach it to; on the name span, which shrink-wraps its text, it lands
   immediately after the name it qualifies. Unscoped now that lobby rows are
   the same `.prow` the local grid uses — only a name ever carries it. */
.hostkey {
  background-image: url("../../icons/98/users_key-16.png");
  background-repeat: no-repeat;
  background-position: right center;
  background-size: 16px 16px;
  image-rendering: pixelated;
  padding-right: 21px;
}

/* --- 8. online lobby and the leaderboard --------------------------------- */

/* A segmented pair — the grid screen's local/online switch, the garage's
   Body/Livery toggle. The selected half reads as pressed in, which is the only
   way Windows shows a mode: no accent borders, no pills. */

/* Who is in the room: the SAME grid the local Players panel draws, because a
   race is a race whoever is sitting in it. The rows are `.prow` boxes with the
   same car tile; what a lobby row lacks is the Human/CPU pair and Remove, so
   the layout rules those occupy simply go unused. Sharing `#playerRows`'s
   selector is what keeps the two panels from drifting apart. */
#netPlayers { min-height: 72px; }

/* A seat the queue has not filled. Sunken rather than raised: there is no car
   in it yet, so it must not read as one — the same distinction `.padd` draws
   on the local grid between a seat and the space for one. */
.prow.pwait {
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
.prow.pwait .pname { font-weight: 400; color: #555; }
/* A lobby row carries a name and nothing else — no Human/CPU pair, no Remove —
   so the name centres against the car instead of sitting up on the top line
   where the local grid puts it to make room for the controls underneath. */
/* A row with a control under it (a CPU the host can remove) lays out like a
   local seat: name on the top line, control beneath. Only the plain rows —
   the ones carrying nothing but a name — centre against the car. */
#netPlayers .prow.pctl .pname { grid-row: 1; align-self: end; }
#netPlayers .prow:not(.pctl) .pname {
  grid-row: 1 / 4;
  align-self: center;
  /* Shrink-wrapped, not stretched across the column: the host key is a
     background on this span, and a span filling its cell parks the key out at
     the panel's right edge with nothing to attach it to. */
  justify-self: start;
}
/* The empty seat keeps the car tile's footprint so the row does not resize
   when its driver turns up — the grid holds still and the car appears in it. */
.pcar.pempty { display: block; width: 62px; height: 46px; }

/* The wait, as Windows reported waits: a sunken well with a bar that fills as
   the grid does, and a line of text under it. Deliberately determinate — the
   bar measures drivers found, which is real information, rather than marching
   to prove the program is awake. (This file has no animations, and a lobby is
   not the place to introduce the first one.) */
#netWait { margin-top: 8px; }
#netWaitTrack {
  height: 14px;
  padding: 2px;
  background: #fff;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey;
}
#netWaitBar { height: 100%; width: 0; background: navy; }
#netWaitText { margin-top: 4px; }

/* The host's own controls, above the grid they shape. */
#roomOpts { margin-bottom: 8px; }
#roomOpts .row + .row { margin-top: 4px; }

/* A seat that is openly a computer says so beside its name — small, and in
   the sunken well a Windows status field wears, so it reads as a label rather
   than as part of the driver's name (DESIGN-custom-rooms.md §4). */
.pkindtag {
  font-weight: 400;
  font-size: 10px;
  padding: 0 3px;
  background: silver;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey;
}

/* The licence under a driver's name in a ranked lobby. Quiet: it is context
   for who you are racing, not a score to stare at. */
.plicence {
  grid-column: 2 / 4;
  grid-row: 2;
  align-self: start;
  justify-self: start;
  font-size: 11px;
  color: #555;
}

/* Browse: the open-room table, in the leaderboard's idiom — a sunken panel of
   rows you pick from. */
#browse > .window { max-width: 640px; }
#browsePanel { height: 260px; overflow-y: auto; }
#browsePanel table { width: 100%; }
#browsePanel tbody tr { cursor: pointer; }
#browsePanel tbody tr:hover { background: navy; color: #fff; }

/* The Circuit preview sits on the desktop teal, which is exactly what the
   board paints the ground with — BOARD.bg in render/palette.js is WIN98.teal.
   It was a deeper shade, which made the preview disagree with the circuit it
   was previewing. The road stays the white paper the canvas paints: the canvas
   is transparent outside the road cells, so this is one background, not a
   repaint. */
#setup .preview { background: #008080; }

/* --- 9. profile ------------------------------------------------------------

   "Your profile": the driver's page from DESIGN-online-league.md, a mockup
   until the players table exists. Nothing new in kind — the car preview is
   the garage's, the facts are the rail's label/value grid, and the history
   is a table in a sunken panel like the leaderboard's. */

#profile > .window { max-width: 620px; }
.profilecols { display: flex; flex-direction: column; gap: 8px; }
.profilecols > fieldset { min-width: 0; }

/* The ID value is the copy control: click or tap it and the tag lands on the
   clipboard, acknowledged by the balloon below. */
#pfTag { cursor: pointer; }

/* The race screen's balloon tip (section 4 draws it), floated over this
   window instead: the window is the positioning box, and the balloon hangs
   just under the title bar. */
#profile > .window { position: relative; }
#pfToast { top: 28px; }

/* Match history holds exactly eight lines — 17px of header and eight 14px
   rows inside the 2px bevel — and scrolls past that. */
.pfhistpanel { max-height: 133px; }

@media (min-width: 900px) and (min-height: 520px) {
  .profilecols { flex-direction: row; align-items: flex-start; }
  .profilecols > fieldset { flex: 1 1 0; }
}

/* --- 10. the move clock ---------------------------------------------------

   Track settings can put a per-move clock on every human seat. It sits in the
   dock between Back and Go: the Windows progress control's sunken well with a
   navy bar that drains as the seconds do, and the count beside it. The bar
   turns maroon for the last three seconds — the game does not do accent
   colours, but Windows did do alarms. */

#moveTimer {
  flex: 1 1 auto;
  max-width: 340px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
#moveTimer[hidden] { display: none; }

#moveTimerTrack {
  flex: 1 1 auto;
  height: 14px;
  padding: 2px;
  background: #fff;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey;
}
#moveTimerBar { height: 100%; width: 100%; background: navy; }
#moveTimer.low #moveTimerBar { background: maroon; }
#moveTimer.low #moveTimerNum { color: maroon; }

#moveTimerNum { min-width: 16px; text-align: right; }

/* --- 11. the results card -------------------------------------------------

   The end of a race stopped being a sentence and became a board
   (DESIGN-results.md): one row per car, the podium picked out, and a Replay
   button beside the usual three. It sits in the same modal card the game has
   always used, over the finished circuit — the final positions are the
   result, and a full-screen table would throw that picture away.

   Nothing here invents a colour. Gold, silver and bronze are already in the
   16-colour palette the board paints with, which is the only reason a podium
   is allowed at all: see "Colour depth" in STYLE.md. */

.rpanel { max-height: 190px; margin-bottom: 8px; }
.rpanel table { width: 100%; }

/* The driver's own colour, so a row is findable at a glance by the thing the
   player recognises: their car, not their name. */
.rswatch {
  display: inline-block;
  width: 9px; height: 9px;
  margin-right: 6px;
  vertical-align: -1px;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff;
}

/* First, second, third. The empty span holds the column steady for everyone
   below the podium, so the numbers do not shuffle sideways. */
.rmedal {
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 6px;
  vertical-align: 0;
}
.rmedal:not([style]) { box-shadow: none; }
.rmedal[style] { box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff; }

/* The chip's finished/out glyph (TASKS.md D2). It sits between the place and
   the colour swatch, where the eye already is. */
.chipmark { margin-right: 4px; vertical-align: -3px; }

/* The licence band's colour, in front of its name — on the leaderboard and
   on a ranked lobby row (ui/profile.js, LEAGUE_COLORS). Sized and bevelled
   like .rswatch above, because it is the same object doing the same job: a
   flat colour, raised off the row, small enough to be a mark rather than a
   block. Only a coloured chip gets the bevel; a Learner's is empty and holds
   the column without drawing a box round nothing. */
.lchip {
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 5px;
  vertical-align: 0;
}
.lchip[style] { box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff; }

/* --- 9. accessibility ---------------------------------------------------- */

/* The accessibility settings on the display screen (no fieldset — a plain
   heading, a live demo, then one titled switch and its note per row). The
   switches are read by the renderer (render/car.js) and prefersReducedMotion/
   buzz; this is only their layout. */
.a11y-head {
  font-weight: bold;
  margin: 12px 0 6px;
}

/* Two columns: the switches on the left, the live board view on the right.
   Wraps to a single column on a narrow screen, the view dropping below. */
.a11y-cols {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.a11y-controls { flex: 1 1 260px; min-width: 240px; }
.a11y-view { flex: 0 0 auto; }

/* The view: the real board, sunken into the surface like the board's own
   frame so it reads as part of the machine rather than pasted on. */
.a11y-demo {
  display: block;
  width: 300px;
  height: 320px;
  max-width: 100%;
  background: #008080;
  box-shadow: inset -1px -1px #fff, inset 1px 1px #808080,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}

.a11y-item { margin: 8px 0; }
.a11y-item .field-row { margin: 0; }

/* The one-line description under each switch, indented to sit under its label
   and dimmed so the switch reads first. */
.a11y-note {
  margin: 2px 0 0 20px;
  max-width: 42ch;
  color: #4d4d4d;
  line-height: 1.35;
}

/* --- 10. phone layout ---------------------------------------------------- */

/* Portrait phones: tighten the game chrome so the board keeps most of the
   height. The menu screens already fit — their windows cap at 460px and
   scroll — so this only touches the race screen. */
@media (max-width: 600px) {
  #chipwrap { min-height: 40px; }
  .chip { padding: 4px 6px; min-height: 22px; }
}

/* Landscape phones: every vertical pixel counts. The standings collapse to a
   thin horizontal chip strip (no fieldset legend, minimal padding), the dock
   tightens, and gaps shrink so the board keeps nearly all the height. */
@media (max-height: 440px) {
  #game > .window > .window-body { gap: 2px; }

  #rail .railbox { padding: 2px; margin: 0; border: 0; }
  #rail legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
  #chipwrap { min-height: 0; }
  #chips { gap: 2px; padding: 1px; }
  .chip { padding: 2px 5px; min-height: 18px; font-size: 10px; }

  #dock { gap: 4px; }
  #btnMenu { min-width: 50px; min-height: 20px; font-size: 10px; padding: 0 6px; }
  #btnConfirm { min-width: 90px; min-height: 24px; font-size: 11px; }
}

/* --- Update bar -------------------------------------------------------- */
.update-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; gap: 6px;
  padding: 4px 12px;
  background: #ffffcc; border-bottom: 2px solid #808080;
  font-size: 11px;
}
.update-bar button { margin-left: auto; }

/* --- Account indicator on profile, account screen ---------------------- */
.acct-notify {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px; margin-bottom: 8px;
  border: 1px solid #808080; background: #ffffcc;
}
.acct-notify button { margin-left: auto; }
#acctToast {
  position: fixed; bottom: 32px; left: 50%; transform: translateX(-50%);
  background: #ffffe1; border: 1px solid #000; padding: 4px 10px;
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .3s;
}
#acctToast.show { opacity: 1; }
.acct-warn {
  margin: 0 0 6px;
  padding: 4px 6px;
  background: #ffffc0;
  border: 1px solid #808000;
  font-size: 11px;
}
.acct-methods { display: flex; flex-direction: column; gap: 6px; }
.acct-btn { align-self: flex-start; }
.acct-or { font-size: 11px; color: gray; text-align: center; margin: 2px 0; }
#acctProviders { margin-bottom: 8px; }
#acctDeleteConfirm { margin-top: 6px; }

