@font-face{font-family:Inter;src:url(/fonts/inter-variable-4.1.woff2) format("woff2");font-weight:100 900;font-display:swap}
:root{--body:#e8e7e2;--panel:#f4f3ef;--ink:#2b2b29;--muted:#77766f;--line:#d6d5ce;--off:#c9c8c1;--green:#4f9a3a;--yellow:#e8b923;--red:#b5452a;--lamp:#3ff0b0}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;background:var(--body);color:var(--ink);font-family:Inter,-apple-system,system-ui,sans-serif;font-feature-settings:"cv06","tnum"}
main{max-width:520px;margin:0 auto;padding:calc(env(safe-area-inset-top) + 14px) 14px calc(env(safe-area-inset-bottom) + 24px)}
[hidden]{display:none!important}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
input{font:inherit;color:inherit}
.big{font-size:28px;font-weight:500;letter-spacing:-.01em;margin:4px 4px 12px}
.nav{display:block;height:30px;font-size:15px;color:var(--ink)}
.hd{font-size:12px;font-weight:400;color:var(--muted);text-transform:uppercase;letter-spacing:.03em;margin:18px 16px 6px}
.ft{font-size:12px;color:var(--muted);margin:6px 14px 16px;line-height:1.45}
.err{color:var(--red)}
.grp{background:var(--panel);border-radius:12px;overflow:hidden;margin-bottom:18px}
.it{display:flex;align-items:center;gap:12px;width:100%;min-height:44px;padding:0 12px;font-size:15px;text-align:left;border-top:.5px solid var(--line)}
.it:first-child{border-top:0}
.tx{flex:1;min-width:0}
.vl{color:var(--muted);font-size:15px;font-variant-numeric:tabular-nums;white-space:nowrap}
.vl.sm{display:block;font-size:13px;margin-top:2px}
.ch{color:#a5a49d;display:flex}.ch svg{width:16px;height:16px}
.center{justify-content:center}.danger{color:var(--red)}
.ic{width:28px;height:28px;border-radius:7px;background:var(--ink);color:var(--panel);display:flex;align-items:center;justify-content:center;flex:none}
.ic svg{width:17px;height:17px;stroke-width:1.75}
.me{min-height:74px;padding:12px}
.me .ic{width:52px;height:52px;border-radius:12px;background:#000;color:var(--lamp);font-size:30px;font-weight:300}
.name{display:block;font-size:17px;font-weight:500}
.led{width:8px;height:8px;border-radius:50%;background:var(--green);display:inline-block;margin-right:6px;vertical-align:1px}
.led.off{background:var(--off)}.led.bad{background:var(--red)}
.sw{width:42px;height:22px;border-radius:3px;background:var(--off);position:relative;flex:none}
.sw::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:2px;background:var(--panel);transition:left .15s}
.sw.on{background:var(--ink)}.sw.on::after{left:22px}
.sw.busy{opacity:.5}
input[type=time],input[type=number]{border:0;background:none;text-align:right;font-size:15px;color:var(--muted);font-variant-numeric:tabular-nums;width:110px}
input[type=range]{width:100%;accent-color:var(--ink)}
.step{display:flex;align-items:center;gap:14px}
.step button{width:30px;height:30px;border-radius:50%;border:.5px solid #b9b8b1;background:var(--body);font-size:18px}
.alarm{min-height:70px}
.alarm .dig{font-size:30px;font-variant-numeric:tabular-nums;line-height:1.05}
.alarm.dim .dig{color:#9b9a93}
.alarm .del{width:30px;height:30px;color:var(--muted);font-size:16px}
.timepick{justify-content:center;min-height:96px}
.timepick input{font-size:50px;width:auto;text-align:center;color:var(--ink)}
.keys{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;padding:12px}
.k{aspect-ratio:1;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;background:var(--body);border:.5px solid #b9b8b1}
.k.on{background:var(--ink);color:var(--panel);border-color:var(--ink)}
.yb{width:58px;height:58px;border-radius:50%;background:var(--yellow);font-size:14px;font-weight:500;flex:none}
.center-block{display:block;margin:4px auto 0}
.link{display:block;margin:18px 0 0;font-size:16px;text-decoration:underline}
/* The physical KERN display: the firmware's digit and colon sprites with the firmware's spacing, the 496x144 block centred in a 640x180 panel. */
/* Like the DN40 itself: the black glass sits in the light case, so the display card is a group like every other one. */
.case{padding:10px}
#login .face{background:#000;border-radius:5px;position:relative;width:100%;aspect-ratio:640/180;overflow:hidden;box-shadow:inset 0 0 0 1px #000,0 0 0 .5px #b9b8b1}
#login .face img{position:absolute;image-rendering:auto}
#login .face .d{top:10%;width:16.5625%;height:80%}
#login .face .d0{left:11.25%}#login .face .d1{left:28.75%}#login .face .d2{left:54.6875%}#login .face .d3{left:72.1875%}
#login .face .dot{width:2.65625%;height:9.444%}
#login .face .dot.up{left:49.21875%;top:31.667%}#login .face .dot.lo{left:47.96875%;top:61.111%}

.me .ic.logo{width:54px;height:54px;border-radius:12px;padding:0}
.sp{margin-top:0}
.pw{flex:1.4;min-width:0;border:0;background:none;text-align:right;font-size:15px;color:var(--ink);outline:none;letter-spacing:2px}
.pw.bad{color:var(--red)}
.strong{font-weight:500}
.front{padding:12px 12px 10px}
.caseline{display:flex;justify-content:space-between;align-items:center;margin-top:10px;padding:0 2px}
.wm{font-size:13px;letter-spacing:.14em;color:var(--ink)}
/* Login fills the screen: clock and selector sit in the optical centre, a little above the middle. */
#login{display:flex;flex-direction:column;justify-content:center;min-height:calc(100svh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 38px);padding-bottom:8vh}
/* Login: the case photo over the display; .win is warped into the photo's window by aurora.js (matrix3d), the case hides its edges. */
.desk{position:relative;width:min(340px,90vw);margin:28px auto 10px;aspect-ratio:960/508}
.desk .shell{position:absolute;inset:0;width:100%;height:100%;display:block}
.desk .win{position:absolute;left:0;top:0;width:640px;height:190px;background:#000;transform-origin:0 0;display:flex;align-items:center}
#login .desk .face{box-shadow:none;border-radius:0}
.state{text-align:center;font-size:13px;color:var(--muted);min-height:18px;margin:0 0 14px}
/* Glass glare: a soft reflection from the upper left plus a faint top sheen, on the warped window so it follows the glass. */
.desk .win{overflow:hidden}
.desk .win::after{content:"";position:absolute;inset:0 -30%;pointer-events:none;transform:translateX(var(--gx,0px));opacity:var(--go,.55);
  background:linear-gradient(112deg,transparent 10%,rgba(255,255,255,.22) 16%,rgba(255,255,255,.18) 25%,rgba(255,255,255,.05) 31%,transparent 36%),
             linear-gradient(180deg,rgba(255,255,255,.07),transparent 38%)}
/* Animation: the clock rises in, then the display lights up; parallax only floats the rigid clock and moves the glare (aurora.js). */
.desk{transform:translate(var(--fx,0px),var(--fy,0px));animation:desk-in .7s cubic-bezier(.2,.7,.2,1) both}
#login .desk .face{animation:display-on .9s .45s ease-out both}
@keyframes desk-in{from{opacity:0;translate:0 14px}}
@keyframes display-on{0%{opacity:0}30%{opacity:.55}40%{opacity:.2}100%{opacity:1}}
@media (prefers-reduced-motion:reduce){.desk,#login .desk .face{animation:none}}
/* The password field is invisible (still focusable); the clock display shows the password mode. */
.pin{position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden;opacity:0}
.pin input{font-size:16px;border:0;width:1px}
.desk.pass{cursor:text}
#login .desk.pass .face .dot{opacity:0}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
#login-error{text-align:center}
/* DN40 rear selector (from the login demo): a round black knob with a raised grip slides in a light recess. */
.mode{display:flex;justify-content:center;align-items:center;gap:18px;margin:18px 0 6px}
.mode-label{position:relative;padding:20px 2px 8px;min-width:56px;font-size:12px;color:#82857c;transition:color .2s}
.mode-label::before{content:"";position:absolute;top:8px;left:calc(50% - 2px);width:4px;height:4px;border-radius:50%;background:#93968b}
.mode-label[aria-pressed=true]{color:var(--ink);font-weight:600}
.mode-label[aria-pressed=true]::before{background:#292e25}
.switch{position:relative;width:120px;height:58px;border-radius:29px;padding:0;background:linear-gradient(165deg,#d6d6cc,#eeeee6 48%,#f5f4ed);box-shadow:inset 2px 3px 6px #666b5930,inset -1px -2px 2px #fff9;isolation:isolate;flex:none}
.switch::before{content:"";position:absolute;left:18px;right:18px;top:23px;height:12px;border-radius:1px;background:#14130f;box-shadow:inset 0 3px 4px #000,0 1px 0 #fff9;z-index:-1}
/* The knob is Ivan's photo of the real black rotary knob with a raised grip (knob.webp). */
.knob{position:absolute;left:5px;top:3px;width:52px;height:52px;background:url(/knob.webp) center/contain no-repeat;filter:drop-shadow(2px 4px 3px rgba(0,0,0,.35));transition:transform .23s ease}
.switch[aria-checked=true] .knob{transform:translateX(58px)}
@media (prefers-reduced-motion:reduce){.knob{transition:none}}
/* Tap glare: one brighter band crosses the glass from left to right. */
.desk .win::before{content:"";position:absolute;inset:0 -40%;z-index:5;pointer-events:none;opacity:0;
  background:linear-gradient(112deg,transparent 36%,rgba(255,255,255,.12) 42%,rgba(255,255,255,.42) 47%,rgba(255,255,255,.42) 50%,rgba(255,255,255,.12) 55%,transparent 61%)}
.desk .win.sweep::before{animation:glare-sweep .9s cubic-bezier(.3,.1,.3,1)}
@keyframes glare-sweep{0%{opacity:1;transform:translateX(-62%)}85%{opacity:1}100%{opacity:0;transform:translateX(62%)}}
