/* Fonts */
@font-face{font-family:Geologica;src:url(/assets/fonts/geologica-cyr.woff2) format("woff2");font-weight:100 900;font-display:optional;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Geologica;src:url(/assets/fonts/geologica-lat.woff2) format("woff2");font-weight:100 900;font-display:optional;unicode-range:U+0000-00FF,U+2000-206F,U+20A0-20BF,U+2190-2193,U+2212}
@font-face{font-family:"Geist Mono";src:url(/assets/fonts/mono-cyr.woff2) format("woff2");font-weight:100 900;font-display:optional;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:"Geist Mono";src:url(/assets/fonts/mono-lat.woff2) format("woff2");font-weight:100 900;font-display:optional;unicode-range:U+0000-00FF,U+2000-206F,U+20A0-20BF,U+2190-2193,U+2212}

@font-face{font-family:Cormorant;font-style:italic;src:url(/assets/fonts/cormorant-cyrillic-wght-italic.woff2) format("woff2");font-weight:300 700;font-display:swap;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Cormorant;font-style:italic;src:url(/assets/fonts/cormorant-latin-wght-italic.woff2) format("woff2");font-weight:300 700;font-display:swap;unicode-range:U+0000-00FF,U+2000-206F,U+20A0-20BF,U+2190-2193,U+2212}

/* Tokens: colours, then the scales everything else is built from. Nothing here is renamed. */
:root{
  color-scheme:dark;
  --void:#0b0c0e;--carbon:#15171b;--line:rgba(255,255,255,.1);--bone:#ece9e2;--ash:#a8acb4;--ion:#c6ff4a;--ember:#ff5c39;
  --wrap:1180px;--pad:max(clamp(20px,2.6vw,40px),env(safe-area-inset-left,0px),env(safe-area-inset-right,0px));
  --safe-b:env(safe-area-inset-bottom,0px);--safe-t:env(safe-area-inset-top,0px);
  --full:100dvh;
  --display:Geologica,system-ui,sans-serif;--voice:Cormorant,Georgia,serif;--field:#10100f;--mono:"Geist Mono",ui-monospace,monospace;--ease:cubic-bezier(.2,.8,.2,1);
  /* Ink: text that is not bone; chart ink and grid */
  --ink-2:#c6c8cd;--ink-nav:#c9ccd2;--ink-chart:#8e929b;--grid:#262a30;
  /* Type scale */
  --t-xs:11px;--t-s:12.5px;--t-m:15px;--t-l:17px;--t-xl:clamp(21px,2.2vw,28px);--t-title:clamp(26px,3vw,36px);
  --t-lead:clamp(32px,3.5vw,48px);--t-figure:clamp(68px,8.4vw,116px);--t-soc:clamp(84px,12vw,176px);
  /* Surfaces: the panel glass, the menu glass, a tile */
  --panel:rgba(11,12,14,.88);--panel-blur:28px;--glass:rgba(14,15,18,.56);--glass-blur:18px;
  --tile:rgba(255,255,255,.05);--tile-line:rgba(255,255,255,.08);--tile-hover:rgba(255,255,255,.08);
  --r-s:10px;--r-m:16px;--r-l:26px;
  --shadow-text:0 1px 8px rgba(0,0,0,.6);--chip:rgba(11,12,14,.72);--glow-ion:0 0 22px 4px rgba(198,255,74,.55);
  /* Motion vocabulary; the same numbers live in ui.js MOTION for GSAP */
  --d-leave:.32s;--d-arrive:1s;--d-rise:.9s;--d-chart:1.5s;--d-fast:.3s;
  /* Series: speed dim to bright, the city's ramp */
  --speed-1:#46561f;--speed-2:#647f27;--speed-3:#86ae30;--speed-4:#a7d63b;--speed-5:#c6ff4a;
  --ramp-1:#2f3a18;--ramp-2:#4c6122;--ramp-3:#6d8f2b;--ramp-4:#9cc936;--ramp-5:#c6ff4a;
}

/* Base */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{background:var(--field);-webkit-text-size-adjust:100%}
body{margin:0;height:var(--full);overflow:hidden;background:transparent;color:var(--bone);font:400 16px/1.5 var(--display);-webkit-font-smoothing:antialiased;font-feature-settings:"tnum"}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
h1,h2,h3,p,dl,dd,figure{margin:0;font-weight:inherit}
:focus-visible{outline:2px solid var(--ion);outline-offset:3px;border-radius:6px}
.mono{font-family:var(--mono);font-size:var(--t-s);letter-spacing:.02em;color:var(--ash)}
small{font-size:inherit}
.good{color:var(--ion)}.bad{color:var(--ember)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.only-scenic{display:none}.scenic .only-scenic{display:inline}

/* The stage */
#gl,#backdrop,#veil{position:fixed;inset:0 0 auto;width:100%;height:var(--full)}
#gl{z-index:0;display:block;opacity:0;transition:opacity 1.1s}
#gl.ready{opacity:1}
#backdrop{z-index:-1;background:var(--field) center/cover no-repeat;filter:blur(14px);transform:scale(1.06)}
.still #backdrop{filter:none;transform:none}
#veil{display:none;z-index:1;background:var(--field);opacity:var(--dim,0)}
.still #veil{display:block}
#scroll{position:fixed;inset:0 0 auto;height:var(--full);z-index:2;overflow:hidden auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;scrollbar-width:none}
#scroll::-webkit-scrollbar{display:none}
#scroll:focus{outline:none}
#app{min-height:100%}

/* Dock: one place on every screen, under the thumb */
#nav{position:fixed;z-index:50;left:50%;bottom:calc(14px + var(--safe-b));transform:translateX(-50%);display:flex;gap:2px;padding:5px;border-radius:999px;background:rgba(10,11,13,.62);backdrop-filter:blur(var(--glass-blur)) saturate(150%);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(150%);border:1px solid rgba(255,255,255,.1)}
#nav[hidden]{display:none}
#nav a{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;gap:8px;min-width:44px;min-height:44px;padding:0 15px;border-radius:999px;font-size:13.5px;color:var(--ink-nav);transition:color var(--d-fast);white-space:nowrap}
#nav a.on{color:var(--void)}
@media (hover:hover){#nav a:hover{color:#fff}#nav a.on:hover{color:var(--void)}a.row:hover .row-k{color:var(--bone)}button.tl:hover{background:rgba(255,255,255,.06)}.step:hover{background:rgba(255,255,255,.2)}.btn:hover{transform:translateY(-1px)}.next a:hover b{letter-spacing:-.02em}a.route:hover b{color:var(--ion)}}
#nav svg,.fp{fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
#nav svg{width:19px;height:19px;flex:none}
#pill{position:absolute;left:0;top:0;border-radius:999px;background:var(--bone)}

/* Chapters */
.ch{position:relative;min-height:var(--full);display:flex;flex-direction:column;justify-content:center;padding:calc(72px + var(--safe-t)) 0 calc(96px + var(--safe-b))}
.wrap{width:min(var(--wrap),100%);margin:0 auto;padding:0 var(--pad)}
.h{font:600 clamp(40px,7.4vw,112px)/.98 var(--display);letter-spacing:-.035em;text-transform:uppercase}
.h em{font:italic 500 1.22em/1 var(--voice);letter-spacing:-.015em;text-transform:none;color:var(--ion)}
.sub{color:var(--ink-2);margin-top:14px;max-width:60ch;font-size:var(--t-l)}
h3{font-size:var(--t-l);font-weight:500}
h3 .count{font-weight:300;color:var(--ash);margin-left:8px}
.hint{color:var(--ash);font-size:var(--t-s);margin-top:1px}
.block-sect{margin-top:64px;content-visibility:auto;contain-intrinsic-size:auto 320px}
.block-sect>div{margin-top:16px}
.foot{margin-top:44px}
.pair{display:grid;grid-template-columns:1fr 1fr;gap:0 56px}
.chart{width:100%;height:auto;display:block;touch-action:pan-y}
.chart [tabindex]:focus-visible,.chart a:focus-visible{outline:2px solid var(--ion);outline-offset:0}
.wait{opacity:0;transform:translateY(32px)}
.wait .chart{clip-path:inset(0 100% 0 0)}
.seen{opacity:1;transform:none;transition:opacity var(--d-rise) var(--ease),transform var(--d-rise) var(--ease)}
.seen .chart{clip-path:inset(0 0 0 0);transition:clip-path var(--d-chart) var(--ease) .1s}

/* A charge in progress: the whole battery, what has been added, where it stops */
.flow{position:relative;height:12px;margin-top:24px;border-radius:6px;background:rgba(255,255,255,.1);overflow:hidden}
.flow i{position:absolute;top:0;bottom:0;left:0;transition:width .8s var(--ease),left .8s var(--ease)}
.flow-was{background:rgba(255,255,255,.28)}.flow-new{background:var(--ion)}
.flow-goal{width:2px;background:var(--bone)}
.status dd span{white-space:nowrap}
.flow-keys{display:flex;justify-content:space-between;gap:12px;margin-top:10px;font-size:var(--t-s);color:var(--ash)}
.charging .rows{margin-top:20px}

/* New data over the same page: nothing moves, and what is off screen keeps its real height */
#app.quiet *{transition:none!important;animation:none!important}
#app.quiet .block-sect{content-visibility:visible}

/* The opening chapter: the car and the sky; words only at the foot */
.hero{justify-content:flex-end;padding:0 0 calc(92px + var(--safe-b));height:var(--full)}
.hero:after{content:"";position:absolute;z-index:-1;inset:auto 0 -36vh 0;height:calc(46% + 36vh);background:linear-gradient(transparent,rgba(11,12,14,.5) 24%,rgba(11,12,14,.9) 56%,rgba(11,12,14,.7) 78%,transparent);pointer-events:none}
.hero-foot{display:flex;justify-content:space-between;align-items:flex-end;gap:32px;width:100%;padding:0 var(--pad)}
.fig{font:200 clamp(96px,17vw,240px)/.9 var(--display);letter-spacing:-.05em}
.fig small{font-size:.24em;color:var(--ash);letter-spacing:0;margin-left:.14em}
.scenic .fig{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.over{color:var(--bone);margin-bottom:10px;width:fit-content;padding:4px 11px;border-radius:999px;background:var(--chip)}
.note{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:8px;font-size:clamp(15px,1.3vw,18px)}.note span{color:var(--ink-2)}.note b{font-weight:500}
.note .note{font-size:inherit}
.sub-note{display:block;max-width:56ch;color:var(--ink-2)}
.sync{display:flex;align-items:center;gap:8px;margin-bottom:12px;width:fit-content;padding:4px 11px 4px 9px;border-radius:999px;background:var(--chip)}.sync .mono{color:var(--bone)}
.sync i{width:7px;height:7px;border-radius:50%;background:var(--ion);animation:ping 2.6s infinite}
.sync.stale i{background:var(--ember);animation:none}.sync.stale .mono{color:var(--ember)}
@keyframes ping{0%{box-shadow:0 0 0 0 rgba(198,255,74,.5)}70%,100%{box-shadow:0 0 0 9px rgba(198,255,74,0)}}
.status{display:grid;grid-auto-flow:column;gap:30px}
.status dt{font-size:17px;white-space:nowrap}.status dd{font-family:var(--mono);font-size:11.5px;color:var(--ink-2);min-height:16px;white-space:nowrap}
.status .warn dt{color:var(--ember)}
.switch{display:flex;align-items:center;gap:14px;margin-bottom:10px}
.switch .mono{color:var(--bone);padding:13px 4px}
.step{width:44px;height:44px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--chip);font-size:19px;transition:background var(--d-fast)}
.step.off{opacity:.3;pointer-events:none}

/* A line of the story: a big word on the left, a big figure on the right */
.rows{border-top:1px solid var(--line);margin-top:28px}
.row{display:flex;align-items:center;gap:16px;min-height:76px;padding:12px 0;border-bottom:1px solid var(--line)}
.rows-month{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 14px;padding:36px 0 12px;border-bottom:1px solid var(--line)}.rows-month:first-child{padding-top:18px}.rows-month b{font-size:var(--t-l);font-weight:500}.rows-month span{font-family:var(--mono);font-size:var(--t-s);color:var(--ash)}
.row-k{flex:1;min-width:0;color:var(--ink-2);font-size:clamp(16px,1.6vw,20px)}
.row-k .sub-k{display:block;font-size:var(--t-s);color:var(--ash)}
.row-v{text-align:right;font-size:clamp(20px,2.4vw,32px);font-weight:300;letter-spacing:-.02em}.row-v small{display:block;font-size:var(--t-s);color:var(--ash);letter-spacing:0;font-weight:400}
.go{width:9px;height:9px;border-top:1.5px solid var(--ash);border-right:1.5px solid var(--ash);transform:rotate(45deg);flex:none}
.route{display:block;margin-top:clamp(28px,4vw,56px)}
.route b{display:block;font:300 clamp(34px,5.6vw,84px)/1.02 var(--display);letter-spacing:-.03em;transition:color var(--d-fast)}
.route span{display:block;margin-top:10px;color:var(--ash)}

/* The car with its light along the sill */
.profile{position:relative;margin:clamp(-60px,-4vw,-20px) 0 clamp(-120px,-8vw,-40px)}
.profile img{display:block;width:100%;height:auto}
.sill{position:absolute;left:37.06%;top:66.2%;width:14.89%;height:.7%;border-radius:4px;overflow:hidden;background:rgba(255,255,255,.1)}
.sill i{position:absolute;inset:0 auto 0 0;width:0;background:var(--ion);box-shadow:var(--glow-ion);transition:width 1.8s var(--ease)}

/* The car from above, lying across the screen, each pressure at its wheel */
.plan{position:relative;display:block;width:min(100%,calc((var(--full) - 330px)*1.72));aspect-ratio:1.72;margin:clamp(16px,3vw,40px) auto 0}
.plan img{position:absolute;left:50%;top:50%;width:37.6%;height:auto;transform:translate(-50%,-50%) rotate(90deg)}
.w{position:absolute;display:block;width:120px;margin-left:-60px;text-align:center;color:inherit}
.w b{display:block;font:200 clamp(32px,4vw,60px)/1 var(--display);letter-spacing:-.03em}
.w span{display:block;font-family:var(--mono);font-size:var(--t-xs);color:var(--ash);white-space:nowrap}
.w .dot{position:absolute;left:50%;width:11px;height:11px;margin-left:-5.5px;border-radius:50%;background:var(--bone);opacity:.5}
.w.fl,.w.fr{left:70.3%}.w.rl,.w.rr{left:30.5%}
.w.fl,.w.rl{bottom:80%}.w.fl .dot,.w.rl .dot{bottom:-22px}
.w.fr,.w.rr{top:80%}.w.fr .dot,.w.rr .dot{top:-22px}
.w.bad b{color:var(--ember)}.w.bad .dot{background:var(--ember);opacity:1;animation:ping-ember 2.2s infinite}
.w.on b{color:var(--ion)}.w.on .dot{background:var(--ion);opacity:1}.w.bad.on b{color:var(--ember)}
button.w{min-height:44px}
@keyframes ping-ember{0%{box-shadow:0 0 0 0 rgba(255,92,57,.6)}70%,100%{box-shadow:0 0 0 14px rgba(255,92,57,0)}}

/* City of days */
.cityc{--wrap:1040px}
/* The tilted city reaches below its own box: the room under it keeps the front rows inside the panel */
.city{perspective:1500px;perspective-origin:50% 26%;margin-top:clamp(0px,3vw,36px);padding-bottom:clamp(28px,6vw,84px);overflow-x:clip}
.plane{--tilt:52deg;--turn:-30deg;display:grid;grid-template-columns:repeat(7,1fr);gap:clamp(3px,.6vw,9px);max-width:680px;margin:0 auto;transform-style:preserve-3d;transform:rotateX(var(--tilt)) rotateZ(var(--turn))}
.wd{font-family:var(--mono);font-size:12px;letter-spacing:.06em;color:var(--ink-2);text-align:center;padding-bottom:4px}
.block{--h:0;position:relative;aspect-ratio:1;transform-style:preserve-3d;display:block}
.block.pad{visibility:hidden}
.block .top{position:absolute;inset:0;border-radius:7px;background:var(--fill,rgba(255,255,255,.06));transform:translateZ(calc(var(--h)*1px));display:flex;flex-direction:column;justify-content:space-between;padding:4px 6px;font-size:12px;color:var(--ink,var(--ash));transition:filter var(--d-fast)}
.block .top b{font-weight:500;align-self:flex-end;font-size:12px}
.block .side{position:absolute;background:var(--fill,#1c1f24)}
.block .side.a{left:0;right:0;bottom:0;height:calc(var(--h)*1px);transform-origin:bottom;transform:rotateX(-90deg);filter:brightness(.42)}
/* The walls the eye sees from where the city is turned: the front (a) and the left (b), each standing up from
   the ground to the roof. The left wall used to hang from the right edge into the ground, and showed as green
   wedges under the days (owner's screenshot, 8 Nov). */
.block .side.b{top:0;bottom:0;left:0;width:calc(var(--h)*1px);transform-origin:left;transform:rotateY(-90deg);filter:brightness(.6)}
.block.today .top{box-shadow:inset 0 0 0 1.5px var(--bone)}
.block .dot{position:absolute;left:5px;bottom:5px;width:6px;height:6px;border-radius:50%;background:var(--ember)}

/* Bits */
.versus{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,5vw,64px);margin-top:clamp(24px,4vw,48px)}
.versus b{display:block;font:200 clamp(56px,9vw,136px)/1 var(--display);letter-spacing:-.04em}.versus b small{font-size:.3em;color:var(--ash);margin-left:.12em;letter-spacing:0}
.versus span{display:block;color:var(--ash);margin:6px 0 14px}
.vs{display:grid;gap:18px;margin-top:28px}.vs p{display:flex;justify-content:space-between;gap:12px;color:var(--ink-2);margin-bottom:6px}.vs b{font-weight:400;color:var(--bone)}
.meter{height:6px;border-radius:3px;background:rgba(255,255,255,.1);overflow:hidden}.meter i{display:block;height:100%;border-radius:3px;background:var(--ion)}.meter.grey i{background:var(--ash)}
.mapc{padding:calc(40px + var(--safe-t)) 0 calc(96px + var(--safe-b))}
.mapbox{width:100%;height:calc(var(--full) - 150px);min-height:360px;background:var(--carbon)}
.mapbox iframe{border:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .8s}
.mapbox iframe.ready{opacity:1}
.timeline{display:grid;gap:2px;margin:28px 0 0 -10px}
.tl{display:grid;grid-template-columns:30px 1fr;gap:14px;padding:12px 10px;border-radius:12px;text-align:left;width:100%}
button.tl.on{background:rgba(255,255,255,.07)}
.tl .n{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--bone);color:var(--void);font-size:13px;font-weight:500}
.tl.charge .n{background:var(--ion)}.tl.stop .n{background:none;box-shadow:inset 0 0 0 1.5px var(--line)}
.tl p{font-size:14px;color:var(--ash)}.tl .w{position:static;width:auto;margin:0;text-align:left;font-size:clamp(17px,1.8vw,22px)}
.tl .m{display:flex;gap:12px;flex-wrap:wrap;font-family:var(--mono);font-size:12.5px;margin-top:4px}
.flag{color:var(--ember)!important;font-size:var(--t-s);margin-top:4px}
.bands{display:flex;gap:2px;height:16px}.bands i{display:block;border-radius:3px}.bands i:focus-visible{outline-offset:1px}
.bandkey{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;font-size:12px;color:var(--ash)}.bandkey b{display:block;color:var(--bone);font-weight:400;font-size:15px}
.tiles{display:grid;grid-template-columns:repeat(2,1fr);gap:0 40px;margin-top:28px;border-top:1px solid var(--line)}
.tile{padding:20px 0;border-bottom:1px solid var(--line);min-width:0}
.tile.me .k{color:var(--ion)}
.tile .k{display:block;color:var(--ash);font-size:var(--t-s)}
.tile .v{font:300 clamp(30px,4vw,52px)/1.1 var(--display);letter-spacing:-.03em;margin-top:4px}
.tile .n{color:var(--ink-2);font-size:var(--t-s);margin-top:6px}
.tile .acts{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px}
.tile .ask{color:var(--ink-2);font-size:var(--t-s)}
.link{font-family:var(--mono);font-size:12px;color:var(--ash);text-decoration:underline;text-underline-offset:3px;min-height:44px;min-width:44px}
.ribbon{position:relative;height:34px;margin:28px 0 8px}
.ribbon:before{content:"";position:absolute;left:0;right:0;top:9px;border-top:1px solid var(--line)}
.ribbon .tick{position:absolute;top:0;transform:translateX(-50%);font-family:var(--mono);font-size:var(--t-xs);color:var(--ash);text-align:center}
.ribbon .tick i{display:block;width:1px;height:8px;margin:5px auto 4px;background:var(--line)}
.ribbon .tick:first-child{transform:none}.ribbon .tick:first-child i{margin-left:0}
.ribbon b{position:absolute;top:5px;width:9px;height:9px;margin-left:-4.5px;border-radius:50%;background:var(--ion);box-shadow:var(--glow-ion)}
.days{display:flex;gap:4px;margin-top:10px}.days button{flex:1 1 0;min-width:0;min-height:44px;font-family:var(--mono);font-size:var(--t-xs);color:var(--ash);border-radius:10px;background:rgba(255,255,255,.07);transition:background .2s,color .2s}.days button.on{color:var(--void);background:var(--ion)}.days button:focus-visible{outline:2px solid var(--bone);outline-offset:2px}.rows>.days{margin:0;padding:10px 0 14px;border-bottom:1px solid var(--line)}.days i{font-style:normal;font-family:var(--mono);font-size:var(--t-xs);color:var(--ash);padding:3px 0;width:30px;text-align:center;border-radius:6px;background:rgba(255,255,255,.06)}
.days i.on{color:var(--void);background:var(--ion)}
.row .dot{display:inline-block;width:8px;height:8px;margin-right:10px;border-radius:50%;background:var(--ion)}.row .dot.off,.row .dot.key_removed{background:var(--ash)}.row .dot.login_failed,.row .dot.all_revoked{background:var(--ember)}.row .dot.key_added{background:var(--bone)}
.row .ring{display:inline-block;width:18px;height:18px;margin-right:10px;vertical-align:-3px;border-radius:50%;border:1.5px solid var(--ion);transform:scale(var(--r,1))}
.danger{border:1px solid rgba(255,92,57,.5);color:var(--ember);border-radius:999px;padding:0 16px;min-height:44px;font-size:13.5px;transition:background var(--d-fast),border-color var(--d-fast)}
.danger.slim{padding:0 14px;font-size:12.5px}.danger[disabled]{opacity:.5}
@media (hover:hover){.danger:hover{background:rgba(255,92,57,.1);border-color:var(--ember)}}

/* Commands: a line of type that fills while it is held */
.cmds{display:grid;grid-template-columns:repeat(2,1fr);gap:0 40px;margin-top:28px;border-top:1px solid var(--line)}
.cmd{position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;min-height:84px;margin:0 -10px;padding:12px 10px;text-align:left;border-bottom:1px solid var(--line);color:var(--bone);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;touch-action:pan-y;-webkit-tap-highlight-color:transparent;transition:background .15s}
.cmd *{pointer-events:none;-webkit-user-select:none;user-select:none}
.cmd b{position:relative;font:300 clamp(22px,2.6vw,34px)/1.15 var(--display);letter-spacing:-.02em;transition:color .12s}
.cmd span{position:relative;min-height:1.4em;color:var(--ash);font-size:var(--t-s);transition:color .12s}
.cmd::before{content:"";position:absolute;inset:0;background:color-mix(in srgb,var(--ion) 34%,transparent);box-shadow:inset -3px 0 0 var(--ion);transform:scaleX(0);transform-origin:left;transition:transform .15s}
.cmd.hold{background:color-mix(in srgb,var(--ion) 9%,transparent)}
.cmd.hold::before{transform:scaleX(1);transition:transform .5s linear}
.cmd.hold b,.cmd.hold span{color:var(--ion)}
.cmd[data-state=ok] span,.cmd[data-state=wait] span{color:var(--ion)}.cmd[data-state=bad] span{color:var(--ember)}
.cmd[disabled]{opacity:.6}.cmd:last-child:nth-child(odd){grid-column:1/-1}
.cmd:focus-visible{outline:2px solid var(--ion);outline-offset:-2px}
@media (hover:hover){.cmd:hover b{color:var(--ion)}}
@media (max-width:480px){.cmds{gap:0 20px}.cmd{min-height:76px}}

/* The car drives on the spot while an installed console starts, then leaves */
#launch{--step:0;display:none;position:fixed;z-index:90;inset:0 0 auto;height:var(--full);overflow:hidden;background:#0b0c0e;place-items:center;animation:launch-giveup .01s 45s forwards}
@media (display-mode:standalone){#launch{display:grid}}
@keyframes launch-giveup{to{visibility:hidden}}
#launch.away{background:transparent;transition:background .55s .4s}
.drive{--w:min(80vw,620px);position:relative;width:var(--w);aspect-ratio:1500/844;animation:drive-rock .46s ease-in-out infinite alternate}
.drive i{display:block;position:absolute}
.drive-body{inset:0;background:url(/assets/img/car-side.webp) 0 0/100% 100%;-webkit-mask:radial-gradient(circle calc(var(--w)*.0587) at 21% 62.3%,transparent 98%,#000) 0 0,radial-gradient(circle calc(var(--w)*.0587) at 77% 62.3%,transparent 98%,#000) 0 0;-webkit-mask-composite:source-in;mask:radial-gradient(circle calc(var(--w)*.0587) at 21% 62.3%,transparent 98%,#000) 0 0,radial-gradient(circle calc(var(--w)*.0587) at 77% 62.3%,transparent 98%,#000) 0 0;mask-composite:intersect}
.drive-wheel{--d:calc(var(--w)*.1173);--x:calc(var(--w)*.21);--y:calc(var(--w)*.3507);width:var(--d);height:var(--d);left:calc(var(--x) - var(--d)/2);top:calc(var(--y) - var(--d)/2);border-radius:50%;background:url(/assets/img/car-side.webp) no-repeat calc(var(--d)/2 - var(--x)) calc(var(--d)/2 - var(--y))/var(--w) auto;animation:wheel .34s linear infinite}
.drive-wheel.rear{--x:calc(var(--w)*.77)}
.drive-beam{right:93%;top:34.9%;width:70vw;height:calc(var(--w)*.2);background:linear-gradient(270deg,rgba(236,255,190,.2),transparent 85%);clip-path:polygon(100% 46%,100% 54%,0 100%,0 10%);filter:blur(5px);animation:beam .92s ease-in-out infinite alternate}
.drive-tail{left:86%;top:37.5%;width:calc(var(--w)*.1);height:calc(var(--w)*.05);background:radial-gradient(closest-side,rgba(255,40,50,.42),transparent);animation:tail 1.3s ease-in-out infinite alternate}
.road{position:absolute;left:0;right:0;top:calc(50% + var(--road));height:2px;--road:calc(min(80vw,620px)*.126);overflow:hidden;background:rgba(255,255,255,.08)}
.road::before{content:"";position:absolute;inset:0 -96px 0 -96px;background:repeating-linear-gradient(90deg,var(--ion) 0 44px,transparent 44px 96px);animation:road .3s linear infinite}
.road-air{position:absolute;left:0;right:0;top:50%;height:40%;margin-top:-30%;overflow:hidden;pointer-events:none}
.road-air::before,.road-air::after{content:"";position:absolute;left:-30vw;width:30vw;height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.3));animation:air .86s linear infinite}
.road-air::before{top:22%}.road-air::after{top:68%;animation-duration:1.24s;animation-delay:.3s}
#launch p{position:absolute;left:0;right:0;bottom:calc(64px + var(--safe-b));margin:0;text-align:center;color:var(--ash);font-size:var(--t-s)}
/* What the launch is waiting for, step by step (main.js launchSay); stuck, it offers to try again */
#launch .launch-bar{position:absolute;left:50%;bottom:calc(48px + var(--safe-b));width:140px;height:2px;margin-left:-70px;border-radius:2px;background:rgba(255,255,255,.12);overflow:hidden}
#launch .launch-bar::after{content:"";position:absolute;inset:0 auto 0 0;width:calc(var(--step) * 33.4%);border-radius:2px;background:var(--ion);transition:width .6s var(--ease)}
#launch.stuck .launch-bar::after{background:var(--ember)}
#launch.stuck p{color:#ffb4a3}
#launch .launch-retry{display:none;position:absolute;left:50%;bottom:calc(104px + var(--safe-b));transform:translateX(-50%)}
#launch.stuck .launch-retry{display:inline-flex}
#launch.away .launch-bar,#launch.away .launch-retry{opacity:0;transition:opacity .35s}
@keyframes drive-rock{to{transform:translateY(1.5px)}}
@keyframes wheel{to{transform:rotate(-360deg)}}
@keyframes beam{to{opacity:.6}}
@keyframes tail{to{opacity:.55}}
@keyframes road{to{transform:translateX(96px)}}
@keyframes air{to{transform:translateX(150vw)}}
#launch.away .drive{animation:none;transform:translateX(-140vw);transition:transform .8s cubic-bezier(.6,0,.9,.25)}
#launch.away .drive-wheel{animation-duration:.12s}
#launch.away .road,#launch.away .road-air,#launch.away p{opacity:0;transition:opacity .35s}
@media (prefers-reduced-motion:reduce){.drive,.drive i,.road::before,.road-air::before,.road-air::after{animation:none}#launch.away .drive{transform:none;opacity:0;transition:opacity .4s}}

/* Installed as an app: above the home indicator, measured from the top of the real screen */
.app #nav{top:calc(var(--full) - 8px - max(var(--safe-b),20px));bottom:auto;transform:translate(-50%,-100%)}
.app #toast{top:calc(var(--full) - 76px - max(var(--safe-b),20px));bottom:auto;transform:translate(-50%,calc(-100% + 20px))}
.app #toast.on{transform:translate(-50%,-100%)}
.app-note{margin-top:14px;color:var(--ink-2);max-width:60ch}

/* The price of a charge away from home */
.toprice{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;padding:18px 0;border-bottom:1px solid var(--line)}
.toprice:first-of-type{margin-top:22px;border-top:1px solid var(--line)}
.toprice p b{display:block;font:300 clamp(24px,3vw,38px)/1.1 var(--display);letter-spacing:-.02em}.toprice p span{color:var(--ash);font-size:var(--t-s)}
.price{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.price label{display:flex;align-items:center;gap:10px;min-height:52px;padding:0 16px;border-radius:999px;background:rgba(255,255,255,.08);color:var(--ash);font-size:var(--t-s)}
.price label:focus-within{outline:2px solid var(--ion);outline-offset:2px}
.price input{width:84px;border:0;background:none;outline:0;color:var(--bone);font:300 22px var(--display);text-align:right;font-feature-settings:"tnum"}
.price input::placeholder{color:var(--ash)}
.when{white-space:nowrap}
.row+div .price{padding:12px 0;justify-content:flex-end;border-bottom:1px solid var(--line)}

/* Empty state */
.empty{display:grid;gap:10px;justify-items:start;padding:18px 0 6px}
.empty img{width:min(320px,76%);height:auto;display:block;margin-left:-7%;mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 45%,transparent);-webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 45%,transparent)}
.empty b{font-weight:400;font-size:var(--t-l)}
.empty p{color:var(--ash);font-size:var(--t-s);max-width:44ch}

/* The last chapter: the car again and the way on */
.next{justify-content:flex-end;padding:0 0 calc(96px + var(--safe-b))}
.next a{display:block;padding:0 var(--pad);text-align:center}
.next .mono{color:var(--bone);display:inline-block;padding:4px 11px;border-radius:999px;background:var(--chip)}
.next b{display:block;font:italic 500 clamp(72px,14vw,220px)/.95 var(--voice);letter-spacing:-.02em;color:var(--bone);text-shadow:0 2px 30px rgba(0,0,0,.45);transition:letter-spacing .5s var(--ease)}

/* Skeleton, buttons, gate */
.sk{height:14px;border-radius:7px;background:linear-gradient(90deg,rgba(255,255,255,.08),rgba(255,255,255,.18),rgba(255,255,255,.08)) 0 0/200% 100%;animation:shimmer 1.4s linear infinite}
.sk.line{width:280px;max-width:70%;margin-bottom:10px}.sk.line.s{width:140px}
@keyframes shimmer{to{background-position:-200% 0}}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:52px;padding:0 26px;border-radius:999px;background:var(--bone);color:var(--void);font-weight:500;transition:transform var(--d-fast) var(--ease)}
.btn.ghost{background:rgba(255,255,255,.1);color:var(--bone)}.btn.ion{background:var(--ion)}.btn[disabled]{opacity:.55;pointer-events:none}
.fp{width:22px;height:22px}
.gate{min-height:var(--full);display:flex;flex-direction:column;justify-content:flex-end;padding:0 var(--pad) calc(44px + var(--safe-b));background:linear-gradient(transparent 58%,rgba(11,12,14,.88))}
.gate-in{width:100%;max-width:520px;display:grid;gap:14px;justify-items:start}
.gate .btn{min-height:56px;padding:0 28px;font-size:var(--t-l)}
.gate .say{color:var(--ink-2);max-width:46ch;font-size:var(--t-m)}
.gate .say.bad{color:var(--ember)}
.code{font-family:var(--mono);font-size:clamp(40px,8vw,64px);letter-spacing:.18em;font-weight:300;color:var(--ion)}
.code[hidden]{display:none}
#tip{position:fixed;z-index:60;pointer-events:none;display:none;background:#000;border:1px solid var(--line);border-radius:10px;padding:7px 11px;font-size:13px;max-width:240px}
#tip b{display:block;font-weight:400}#tip span{color:var(--ash);font-size:12px}
#toast{position:fixed;z-index:70;left:50%;bottom:calc(92px + var(--safe-b));transform:translate(-50%,20px);opacity:0;background:var(--bone);color:var(--void);padding:11px 18px;border-radius:999px;font-size:14px;transition:opacity .3s,transform .3s;pointer-events:none;max-width:calc(100% - 32px)}
#toast.on{opacity:1;transform:translate(-50%,0)}

/* Phone: the dock shows one word, the car stands up, the chapters breathe less */
@media (max-aspect-ratio:1/1){
  #nav{left:12px;right:12px;transform:none;justify-content:space-between}
  .app #nav{transform:translateY(-100%)}
  #nav a{flex:0 0 auto;padding:0 12px}
  #nav a:not(.on) span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .ch{padding:calc(56px + var(--safe-t)) 0 calc(104px + var(--safe-b))}
  .hero{padding:0 0 calc(86px + var(--safe-b))}
  .hero:after{height:calc(52% + 36vh);background:linear-gradient(transparent,rgba(11,12,14,.62) 16%,rgba(11,12,14,.82) 33%,rgba(11,12,14,.92) 59%,rgba(11,12,14,.7) 80%,transparent)}
  .hero-foot{flex-direction:column;align-items:stretch;gap:14px}
  .status{grid-auto-flow:row;grid-template-columns:repeat(3,1fr);gap:10px;border-top:1px solid rgba(255,255,255,.16);padding-top:10px}
  .status dt{font-size:14px;white-space:normal}.status dd{font-size:11.5px;white-space:normal}.status>div:only-child{grid-column:1/-1}
  .pair{grid-template-columns:1fr}
  .plane{--tilt:24deg;--turn:0deg;max-width:none;gap:4px;transform:rotateX(var(--tilt)) rotateZ(var(--turn)) scale(.93)}
  .city{perspective:2200px;perspective-origin:50% 0}
  a.block:after{content:"";position:absolute;inset:-4px}
  /* The car stands up, each pressure beside its wheel */
  .plan{aspect-ratio:.82;width:min(100%,calc((var(--full) - 300px)*.82))}
  .plan img{width:56%;transform:translate(-50%,-50%)}
  .w{width:21%;margin:0;text-align:left;transform:translateY(-50%)}.w b{font-size:clamp(24px,7.4vw,32px)}
  .w.fl,.w.rl{left:0;bottom:auto;text-align:right}.w.fr,.w.rr{left:auto;right:0}
  .w.fl,.w.fr{top:27%}.w.rl,.w.rr{top:73%}
  .w .dot{display:none}
  .w.bad b{color:var(--ember)}
  .tiles{grid-template-columns:1fr}
  .versus{grid-template-columns:1fr}
  .mapbox{height:calc(var(--full) - 190px)}
}
/* A phone on its side: icons in the dock, the figures one step down */
@media (min-aspect-ratio:1/1) and (max-height:520px){
  #nav a span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  #nav{bottom:calc(6px + var(--safe-b))}
  .hero{padding-bottom:64px}.status{gap:18px}.status dt{font-size:14px}
  .h{font-size:clamp(32px,9vh,48px)}
  .ch{padding-top:32px;padding-bottom:72px}
  .plan{max-width:520px;margin-inline:auto}
}
/* A small screen: the car's chapters keep the whole screen, the data follows on without a gap */
@media (max-aspect-ratio:1/1),(max-height:520px){
  [data-ch=field] .ch{min-height:0;padding:36px 0}
  [data-ch=field] .ch:first-child{padding-top:56px}
  [data-ch=field] .ch:last-child{padding-bottom:calc(104px + var(--safe-b))}
}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important;animation:none!important}.wait{opacity:1;transform:none}.wait .chart{clip-path:none}}

/* Приложение: a phone held upright gets the console as an app (views/cockpit.js appHome, js/app.js) */
/* --ring, not --fill: the month's city colours its blocks with --fill, and a typed property would void it */
@property --ring{syntax:'<number>';inherits:false;initial-value:0}
#ptr{display:none}
@media (max-width:600px) and (orientation:portrait){
  #scroll{overscroll-behavior-y:none}
  /* The tab bar of an app: every item named, the one you are on lit, flush with the bottom edge */
  #nav{left:0;right:0;bottom:0;transform:none;justify-content:space-around;gap:0;padding:6px 2px calc(6px + var(--safe-b));border:0;border-top:1px solid rgba(255,255,255,.08);border-radius:0;background:rgba(10,11,13,.86)}
  .app #nav{top:var(--full);bottom:auto;transform:translateY(-100%);padding-bottom:max(var(--safe-b),18px)}
  #nav a,#nav a.on{flex:1 1 0;min-width:0;flex-direction:column;gap:3px;padding:5px 0 2px;min-height:48px;font-size:10.5px;letter-spacing:.01em;color:var(--ink-nav)}
  #nav a:not(.on) span,#nav a span{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:nowrap}
  #nav a.on{color:var(--ion)}
  #nav svg{width:23px;height:23px}
  #pill{display:none}
  /* Installed: a frosted strip under the clock, so what scrolls up never runs beneath the status bar */
  .app body::before{content:"";position:fixed;z-index:46;left:0;right:0;top:0;height:var(--safe-t);background:rgba(13,14,17,.72);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);pointer-events:none}
  #toast{bottom:calc(84px + var(--safe-b))}
  .app #toast{top:calc(var(--full) - 96px - max(var(--safe-b),18px))}

  /* Home: the car on top, a sheet over it */
  .ah-top{position:relative;height:calc(var(--full) * .5);padding:calc(14px + var(--safe-t)) 18px 0;display:flex;flex-direction:column;align-items:flex-start;gap:8px}
  .ah-name{font:600 22px/1.1 var(--display);letter-spacing:-.01em;text-shadow:0 1px 14px rgba(0,0,0,.45)}
  .ah-top .sync{margin:0}
  .ah-place{font-size:13px;color:var(--bone);text-shadow:0 1px 10px rgba(0,0,0,.6)}
  /* Opaque, no live blur and no shadow: a blur over the moving scene is the dearest thing a phone's GPU
     can be asked for, and the rounded shadow read as a dark band with cut corners above the controls. */
  .ah-sheet{position:relative;min-height:calc(var(--full) * .62);padding:10px 18px calc(108px + var(--safe-b));border-radius:24px 24px 0 0;
    background:linear-gradient(180deg,#191b1f,#111215 140px);border-top:1px solid rgba(255,255,255,.1)}
  .ah-sheet svg{fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
  .ah-grip{display:block;width:38px;height:5px;margin:0 auto 14px;border-radius:3px;background:rgba(255,255,255,.22)}
  .ah-charge{display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
  .ah-soc{font:200 66px/.9 var(--display);letter-spacing:-.04em}.ah-soc small{font-size:24px;color:var(--ash);margin-left:4px;letter-spacing:0}
  /* Battery temperature and range side by side, one type, one baseline, a hairline between */
  .ah-figs{display:flex;align-items:flex-end;gap:12px;text-align:right}
  .ah-fig b{display:block;font:300 26px/1.1 var(--display);letter-spacing:-.02em;white-space:nowrap}.ah-fig span{display:block;font-size:12px;color:var(--ash);white-space:nowrap}
  .ah-fig+.ah-fig{padding-left:12px;border-left:1px solid rgba(255,255,255,.1)}
  .ah-pack.on b,.ah-pack.on span{color:var(--ion)}.ah-pack.warn b,.ah-pack.warn span{color:var(--ember)}.ah-pack.cold span{color:#9cc8ff}
  @media (max-width:380px){.ah-figs{gap:10px}.ah-fig+.ah-fig{padding-left:10px}.ah-fig b{font-size:23px}.ah-fig span{font-size:11.5px}}
  .ah-bar{position:relative;height:8px;margin:14px 0 16px;border-radius:4px;background:rgba(255,255,255,.1)}
  .ah-bar i{position:absolute;inset:0 auto 0 0;border-radius:4px;background:var(--ion);box-shadow:0 0 14px rgba(198,255,74,.45)}
  .ah-bar b{position:absolute;top:-4px;width:2px;height:16px;margin-left:-1px;border-radius:1px;background:var(--bone)}
  .ah-states{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin:0;padding:0;list-style:none}
  .ah-states li{min-width:0;padding:10px 9px;border-radius:14px;background:rgba(255,255,255,.06)}
  .ah-states b{display:block;font:500 15px/1.2 var(--display);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ah-states span{display:block;font-size:11px;color:var(--ash);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ah-states .warn b{color:var(--ember)}.ah-states .on b{color:var(--ion)}
  @media (max-width:380px){.ah-states{gap:5px}.ah-states li{padding:9px 7px}.ah-states b{font-size:13.5px;letter-spacing:-.01em}.ah-states span{font-size:10.5px}}

  /* The card of the moment */
  .live{display:block;margin:14px 0 0;padding:14px 16px;border-radius:18px;background:rgba(198,255,74,.07);border:1px solid rgba(198,255,74,.22);color:var(--bone)}
  .live.warm{background:rgba(255,176,32,.07);border-color:rgba(255,176,32,.28)}
  .live.bad{background:rgba(255,92,57,.08);border-color:rgba(255,92,57,.35)}
  .live-k{font-size:12.5px;color:var(--ash)}.live-k b{color:var(--ion);font-weight:500}
  .live-v{font:300 26px/1.2 var(--display);letter-spacing:-.02em;margin-top:2px}.live-v small{font-size:14px;color:var(--ink-2);letter-spacing:0}
  .live .flow{margin-top:12px}.live .flow-keys{margin-top:8px}
  .live-n{font-size:12.5px;color:var(--ink-2);margin-top:6px}
  .live.bad .live-v{color:var(--ember)}

  /* Quick controls: round keys, a ring fills while held */
  .ah-h{font:500 12px/1 var(--mono);text-transform:uppercase;letter-spacing:.1em;color:var(--ash);margin:24px 0 12px}
  .ah-quick{display:grid;grid-template-columns:repeat(4,1fr);gap:16px 6px;margin:0;border:0}
  .ah-quick .cmd{margin:0;padding:0;border:0;min-height:0;align-items:center;gap:7px;background:none;border-radius:0}
  .ah-quick .cmd::before{display:none}
  .ah-quick .cmd b{--ring:0;display:grid;place-items:center;width:60px;height:60px;border-radius:50%;font-size:0;
    background:radial-gradient(closest-side,#1a1c20 91%,transparent 92%),conic-gradient(var(--ion) calc(var(--ring) * 360deg),rgba(255,255,255,.13) 0);transition:--ring .15s}
  .ah-quick .cmd b svg{width:25px;height:25px;color:var(--bone)}
  .ah-quick .cmd.hold b{--ring:1;transition:--ring .5s linear}
  .ah-quick .cmd.hold b svg{color:var(--ion)}
  .ah-quick .cmd[data-state=ok] b{--ring:1}
  .ah-quick .cmd span{min-height:2.6em;max-width:84px;font-size:11.5px;line-height:1.3;text-align:center;color:var(--ink-2)}
  .ah-quick .cmd[data-state=ok] span,.ah-quick .cmd[data-state=wait] span{color:var(--ion)}.ah-quick .cmd[data-state=bad] span{color:var(--ember)}
  .ah-quick .cmd:focus-visible{outline-offset:2px;border-radius:12px}
  .ah-hint{margin-top:10px;font-size:12px;color:var(--ash);text-align:center}

  /* Sections, as in the phone's own settings */
  .ah-list{display:block;border-radius:18px;background:rgba(255,255,255,.05);overflow:hidden}
  .ah-list a{display:flex;align-items:center;gap:12px;min-height:62px;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.06)}
  .ah-list a:last-child{border-bottom:0}
  .ah-list a:active{background:rgba(255,255,255,.06)}
  .ah-list i:first-child{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:rgba(255,255,255,.08)}
  .ah-list i:first-child svg{width:19px;height:19px}
  .ah-list span{flex:1;min-width:0}.ah-list span b{display:block;font-weight:500;font-size:16px}
  .ah-list span small{display:block;font-size:12.5px;color:var(--ash);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ah-list em{font-style:normal;font-size:15px;color:var(--bone);white-space:nowrap}.ah-list em.bad{color:var(--ember)}
  .ah-foot{margin-top:18px;font-size:12px;color:var(--ash);text-align:center}

  /* Pull to refresh (js/app.js) */
  #ptr{position:fixed;z-index:55;left:50%;top:calc(6px + var(--safe-t));width:34px;height:34px;margin-left:-17px;border-radius:50%;background:rgba(13,14,17,.85);border:1px solid rgba(255,255,255,.14);
    display:grid;place-items:center;opacity:0;transform:translateY(calc(var(--pull,0) * 1px - 40px));pointer-events:none}
  #ptr svg{width:18px;height:18px;fill:none;stroke:var(--ion);stroke-width:2;stroke-linecap:round;transform:rotate(calc(var(--pull,0) * 4deg))}
  #ptr.on{opacity:1}
  #ptr.busy svg{animation:ptr-spin .8s linear infinite}
}
@keyframes ptr-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.ah-quick .cmd.hold b{transition:none}}

/* Приложение, этап 2: every section as an app screen. html raises these over the design layers. */
#apphead,.at-large{display:none}
@media (max-width:600px) and (orientation:portrait){
  html #progress,html #rail{display:none}
  /* The scene keeps the top half; the sheet with the large title takes over from there */
  html .hero{height:calc(var(--full) * .6);min-height:0;padding-bottom:14px}
  html .hero .fig{font-size:clamp(64px,20vw,96px)}
  /* The half-height cover needs its own shade under the words, or bright fog and snow skies drop them below AA */
  /* The cover's words on a card of their own at the foot of the scene, as Weather does: the car stays clear
     above it, and the words sit on a solid ground, so no sky can take their contrast away. */
  html .hero:after{display:none}
  html .hero .hero-foot{width:auto;margin:0 10px;padding:12px 14px 12px;border-radius:18px;background:rgba(17,18,21,.9);border:1px solid rgba(255,255,255,.08)}
  html .hero .hero-foot .over,html .hero .hero-foot .sync{background:rgba(255,255,255,.07)}
  .at-large{display:block;position:absolute;z-index:3;left:18px;right:18px;top:calc(var(--full) * .6 + 18px);margin:0;font:700 32px/1.1 var(--display);letter-spacing:-.02em;pointer-events:none}
  /* No backdrop blur here: it flattens the 3D city of the month into bare numbers */
  html [data-ch=field]{position:relative;padding-top:58px;border-radius:24px 24px 0 0;
    background:linear-gradient(180deg,#191b1f,#111215 140px);border-top:1px solid rgba(255,255,255,.1)}
  html [data-ch=field] .ch{min-height:0;padding:14px 0 10px;border:0}
  html [data-ch=field] .ch:first-child{padding-top:0}
  html [data-ch=field] .ch:last-child{padding-bottom:calc(104px + var(--safe-b))}
  html [data-ch=field] .ch>.wrap{width:auto;max-width:none;margin:0;padding:0 16px;background:none;border:0;border-radius:0;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;animation:none}
  html [data-ch=field] .ch>.wrap::before{display:none}
  html [data-ch=field] .h{font:600 22px/1.25 var(--display);letter-spacing:-.01em;text-transform:none;text-shadow:none;margin:10px 2px 10px;padding:0;background:none}
  html [data-ch=field] .h::before{display:none}
  html [data-ch=field] .h em{font:italic 500 1.22em/1 var(--voice);color:var(--ion);text-transform:none;letter-spacing:0;text-shadow:none}
  html [data-ch=field] .h.rise.wait{opacity:1;filter:none;letter-spacing:-.01em;clip-path:none;transform:none}
  html [data-ch=field] .sub{font-size:14px;margin:6px 2px 0}
  html [data-ch=field] .hint{font-size:12px;margin:2px 0 0}
  html [data-ch=field] h3{font-size:14px;font-weight:600}
  /* Grouped, as in the phone's own settings: lists and charts each on a card */
  html [data-ch=field] .rows,html [data-ch=field] .vs,html [data-ch=field] .tiles,html [data-ch=field] .timeline,html [data-ch=field] .block-sect,html [data-ch=field] .toprice,html [data-ch=field] .versus{
    margin-top:10px;border:0;border-radius:16px;background:rgba(255,255,255,.055)}
  html [data-ch=field] .block-sect{padding:14px 14px 12px}
  html [data-ch=field] .block-sect .rows,html [data-ch=field] .block-sect .vs,html [data-ch=field] .block-sect .tiles{margin:10px -14px -12px;border-radius:0 0 16px 16px;background:none}
  html [data-ch=field] .rows{overflow:hidden}
  html [data-ch=field] .row{min-height:58px;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.06)}
  html [data-ch=field] .row:last-child{border-bottom:0}
  html [data-ch=field] .row-k{font-size:15px}
  html [data-ch=field] .row-v{font-size:19px;font-weight:400}
  html [data-ch=field] .rows-month{padding:16px 14px 8px;border-bottom:1px solid rgba(255,255,255,.06)}
  html [data-ch=field] .vs{padding:14px;gap:14px}
  html [data-ch=field] .tiles{padding:0 14px}
  html [data-ch=field] .tile{border-bottom:1px solid rgba(255,255,255,.06)}
  html [data-ch=field] .tile:last-child{border-bottom:0}
  html [data-ch=field] .timeline{margin-left:0;padding:6px}
  html [data-ch=field] .toprice{padding:14px}
  html [data-ch=field] .toprice:first-of-type{border-top:0}
  html [data-ch=field] .versus{padding:16px;gap:16px}
  html [data-ch=field] .versus b{font-size:52px}
  html .mapc{padding:0 0 10px}
  html .mapc .wrap{padding:0 16px}
  html .mapbox{height:calc(var(--full) * .5);min-height:300px;border-radius:16px;overflow:hidden}

  /* The compact header: comes in as the large title goes, «‹ Статистика» on a day */
  #apphead{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;position:fixed;z-index:47;left:0;right:0;top:0;height:calc(44px + var(--safe-t));padding:var(--safe-t) 8px 0;
    opacity:0;transform:translateY(-6px);pointer-events:none;transition:opacity .2s,transform .2s,background .2s;border-bottom:1px solid transparent}
  #apphead.on{opacity:1;transform:none;pointer-events:auto}
  #apphead.solid{background:rgba(13,14,17,.8);-webkit-backdrop-filter:blur(20px) saturate(150%);backdrop-filter:blur(20px) saturate(150%);border-bottom-color:rgba(255,255,255,.08)}
  #apphead b{grid-column:2;font:600 16px/1 var(--display);opacity:0;transition:opacity .2s;white-space:nowrap}
  #apphead.solid b{opacity:1}
  #apphead .back{grid-column:1;justify-self:start;display:flex;align-items:center;gap:1px;min-height:40px;padding:0 12px 0 4px;border-radius:999px;color:var(--ion);font-size:16px}
  #apphead .back[hidden]{display:none}
  #apphead:not(.solid) .back{background:rgba(13,14,17,.55);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
  #apphead .back svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
}

/* «Нет связи»: a quiet strip at the top, the last data stays on screen under it (js/app.js) */
#netbar{position:fixed;z-index:48;left:50%;top:calc(10px + var(--safe-t));transform:translate(-50%,-140%);max-width:calc(100% - 32px);padding:8px 14px;border-radius:999px;
  background:rgba(40,20,14,.92);border:1px solid rgba(255,92,57,.5);color:#ffd9cf;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;pointer-events:none;transition:transform .3s var(--ease),opacity .3s}
#netbar.on{transform:translate(-50%,0);opacity:1}
/* On the phone it rises above the tab bar, clear of the car's own «на связи» line at the top */
@media (max-width:600px) and (orientation:portrait){
  #netbar{top:auto;bottom:calc(74px + var(--safe-b));transform:translate(-50%,160%)}
  .app #netbar{top:calc(var(--full) - 118px - max(var(--safe-b),18px));bottom:auto}
  #netbar.on{transform:translate(-50%,0)}
}
@media (max-width:600px) and (orientation:portrait){
  .ah-sheet .sk{margin-top:14px}.ah-sheet .sk-big{width:46%;height:56px;border-radius:14px;margin-top:0}
  .sk-row{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:16px}.sk-row .sk{height:54px;margin:0;border-radius:14px}
  .sk-row.round{gap:14px 6px;margin-top:28px}.sk-row.round .sk{width:60px;height:60px;border-radius:50%;justify-self:center}
}

/* The phone's launch, calm (owner, 8 Nov): the car standing, a word on what it waits for and a thin grey
   scale; no running road, no wind, no rocking, and it fades instead of driving off. */
@media (max-width:600px) and (orientation:portrait){
  #launch .road,#launch .road-air,#launch .drive-beam,#launch .drive-tail{display:none}
  #launch .drive,#launch .drive i{animation:none}
  #launch .launch-bar::after{background:var(--bone);opacity:.7}
  #launch.away .drive{transform:none;opacity:0;transition:opacity .45s var(--ease)}
}

/* Where the car stands (spot.js): the line under the car's name opens the map */
.spot-line{display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:100%;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent}
.spot-line svg{flex:none;width:15px;height:15px;fill:none;stroke:var(--ion);stroke-width:1.8;stroke-linejoin:round}
.spot-line span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.note-spot{color:var(--ink-2)}.note-spot span{text-decoration:underline dotted rgba(255,255,255,.35);text-underline-offset:4px}
@media (hover:hover){.note-spot:hover span{color:var(--bone);text-decoration-color:var(--ion)}}
.spot-line:focus-visible{outline:2px solid var(--ion);outline-offset:4px;border-radius:6px}

#spot{position:fixed;inset:auto 0 0;width:100%;max-width:none;height:min(88dvh,760px);max-height:none;margin:0;padding:0;border:0;border-radius:24px 24px 0 0;background:#111215;color:var(--bone);overflow:hidden;
  display:none;flex-direction:column;box-shadow:0 -1px 0 rgba(255,255,255,.1);transition:transform .26s var(--ease)}
#spot[open]{display:flex;animation:spot-up .32s var(--ease)}
#spot.leaving{transform:translateY(105%);transition:transform .22s cubic-bezier(.4,0,1,1)}
#spot::backdrop{background:rgba(0,0,0,.5);animation:spot-dim .32s ease}
@keyframes spot-up{from{transform:translateY(100%)}}
@keyframes spot-dim{from{background:rgba(0,0,0,0)}}
.spot-map{position:relative;flex:1 1 auto;min-height:0;background:#1a1c20}
.spot-canvas{position:absolute;inset:0;width:100%;height:100%;border:0;background:#1a1c20}
.spot-card{flex:none;position:relative;padding:12px 20px calc(18px + var(--safe-b));background:#111215;border-top:1px solid rgba(255,255,255,.08)}
.spot-grip{display:block;width:38px;height:5px;margin:0 auto 12px;border-radius:3px;background:rgba(255,255,255,.22)}
.spot-k{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--ash)}
.spot-title{margin:4px 0 2px;font:500 22px/1.25 var(--display);letter-spacing:-.01em}
.spot-sub{font-size:14px;color:var(--ash);min-height:1.4em}
.spot-actions{display:flex;gap:8px;margin-top:16px}
.spot-actions .btn{min-height:48px;padding:0 18px;font-size:15px;gap:8px;white-space:nowrap}
.spot-actions .spot-route{flex:1 1 auto}.spot-actions .spot-ya{flex:1 1 auto}.spot-actions .spot-copy{flex:none;width:48px;padding:0}
.spot-actions svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.spot-copy.done{color:var(--ion)}
.spot-close,.spot-aim{position:absolute;z-index:500;display:grid;place-items:center;width:40px;height:40px;border:0;border-radius:50%;background:rgba(17,18,21,.82);color:var(--bone);cursor:pointer}
.spot-close{top:12px;right:12px}.spot-aim{right:12px;bottom:28px}
.spot-close svg,.spot-aim svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
@media (prefers-reduced-motion:reduce){#spot[open],#spot::backdrop{animation:none}}
/* A big screen: a window in the middle, the map beside nothing, the card under it */
@media (min-width:601px),(orientation:landscape){
  #spot{inset:0;margin:auto;width:min(760px,calc(100vw - 48px));height:min(640px,calc(100dvh - 48px));border-radius:24px;box-shadow:0 30px 80px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}
  #spot[open]{animation:spot-in .26s var(--ease)}
  #spot.leaving{transform:none;opacity:0;transition:opacity .18s}
  @keyframes spot-in{from{opacity:0;transform:scale(.97)}}
  .spot-grip{display:none}
  .spot-card{padding:18px 24px 22px}
  .spot-actions{max-width:520px}
}
/* The phone: the line under the name is a chip, like «на связи» above it */
@media (max-width:600px) and (orientation:portrait){
  .ah-place.spot-line{padding:6px 12px 6px 9px;border-radius:999px;background:var(--chip);color:var(--bone);font-size:13px;text-shadow:none;max-width:calc(100vw - 36px)}
}

/* The phone's month is a flat calendar (owner, 8 Nov: no effects on the phone): the colour says how far,
   no towers leaning over the next row. The big screens keep the city. */
@media (max-width:600px) and (orientation:portrait){
  .city{perspective:none;padding-bottom:0;margin-top:8px}
  .plane{transform:none;gap:6px}
  .block{--h:0!important}
  .block .side{display:none}
  .block .top{border-radius:10px;padding:6px 7px;font-size:13px}.block .top b{font-size:13px}
}

/* Audit of 8 Nov: the details */
@media (max-width:600px) and (orientation:portrait){
  /* The header and the tab bar are solid: see-through without blur showed text and buttons as ghosts
     under them, and a live blur on the phone is the GPU cost the sheet already gave up */
  #nav{background:#0d0e11;-webkit-backdrop-filter:none;backdrop-filter:none}
  #apphead.solid{background:#0d0e11;-webkit-backdrop-filter:none;backdrop-filter:none}
  #apphead:not(.solid) .back{background:rgba(13,14,17,.82);-webkit-backdrop-filter:none;backdrop-filter:none}
  .hero .over,.hero .sync{-webkit-backdrop-filter:none;backdrop-filter:none}
  /* Nothing pulses on the phone: the dot says «on line» by its colour */
  .sync i{animation:none}
  /* A finger's worth (44 px) for the back button, the map's buttons and the address chip */
  #apphead .back{min-height:44px}
  .spot-close,.spot-aim{width:44px;height:44px}
  .ah-place.spot-line{min-height:44px;padding:10px 14px 10px 10px}
  /* Lists that clip their corners must not clip the keyboard's focus ring: it is drawn inside */
  .ah-list a:focus-visible,html [data-ch=field] a.row:focus-visible{outline-offset:-2px}
  /* The month's squares hold the day and the km at 360 px too */
  .block .top{line-height:1.15;padding:5px 6px}
  /* A rule's day chips keep the list's inner edge, as the departures' chips do */
  html [data-ch=field] .rows>.days{padding:10px 14px 14px;border-bottom-color:rgba(255,255,255,.06)}
  html [data-ch=field] .rows>.days:last-child{border-bottom:0}
  /* The toast rises above «нет связи» when both are up */
  body:has(#netbar.on) #toast{bottom:calc(128px + var(--safe-b))}
  .app body:has(#netbar.on) #toast{top:calc(var(--full) - 140px - max(var(--safe-b),18px))}
}
/* The login screen has no page title and no header over it (a «Доступ» stayed there after logging out) */
body[data-mode=gate] .at-large,body[data-mode=gate] #apphead{display:none}
/* The launch screen gives up on its car after 45 s, never on its «Повторить» */
#launch.stuck{animation:none}

/* A phone on its side: the month's city a size smaller, so its front rows stay clear of the menu */
@media (min-aspect-ratio:1/1) and (max-height:520px){.plane{max-width:440px}.city{padding-bottom:12px}}

/* Audit of 8 Nov, second pass */
@media (max-width:600px) and (orientation:portrait){
  /* What the keyboard focuses is scrolled clear of the tab bar and the header, never under them */
  #scroll{scroll-padding-top:calc(56px + var(--safe-t));scroll-padding-bottom:calc(84px + max(var(--safe-b),18px))}
  /* The narrowest phones (320 px): the charge row gives a little instead of pushing the page sideways */
  .ah-charge{min-width:0}
}
@media (max-width:340px) and (orientation:portrait){
  .ah-soc{font-size:54px}.ah-soc small{font-size:20px}
  .ah-figs{gap:8px}.ah-fig+.ah-fig{padding-left:8px}.ah-fig b{font-size:19px}.ah-fig span{font-size:10.5px}
  .ah-states{gap:4px}.ah-states li{padding:9px 6px}.ah-states b{font-size:13px}
}
