:root{--bg:#0f1522;--rail:#0b101b;--panel:#151d2d;--panel2:#101827;--line:#232c3f;
 --line2:#1d2636;--ink:#d7dee9;--bright:#f2f6fc;--muted:#8a97ab;--dim:#8391a8;
 --green:#58d68d;--green-bg:#10331f;--amber:#f0c064;--amber-bg:#3a2d10;
 --red:#e0654f;--red-bg:#4d2323;--blue:#7fb4ff;--blue-bg:#16324f;--violet:#c9b8f0;
 --violet-bg:#2c1f3d;--accent:#2563c4;--accent-hi:#2f74e0;--focus:#7fb4ff;
 --sans:'IBM Plex Sans',system-ui,sans-serif;
 --mono:'IBM Plex Mono',ui-monospace,monospace}
*{box-sizing:border-box}
html{color-scheme:dark}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);
 font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:var(--blue);text-decoration:none} a:hover{color:#a8ccff}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion:no-preference){
 a,button,.btn,input,textarea,select,tr{transition:background-color .12s,
  border-color .12s,color .12s}}
.shell{display:flex;min-height:100vh}
/* ---- the rail */
nav{width:224px;flex-shrink:0;background:var(--rail);border-right:1px solid
 var(--line2);
 padding:22px 12px 16px;display:flex;flex-direction:column;gap:3px;position:sticky;
 top:0;height:100vh}
nav .brand{display:flex;align-items:center;gap:10px;font-weight:600;font-size:15px;
 letter-spacing:.4px;color:#eef3fa;padding:2px 12px 22px}
nav .brand svg{flex-shrink:0}
nav a{display:flex;align-items:center;gap:11px;height:40px;padding:0 12px;
 border-radius:7px;color:#9aa7ba;font-size:14px;position:relative}
nav a svg{width:17px;height:17px;flex-shrink:0;opacity:.85}
nav a:hover{color:#fff;background:#141c2b}
nav a.here{background:#1a2334;color:#fff;font-weight:500}
nav
 a.here::before{content:"";position:absolute;left:-12px;top:10px;bottom:10px;width:3px;
 border-radius:0 3px 3px 0;background:#4f8ef7}
nav a .n{margin-left:auto;font-family:var(--mono);font-size:12px;color:var(--dim)}
nav a .n.hot{min-width:20px;height:20px;display:flex;align-items:center;
 justify-content:center;border-radius:10px;background:var(--amber-bg);
 color:var(--amber);font-weight:500}
nav form{margin-top:auto;display:flex;align-items:center;gap:10px;padding:14px 8px 0;
 border-top:1px solid var(--line2)}
nav form .av{width:30px;height:30px;border-radius:15px;background:#24314a;display:flex;
 align-items:center;justify-content:center;font-size:13px;font-weight:600;color:#b9cae6;
 flex-shrink:0;text-transform:uppercase}
nav form span.who{color:#b9c4d4;font-size:13px;overflow:hidden;text-overflow:ellipsis;
 white-space:nowrap}
nav form button{margin-left:auto;background:none;border:0;color:var(--dim);
 font-size:12px;cursor:pointer;font-family:inherit;padding:6px 8px;border-radius:5px}
nav form button:hover{color:#fff;background:#141c2b}
/* ---- the phones table, standing in its own panel */
.slab{background:var(--panel);border:1px solid var(--line);border-radius:10px;
 overflow:hidden}
.slab>.tscroll{margin:0}
.slab table{margin:0}
.slab thead th{background:var(--panel2);border-bottom:1px solid var(--line);
 font-size:10.5px;letter-spacing:.9px;text-transform:uppercase;
 color:var(--dim);font-weight:500;padding:10px 15px;white-space:nowrap}
.slab tbody td{padding:11px 13px;border-bottom:1px solid var(--line2)}
/* The three narrow ones shrink to their words so the two address columns
   keep the width. Without this the row runs past its box and the last
   button - the one a person came for - is the half that is cut off. */
.slab td:nth-child(5),.slab td:nth-child(6),.slab th:nth-child(5),
.slab th:nth-child(6){width:1%;white-space:nowrap}
.slab thead th:first-child,.slab tbody td:first-child{width:1%}
.slab tbody tr:last-child td{border-bottom:0}
.slab tbody tr:hover{background:#141c2b}
.slab td.act{text-align:right;white-space:nowrap}
.slab td.act form{display:inline}
.slab .addr{font-family:var(--mono);font-size:12.5px;display:block;
 max-width:17ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (min-width:1500px){.slab .addr{max-width:24ch}}
.nowrap{white-space:nowrap}
/* A dot before the word, so a state reads as a state from a distance
   and not as one more piece of text in a row made of text. */
.slab .badge::before{content:"";display:inline-block;width:5px;height:5px;
 border-radius:50%;background:currentColor;margin-right:6px;
 vertical-align:middle}
.slab .badge.running::before{margin-right:6px}
/* Every button in a row, one size and one rhythm. The exit button wore
   the amber of a warning and is not one: it is the ordinary thing you do
   to a phone whose way out is refused. */
.slab td.act button,.slab td.act .btn{padding:5px 9px;font-size:12px;
 border-radius:7px;margin-left:4px}
.slab thead th:last-child,.slab td.act{padding-right:15px}
/* ---- the pool cards on the rail, and the manager they open */
.pool{background:var(--panel);border:1px solid var(--line);border-radius:10px;
 overflow:hidden}
.pool>header{display:flex;align-items:center;gap:11px;padding:13px 15px 11px}
.pool>header b{font-family:var(--mono);font-size:27px;line-height:1;
 font-weight:500;letter-spacing:-.5px;font-variant-numeric:tabular-nums;
 min-width:34px}
.pool>header .t{display:flex;flex-direction:column;font-size:13.5px;
 font-weight:600;color:#c6d1e0;line-height:1.25}
.pool>header .t i{font-style:normal;font-size:11.5px;font-weight:400;
 color:var(--dim)}
.pool>header .go,.pool>header .lock{margin-left:auto}
.go.small{padding:5px 11px;font-size:12.5px}
.pool .queue{list-style:none;margin:0;padding:0;border-top:1px solid var(--line2);
 max-height:176px;overflow-y:auto;overscroll-behavior:contain}
.pool .queue li{display:flex;align-items:center;gap:8px;padding:6px 15px;
 font-size:12px}
.pool .queue li+li{border-top:1px solid var(--line2)}
.pool .queue .t{font-family:var(--mono);color:var(--muted);overflow:hidden;
 text-overflow:ellipsis;white-space:nowrap}
.pool .queue .t{flex:1;min-width:0;display:flex;align-items:baseline}
/* The name first and whole, the domain after it and clipped: every row
   in a 314px card ended in an ellipsis where the name should be, and
   the name is what tells one account from another (the operator,
   2026-09-18). The two halves are drawn alike on purpose - it is one
   address, and the domains are not all the same one, so neither half
   is decoration. The split decides only which end clips.
   `inherit` and `normal`, not nothing: b and i are bold and italic to
   a browser left to itself, and the point here is that they are not. */
.pool .queue .t b{font-weight:inherit;max-width:70%;overflow:hidden;
 text-overflow:ellipsis;flex:0 0 auto}
.pool .queue .t i{font-style:normal;min-width:0;
 overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
/* The kind, as the mark alone. The word costs half the row and the
   shape is the same one the split above and the sheet below wear: a
   circle for normal, a triangle for error (2026-09-18). */
.pool .queue .cat.dot{background:none;padding:0;gap:0;border-radius:0;
 flex-shrink:0}
.pool .queue .tag{margin-left:auto;font-size:11px;color:var(--dim);
 white-space:nowrap}
.pool .queue form{margin-left:auto;display:inline;flex-shrink:0}
.pool .queue form button{padding:2px 8px;font-size:11px;border-radius:5px;
 white-space:nowrap}
.pool .railnote{margin:0;padding:9px 15px;font-size:11.5px;color:var(--dim);
 border-top:1px solid var(--line2)}
.pool .railnote.bad,.pool .railnote.warn{font-weight:500}
.pool .railnote.bad{color:var(--red)} .pool .railnote.warn{color:var(--amber)}
.pool .railnote.bad::before,.pool .railnote.warn::before{content:"! ";
 font-family:var(--mono);font-weight:600}
.pool .more{display:block;width:100%;background:none;border:0;
 border-top:1px solid var(--line2);color:var(--blue);padding:9px;
 cursor:pointer;font:inherit;font-size:12px}
.pool .more:hover{background:#141c2b;color:#a8ccff}
.ov{position:fixed;inset:0;background:rgba(4,7,13,.72);display:flex;
 align-items:center;justify-content:center;padding:24px;z-index:40}
[hidden]{display:none!important}
.ov .sheet{background:var(--panel);border:1px solid var(--line);
 border-radius:12px;width:min(940px,100%);max-height:88vh;display:flex;
 flex-direction:column;box-shadow:0 24px 70px rgba(0,0,0,.55)}
.ov .sheet>header{display:flex;align-items:center;gap:12px;padding:15px 18px;
 border-bottom:1px solid var(--line)}
.ov .sheet>header h3{font-size:16px}
.ov .sheet .x{margin-left:auto;background:none;border:0;color:var(--muted);
 font-size:22px;line-height:1;cursor:pointer;padding:0 4px}
.ov .sheet .x:hover{color:var(--bright)}
.sheetbody{overflow:auto;padding:15px 18px}
/* A sheet showing a page of its own - a preview, a confirm. It was
   `.sub`, which is also the subtitle class, so the whole body was capped
   at 78ch and coloured muted: the preview sat in two thirds of the sheet
   with its table cut off at the edge (the operator, 2026-09-08). */
.sheetbody.shown{display:flex;flex-direction:column;gap:12px}
.sheetbody.shown>*{width:100%;max-width:none;margin:0}
.sheetbody.shown .top,.sheetbody.shown .narrow>.top,
.sheetbody.shown .alerts{display:none}
/* The edit-and-preview-again box of the preview page is the paste box the
   sheet already has - Back returns to it with the paste still in it. */
.sheetbody.shown form[action$="/preview"],
.sheetbody.shown .panel:has(form[action$="/preview"]){display:none}
.sheetbody.shown .panel .row{justify-content:flex-end;gap:8px}
.sheetbody.shown .panel .row .right{display:none}
.sheetbody.shown .panel .row .dim{margin-right:auto}
/* The preview: one card, the table scrolling inside it rather than
   pushing the whole sheet sideways (2026-09-08). */
.preview .lede{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.preview .wrap{overflow-x:auto}
.preview th,.preview td{white-space:nowrap}
.preview td:first-child{color:var(--ink)}
form.busy{cursor:progress}
form.busy button{opacity:.45;filter:grayscale(1);pointer-events:none}
/* The rows a press is working on. Dimmed, not hidden: what is happening
   is happening to these, and a row that vanished mid-press would read as
   done (2026-09-14). */
tr.acting{opacity:.45;transition:opacity .12s}
tr.acting td{cursor:progress}
/* A row a press moved out from under the chip being looked at. It is
   kept for one sift wearing where it went, rather than vanishing on the
   spot - which is what "I could not tell whether it worked" was made of
   (the operator, 2026-09-20). */
tr.moved{background:var(--green-bg)}
.movedto{display:inline-block;margin-left:8px;padding:1px 7px;
 border-radius:999px;background:var(--green-bg);color:var(--green);
 font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;
 vertical-align:middle}
.addbox{background:var(--panel2);border:1px solid var(--line);
 border-radius:9px;padding:12px;margin-bottom:14px}
.addbox label{display:block;font-size:11px;letter-spacing:.6px;
 text-transform:uppercase;color:var(--dim);margin-bottom:7px}
.addbox textarea{width:100%}
/* Which kind of Spotify account a paste is: two tiles, not a dropdown.
   The two go on different kinds of phone, so the rule for each is
   written on the tile rather than hidden in an option list, and each
   wears the mark its rows wear in the table (2026-09-17). */
.kindpick{display:flex;gap:10px}
.kindpick input{position:absolute;width:1px;height:1px;opacity:0}
.addbox .kindpick label{flex:1 1 0;min-width:0;display:block;margin:0;
 padding:9px 11px;border:1px solid var(--line);border-radius:9px;
 background:var(--bg);cursor:pointer;text-transform:none;letter-spacing:0;
 font-size:12px}
.kindpick label b{display:flex;align-items:center;gap:7px;
 font-family:var(--mono);font-size:12.5px;font-weight:600;color:var(--muted)}
.kindpick label b::before{content:"";width:8px;height:8px;
 background:currentColor}
.kindpick label.normal b::before{border-radius:50%}
.kindpick label.error b::before{clip-path:polygon(50% 0,100% 100%,0 100%)}
/* The two GPT tiles: a square for the kind this pool has always held,
   the same square its rows wear in the phones table, and a ring for an
   eco account - an address with a hole where the password was. */
.kindpick label.plain b::before{border-radius:2px}
.kindpick label.eco b::before{border-radius:50%;background:none;
 box-shadow:inset 0 0 0 2px currentColor}
.kindpick label i{display:block;font-style:normal;font-size:11px;
 color:var(--dim);margin-top:4px}
.kindpick label:hover{border-color:#3d4f6e}
.kindpick input:checked+label.normal{border-color:#2a6b55;background:#0f2a22}
.kindpick input:checked+label.normal b{color:#4fd1a5}
.kindpick input:checked+label.error{border-color:#7a5320;background:#2b1f10}
.kindpick input:checked+label.error b{color:#f2a35c}
.kindpick input:checked+label.plain{border-color:#33507d;background:#101b2c}
.kindpick input:checked+label.plain b{color:#8ab4f8}
.kindpick input:checked+label.eco{border-color:#2a6b55;background:#0f2a22}
.kindpick input:checked+label.eco b{color:#4fd1a5}
.kindpick input:focus-visible+label{outline:2px solid var(--blue);
 outline-offset:2px}
.addbox .addrow{display:flex;align-items:center;gap:10px;margin-top:9px;
 font-size:11.5px}
.filters{display:flex;align-items:center;gap:7px;flex-wrap:wrap;
 margin-bottom:10px}
.filters .poolfind{min-width:190px}
.filters .tally{margin-left:auto;font-size:11.5px}
.filters .pill{background:var(--panel2);border:1px solid var(--line);
 color:var(--muted);padding:4px 11px;border-radius:999px;cursor:pointer;
 font:inherit;font-size:12px}
.filters .pill[aria-pressed=true]{background:var(--blue-bg);
 border-color:#2c4d80;color:#a8ccff}
.filters .pill b{font-weight:600;margin-left:4px;font-variant-numeric:tabular-nums}
.filters .chips{gap:5px;margin-right:4px}
/* The kind chips, Spotify only: their own two colours and their own two
   marks, so a chip and the rows it shows read as the same thing. Set
   off from the status chips by a rule - they are two questions, asked
   side by side (2026-09-17). */
.filters .chips.kinds{margin-left:3px;padding-left:10px;
 border-left:1px solid var(--line2)}
.filters .pill.kind::before{content:"";display:inline-block;width:7px;
 height:7px;background:currentColor;margin-right:6px}
.filters .pill.kind.normal{color:#4fd1a5}
.filters .pill.kind.normal::before{border-radius:50%}
.filters .pill.kind.error{color:#f2a35c}
.filters .pill.kind.error::before{clip-path:polygon(50% 0,100% 100%,0 100%)}
/* The two GPT chips, wearing the marks their tiles wear: a square for
   the kind this pool has always held, a ring for an eco account. */
.filters .pill.kind.standard{color:#8ab4f8}
.filters .pill.kind.standard::before{border-radius:2px}
.filters .pill.kind.eco{color:#4fd1a5}
.filters .pill.kind.eco::before{border-radius:50%;background:none;
 box-shadow:inset 0 0 0 2px currentColor}
.filters .pill.kind.standard[aria-pressed=true]{background:#16243a;
 border-color:#33507d}
.filters .pill.kind.eco[aria-pressed=true]{background:#0f3a2c;
 border-color:#2a6b55}
.filters .pill.kind.normal[aria-pressed=true]{background:#0f3a2c;
 border-color:#2a6b55}
.filters .pill.kind.error[aria-pressed=true]{background:#3d2a12;
 border-color:#7a5320}
table.pooltable td{vertical-align:middle}
table.pooltable .doors{display:flex;gap:6px;justify-content:flex-end}
table.pooltable .doors form{display:inline}
/* The row editor is a dialog of its own, in the top layer, one per
   sheet: it used to be a row of six boxes squeezed under the row, with
   the password and the key blanked - a form for retyping, not for
   correcting (the operator, 2026-09-08). */
dialog.editor{background:var(--panel);color:var(--ink);border:1px solid
 var(--line2);border-radius:12px;padding:0;width:min(560px,calc(100vw - 32px));
 box-shadow:0 24px 70px rgba(0,0,0,.6)}
dialog.editor::backdrop{background:rgba(4,7,13,.6)}
dialog.editor form{display:flex;flex-direction:column;gap:12px;padding:16px 18px}
dialog.editor header{display:flex;align-items:baseline;gap:10px;
 padding-bottom:12px;border-bottom:1px solid var(--line2)}
dialog.editor h4{margin:0;font-size:14px;font-weight:600;color:var(--bright)}
dialog.editor header .mono{color:var(--muted);font-size:12.5px;overflow:hidden;
 text-overflow:ellipsis;white-space:nowrap;min-width:0}
dialog.editor .field input,dialog.editor .field select{width:100%;height:36px;
 font-family:var(--mono);font-size:12.5px}
dialog.editor .two{display:grid;gap:10px;
 grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
dialog.editor .tick{display:flex;align-items:center;gap:8px;font-size:12.5px;
 color:var(--muted)}
dialog.editor .tick input{accent-color:var(--accent);width:15px;height:15px}
/* What the editor was told, inside the editor. */
.editsay{margin:0;padding:9px 11px;border-radius:8px;font-size:12.5px;
 background:var(--panel2);border:1px solid var(--line2);color:var(--muted)}
.editsay.bad{background:#2a1512;border-color:#57241c;color:#f0a094}
/* And its own confirm, inside it too: a modal dialog is in the top
   layer and its backdrop takes every click underneath, so a `.mini`
   bubble hanging off the body would be drawn behind it and could not
   be pressed. */
dialog.editor .editask{position:static;width:auto;margin:0 18px 16px;
 box-shadow:none}
dialog.editor .row{justify-content:flex-end;padding-top:4px}
dialog.editor .row button{height:36px}
/* ---- polish, from the contract (2026-09-05): nothing here changes what a
   thing does; each rule is what makes the page feel finished. */
::selection{background:var(--blue-bg);color:#fff}
*{scrollbar-width:thin;scrollbar-color:var(--line2) transparent}
*::-webkit-scrollbar{width:8px;height:8px}
*::-webkit-scrollbar-thumb{background:var(--line2);border-radius:8px}
.mono,.serial,.addr,.age,.pool>header b,.queue .t,.queue .tag,.status{
 font-variant-numeric:tabular-nums}
button:active,.btn:active{transform:translateY(1px)}
input,select,textarea{color-scheme:dark}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--blue);
 box-shadow:0 0 0 3px var(--blue-bg)}
/* Sticky needs a scrollport to stick inside. `.tscroll` was the nearest
   one and it only scrolls sideways - no height, so it never scrolled down
   and the headers never stuck, in a table of a hundred and ninety rows
   (2026-09-07). And a sticky header needs its own background, or the rows
   pass through the column names. */
.slab thead th,.pooltable thead th{position:sticky;top:0;z-index:1}
.pooltable thead th{background:var(--panel2)}
.slab>.tscroll{max-height:calc(100vh - 260px);overflow:auto}
.slab th.num,.slab td.num{text-align:right}
.slab tbody tr:hover .addr{color:var(--ink)}
.status .live{animation:breathe 1.6s ease-in-out infinite;display:inline-block}
@keyframes breathe{50%{opacity:.35}}
.slab .badge.info::before{animation:blink 1.2s ease-in-out infinite}
@keyframes blink{50%{opacity:.2}}
.slab td.progress{position:relative;padding-bottom:14px}
.slab td.progress::after{content:"";position:absolute;left:15px;right:15px;
 bottom:8px;height:2px;background:linear-gradient(90deg,transparent,var(--blue),
 transparent);background-size:40% 100%;animation:slide 1.6s linear infinite}
@keyframes slide{from{background-position:-40% 0}to{background-position:140% 0}}
.pool>header .go{background:transparent;color:var(--blue);
 border:1px solid #2c4d80}
.pool>header .go:hover{background:var(--blue-bg);border-color:var(--blue)}
.pool .queue li:hover{background:#141c2b}
.byhand .field input,.byhand button.go{height:38px}
.byhand.js details.newone[open]{display:flex;flex-wrap:wrap;gap:10px;
 align-items:center;padding:10px 12px;background:var(--panel2);
 border:1px dashed #2c4d80;border-radius:8px}
.byhand.js details.newone[open] summary{display:none}
.byhand details.newone .lead{font-size:12px;color:var(--dim)}
.byhand details.newone input{margin:0;width:200px}
.byhand input:disabled,.byhand select:disabled{opacity:.45}
.maker{display:block;font-size:11px;margin-top:3px;white-space:nowrap}
/* What is signed in on the phone, under the word for what the phone is:
   a square for GPT, a circle for a normal Spotify account, a triangle
   for an error one - the marks the pool wears (2026-09-17). */
.carries{display:block;font-family:var(--mono);font-size:11px;margin-top:3px;
 white-space:nowrap;color:var(--dim)}
.carries::before{content:"";display:inline-block;width:6px;height:6px;
 background:currentColor;margin-right:5px}
.carries.normal{color:#4fd1a5} .carries.normal::before{border-radius:50%}
.carries.error{color:#f2a35c}
.carries.error::before{clip-path:polygon(50% 0,100% 100%,0 100%)}
/* The other two products a phone can carry: a ring for an eco account,
   the same ring its tile and its chip wear, and one colour of its own
   for Claude so it is never read as a ChatGPT phone. */
.carries.eco{color:#4fd1a5}
.carries.eco::before{border-radius:50%;background:none;
 box-shadow:inset 0 0 0 2px currentColor}
.carries.claude{color:#c9905c}
.carries.claude::before{border-radius:2px;transform:rotate(45deg)}
.byhand label.field select{min-width:230px;height:38px}
dialog.editor .or{font-size:12.5px;color:var(--muted);padding-top:6px;
 border-top:1px solid var(--line2)}
dialog.editor .pick{max-height:170px;overflow:auto;border:1px solid var(--line2);
 border-radius:7px;background:var(--panel2)}
dialog.editor .pick label{display:flex;gap:10px;align-items:center;padding:7px 11px;
 font-family:var(--mono);font-size:12.5px;border-top:1px solid var(--line2);
 cursor:pointer}
dialog.editor .pick label:first-child{border-top:0}
dialog.editor .pick label:hover{background:#141d2f}
dialog.editor .pick .none{padding:10px 11px;font-size:12.5px;color:var(--dim)}
dialog.editor .dlg{display:flex;flex-direction:column;gap:12px;padding:16px 18px}
dialog.editor .dlg .field input{width:100%;height:36px;font-family:var(--mono);
 font-size:12.5px}
.ov .sheet.narrow{width:min(520px,100%)}
.ov .sheet.drawer{position:fixed;right:0;top:0;bottom:0;width:min(480px,100%);
 max-height:none;border-radius:0;border-right:0}
.ov .sheet.drawer .narrow{width:auto;max-width:none}
.ov .sheet.drawer .top{display:none}
.ov .sheet.drawer .acts{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
/* A fold for what only a person debugging a flow wants: the archived
   screen files, the raw fields of a history line. Shut, it is one word. */
details.tech{display:inline}
details.tech>summary{display:inline;cursor:pointer;color:var(--dim);
 font-size:12px;list-style:none}
details.tech>summary::-webkit-details-marker{display:none}
details.tech>summary::after{content:" \2304"}
details.tech[open]>summary::after{content:" \2303"}
details.tech[open]{display:block;margin-top:4px}
/* A phone somebody asked for, before it is a phone. One line each,
   the same rhythm as the table under it. */
.wishes{padding:12px 14px}
.wishes h3{margin:0 0 8px}
.wish{display:flex;align-items:center;gap:10px;padding:6px 0;
 border-top:1px solid var(--line2);font-size:13px}
.wish:first-of-type{border-top:0}
.wish .who{flex:0 0 auto;color:var(--ink)}
.wish .why{color:var(--dim);font-size:12.5px}
.wish .age{flex:0 0 46px;color:var(--dim);font-size:12px}
/* The search and the chips live inside the one scrolling body, so they
   left the screen the moment somebody scrolled to the row they wanted -
   which is exactly when they want to search (2026-09-07). The paste box
   stuck too, and the two slid over each other (2026-09-08): only this
   row stays. The negative top cancels the padding on that body; the
   negative sides run its background to the edges, so nothing shows
   through beside it. */
.sheetbody .filters{position:sticky;top:-15px;margin:0 -18px 0;
 padding:12px 18px 10px;background:var(--panel);z-index:2;
 border-bottom:1px solid var(--line2)}
/* Under that row, not under the top edge it covers: the row is 59px
   tall in the same inset frame the -15px is measured in. And the table
   wrapper must not be a scrollport of its own here, or the column names
   stick to a box that never scrolls - which is why they never stuck in
   the sheet (2026-09-08). */
.sheetbody>.tscroll{overflow:visible}
.sheetbody .pooltable thead th{top:44px}
.pickrow{display:flex;align-items:center;gap:10px;padding:9px 12px;
 border-bottom:1px solid var(--line2)}
.pickrow:last-child{border-bottom:0}
.pickrow .serial{min-width:56px;font-weight:500}
.statepick{display:flex;flex-direction:column;gap:4px;font-size:10.5px;
 letter-spacing:.07em;text-transform:uppercase;color:var(--dim)}
.statepick select{background:var(--panel2);border:1px solid var(--line);
 color:var(--ink);border-radius:7px;padding:7px 10px;font:12.5px var(--mono)}
.statepick select:disabled{opacity:.5}
@media (prefers-reduced-motion:no-preference){
 .ov .sheet.drawer{animation:slidein .2s ease-out}
 @keyframes slidein{from{transform:translateX(24px);opacity:0}}
}
.filters .sellerpick{background:var(--panel2);border:1px solid var(--line);
 color:var(--ink);border-radius:7px;padding:6px 10px;font:12.5px var(--mono)}
.filters .poolfind{flex:1}
.addbox .addrow .seller{min-width:230px}
@media (prefers-reduced-motion:no-preference){
 .ov{animation:fade .16s ease-out} .ov .sheet{animation:rise .18s ease-out}
 .said.toast.up{animation:rise .18s ease-out}
 @keyframes fade{from{opacity:0}}
 @keyframes rise{from{opacity:0;transform:translateY(8px)}}
}
/* A small yes-or-no where the button was pressed, for the one destructive
   thing on the page. The full confirm page is what a browser without the
   script gets. */
/* Fixed, and clamped by the script. It used to be placed at the
   row position on the document, so a Remove near the foot of a long
   list put the question below the fold - the press looked like it had
   done nothing - and scrolling left the bubble over an unrelated row
   Remove was not the one that would fire (2026-09-07). */
.mini{position:fixed;z-index:50;background:var(--panel);
 border:1px solid var(--line2);border-radius:10px;padding:12px 14px;
 box-shadow:0 14px 40px rgba(0,0,0,.55);width:min(320px,90vw);font-size:13px}
.mini p{margin:0 0 10px} .mini .row{display:flex;gap:8px;justify-content:flex-end}
/* ---- the page */
main{flex:1;min-width:0;padding:24px 32px 56px;display:flex;flex-direction:column;
 gap:16px}
/* The sign-in card, and only it: `main` is a column flex box at least
   100vh tall, so centring it vertically centres the whole dashboard -
   and re-centres it after every live swap, which slides the page half a
   row under the cursor every time a row appears (2026-09-07). */
main.alone{align-items:center;justify-content:center;padding:40px 20px}
main.full{padding:40px 20px}
h2{font-size:25px;font-weight:600;color:var(--bright);margin:0;letter-spacing:-.3px}
h3{font-size:13.5px;font-weight:600;color:#c6d1e0;margin:0;display:flex;align-items:center;
 gap:8px;flex-wrap:wrap}
h3 .n{font-family:var(--mono);font-size:12px;font-weight:400;color:var(--dim)}
.top{display:flex;align-items:center;gap:14px 18px;flex-wrap:wrap;min-height:42px}
.top
 .status{margin-left:auto;font-family:var(--mono);font-size:12.5px;color:var(--muted);
 display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.sub{color:var(--muted);font-size:13.5px;max-width:78ch;margin-top:-8px}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:10px;
 padding:16px 18px;display:flex;flex-direction:column;gap:12px}
.panel.warn{background:#1c1a15;border-color:#57431c} .panel.warn
 h3{color:var(--amber)}
.panel.bad{background:#201414;border-color:var(--red-bg)} .panel.bad
 h3{color:var(--red)}
.panel.ok{border-color:#1e5b2a} .panel.ok h3{color:var(--green)}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
.tile{background:var(--panel);border:1px solid var(--line);border-radius:10px;
 padding:14px 18px;display:flex;flex-direction:column;gap:4px}
.tile
 .l{font-size:12.5px;color:var(--muted);display:flex;align-items:baseline;gap:8px}
.tile .l a{margin-left:auto;font-size:12px}
.tile b{display:block;font-family:var(--mono);font-size:30px;font-weight:500;
 line-height:1.15;font-variant-numeric:tabular-nums}
.tile .s{font-size:12.5px;color:var(--muted)}
.tile.warn{border-color:#57431c} .tile.bad{border-color:var(--red-bg)}
/* ---- tables */
.wrap{overflow-x:auto}
table{border-collapse:collapse;width:100%;font-family:var(--mono);font-size:12.5px;
 font-variant-numeric:tabular-nums}
th{text-align:left;padding:0 10px 8px 0;font-weight:500;font-size:11.5px;
 letter-spacing:.4px;text-transform:uppercase;color:var(--dim);
 border-bottom:1px solid var(--line);white-space:nowrap}
td{padding:8px 10px 8px 0;border-bottom:1px solid var(--line2);color:#b9c4d4;
 vertical-align:top}
tr:last-child td{border-bottom:0}
tbody tr:hover td,table tr:hover td{background:rgba(127,180,255,.035)}
td.act,td:has(> form.inline){white-space:nowrap;text-align:right;padding-right:0}
td.num{text-align:right}
td .badge{vertical-align:middle}
/* ---- pills, chips, badges */
.pills{display:flex;border:1px solid #2c3a52;border-radius:7px;
 overflow:hidden;align-items:stretch}
/* Direct children only. `.pills span` also matched the count inside each
   pill, which then wore the background, the padding and the divider of
   the pill around it - four boxes inside four boxes (2026-09-04). */
.pills>a,.pills>span{display:inline-flex;align-items:center;gap:9px;
 padding:8px 15px;font-size:13px;line-height:1.2;color:var(--muted);
 font-family:var(--sans);border-right:1px solid #2c3a52}
.pills>a:last-child,.pills>span:last-child{border-right:0}
.pills>a:hover{background:#141c2b;color:var(--bright)}
.pills>span,.pills>a.here{background:#1a2334;color:var(--bright)}
.pills .n{font-family:var(--mono);font-size:12px;color:var(--dim);
 font-variant-numeric:tabular-nums}
.figure{font-family:var(--mono);font-size:20px;font-weight:600;
 line-height:1;font-variant-numeric:tabular-nums;vertical-align:-1px}
.addbox{background:var(--panel2);border:1px solid var(--line2);
 border-radius:12px;padding:14px;display:flex;flex-direction:column;
 gap:11px}
.addbox textarea{background:var(--bg)}
.secret{display:flex;flex-direction:column;gap:3px}
.chips{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.chips a,.chips span{padding:4px 11px;border-radius:12px;font-size:12px;
 border:1px solid #2c3a52;color:#9aa7ba}
.chips a:hover{color:#fff;border-color:#3d4f6e}
.chips span,.chips a.here{background:#1a2334;color:#fff;border-color:transparent}
.badge{display:inline-block;padding:1px 9px;border-radius:9px;font-size:11.5px;
 background:#1d2636;color:#9aa7ba;white-space:nowrap;font-family:var(--sans);
 font-weight:500;line-height:1.6}
.badge.ok,.badge.done,.badge.free,.badge.ready{background:var(--green-bg);
 color:var(--green)}
.badge.warn,.badge.queued,.badge.on_phone,.badge.in_use,.badge.claimed{
 background:var(--amber-bg);color:var(--amber)}
.badge.bad,.badge.failed,.badge.refused,.badge.dead{background:var(--red-bg);
 color:var(--red)}
.badge.info,.badge.running,.badge.panel{background:var(--blue-bg);color:var(--blue)}
.badge.running::before{content:"";display:inline-block;width:6px;height:6px;
 border-radius:3px;background:var(--blue);margin-right:6px;vertical-align:1px}
.badge.manual{background:var(--violet-bg);color:var(--violet)}
.badge.attn{background:#4b2a12;color:#f0a24a}
.badge.cancelled{text-decoration:line-through;opacity:.8}
/* A Spotify account kind: its own two colours, and its own shape of
   dot - a round one for the account that wants a bare phone, a
   triangle for the one that wants a Gmail on it - so the two are told
   apart at a glance and not only by reading (2026-09-17). */
.cat{display:inline-flex;align-items:center;gap:5px;padding:1px 8px;
 border-radius:9px;font-family:var(--mono);font-size:11px;font-weight:500;
 white-space:nowrap}
.cat::before{content:"";width:7px;height:7px;background:currentColor}
.cat.normal{background:#0f3a2c;color:#4fd1a5}
.cat.normal::before{border-radius:50%}
.cat.error{background:#3d2a12;color:#f2a35c}
.cat.error::before{clip-path:polygon(50% 0,100% 100%,0 100%)}
/* ---- text helpers */
.muted{color:var(--muted)} .dim{color:var(--dim);font-size:12px}
.mono{font-family:var(--mono)}
.empty{color:var(--muted);text-align:center;padding:22px 10px;font-size:13.5px}
.err{background:#2a1512;border:1px solid #57241c;color:#f0a094;padding:10px 14px;
 border-radius:8px;font-size:13px}
.err::before,.said::before{font-family:var(--mono);margin-right:8px;font-weight:600}
.err::before{content:"!"}
.said{background:#0f2b1a;border:1px solid #1e5b2a;color:#9be3b3;padding:10px 14px;
 border-radius:8px;font-size:13px;margin:0}
.said::before{content:"✓ "}
/* An answer that is not a yes. Every press wore the green tick, so a
   refusal read as a success and the person walked away (2026-09-07). */
.said.no{background:#2a1512;border-color:#57241c;color:#f0a094}
.said.no::before{content:"! "}
.said.toast.up{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);
 z-index:60;box-shadow:0 12px 34px rgba(0,0,0,.5);
 transition:opacity .4s,transform .4s}
.said.toast.gone{opacity:0;transform:translate(-50%,8px)}
.said.toast form{display:inline;margin-left:10px}
.said.toast form button{padding:3px 10px;font-size:12px;color:var(--blue);
 border-color:#22406e}
.hint{color:var(--dim);font-size:12px;line-height:1.55}
/* ---- forms */
input,textarea,select{background:var(--panel2);border:1px solid #2c3a52;
 border-radius:7px;color:var(--ink);padding:8px 12px;font-family:var(--mono);
 font-size:12.5px;min-height:36px}
input:hover,textarea:hover{border-color:#3d4f6e}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--focus);
 box-shadow:0 0 0 3px rgba(127,180,255,.15)}
textarea{width:100%;min-height:110px;line-height:1.7;resize:vertical}
/* The palest thing on the page was the format of the paste box, at
   about 2.8:1 - and a placeholder is erased by the first keystroke, so
   the one text somebody needs while typing was the one that left
   (2026-09-07). */
input::placeholder,textarea::placeholder{color:var(--dim)}
input[type=checkbox],input[type=radio]{min-height:0;width:16px;height:16px;
 accent-color:var(--accent-hi);margin:0}
button,.btn{cursor:pointer;background:var(--accent);color:#fff;border:0;
 border-radius:7px;padding:9px 18px;font-family:var(--sans);font-size:13.5px;
 font-weight:600;line-height:1.3;white-space:nowrap;display:inline-flex;
 align-items:center;gap:6px}
button:hover,.btn:hover{background:var(--accent-hi);color:#fff}
button:active{transform:translateY(1px)}
button.quiet,.btn.quiet{background:none;border:1px solid #2c3a52;color:#9db4d4;
 font-weight:500;padding:5px 11px;font-size:12px}
button.quiet:hover,.btn.quiet:hover{background:#141c2b;border-color:#3d4f6e;color:#fff}
button.quiet.warn,.btn.quiet.warn{border-color:#57431c;color:var(--amber)}
button.quiet.warn:hover,.btn.quiet.warn:hover{background:var(--amber-bg);
 color:#ffd89a}
button.quiet.bad,.btn.quiet.bad{border-color:#4d2323;color:var(--red)}
button.quiet.bad:hover,.btn.quiet.bad:hover{background:var(--red-bg);
 color:#ffb3a6}
button.quiet.ok,.btn.quiet.ok{border-color:#1d4530;color:var(--green)}
button.quiet.ok:hover,.btn.quiet.ok:hover{background:var(--green-bg);
 color:#8ff0b5}
button.quiet.go,.btn.quiet.go{border-color:#22406e;color:var(--blue)}
button.quiet.go:hover,.btn.quiet.go:hover{background:var(--blue-bg);
 color:#c6dcff}
button.quiet.live,.btn.quiet.live{border-color:#3a2c55;color:var(--violet)}
button.quiet.live:hover,.btn.quiet.live:hover{background:var(--violet-bg);
 color:#e2d8ff}
/* Boot: the one button on a free row, and the one that starts something
   - filled, where every other row button is an outline. */
button.boot,.btn.boot{background:linear-gradient(135deg,#5b47c9,#8a6cf5);
 color:#fff;border:0;border-radius:999px;padding:5px 13px 5px 10px;
 font-size:12px;font-weight:600;letter-spacing:.02em;gap:5px;
 box-shadow:0 1px 2px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,255,255,.16)}
button.boot:hover,.btn.boot:hover{background:linear-gradient(135deg,#6a56dc,#9d82ff);
 color:#fff;box-shadow:0 2px 8px rgba(124,92,230,.45),
 inset 0 1px 0 rgba(255,255,255,.2)}
button.boot svg{flex:none}
button.big{height:44px;justify-content:center;width:100%;font-size:14px}
form.inline{display:inline}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.row .right{margin-left:auto}
label{display:flex;gap:8px;align-items:center;font-size:13px}
.seg{display:inline-flex;border:1px solid #2c3a52;border-radius:7px;overflow:hidden}
.seg label{padding:6px 12px;gap:7px;cursor:pointer;border-right:1px solid #2c3a52;
 font-size:13px}
.seg label:last-child{border-right:0}
.seg label:has(input:checked){background:#1a2334;color:#fff}
.row .seg{margin-left:auto;background:var(--panel2);padding:2px;gap:0}
.seg button{background:none;border:0;padding:4px 12px;border-radius:5px;
 cursor:pointer;font:inherit;font-size:12.5px;color:var(--muted)}
.seg button:hover{color:var(--bright);background:transparent}
.seg button[aria-pressed=true]{background:var(--panel);color:var(--bright);
 box-shadow:0 1px 0 rgba(0,0,0,.4)}
.ticks{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.ticks label{align-items:flex-start;padding:9px 12px;border:1px solid var(--line2);
 border-radius:8px;background:var(--panel2);line-height:1.4;cursor:pointer}
.ticks label:has(input:checked){border-color:#2c4a7a;background:#111b2e}
.ticks label input{margin-top:3px}
.ticks label .muted{display:block;font-size:12px}
.pick{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 10px;
 align-items:center;padding:9px 10px;border-radius:8px;background:var(--panel2);
 border:1px solid var(--line2)}
.pick.tick{grid-template-columns:auto minmax(0,1fr) auto;cursor:pointer}
.pick:has(input:checked){border-color:#2c4a7a;background:#111b2e}
.switches{display:flex;gap:6px 18px;flex-wrap:wrap}
.card{width:min(420px,100%);background:var(--panel);border:1px solid var(--line);
 border-radius:12px;padding:28px 28px 24px;display:flex;flex-direction:column;gap:14px}
.card .brand{display:flex;align-items:center;gap:10px;font-weight:600;font-size:15px;
 color:#eef3fa;letter-spacing:.4px;margin-bottom:6px}
.card input{width:100%}
.card button{width:100%;justify-content:center;height:42px;font-size:14px}
.field{display:flex;flex-direction:column;gap:5px;align-items:stretch}
label.field{align-items:stretch}
.field span{font-size:12.5px;color:var(--muted)}
.code{font-family:var(--mono);font-size:22px;letter-spacing:1px;background:var(--panel2);
 border:1px dashed #3d4f6e;border-radius:8px;padding:14px 18px;color:var(--bright);
 user-select:all;text-align:center}
.story{display:flex;flex-direction:column}
.story .item{display:grid;grid-template-columns:150px auto 1fr;gap:12px;
 align-items:flex-start;padding:10px 0;border-bottom:1px solid var(--line2)}
.story .item:last-child{border-bottom:0}
.subrow td{color:var(--dim);background:rgba(255,255,255,.015)}
.subrow td:first-child{border-left:2px solid var(--line)}
p{margin:0}
.narrow{width:100%;max-width:1060px;margin:0 auto;display:flex;
 flex-direction:column;gap:26px}
/* The dashboard is two columns: what an operator watches on the left,
   what they reach for on the right. Everything else on the console keeps
   the single centred column. */
.wide{width:100%;max-width:1340px;margin:0 auto;display:flex;
 flex-direction:column;gap:20px}
/* Two rails, and what each is for. What the farm is BUILT FROM - the
   Gmails and the exits - stands across the top of the table as a short
   strip: stock is checked, not watched, and standing it there gives the
   table the width the left rail used to take. What is SIGNED IN ON
   PHONES - the accounts a person sends - keeps the right, where the
   presses are (the operator, 2026-09-17). */
.desk{display:grid;grid-template-columns:minmax(0,1fr) 314px;
 gap:20px 30px;align-items:start;
 grid-template-areas:"supply side" "main side"}
.deskmain{grid-area:main;display:flex;flex-direction:column;gap:20px;
 min-width:0}
.desk>.side{grid-area:side}
.rail{grid-area:supply;display:flex;gap:16px;flex-wrap:wrap;
 align-items:flex-start}
/* A pool that is not open yet - the Claude accounts, which will arrive
   from the bot: the card stands where it will live, dimmed, with no
   door and no number, so the rail already reads as the three products
   it is going to be (the operator, 2026-09-17). */
.pool.off{opacity:.6}
.pool.off>header b{color:var(--dim)}
.pool.off>header .lock{font-family:var(--mono);font-size:10.5px;
 letter-spacing:.08em;text-transform:uppercase;color:var(--dim);
 border:1px solid var(--line2);border-radius:999px;padding:3px 9px}
.rail>.pool{flex:1 1 280px;min-width:0}
.rail>.pool>header{padding:11px 14px 9px}
.rail>.pool>header b{font-size:22px}
/* Two across rather than one down. The strip is as wide as the table
   and a list one name wide was leaving half of it empty: eight names
   where two were, for fifty pixels of height (2026-09-17). */
.rail>.pool .queue{max-height:122px;overflow:hidden auto;display:grid;
 grid-template-columns:minmax(0,1fr) minmax(0,1fr);border-top:0}
/* `minmax(0,...)` and min-width:0, or a long address plus its seller
   widens the column past its track and the box scrolls sideways - the
   name is clipped with an ellipsis instead (the operator, 2026-09-17). */
.rail>.pool .queue li{min-width:0;border-top:1px solid var(--line2)}
.rail>.pool .queue li:nth-child(even){border-left:1px solid var(--line2)}
/* The Spotify card split: how many of each kind are free, because
   the two go on different phones (2026-09-17). */
.split{display:flex;gap:8px;align-items:center;margin:0;
 padding:0 15px 10px;font-family:var(--mono);font-size:11.5px}
.split b{color:var(--ink);font-weight:600;margin-right:4px}
.railcap{width:100%;margin:0;font-family:var(--mono);font-size:10.5px;
 letter-spacing:.09em;text-transform:uppercase;color:var(--dim);padding:0 2px}
/* What GeeLark says about the account, at the foot of the page: a
   small spec block, not a sentence. The sentence version wrapped into
   a ragged second row and read as clutter, and cutting it to fit
   dropped readings that were wanted (the operator, 2026-09-20). A
   grid holds more and reads as less.
   Quiet by default and never quiet when it should not be: `bad` and
   `warn` come from the same judgement the alert strip at the top uses,
   and they carry the hairline, the dot, the wordmark and the reading
   itself, so no glance at the bottom of the page can come away calm
   while the top of it is red. */
.glfoot{width:100%;max-width:1340px;margin:34px auto 10px;
 padding:14px 2px 6px;border-top:1px solid var(--line2);
 font-family:var(--mono)}
.glfoot.warn{border-top-color:#3c3115}
.glfoot.bad{border-top-color:#4d2323;
 background:linear-gradient(180deg,rgba(224,101,79,.06),transparent 64%)}
.glhead{display:flex;align-items:center;flex-wrap:wrap;gap:3px 9px;
 margin:0 0 13px;font-size:10.5px;letter-spacing:.09em;
 text-transform:uppercase}
.gldot{width:6px;height:6px;flex:none;border-radius:50%;
 background:var(--green);box-shadow:0 0 0 3px rgba(88,214,141,.13)}
.glfoot.warn .gldot{background:var(--amber);
 box-shadow:0 0 0 3px rgba(240,192,100,.15)}
.glfoot.bad .gldot{background:var(--red);
 box-shadow:0 0 0 3px rgba(224,101,79,.18)}
.gltag{color:var(--muted);cursor:help}
.glfoot.warn .gltag{color:var(--amber)}
.glfoot.bad .gltag{color:var(--red)}
.glage{margin-left:auto;color:var(--dim);opacity:.65;letter-spacing:.06em;
 cursor:help}
.glage.warn{color:var(--amber);opacity:1}
.glstats{display:grid;gap:14px 28px;margin:0;
 grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.glcell{min-width:0}
.glcell dt{font-size:10px;letter-spacing:.085em;text-transform:uppercase;
 color:var(--muted);opacity:.75}
.glcell dd{margin:4px 0 0;font-size:13.5px;line-height:1.25;
 color:var(--ink);font-variant-numeric:tabular-nums}
.glcell.quiet dd{color:var(--dim)}
.glcell.warn dd{color:var(--amber)}
.glcell.bad dd{color:var(--red)}
.glnote{display:block;margin-top:3px;font-size:10.5px;line-height:1.35;
 color:var(--dim);opacity:.7}
.glcell.warn .glnote,.glcell.bad .glnote{opacity:.92}
@media (max-width:1100px){
 .desk{grid-template-columns:minmax(0,1fr);
  grid-template-areas:"supply" "main" "side"}
}
/* The table scrolls inside its own column rather than taking the page
   sideways with it - the rail has to stay where it was put. */
.tscroll{overflow-x:auto}
.whoout{display:flex;align-items:center;gap:9px;margin-left:22px;
 padding-left:22px;border-left:1px solid var(--line2)}
.whoout .av{width:26px;height:26px;border-radius:50%;background:var(--panel);
 border:1px solid var(--line);display:flex;align-items:center;
 justify-content:center;font-size:12px;text-transform:uppercase}
.whoout .who{font-size:12.5px;color:var(--muted)}
.addfold{margin-left:auto}
.addfold summary{list-style:none;cursor:pointer}
.addfold summary::-webkit-details-marker{display:none}
.addfold[open]{margin-left:0;width:100%;padding-top:10px}
.addfold[open] summary{display:inline-block;margin-bottom:8px}
.addfold form{display:flex;flex-direction:column;gap:8px}
.addfold textarea{background:var(--panel2);border:1px solid var(--line);
 border-radius:6px;color:var(--ink);font:400 11.5px/1.6 var(--mono);
 padding:8px 9px;resize:vertical;width:100%}
.addfold textarea:focus{outline:none;border-color:#3a5c96}
.byhand{display:flex;flex-wrap:wrap;gap:12px 14px;align-items:flex-end;
 padding-top:4px}
/* Three boxes, the tick and the button on one line, left to right and no
   wider than their words. Stretched to fill, the row read as four things
   scattered across a page; this reads as one sentence. */
.byhand label{display:flex;flex-direction:column;align-items:flex-start;
 gap:5px;font-size:10.5px;letter-spacing:.7px;text-transform:uppercase;
 color:var(--dim);flex:0 0 auto;text-align:left}
.byhand label input{width:220px}
.byhand label.tick{flex-direction:row;align-items:center;gap:8px;
 font-size:12.5px;letter-spacing:0;text-transform:none;color:var(--ink);
 padding-bottom:9px}
.byhand label.tick input{accent-color:var(--accent);width:15px;height:15px}
.byhand select,.byhand input[type=text],.byhand input:not([type]){
 background:var(--panel2);border:1px solid var(--line);border-radius:7px;
 color:var(--ink);font:400 12.5px/1 var(--mono);padding:9px 10px;
 font-family:var(--mono);min-width:0}
.byhand select:focus,.byhand input:focus{outline:none;border-color:#3a5c96}
.byhand button.go{padding:9px 18px;align-self:flex-end;margin-bottom:1px}
.byhand details.newone{flex:1 1 100%;order:10;font-size:12px;
 color:var(--dim)}
/* With the script running, the fold exists only while it is needed -
   an address the pool does not know has been typed. Without it, the
   fold is simply there, shut, as a fold. */
.byhand.js details.newone:not([open]){display:none}
.byhand details.newone summary{cursor:pointer;padding:2px 0}
.byhand details.newone input{margin:8px 8px 0 0;width:220px}
.byhand p{flex:1 1 100%;order:11;font-size:11px;line-height:1.5;margin:0}
.stopped h3 .ct{margin-left:auto;font-family:var(--mono);color:var(--red);
 letter-spacing:0}
.stopped details.fold{padding:0 15px 12px}
.stopped details.fold summary{padding:10px 0 6px}
.stoprow{padding:9px 0;border-bottom:1px solid var(--line2);font-size:12px}
.stoprow:last-child{border-bottom:0}
.stoprow .why{display:block;color:var(--red);margin-top:3px;line-height:1.45}
.stoprow .dim{display:block;margin-top:2px;font-size:11px}
/* Anything a person copies out of this console, they copy by hand today. */
.cp{cursor:copy;border-radius:3px}
.cp:hover{background:var(--blue-bg);box-shadow:0 0 0 3px var(--blue-bg)}
.cp.flash{background:var(--green-bg);box-shadow:0 0 0 3px var(--green-bg)}
.find{margin-left:auto;position:relative}
.find input{background:var(--panel2);border:1px solid var(--line);
 border-radius:7px;color:var(--ink);font:400 12.5px/1 var(--sans);
 padding:8px 11px;width:210px;font-family:inherit}
.find input:focus{outline:none;border-color:#3a5c96;
 box-shadow:0 0 0 3px rgba(37,99,196,.16)}
.railfind{padding:9px 15px;border-bottom:1px solid var(--line2)}
.railfind input{width:100%;background:var(--panel2);border:1px solid var(--line);
 border-radius:6px;color:var(--ink);font:400 12px/1 var(--sans);padding:7px 9px}
.railfind input:focus{outline:none;border-color:#3a5c96}
.side{position:sticky;top:18px;display:flex;flex-direction:column;gap:14px}
.side .panel{padding:0;gap:0;overflow:hidden}
.side h3{font-size:10.5px;letter-spacing:.9px;text-transform:uppercase;
 color:var(--dim);padding:13px 15px;border-bottom:1px solid var(--line2);
 background:var(--panel2);display:flex;align-items:center;gap:8px;margin:0}
.side h3 .ct{margin-left:auto;font-family:var(--mono);color:var(--muted);
 letter-spacing:0}
.stockrow{display:flex;align-items:center;gap:11px;padding:12px 15px;
 border-bottom:1px solid var(--line2)}
.stockrow b{font-family:var(--mono);font-size:19px;font-weight:500;
 font-variant-numeric:tabular-nums;width:34px;flex:none;line-height:1.1}
.stockrow .t{font-size:12.5px;color:var(--ink);line-height:1.35}
.stockrow .t i{display:block;font-style:normal;font-size:11px;color:var(--dim)}
.stockrow .plus{margin-left:auto;border:1px solid var(--line);border-radius:6px;
 color:var(--muted);font-size:11px;padding:7px 9px}
.stockrow .plus:hover{color:var(--blue);border-color:#2c4a7a;
 background:var(--blue-bg)}
.stockrow .lock{margin-left:auto;font-size:10.5px;color:#54627a;
 letter-spacing:.5px;text-transform:uppercase}
.failrow{display:flex;align-items:center;gap:8px;padding:11px 15px;
 background:var(--red-bg);color:var(--red);font-size:11.5px;line-height:1.45}
.failrow:hover{filter:brightness(1.25)}
.failrow b{font-family:var(--mono)}
.failrow .arrow{margin-left:auto;opacity:.6}
/* A phone that did not finish is not stock, so it does not stand in the
   shelf. It still costs a slot and an exit, so it does not vanish either. */
.didnot{border:1px solid var(--line2);border-left:2px solid var(--red-bg);
 border-radius:9px;background:var(--panel2);overflow:hidden}
.didnot h3{font-size:10.5px;letter-spacing:.9px;text-transform:uppercase;
 color:#c07f6d;padding:12px 15px;border-bottom:1px solid var(--line2);
 display:flex;align-items:center;gap:8px;margin:0}
.didnot h3 .why{margin-left:auto;text-transform:none;letter-spacing:0;
 font-size:11.5px;color:var(--dim)}
.didnot .r{display:flex;align-items:center;gap:16px;padding:11px 15px;
 border-bottom:1px solid var(--line2)}
.didnot .r:last-child{border-bottom:0}
.didnot .r .body{flex:1;min-width:0;font-size:12.5px}
.didnot .r .body .why{color:var(--red)}
.didnot .r .act{margin-left:auto;display:flex;gap:5px}
@media (max-width:1180px){
 .desk{display:flex;flex-direction:column}
 .side{position:static}
}
.headline{display:flex;align-items:flex-start;gap:24px;flex-wrap:wrap}
.strip{display:flex;gap:2px;flex-wrap:wrap}
.strip.pools{margin-left:auto}
.strip a,.strip span{display:flex;flex-direction:column;align-items:center;
 gap:5px;min-width:88px;padding:10px 14px;border-radius:10px;
 color:var(--muted);border:1px solid transparent}
.strip a:hover{background:var(--panel2);border-color:var(--line);
 color:var(--bright)}
.strip b{font-family:var(--mono);font-size:27px;font-weight:500;
 line-height:1;font-variant-numeric:tabular-nums}
.strip i{font-style:normal;font-size:11.5px;letter-spacing:.3px}
.svc{display:flex;align-items:center;gap:14px;padding-top:12px;
 border-top:1px solid var(--line2);font-size:12px;color:#55627a}
.svc button{background:none;border:0;color:var(--dim);font-size:12px;
 font-family:inherit;cursor:pointer;padding:2px 0}
.svc button:hover{color:#fff;background:none}
.svc .right{margin-left:auto}
details.fold{display:inline}
details.fold summary{cursor:pointer;color:var(--dim);font-size:12px;
 list-style:none;padding:5px 0}
details.fold summary::-webkit-details-marker{display:none}
details.fold summary:hover{color:#fff}
details.fold[open]{display:block;width:100%}
.alerts{display:flex;flex-direction:column;gap:6px}
.alert{display:flex;align-items:center;gap:10px;padding:10px 14px;
 border-radius:8px;font-size:13px;border:1px solid;border-left-width:3px;
 color:var(--ink)}
.alert a{color:inherit;flex:1} .alert a:hover{color:#fff}
.alert b{color:#fff;font-weight:600}
.alert .x{background:none;border:0;color:var(--muted);font-size:18px;
 line-height:1;cursor:pointer;padding:0 2px}
.alert .x:hover{color:#fff;background:none}
.alert::before{font-family:var(--mono);font-weight:600}
.alert.warn{background:#1c1a15;border-color:#57431c}
.alert.warn::before{content:"!";color:var(--amber)}
.alert.bad{background:#201414;border-color:var(--red-bg)}
.alert.bad::before{content:"!";color:var(--red)}
.alert:hover{color:#fff}
tr.hi td{background:rgba(127,180,255,.10)}
tr.warn td{background:rgba(240,192,100,.06)} tr.warn td.msg{color:var(--amber)}
tr.bad td{background:rgba(224,101,79,.08)} tr.bad td.msg{color:var(--red)}
tr.off td{opacity:.55}
.avatar{display:inline-flex;width:26px;height:26px;border-radius:13px;
 background:#24314a;align-items:center;justify-content:center;font-size:12px;
 font-weight:600;color:#b9cae6;text-transform:uppercase;margin-right:8px;
 vertical-align:middle;flex-shrink:0}
.entry{display:flex;gap:12px;align-items:flex-start;padding:9px 0;
 border-bottom:1px solid var(--line2)}
.entry:last-child{border-bottom:0}
.entry .when{min-width:150px;font-family:var(--mono);color:var(--dim);
 font-size:12px;padding-top:2px}
.entry .lines{display:flex;flex-direction:column;gap:2px;min-width:0}
.entry .head{color:var(--bright)}
tr.now td{background:rgba(127,180,255,.05)}
tr.now td:first-child{border-radius:8px 0 0 8px}
tr.now td:last-child{border-radius:0 8px 8px 0}
.facts{font-family:var(--mono);font-size:13px;color:var(--ink);
 margin-top:-10px}
.facts .hand{user-select:all}
.live{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);
 font-size:12px;color:var(--green)}
.live::before{content:"";width:8px;height:8px;border-radius:50%;
 background:var(--green);box-shadow:0 0 6px var(--green)}
@media (max-width:900px){
 .shell{flex-direction:column}
 nav{width:auto;height:auto;position:static;flex-direction:row;flex-wrap:wrap;
  align-items:center;padding:10px 12px;gap:2px;border-right:0;
  border-bottom:1px solid var(--line2)}
 nav .brand{padding:4px 10px;width:100%}
 nav a{height:34px;padding:0 10px;font-size:13px}
 nav a.here::before{display:none}
 nav form{margin-top:0;margin-left:auto;padding:0;border:0}
 main{padding:18px 16px 40px}
 .grid2,.grid3,.tiles,.ticks{grid-template-columns:1fr}
 .story .item{grid-template-columns:1fr}
}
