/* One integrated dashboard: insight tiles, level chart and data center map over a plan table, all linked */
:root{color-scheme:light}
:root{
  --bg:#ffffff; --surface:#f5f7f6; --fg:#16201c; --muted:#5d6b65; --line:#dde3e0;
  --accent:#0b6b4f; --ssd:#9a5b00; --ssd-bg:#fdf0da; --nvme:#0b6b4f; --nvme-bg:#dff3ea; --warn:#a4262c;
  --page:#eef2f0; --shadow:0 1px 2px rgba(16,32,28,.06),0 8px 24px rgba(16,32,28,.06);
  --ease:cubic-bezier(.2,.8,.2,1);
  --display:'Sora',-apple-system,'Segoe UI',sans-serif; --body:'IBM Plex Sans',-apple-system,'Segoe UI',sans-serif;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#111715; --surface:#1a221f; --fg:#e8efec; --muted:#9aa9a2; --line:#2c3833;
  --accent:#4fd1a1; --ssd:#f0b45a; --ssd-bg:#3a2c12; --nvme:#4fd1a1; --nvme-bg:#143328; --warn:#f08a8f;
  --page:#0c110f; --shadow:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.3); color-scheme:dark}}
:root[data-theme="dark"]{
  --bg:#111715; --surface:#1a221f; --fg:#e8efec; --muted:#9aa9a2; --line:#2c3833;
  --accent:#4fd1a1; --ssd:#f0b45a; --ssd-bg:#3a2c12; --nvme:#4fd1a1; --nvme-bg:#143328; --warn:#f08a8f;
  --page:#0c110f; --shadow:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.3); color-scheme:dark}
/* Provider colours: light = Okabe-Ito; dark steps validated separately against surface #1a221f */
:root{--c-vultr:#0072B2;--c-do:#E69F00;--c-linode:#009E73;--c-hetzner:#D55E00;--c-hostinger:#CC79A7;--c-ovh:#7B61D9;--land:#e6ebe8;--land-line:#cfd8d3;--sea:#f1f5f3}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--land:#26322d;--land-line:#33423b;--sea:#151c19;--c-vultr:#3a8fd6;--c-do:#b98200;--c-linode:#0aa37a;--c-hetzner:#e0652a;--c-hostinger:#c86fb8;--c-ovh:#6f7cf0}}
:root[data-theme="dark"]{--land:#26322d;--land-line:#33423b;--sea:#151c19;--c-vultr:#3a8fd6;--c-do:#b98200;--c-linode:#0aa37a;--c-hetzner:#e0652a;--c-hostinger:#c86fb8;--c-ovh:#6f7cf0}

*{box-sizing:border-box}
[hidden]:not([hidden=until-found i]){display:none!important}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
body{background:var(--page);color:var(--fg);font-family:var(--body);font-size:14px;margin:0;line-height:1.45;
  padding-block:.75rem;padding-left:max(12px,env(safe-area-inset-left,0px));padding-right:max(12px,env(safe-area-inset-right,0px))}
.wrap{max-width:1680px;margin:0 auto;display:flex;flex-direction:column;gap:.6rem}
h1{font-family:var(--display);font-size:1.1rem;margin:0;white-space:nowrap}
h2{font-size:.7rem;font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0;white-space:nowrap}
.lbl{font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-right:.1rem}
button{font:inherit;color:var(--fg)}
button:focus-visible,input:focus-visible,summary:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* toolbar; its entrance animation makes it a stacking context, so it needs its own z-index for the Notes popup to sit above the dashboard */
.bar{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .9rem;position:relative;z-index:20}
.meta{color:var(--muted);font-size:.78rem}
.levels,.pfilter{display:flex;flex-wrap:wrap;gap:.3rem;align-items:center}
.bar .end{margin-left:auto;display:flex;gap:.5rem;align-items:center}
.lvbtn,.chip,.pchip,.vbtn,.tbtn,.about summary{font-size:.78rem;padding:.2rem .6rem;border:1px solid var(--line);background:var(--bg);border-radius:999px;cursor:pointer}
.lvbtn{font-variant-numeric:tabular-nums}
.lvbtn b{font-weight:600;margin-right:.3rem}
.lvbtn[aria-pressed="true"],.chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--bg)}
.pchip{display:inline-flex;align-items:center;gap:.38rem}
.pchip i{width:.58rem;height:.58rem;border-radius:50%;background:var(--c);display:inline-block;border:2px solid var(--c)}
.pchip[aria-pressed="false"]{opacity:.5}
.pchip[aria-pressed="false"] i{background:transparent}
.pchip small{color:var(--muted);font-variant-numeric:tabular-nums}
.pchip.pinned{border-color:var(--fg)}
.link{font-size:.78rem;background:none;border:0;color:var(--accent);cursor:pointer;text-decoration:underline;padding:.2rem}
.focus{font-size:.76rem;color:var(--muted);display:inline-flex;align-items:center}
.focus span{color:var(--fg);font-weight:500}
.about{position:relative}
.about summary{list-style:none}
.about summary::-webkit-details-marker{display:none}
.about[open] summary{border-color:var(--accent)}
.pop{position:absolute;right:0;top:calc(100% + 6px);z-index:5;width:min(560px,calc(100vw - 32px));max-height:70vh;overflow:auto;background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:.4rem 1rem;box-shadow:var(--shadow);color:var(--muted);font-size:.82rem}
.pop p{margin:.5rem 0}
noscript p{background:var(--surface);padding:.5rem .8rem;border-radius:6px;font-size:.82rem;margin:0}

/* the dashboard panel */
.dash{background:var(--bg);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:.7rem;display:flex;flex-direction:column;gap:.7rem;min-width:0}
.ph{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem .7rem;min-height:1.5rem}
.cap,.key,.use{color:var(--muted);font-size:.72rem;margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pane{display:flex;flex-direction:column;gap:.3rem;min-width:0;min-height:0}

/* insight tiles */
.ins{margin:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:.5rem}
.ins>div{background:var(--surface);border:1px solid transparent;border-radius:10px;padding:.45rem .65rem;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:.5rem;align-items:baseline;min-width:0}
.ins dt{font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ins dd{margin:0}
.ins .v{font-family:var(--display);font-weight:600;font-size:1.02rem;text-align:right;white-space:nowrap}
.ins .d{grid-column:1/-1;font-size:.74rem;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ins>div[data-k]{cursor:pointer;position:relative}
.ins>div[data-k]::before{content:"";position:absolute;left:0;top:.5rem;bottom:.5rem;width:3px;border-radius:2px;background:var(--c);opacity:.9}

/* chart + map row */
.mid{display:grid;grid-template-columns:minmax(0,1fr);gap:.7rem}
.chart{position:relative;height:240px}
.chart svg{display:block;width:100%;height:100%;overflow:visible}
.chart .grid line{stroke:var(--line);stroke-width:1}
.chart .axis text{fill:var(--muted);font-size:10.5px;font-family:var(--body);font-variant-numeric:tabular-nums}
.chart .axis text.sel{fill:var(--fg);font-weight:600}
.chart .band{fill:var(--surface)}
.chart .series path{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart .xhair{stroke:var(--muted);stroke-width:1}
.chart .hit{fill:transparent;cursor:pointer}
.chart .hit:focus-visible{outline:none;stroke:var(--accent);stroke-width:2}
.tip{position:absolute;pointer-events:none;background:var(--bg);border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;font-size:.76rem;box-shadow:var(--shadow);min-width:180px;z-index:3}
.tip h3{margin:0 0 .25rem;font-size:.68rem;font-weight:500;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.tip .r{display:flex;align-items:baseline;gap:.4rem;line-height:1.5;white-space:nowrap}
.tip .k{display:inline-block;width:12px;height:2px;border-radius:1px;flex:none;transform:translateY(-3px)}
.tip strong{font-variant-numeric:tabular-nums;min-width:3.4rem}
.tip span.n{color:var(--muted)}
.tip .r.on strong,.tip .r.on span.n{color:var(--fg);font-weight:600}
.legend{display:flex;flex-wrap:wrap;gap:.1rem .55rem;font-size:.7rem;color:var(--muted);margin-left:auto}
.legend span,.legend button{display:inline-flex;align-items:center;gap:.28rem}
.legend button{font:inherit;font-size:.7rem;color:var(--muted);background:none;border:0;padding:0 .1rem;cursor:pointer}
.legend button:hover{color:var(--fg)}
.legend i{display:inline-block;width:11px;height:2px;border-radius:1px}
.legend i.hollow{width:7px;height:7px;border-radius:50%;border:2px solid var(--muted)}
.mapframe{border-radius:10px;overflow:hidden;background:var(--sea);position:relative;aspect-ratio:960/500}
.mapframe svg{display:block;width:100%;height:100%}
.land{fill:var(--land);stroke:var(--land-line);stroke-width:.5}
.pin{cursor:pointer}
.pin:focus-visible{outline:none}
.pin:focus-visible circle{stroke:var(--fg);stroke-width:2}
.views{display:flex;gap:.2rem;margin-left:auto}
.vbtn{border-radius:6px;padding:.1rem .45rem;font-size:.72rem}
.vbtn[aria-pressed="true"]{border-color:var(--accent);color:var(--accent);font-weight:600}
.info{position:absolute;left:.5rem;bottom:.5rem;max-width:calc(100% - 1rem);background:var(--bg);opacity:.96;border:1px solid var(--line);border-radius:8px;padding:.3rem .55rem;font-size:.72rem;line-height:1.4;box-shadow:var(--shadow)}
.info b{font-weight:600}
.info .dot{display:inline-block;width:.55rem;height:.55rem;border-radius:50%;margin-right:.3rem}

/* plan table */
.tablepane{display:flex;flex-direction:column;gap:.3rem;min-height:0;border-top:1px solid var(--line);padding-top:.6rem}
.tablepane .use{flex:1 1 120px;min-width:0}
.controls{display:flex;flex-wrap:wrap;gap:.3rem;align-items:center;margin-left:auto}
input{font:inherit;font-size:.78rem;padding:.2rem .6rem;border:1px solid var(--line);border-radius:6px;background:var(--surface);color:var(--fg);min-width:0;width:190px}
.scroll{overflow:auto;border:1px solid var(--line);border-radius:10px;min-height:0}
table{border-collapse:collapse;width:100%;min-width:820px;font-size:.8rem}
th{position:sticky;top:0;z-index:1;text-align:left;font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);background:var(--surface);padding:.35rem .7rem;border-bottom:1px solid var(--line);white-space:nowrap;font-weight:500}
td{padding:.3rem .7rem;border-bottom:1px solid var(--line);vertical-align:top;line-height:1.35}
tr:last-child td{border-bottom:0}
tbody tr{cursor:pointer}
tbody tr:hover td,tbody tr.hl td{background:var(--surface)}
tbody tr.dim td{opacity:.4}
.js .lvlc{display:none}
.lvl{font-size:.72rem;font-weight:600;color:var(--muted);font-variant-numeric:tabular-nums}
.prov{font-weight:600}
.plan{color:var(--muted);font-size:.75rem}
.price{font-family:var(--display);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
td.price{position:relative}
.price small{display:block;font-family:var(--body);font-weight:400;font-size:.7rem;color:var(--muted)}
.pbar{position:absolute;left:.7rem;bottom:2px;height:3px;border-radius:2px;width:calc((100% - 1.4rem) * var(--w,0));opacity:.85}
th.num,td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
td.num{color:var(--muted)}
.specs{font-variant-numeric:tabular-nums;white-space:nowrap}
.tag{display:inline-block;font-size:.64rem;font-weight:600;padding:.04rem .38rem;border-radius:4px;margin-left:.35rem}
.tag.nvme{background:var(--nvme-bg);color:var(--nvme)}
.tag.ssd{background:var(--ssd-bg);color:var(--ssd)}
.note{color:var(--muted);font-size:.75rem;min-width:160px}
.note div{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.empty{padding:1rem;text-align:center;color:var(--muted)}

/* tablet: chart and map side by side */
@media (min-width:640px){
  .mid{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}
  .mappane{border-left:1px solid var(--line);padding-left:.7rem}
}
/* desktop (900px+ wide, any height): the page never scrolls; only the plan list scrolls inside if space runs out */
@media (min-width:900px){
  html,body{height:100%}
  body{height:100vh;height:100dvh;overflow:hidden}
  .wrap{height:100%}
  .dash{flex:1 1 0;min-height:0}
  .mid{flex:1 1 0;min-height:140px}
  .chart{height:auto;flex:1 1 0;min-height:90px}
  .mapslot{flex:1 1 0}
  .mapframe{aspect-ratio:auto;flex:1 1 0;min-height:0}
  .tablepane{flex:0 1 auto;min-height:96px;max-height:46%;overflow:hidden}
  .scroll{flex:0 1 auto}
  /* one line per plan row */
  td br{display:none}
  .plan{margin-left:.4rem}
  .price small{display:inline-block;max-width:15rem;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;margin-left:.4rem}
  .note div{-webkit-line-clamp:1}
  #t td:nth-child(2){white-space:nowrap}
}
@media (min-width:900px) and (max-height:620px){
  .ins .d{display:none}
  .cap,.key{display:none}
}

/* linked highlight */
.chart [data-k],#pins [data-k],.legend [data-k]{transition:opacity .2s,stroke-width .2s}
.chart .dim,#pins .dim{opacity:.12}
.chart path.focus{stroke-width:3}
.legend .dim{opacity:.4}
.ins>div.dim{opacity:.5}
.ins>div.focus{border-color:var(--c)}

/* motion: entrances, button feedback, chart and data transitions */
@keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes pop{0%{transform:scale(0)}65%{transform:scale(1.3)}100%{transform:scale(1)}}
@keyframes glow{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 45%,transparent)}100%{box-shadow:0 0 0 8px transparent}}
@keyframes ping{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--c,var(--accent)) 50%,transparent)}100%{box-shadow:0 0 0 10px transparent}}
body,.dash,.pop,.tip,.info,input,.scroll,th,.ins>div{transition:background-color .3s,color .3s,border-color .3s,opacity .2s,transform .2s var(--ease),box-shadow .2s}
.bar{animation:fade .4s ease-out both}
.dash{animation:rise .55s var(--ease) both .05s}
.kpis,.chartpane,.mappane,.tablepane{animation:rise .5s var(--ease) both}
.kpis{animation-delay:.12s}.chartpane{animation-delay:.2s}.mappane{animation-delay:.26s}.tablepane{animation-delay:.32s}
.lvbtn,.chip,.pchip,.vbtn,.tbtn,.about summary,.legend button,.link{transition:background-color .2s,color .2s,border-color .2s,opacity .2s,transform .15s var(--ease),box-shadow .2s}
.lvbtn:hover,.chip:hover,.pchip:hover,.vbtn:hover,.tbtn:hover,.about summary:hover{transform:translateY(-1px);box-shadow:0 3px 10px rgba(0,0,0,.1);border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}
.lvbtn:active,.chip:active,.pchip:active,.vbtn:active,.tbtn:active,.legend button:active{transform:scale(.95);box-shadow:none}
.lvbtn[aria-pressed="true"],.chip[aria-pressed="true"]{animation:glow .5s ease-out}
.pchip i{transition:background-color .2s,transform .2s}
.pchip:hover i{transform:scale(1.25)}
.ins>div:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.ins>div:active{transform:scale(.98)}
.ins>div.ping{animation:ping .5s ease-out}
.pane h2{transition:color .2s}
.pane:hover h2,.tablepane:hover h2{color:var(--fg)}
.about[open] .pop{animation:rise .2s ease-out}
.tip:not([hidden]){animation:fade .12s ease-out}
.tip{transition:left .16s var(--ease)}
.info.fade{animation:rise .2s var(--ease)}
.chart .band{transition:transform .38s var(--ease)}
.chart .grid.fade,.chart .axis.fade{animation:fade .45s ease-out}
.chart .series.draw path,.chart path.draw{stroke-dasharray:1;animation:draw .8s cubic-bezier(.4,0,.2,1) both}
.chart .series.draw circle,.chart circle.draw{animation:fade .3s .55s both}
.chart circle.sel{transform-box:fill-box;transform-origin:center;animation:pop .45s var(--ease)}
.chart .series.draw circle.sel{animation:fade .3s .55s both}
#pins .pin{transform-box:fill-box;transform-origin:center;transition:transform .28s cubic-bezier(.34,1.56,.64,1),filter .2s}
/* dot magnification only in the maximized map; the dashboard map stays still on hover */
.mm-body #pins .pin:hover,.mm-body #pins .pin:focus-visible{transform:scale(3.2);filter:drop-shadow(0 0 1.2px var(--bg)) drop-shadow(0 1px 3px rgba(0,0,0,.45))}
#pins circle{transform-box:fill-box;transform-origin:center;transition:opacity .2s,transform .28s cubic-bezier(.34,1.56,.64,1)}
.mm-body #pins circle.focus{transform:scale(1.5)}
#pins .pin.pop{animation:pop .4s var(--ease) both}
.ins>div.rise,tbody tr.rise{animation:rise .35s var(--ease) both}
.pbar{transition:width .6s var(--ease),opacity .2s}
tbody tr td{transition:background-color .15s,opacity .15s}
/* maximized map: modal card */
.mapslot{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
.vbtn.icon{display:inline-flex;align-items:center;justify-content:center;padding:.18rem .4rem;line-height:0}
.mapmodal{padding:0;border:0;background:transparent;width:min(1500px,95vw);height:min(900px,90vh);max-width:none;max-height:none;overflow:visible;color:var(--fg)}
.mapmodal::backdrop{background:rgba(6,12,10,.5);backdrop-filter:blur(4px);animation:fade .3s ease-out}
.mapmodal.closing::backdrop{animation:fadeout .36s ease-in forwards}
@keyframes fadeout{to{opacity:0}}
.mm-card{width:100%;height:100%;background:var(--bg);border:1px solid var(--line);border-radius:18px;box-shadow:0 30px 80px rgba(0,0,0,.35);padding:.9rem 1rem;display:flex;flex-direction:column;gap:.55rem;will-change:transform}
.mm-card h2{font-size:.8rem;color:var(--fg)}
.mm-body{flex:1 1 0;min-height:0;display:flex;flex-direction:column}
.mm-body .mapframe{flex:1 1 0;min-height:0;aspect-ratio:auto}
.mm-views{margin-left:auto}
.mm-views .views{margin:0}
.mm-legend{display:flex;flex-wrap:wrap;gap:.25rem .4rem}
.mm-legend button{font:inherit;font-size:.74rem;display:inline-flex;align-items:center;gap:.3rem;padding:.12rem .5rem;border:1px solid var(--line);background:var(--surface);border-radius:999px;cursor:pointer;color:var(--fg);transition:opacity .2s,transform .15s var(--ease),border-color .2s}
.mm-legend button:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}
.mm-legend i{width:.55rem;height:.55rem;border-radius:50%;display:inline-block}
.mm-legend small{color:var(--muted)}
.mm-legend .dim{opacity:.45}
.mm-body .info{font-size:.8rem;padding:.45rem .7rem}
.mapmodal .key{white-space:normal}

/* city labels on the maximized map */
#labels{pointer-events:none}
#labels text{font-family:var(--body);font-weight:500;fill:var(--fg);stroke:var(--sea);stroke-linejoin:round;paint-order:stroke;opacity:.88}
#labels tspan.prov{font-weight:400;fill:var(--muted)}

/* modal zoom controls and pan cursor */
.mm-zoom{display:flex;align-items:center;gap:.2rem}
.mm-zoom .zl{min-width:2.6rem;text-align:center;font-size:.72rem;color:var(--muted);font-variant-numeric:tabular-nums}
.mm-body svg{cursor:grab;touch-action:none}
.mm-body svg.dragging{cursor:grabbing}
.mm-body svg.dragging .pin{pointer-events:none}
/* dashboard dots: plain pointer (click opens the maximized map); magnifier cursor only inside the maximized map */
#pins .pin{cursor:pointer}
.mm-body #pins .pin{cursor:zoom-in}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
}
