/* orble's UI kit for the pages sbxd renders. Tokens first, then one section per component; components.tmpl holds
   the markup each section styles. Light only. */

/* --- tokens ------------------------------------------------------------------------------------------------------ */
:root{--bg:#fbfaf7;--panel:#fff;--ink:#17161c;--ink-2:#46434f;--muted:#6c6878;--line:#e6e3ec;--line-2:#f2f0f5;
--accent:#5b3fd9;--accent-2:#4a31c0;--accent-soft:#efebff;--live:#1c8a50;--asleep:#a29eb2;--warn:#a45a00;
--tray:#f1eff5;--code-bg:#17161c;--code-ink:#ebe7f6;
--mono:"IosevkaLXETerm",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
--sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
--edge:rgb(23 22 28/.1);--edge-low:rgb(23 22 28/.17);
--lift:inset 0 1px 0 #fff,0 1px 1.5px rgb(23 22 28/.06);
--primary:#1d1c22;--primary-2:#0e0d12;
/* Two radii, both squircles where the browser draws them: --r-box for every box (panels, the menu, dialogs, row menus,
   code blocks, the terminal), --r-control for every control (buttons, fields, the amount tray, tiles, toasts).
   Pills and circles (the credit button, switches, the avatar, status dots) keep their shapes. */
--r-control:8px;--r-box:14px}
@supports (corner-shape:squircle){:root{--r-control:13px;--r-box:26px}
.panel,.menu,.modal,.rowmenu,pre,.term,
.btn,.icon,.toast,.amounts,.amounts>label,.custom .x,.features dt svg,.addkey textarea,.delete-account input,.slugrow input{
corner-shape:squircle}}

/* Iosevka Term (lxe's build, as on Pocket Model): every monospace place, code and the terminal blocks. */
@font-face{font-family:"IosevkaLXETerm";src:url("/fonts/IosevkaLXETerm-Regular.woff2") format("woff2");font-weight:400;
font-style:normal;font-display:swap}

/* --- base -------------------------------------------------------------------------------------------------------- */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scrollbar-color:#cfcad9 transparent}
body{margin:0;font:15px/1.55 var(--sans);color:var(--ink);background:var(--bg);caret-color:var(--accent)}
::selection{background:#ddd5ff;color:var(--ink)}
a{color:var(--accent);text-underline-offset:.18em;text-decoration-thickness:1px}a:hover{color:var(--accent-2)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
h1{font-size:1.75rem;line-height:1.2;letter-spacing:-.02em;margin:0 0 .5rem;text-wrap:balance}
h1.big{font-size:2.6rem;letter-spacing:-.03em;max-width:18ch;margin-bottom:.9rem}
h2{font-size:1.02rem;letter-spacing:-.005em;margin:2.75rem 0 .8rem}
p{margin:.5rem 0;max-width:68ch}.lead{font-size:1.12rem;color:var(--ink-2);max-width:56ch}
.muted{color:var(--muted)}.num{font-variant-numeric:tabular-nums}
code{font:.88em var(--mono)}p code{white-space:nowrap}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
svg.i{width:1.05rem;height:1.05rem;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;
stroke-linejoin:round}

/* --- layout: header, main, footer, the dashboard's rail ---------------------------------------------------------- */
.wrap{max-width:60rem;margin:0 auto;padding:0 1.25rem;display:flex;flex-direction:column;min-height:100vh;
min-height:100dvh}
header.top{display:flex;align-items:center;gap:1.5rem;height:3.75rem}
.brand{display:inline-flex;align-items:center;gap:.45rem;font-weight:700;font-size:1.25rem;letter-spacing:-.015em;
color:var(--ink);text-decoration:none;margin-right:auto}
.brand img{width:34px;height:34px;flex:none}
.brand:hover{color:var(--ink)}
/* The name: the word, with "alpha" in small muted type close under it, left-aligned. Both are trimmed to their capitals
   (cap height to baseline). Centering the pair as one block would leave the heavy word high and the light "alpha" low,
   so the pair is moved down until the word's capitals sit just above the logo's middle (their middle about 1.5 px above it)
   and "alpha" ends level with the bottom of the box drawing. */
.brand .name{display:flex;flex-direction:column;align-items:flex-start;gap:.13rem;translate:0 .13em}
.brand .word{text-box:trim-both cap alphabetic}
.brand .stage{font-size:.52rem;font-weight:500;letter-spacing:0;color:var(--muted);text-box:trim-both cap alphabetic}
.links{display:flex;align-items:center;gap:1.5rem}
.links a,.linkbtn{color:var(--ink-2);text-decoration:none;font-size:.93rem}
.links a{display:inline-flex;align-items:center;gap:.4rem}
.links a svg{width:1rem;height:1rem;color:var(--muted)}.links a[aria-current=page] svg{color:var(--ink)}
.links a:hover,.linkbtn:hover,.links a[aria-current=page]{color:var(--ink)}
.links a[aria-current=page]{font-weight:550}
.linkbtn{background:none;border:0;padding:0;font-family:inherit;cursor:pointer}
main{flex:1 0 auto;padding:2.25rem 0 4.5rem}
footer{color:var(--muted);font-size:.85rem;padding:1.5rem 0 2rem}
footer a{color:var(--muted);text-decoration:none}footer a:hover{color:var(--ink)}footer .sep{margin:0 .5rem;color:var(--line)}

/* --- button: .btn (text), .btn.primary, .btn.block, .icon (square, icon only), .icon.ghost ----------------------- */
.btn,.icon,.menu-btn{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--edge);
border-bottom-color:var(--edge-low);background:linear-gradient(#fff,#f8f7fa);box-shadow:var(--lift);
border-radius:var(--r-control);font-family:inherit;color:var(--ink);cursor:pointer;text-decoration:none;
-webkit-tap-highlight-color:transparent;transition:background .15s,border-color .15s,color .15s}
.btn{gap:.35rem;height:2rem;padding:0 .8rem;font-size:.87rem;font-weight:550}
.btn:hover{border-color:rgb(23 22 28/.16);border-bottom-color:rgb(23 22 28/.22);background:linear-gradient(#fff,#f3f1f7);color:var(--ink)}
.btn.primary{background:linear-gradient(#34333b,var(--primary));border-color:var(--primary-2);border-bottom-color:#000;
color:#fff;box-shadow:inset 0 1px 0 rgb(255 255 255/.16),0 1px 2px rgb(14 13 18/.35)}
.btn.primary:hover{background:linear-gradient(#2a2930,var(--primary-2));color:#fff}
.btn.block{display:flex;width:100%;height:2.4rem;font-size:.93rem}
.btn[disabled]{opacity:.5;cursor:default}
.icon{width:2rem;height:2rem;padding:0;color:var(--ink-2)}
.icon:hover{color:var(--accent);border-color:#d6cdfa;border-bottom-color:#c6bbf6;background:linear-gradient(#fff,var(--accent-soft))}
.icon[aria-pressed=true]{color:var(--accent);border-color:#cdc2f9;border-top-color:#bfb2f5;
background:var(--accent-soft);box-shadow:inset 0 1px 2px rgb(61 37 168/.2)}
.icon[aria-pressed=true]:hover{background:#e6e0ff}
.icon.ghost,.icon.ghost:hover{width:1.6rem;height:1.6rem;border:0;background:none;box-shadow:none}
.icon.ghost svg{width:.9rem;height:.9rem}

/* --- panel: the white card everything sits in -------------------------------------------------------------------- */
.panel{background:var(--panel);border:1px solid rgb(23 22 28/.075);border-top-color:rgb(23 22 28/.05);
border-bottom-color:rgb(23 22 28/.12);border-radius:var(--r-box);overflow:hidden;
box-shadow:0 1px 1px rgb(23 22 28/.03),0 2px 5px -3px rgb(23 22 28/.06),0 18px 36px -28px rgb(23 22 28/.22)}
.panel.pad{padding:1.25rem 1.35rem}.panel.pad>p:first-child{margin-top:0}.panel.pad>p:last-child{margin-bottom:0}
.empty{padding:1.5rem 1.25rem}.empty.row{display:flex;align-items:center;min-height:3.2rem;padding:.6rem .9rem}
/* The dashboard with no boxes: the line and the install commands' terminal on the page, without a panel around them. */
.no-boxes p{margin:0}.no-boxes .term{margin:.75rem 0 0}

/* --- toast: one short message centered at the bottom of the window, dark like the primary button (components.tmpl,
   ui.js): a green check for news, an amber "!" for a problem, then the text and a close button, on one center line. */
.toast{position:fixed;left:50%;bottom:1.5rem;z-index:40;display:flex;align-items:center;gap:.65rem;width:max-content;
max-width:min(36rem,calc(100vw - 1.5rem));min-height:2.75rem;padding:.4rem .45rem .4rem .85rem;
border:1px solid var(--primary-2);border-radius:var(--r-control);background:linear-gradient(#2c2b32,var(--primary));
color:#f3f1f7;font-size:.9rem;line-height:1.4;
box-shadow:inset 0 1px 0 rgb(255 255 255/.1),0 2px 6px rgb(14 13 18/.18),0 16px 36px -14px rgb(14 13 18/.55);
transform:translateX(-50%);animation:toast-in .24s cubic-bezier(.2,.8,.2,1)}
.toast.out{opacity:0;transform:translate(-50%,.5rem);transition:opacity .18s,transform .18s}
.toast>svg{flex:none;width:1.1rem;height:1.1rem}
.toast .t-ok{color:#5fcf8f;stroke-width:2.2}.toast .t-error{display:none;color:#eea155}
.toast.error .t-ok{display:none}.toast.error .t-error{display:block}
.toast .msg{flex:1;min-width:0;padding-block:.2rem}
.toast .icon.ghost{flex:none;width:1.9rem;height:1.9rem;color:rgb(243 241 247/.6);border-radius:var(--r-control)}
.toast .icon.ghost:hover{color:#fff;background:rgb(255 255 255/.08)}
@keyframes toast-in{from{opacity:0;transform:translate(-50%,.6rem)}}
@media (prefers-reduced-motion:reduce){.toast{animation:none}.toast.out{transition:none}}

/* --- lists: the boxes table, and the keys and apps lists ----------------------------------------------------- */
table{width:100%;border-collapse:collapse;font-size:.92rem}
th{font-weight:500;color:var(--muted);font-size:.8rem;text-align:left;padding:.6rem .9rem;border-bottom:1px solid var(--line-2)}
td{padding:.7rem .9rem;border-bottom:1px solid var(--line-2);vertical-align:middle}
td.right,th.right{text-align:right}

/* --- legal: the privacy policy, cookie policy and terms, in one column at reading width ------------------------- */
.legal{max-width:68ch}
.legal p{max-width:none}
.legal h2{margin:2.25rem 0 .6rem}
.legal ul{margin:.6rem 0;padding-left:1.25rem}
.legal li{margin:.4rem 0;padding-left:.15rem}
.legal li::marker{color:var(--muted)}
.legal table{margin:1rem 0;font-size:inherit}
.legal th,.legal td{padding:.55rem 1rem .55rem 0;vertical-align:top}
.legal th:last-child,.legal td:last-child{padding-right:0}
tr:last-child td{border-bottom:0}
.actions{display:flex;gap:.4rem;justify-content:flex-end}
tr[data-state=running] .when-asleep,tr:not([data-state=running]) .when-live{display:none}
tr[data-busy] .switch{opacity:.5;pointer-events:none}
.toolbar{display:flex;justify-content:flex-end;margin:0 0 .8rem}
.toolbar .btn svg,.btn.small svg{width:.95rem;height:.95rem}
.btn[aria-busy=true]{opacity:.7;pointer-events:none}
/* .btn.destructive: the solid red confirm button of a delete dialog (.btn.danger is Settings' outlined one). */
.btn.destructive{background:linear-gradient(#e0453a,#c9352b);border-color:#b02d24;border-bottom-color:#96261f;color:#fff;
box-shadow:inset 0 1px 0 rgb(255 255 255/.22),0 1px 2px rgb(150 38 31/.3)}
.btn.destructive:hover{background:linear-gradient(#d63d33,#bd3026);border-color:#a32a22;color:#fff}
.icon[data-delete]:hover{color:#c9352b;border-color:#f0c4c0;background:linear-gradient(#fff,#fdf0ef)}
.modal-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.1rem}
.modal p{margin:.35rem 0 0;font-size:.92rem}
.modal .error{color:#b02d24}
.rowmenu .item.danger,.rowmenu .item.danger svg{color:#c9352b}

/* --- switch: an on/off control (the box row's Keep awake) --------------------------------------------------- */
.switch{display:inline-flex;align-items:center;gap:.5rem;padding:0;border:0;background:none;font:inherit;font-size:.82rem;
color:var(--ink-2);cursor:pointer;-webkit-tap-highlight-color:transparent}
.switch .track{position:relative;flex:none;width:2rem;height:1.15rem;border-radius:999px;background:#d8d4e1;
box-shadow:inset 0 1px 2px rgb(23 22 28/.16);transition:background .15s}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;width:calc(1.15rem - 4px);height:calc(1.15rem - 4px);
border-radius:50%;background:#fff;box-shadow:0 1px 2px rgb(23 22 28/.3);transition:transform .15s}
.switch[aria-checked=true] .track{background:var(--accent)}
.switch[aria-checked=true] .track::after{transform:translateX(.85rem)}
.switch[aria-checked=true]{color:var(--ink)}
.switch:hover .track{background:#cbc6d8}.switch[aria-checked=true]:hover .track{background:var(--accent-2)}
.switch:focus-visible{outline:none}.switch:focus-visible .track{outline:2px solid var(--accent);outline-offset:2px}
#boxes td.st{width:1%;padding-right:0}
#boxes td.nm{width:1%;white-space:nowrap}
#boxes td.sshcell{width:100%;max-width:0}
#boxes td.awcell{width:1%;white-space:nowrap}
#boxes td.active{width:1%;white-space:nowrap;text-align:right;color:var(--muted);font-size:.84rem;font-variant-numeric:tabular-nums}
/* Trimmed to its x-height, so "now" is on the row's center line, and in "3h ago" the digits rise above it about as far as
   the g drops below. */
#boxes td.active time{display:block;text-box:trim-both ex alphabetic}
#boxes td.actcell{width:1%;padding-left:.4rem}
#boxes td.morecell{display:none}
/* An item alone in a cell is a block, so the cell centers its box, not a text line's baseline. */
#boxes td.st .state{display:grid}#boxes td.st form{display:flex}#boxes td.awcell .switch{display:flex}

/* --- rowmenu: a box row's ⋯ menu on phones (dashboard.tmpl), placed under its button by ui.js ---------------- */
.rowmenu{position:fixed;margin:0;padding:.3rem 0;min-width:12.5rem;background:#fff;border:1px solid var(--edge);
border-radius:var(--r-box);box-shadow:0 1px 2px rgb(23 22 28/.06),0 20px 40px -14px rgb(23 22 28/.3)}
.rowmenu:not(:popover-open){display:none}
.rowmenu .item{display:flex;align-items:center;gap:.65rem;width:100%;padding:.65rem 1rem;border:0;background:none;
font:inherit;font-size:.93rem;color:var(--ink);text-align:left;cursor:pointer}
.rowmenu .item:hover{background:#faf9fc}
.rowmenu .item svg{width:1.05rem;height:1.05rem;color:var(--muted)}
.rowmenu .item.switch{justify-content:space-between}
.rowmenu .item .lbl{flex:1}
.list{list-style:none;margin:0;padding:0}
.list li{display:flex;align-items:center;gap:1rem;min-height:3.1rem;padding:.6rem .9rem;border-bottom:1px solid var(--line-2)}
.list li:last-child{border-bottom:0}
.list .name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.keys .name{flex:none;max-width:55%}
.keys .fp{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right;
font:.82rem var(--mono);color:var(--muted)}
.apps .name{flex:1}
.apps .when{display:flex;gap:1.25rem;font-size:.86rem;white-space:nowrap}

/* --- state: a box's state as an icon (components.tmpl: state) -------------------------------------------------- */
.state{display:inline-grid;place-items:center;width:1.25rem;height:1.25rem;vertical-align:middle}
/* The dot is also a button: hovering a live box shows pause, a sleeping one play; a click does it. */
.state-btn{display:grid;place-items:center;width:1.7rem;height:1.7rem;margin:-.225rem;padding:0;border:0;
border-radius:50%;background:none;color:var(--ink-2);cursor:pointer;-webkit-tap-highlight-color:transparent}
.state-btn>*{grid-area:1/1}
.state-btn .s-pause,.state-btn .s-play{display:none;width:.95rem;height:.95rem}
.state-btn .s-play{fill:currentColor}
.state-btn:is(:hover,:focus-visible):has(.state.live,.state.asleep){background:var(--tray)}
.state-btn:is(:hover,:focus-visible) .state:is(.live,.asleep)::before{content:none}
.state-btn:is(:hover,:focus-visible):has(.state.live) .s-pause,
.state-btn:is(:hover,:focus-visible):has(.state.asleep) .s-play{display:block}
.state-btn:has(.state.busy,.state.error){cursor:default}
.state svg{display:none;width:1rem;height:1rem}
.state.live::before,.state.asleep::before{content:"";width:.55rem;height:.55rem;border-radius:50%}
.state.live::before{background:var(--live);box-shadow:0 0 0 3px rgb(28 138 80/.16)}
.state.asleep::before{background:var(--asleep)}
.state.busy .s-busy{display:block;color:var(--accent)}
.state.error .s-error{display:block;color:var(--warn)}
@media (prefers-reduced-motion:no-preference){
.state.live::before{animation:live 2.6s ease-out infinite}
.state.busy .s-busy{animation:spin .9s linear infinite}}
@keyframes live{0%{box-shadow:0 0 0 0 rgb(28 138 80/.35)}70%,100%{box-shadow:0 0 0 6px rgb(28 138 80/0)}}
@keyframes spin{to{transform:rotate(360deg)}}
/* A new box arrives at the top of the list: it fades and settles into place, and its row glows faintly green for a
   moment. A deleted one fades out before the rows below close up. */
#boxes tr.arrive{animation:row-in .45s cubic-bezier(.2,.8,.2,1)}
#boxes tr.arrive td{animation:row-glow 1.8s ease-out}
#boxes tr.leave{animation:row-out .22s ease-in forwards}
@keyframes row-in{from{opacity:0;transform:translateY(-8px) scale(.985)}}
@keyframes row-glow{from{background:rgb(28 138 80/.09)}}
@keyframes row-out{to{opacity:0;transform:scale(.985)}}
@media (prefers-reduced-motion:reduce){#boxes tr.arrive,#boxes tr.arrive td,#boxes tr.leave{animation:none}}
/* No SSH key yet: a short line and a small white button that opens the settings page's add-key dialog, centered
   under the boxes. The text and the button's label are trimmed to their capitals, so they share one center line. */
.nokeys{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:.5rem .75rem;margin:1.25rem 0 0;
font-size:.88rem;color:var(--muted)}
.nokeys>span,.nokeys .btn span{text-box:trim-both cap alphabetic}

/* --- copy: a command with a copy button -------------------------------------------------------------------------- */
.copyable{display:inline-flex;align-items:center;gap:.25rem;max-width:100%}
.copyable code{min-width:0;overflow:hidden;text-overflow:ellipsis;font:.86rem var(--mono);color:var(--ink-2);white-space:nowrap}
#boxes td.sshcell{width:100%;max-width:0}
.copy .i-check,.copy.done .i-copy{display:none}.copy.done .i-check{display:block}.copy.done{color:var(--live)}

/* --- credit: the balance and the amount picker ------------------------------------------------------------------- */
.credit{display:flex;align-items:center;justify-content:space-between;gap:.6rem}
/* Text in these rows is trimmed to cap height and baseline, so centering lines up the letters themselves. */
.credit .total,.credit .btn span,.menu .foot .who,.menu .foot .btn span{text-box:trim-both cap alphabetic}
.credit .total{font-size:.98rem;font-weight:600;font-variant-numeric:tabular-nums}
.credit .total.low,.topup .bal .low{color:var(--warn)}
.btn.small{height:1.75rem;padding:0 .65rem;font-size:.82rem}

/* --- modal: a dialog over the page (components.tmpl: topup) -------------------------------------------------- */
.modal{width:min(23rem,calc(100vw - 2rem));margin:auto;padding:1.15rem 1.25rem 1.1rem;border:1px solid var(--edge);
border-radius:var(--r-box);background:#fff;color:var(--ink);
box-shadow:0 1px 2px rgb(23 22 28/.06),0 32px 64px -20px rgb(23 22 28/.4)}
.modal::backdrop{background:rgb(23 22 28/.32);backdrop-filter:blur(2px)}
.modal-head{display:flex;align-items:center;justify-content:space-between;margin:-.25rem -.4rem .35rem 0}
.modal-head h2{margin:0;font-size:1.08rem}
.topup .bal{display:flex;justify-content:space-between;align-items:baseline;margin:0 0 .35rem;font-size:.9rem}
.topup .bal .num{font-weight:600}
@media (prefers-reduced-motion:no-preference){
.modal[open]{animation:modal-in .16s ease-out}
.modal[open]::backdrop{animation:fade-in .16s ease-out}}
@keyframes modal-in{from{opacity:0;transform:translateY(6px) scale(.98)}}
@keyframes fade-in{from{opacity:0}}
.topup{display:grid;gap:.6rem}
.amounts{position:relative;display:grid;grid-template-columns:repeat(3,1fr) 2.3rem;gap:2px;padding:2px;
border-radius:var(--r-control);background:var(--tray);box-shadow:inset 0 0 0 1px rgb(23 22 28/.06)}
.amounts>input[type=radio]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.amounts>label{display:flex;align-items:center;justify-content:center;height:2.1rem;border-radius:var(--r-control);
font-size:.88rem;font-weight:550;color:var(--ink-2);cursor:pointer;font-variant-numeric:tabular-nums;
-webkit-tap-highlight-color:transparent;transition:background .12s,color .12s,box-shadow .12s}
.amounts>label:hover{color:var(--ink)}
.amounts>input:checked+label{background:#fff;color:var(--ink);box-shadow:0 1px 2px rgb(23 22 28/.12),0 0 0 1px rgb(23 22 28/.06)}
.amounts>input:focus-visible+label{outline:2px solid var(--accent);outline-offset:1px}
.amounts .custom{display:none;grid-column:1/-1;align-items:center;height:2.1rem;padding:0 .2rem 0 .75rem;
border-radius:var(--r-control);background:#fff;box-shadow:0 1px 2px rgb(23 22 28/.12),0 0 0 1px rgb(23 22 28/.06)}
.amounts:has(.pick-custom:checked)>label{display:none}
.amounts:has(.pick-custom:checked) .custom{display:flex}
.amounts:has(.custom input:focus-visible) .custom{box-shadow:0 0 0 2px var(--accent)}
.custom .cur{color:var(--muted);font-weight:550}
.custom input{flex:1;min-width:0;height:100%;border:0;outline:0;background:none;padding:0 .2rem;font:550 .95rem var(--sans);
color:var(--ink);font-variant-numeric:tabular-nums;appearance:textfield;-moz-appearance:textfield}
.custom input::-webkit-inner-spin-button,.custom input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.custom .x{display:grid;place-items:center;width:1.8rem;height:1.8rem;border-radius:var(--r-control);color:var(--muted);cursor:pointer}
.custom .x:hover{color:var(--ink);background:var(--tray)}
.custom .x svg{width:.95rem;height:.95rem}
.topup .hint{margin:.1rem 0 0;font-size:.78rem;color:var(--muted);text-align:center}

/* --- menu: the credit button in the header, and what it opens: the credit, and on narrow screens the links --- */
.menu-btn{gap:.25rem;height:1.85rem;padding:0 .35rem 0 .65rem;border-radius:999px;font-size:.82rem;font-weight:550;
color:var(--ink-2);font-variant-numeric:tabular-nums;anchor-name:--menu}
.menu-btn:hover{border-color:rgb(23 22 28/.16);background:linear-gradient(#fff,#f3f1f7)}
.menu-btn svg{width:.95rem;height:.95rem;color:var(--muted)}
.menu-btn .low{color:var(--warn)}
/* Under a dollar of credit the button shows a "!" after the amount (dashboard.js toggles .low as the credit changes). */
.menu-btn .lowmark{display:none;width:.85rem;height:.85rem;margin-left:.1rem;color:var(--warn)}
.menu-btn:has(.num.low) .lowmark{display:block}
/* The credit went up: dashboard.js counts the amounts up and the button glows green for a moment. */
.menu-btn.gain{animation:gain-box 2.4s ease-out}
[data-credit].gain{animation:gain-text 2.4s ease-out}
@keyframes gain-box{0%,40%{border-color:rgb(28 138 80/.4);background:#ecf7f0;box-shadow:0 0 0 3px rgb(28 138 80/.12)}}
@keyframes gain-text{0%,40%{color:var(--live)}}
/* The price's box is trimmed to its digits (cap height to baseline), so centering puts the digits, not the font's
   line box, on the avatar's center line whatever the system font's metrics are. */
.menu-btn .num{text-box:trim-both cap alphabetic}
/* Below 2x, browsers draw text on a whole-pixel baseline, and the digits' ink is a little shorter than the font's cap
   height, so they landed half a pixel or more under the button's center line (Chromium and Firefox, and lxe's 1x
   screen). Half a pixel up puts them on it or, where their height can't center, half a pixel above. */
@media (max-resolution:1.99dppx){.menu-btn .num{position:relative;top:-.5px}}
.avatar{display:grid;place-items:center;flex:none;width:1.5rem;height:1.5rem;border-radius:50%;overflow:hidden;
background:var(--tray);color:var(--muted);font-size:.7rem;font-weight:650;line-height:1;
box-shadow:inset 0 0 0 1px rgb(23 22 28/.06)}
.avatar img{display:block;width:100%;height:100%;object-fit:cover}
.menu-btn .avatar{width:1.3rem;height:1.3rem;margin:0 .15rem 0 -.42rem}
.menu-btn .narrow,.menu .items a.narrow{display:none}
.menu{position:fixed;inset:3.25rem max(.75rem,calc((100vw - 60rem)/2 + 1.25rem)) auto auto;margin:0;padding:0;
width:min(18.5rem,calc(100vw - 1.5rem));max-height:calc(100dvh - 4.5rem);overflow:auto;color:var(--ink);
background:#fff;border:1px solid var(--edge);border-radius:var(--r-box);
box-shadow:0 1px 2px rgb(23 22 28/.06),0 28px 56px -16px rgb(23 22 28/.32)}
@supports (position-anchor:--menu){.menu{position-anchor:--menu;inset:auto;top:calc(anchor(bottom) + .45rem);right:anchor(right)}}
.menu:not(:popover-open):not(.open){display:none}
.menu .credit{padding:.9rem 1rem;border-bottom:1px solid var(--line-2)}
.menu .btn.block{height:2.15rem;font-size:.88rem}
.menu .items{display:none;padding:.3rem 0;border-bottom:1px solid var(--line-2)}
.menu .foot .settings{flex:none;width:1.75rem;height:1.75rem}
.menu .foot .settings svg{width:1rem;height:1rem}
.menu .foot .btn svg{width:.95rem;height:.95rem;color:var(--muted)}
.menu .items a{display:flex;align-items:center;gap:.65rem;padding:.55rem 1rem;color:var(--ink);text-decoration:none;
font-size:.93rem}
.menu .items a:hover{background:#faf9fc}
.menu .items a svg{width:1.05rem;height:1.05rem;color:var(--muted)}
.menu .items a[aria-current=page]{color:var(--accent);font-weight:550}
.menu .items a[aria-current=page] svg{color:var(--accent)}
.menu .foot{display:flex;align-items:center;gap:.7rem;padding:.7rem 1rem;font-size:.85rem;color:var(--muted)}
/* The email is trimmed to cap height like the other labels; the equal padding above and below gives its descenders
   and the @ room inside the box that clips it for the ellipsis, without moving its center. */
.menu .foot .who{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-block:.35em}
.menu .foot form{display:flex}
.keys li form{flex:none;margin:0}
#addkey{width:min(32rem,calc(100vw - 2rem))}
.addkey textarea{display:block;box-sizing:border-box;width:100%;min-height:7.5rem;margin:.4rem 0 .35rem;padding:.55rem .6rem;
resize:vertical;font:.82rem/1.45 var(--mono);color:var(--ink);background:#fff;border:1px solid var(--edge);
border-bottom-color:var(--edge-low);border-radius:var(--r-control);word-break:break-all}
.addkey textarea:focus{outline:2px solid var(--accent);outline-offset:1px}
.addkey .hint{margin:0 0 .9rem;font-size:.82rem;color:var(--muted)}
.section-head .btn svg{width:.95rem;height:.95rem}
/* delete-account: the warning on its own row, then the confirm field with the button to its right (on a phone, below
   it), at any width. */
.delete-account{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:.6rem 1rem;padding:.8rem .9rem}
.delete-account p{grid-column:1/-1;margin:0;color:var(--ink-2)}
.delete-account label{display:flex;align-items:center;gap:.6rem;min-width:0;font-size:.92rem}
.delete-account label span{flex:none;color:var(--muted)}.delete-account label b{color:var(--ink);font-weight:550}
.delete-account input{flex:1;min-width:0;height:2rem;padding:0 .45rem;font:.92rem var(--mono);color:var(--ink);
background:#fff;border:1px solid var(--edge);border-bottom-color:var(--edge-low);border-radius:var(--r-control)}
.delete-account input:focus{outline:2px solid var(--accent);outline-offset:1px}
@media (max-width:719px){.keys li form{align-self:flex-start;margin-top:.35rem}
.delete-account{grid-template-columns:minmax(0,1fr)}.delete-account .btn{justify-self:start}
.delete-account label{flex-direction:column;align-items:stretch;gap:.45rem}
.delete-account input{flex:none;height:2.3rem}}
.btn.danger{color:var(--warn)}.btn.danger:hover{color:#8a4300;border-color:#e8c9a8;background:linear-gradient(#fff,#fdf3e8)}
@media (prefers-reduced-motion:no-preference){
.menu{transition:opacity .14s,transform .14s,overlay .14s allow-discrete,display .14s allow-discrete;transform-origin:top right}
@starting-style{.menu:popover-open{opacity:0;transform:scale(.97) translateY(-4px)}}}

.cli-form,.consent{max-width:38rem;margin-top:1.25rem}
.decide{display:flex;gap:.5rem;margin:1.25rem 0 .75rem}
.slugrow{display:flex;align-items:center;gap:.1rem;max-width:26rem;font:.92rem var(--mono)}
.slugrow input{flex:1;min-width:0;height:2rem;padding:0 .45rem;font:inherit;color:var(--ink);background:#fff;
border:1px solid var(--edge);border-bottom-color:var(--edge-low);border-radius:var(--r-control)}
.slugrow input:focus{outline:2px solid var(--accent);outline-offset:1px}

/* --- content: landing, commands, pricing, legal ------------------------------------------------------------------ */
pre{font:13.5px/1.6 var(--mono);background:var(--code-bg);color:var(--code-ink);padding:1rem 1.15rem;
border-radius:var(--r-box);overflow-x:auto;margin:1.25rem 0;border:1px solid #0b0a0f;
box-shadow:inset 0 1px 0 rgb(255 255 255/.08),0 1px 2px rgb(23 22 28/.12),0 16px 32px -26px rgb(23 22 28/.45)}
pre .c{color:#8f8aa3}

/* --- term: a terminal window around a <pre> of prompts ($) and output ------------------------------------------ */
.term{margin:1.25rem 0;border-radius:var(--r-box);background:var(--code-bg);border:1px solid #0b0a0f;overflow:hidden;
box-shadow:inset 0 1px 0 rgb(255 255 255/.08),0 1px 2px rgb(23 22 28/.12),0 16px 32px -26px rgb(23 22 28/.45)}
.term-bar{display:flex;align-items:center;gap:.4rem;height:1.9rem;padding:0 .8rem;border-bottom:1px solid #26242e}
.term-bar i{width:.6rem;height:.6rem;border-radius:50%;background:#3a3843}
/* A command keeps one line. The text is 14px, smaller only where the block is too narrow for the longest command,
   "$ curl -fsSL https://orble.tech/install.sh | sh": 46.6 characters at half an em each (Iosevka), plus the padding.
   On phones the copy buttons go to make room (a tap on a command selects all of it), and anything longer still
   scrolls sideways inside the block. */
.term{container-type:inline-size}
.term pre{margin:0;border:0;border-radius:0;box-shadow:none;background:none;line-height:1.65;
font-size:min(14px,calc((100cqi - 2.3rem) / 23.4))}
.term .cmd{display:flex;align-items:center;gap:.6ch;min-height:1.65em}
/* The command selects as one piece: a click or a triple-click takes exactly it, without the prompt, spaces or the
   line break. */
.term .cmd-text{white-space:pre;user-select:all;text-box:trim-both cap alphabetic}
.term .cmd .p{text-box:trim-both cap alphabetic}
.term .cmd .copy{width:1.5rem;height:1.5rem;margin:-.2rem 0;color:#7d7891;user-select:none}
.term .cmd .copy:hover{color:#ebe7f6;background:rgb(255 255 255/.08)}.term .cmd .copy.done{color:#5fd39a}
.term .cmd .copy svg{width:.95rem;height:.95rem}
@media (max-width:640px){.term pre{padding-inline:.9rem;font-size:min(14px,calc((100cqi - 1.8rem) / 23.4))}
.term .cmd .copy{display:none}}
.term .ln{display:block;min-height:1.65em}
.term .p{color:#7d7891;user-select:none}.term .o{color:#8f8aa3}.term .ok{color:#5fd39a}
.term .host{color:#5fd39a}.term .dir{color:#8ab4f8}
.term .cursor{display:inline-block;width:.6em;height:1.15em;margin-bottom:-.2em;background:#ebe7f6}
@media (prefers-reduced-motion:no-preference){.term .cursor{animation:blink 1.1s steps(1) infinite}}
@keyframes blink{50%{opacity:0}}
.perks{display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;list-style:none;margin:0 0 .4rem;padding:0;color:var(--ink-2)}
.perks li{display:flex;align-items:center;gap:.5rem;line-height:1.3}
.perks svg{display:block;width:1.15rem;height:1.15rem;color:var(--muted)}
.features{margin-top:2rem}
.features dl{margin:0}
/* A feature: its icon tile, title and description. Title and description are trimmed to their capitals and baseline.
   Side by side, all three are centered on the row's middle line; stacked (two columns of plans, and phones), the tile hangs
   from the line where the title's capitals start, beside the title and the description under it. The row is at least
   as tall as the tile. */
.features dl>div{display:grid;grid-template-columns:14rem 1fr;align-items:center;gap:1rem;padding:.8rem 1.15rem;
min-height:calc(1.95rem + 1.6rem + 1px);border-bottom:1px solid var(--line-2)}
.features dl>div:last-child{border-bottom:0}
.features dt{position:relative;padding-left:2.7rem;font-weight:600;text-box:trim-both cap alphabetic}
.features dt svg{position:absolute;left:0;top:50%;translate:0 -50%;width:1.95rem;height:1.95rem;padding:.42rem;
border-radius:var(--r-control);background:var(--tray);color:var(--muted);stroke-width:1.7}
.features dd{margin:0;color:var(--ink-2);text-box:trim-both cap alphabetic}
.features.enterprise{max-width:44rem;margin-top:0}
/* Enterprise's rows have two lines of text with the tile hanging from the first; their text gets as much room above and
   below as the landing page's one-line rows, whose text is centered on the tile. */
.features.enterprise dl>div{padding-block:calc((1.95rem + 1.6rem - 1cap) / 2)}
/* section-head: a heading with an optional button or address beside it. The heading is trimmed to its capitals and
   padded to the height of a small button, so the gap above and below each heading is the same whatever sits beside
   it, including on a narrow screen, where what sits beside the heading moves to its own line. */
.section-head{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem .85rem;margin:2.75rem 0 .8rem}
.section-head h2{flex:none;margin:0;line-height:1.75rem}
@supports (text-box:trim-both cap alphabetic){
.section-head h2{text-box:trim-both cap alphabetic;padding-block:calc((1.75rem - 1cap)/2)}}
/* Connected apps has the MCP server's address beside it. Both are text, so they sit on one baseline. The address is
   trimmed like the heading, with room below for its descenders inside the box that clips it for the ellipsis. */
.section-head:has(> .mcp){align-items:baseline}
.section-head .mcp{display:flex;min-width:0}
.section-head .copyable{min-width:0}
.section-head .copyable code{text-box:trim-both cap alphabetic;padding-block:.3em}
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1.4rem 2.5rem;margin:2rem 0 0;padding:0}
.facts dt{font-weight:600}.facts dd{margin:.2rem 0 0;color:var(--ink-2)}
.cmds{display:grid;grid-template-columns:17.5rem 1fr;margin:0;padding:0;border-top:1px solid var(--line)}
.cmds dt,.cmds dd{padding:.62rem 0;border-bottom:1px solid var(--line-2)}
.cmds dt{font:.88rem/1.5 var(--mono);color:var(--ink);white-space:nowrap;padding-right:2rem}
.cmds dd{margin:0;color:var(--ink-2);font-size:.93rem}
/* plans: pay as you go, then Enterprise. On wide screens they sit in two columns, each panel as tall as its own rows;
   both headings are 2rem tall (one has a button), so the two panels start on one line. */
.plans .section-head{min-height:2rem}
.prices-panel{max-width:44rem}
@media (min-width:860px){
.plans{display:grid;grid-template-columns:1fr 1fr;column-gap:2rem;align-items:start;margin-top:2.25rem}
.plans .section-head{margin-top:0}
.plans .prices-panel,.plans .features.enterprise{max-width:none}
.plans .features dl>div{grid-template-columns:1fr;align-items:start;gap:.6rem}.plans .features dd{padding-left:2.7rem}
.plans .features dt svg{top:0;translate:none}}
/* price-row: what (a name) on the left, its price on the right, both centered on the row's middle line.
   price-row.lines, for a box: two lines, each split left and right: the name with the per-second price, then the specs
   (as icons) with the hourly price. Each line shares its width only with its own price, so the specs stay on one line
   in the two-column layout, where the per-second price alone is about half the panel.
   Below 32rem every price goes under its name: on phones the box's order is name, specs, then both prices. */
.price-row{display:flex;align-items:center;justify-content:space-between;gap:.4rem 1.5rem;
padding:.95rem 1.1rem;border-bottom:1px solid var(--line-2)}
.price-row:last-child{border-bottom:0}
.price-row .what,.price-row .cost{display:flex;flex-direction:column;gap:.3rem}
.price-row .what b,.price-row .cost b{font-weight:550}
.price-row .what{flex:1 1 auto;min-width:0}
.price-row .cost{flex:none;align-items:flex-end;text-align:right;white-space:nowrap}
.price-row .per{color:var(--muted);font-size:.85rem}
.price-row.lines{display:block}
.price-row .line{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
.price-row .line+.line{align-items:center;margin-top:.3rem}
.price-row .line b{font-weight:550}.price-row .line .price,.price-row .line .per{white-space:nowrap}
.specs{display:flex;flex-wrap:wrap;align-items:center;gap:.3rem .9rem;color:var(--ink-2);font-size:.85rem;white-space:nowrap}
.specs>span{display:inline-flex;align-items:center;gap:.3rem}
.specs svg{width:1rem;height:1rem;color:var(--muted)}

/* --- narrow screens --------------------------------------------------------------------------------------------- */
@media (max-width:719px){
header.top.has-menu .links{display:none}
.menu-btn .wide{display:none}.menu-btn .narrow{display:block}.menu .items a.narrow{display:flex}.menu .items{display:block}
.menu{width:min(21rem,calc(100vw - 1.5rem))}}
@media (max-width:32rem){
.price-row{flex-direction:column;align-items:stretch}
.price-row .cost{flex-direction:row;align-items:baseline;justify-content:flex-start;gap:.5rem;text-align:left}
.price-row.lines{display:flex;flex-wrap:wrap;align-items:baseline;gap:.3rem .5rem}.price-row.lines .line{display:contents}
.price-row.lines .name,.price-row.lines .specs{flex-basis:100%}
.price-row.lines .name{order:1}.price-row.lines .specs{order:2}.price-row.lines .price{order:3}.price-row.lines .per{order:4}}
@media (max-width:640px){
h1.big{font-size:2rem}.hide-sm{display:none}
.cmds{grid-template-columns:1fr}.cmds dt{border-bottom:0;padding-bottom:0}.cmds dd{padding-top:.15rem}
.features dl>div{grid-template-columns:1fr;align-items:start;gap:.6rem}.features dd{padding-left:2.7rem}
.features dt svg{top:0;translate:none}
#boxes tr{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"st nm act more" "ssh ssh ssh ssh";
align-items:center;gap:.3rem .55rem;padding:.75rem .8rem .8rem;border-bottom:1px solid var(--line-2)}
#boxes tr:last-child{border-bottom:0}
#boxes td{display:block;width:auto!important;max-width:none!important;padding:0;border:0}
#boxes td.st{grid-area:st}#boxes td.nm{grid-area:nm}#boxes td.actcell{grid-area:ac}
#boxes td.awcell{grid-area:aw}#boxes td.nm{min-width:0;overflow:hidden;text-overflow:ellipsis;text-align:left}
#boxes td.awcell,#boxes td.actcell{display:none}
#boxes td.morecell{display:block;grid-area:more;margin:-.3rem -.35rem -.3rem 0}
#boxes td.sshcell{grid-area:ssh;min-width:0}#boxes td.active{grid-area:act}
.keys li{flex-direction:column;align-items:stretch;gap:.1rem}.keys .name{max-width:none}.keys .fp{text-align:left}
.apps li{flex-wrap:wrap;gap:.15rem .75rem}.apps .name{flex:1 1 60%}.apps .when{order:3;flex-basis:100%;gap:1rem}
.apps .when .added{display:none}.apps form{margin-left:auto}}
@media (max-width:440px){header.top{gap:1rem}.links{gap:1rem}.brand .word{display:none}.brand .name{translate:none}}
