/*
 * Served from /app.css, NOT inlined.
 *
 * The Content-Security-Policy is style-src 'self', which does not permit an
 * inline <style> block — the browser silently drops every rule and the page
 * renders unstyled, with elements meant to be hidden fully visible. The
 * page is built to fit the policy; the policy is not widened to fit the page.
 */
:root{
  --bg:#f6f8fa; --panel:#ffffff; --line:#d8dee4; --line2:#eaeef2;
  --fg:#1f2328; --dim:#656d76;
  --ok:#1a7f37; --warn:#9a6700; --bad:#cf222e; --acc:#0969da;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);
font:14px/1.5 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}
header{display:flex;align-items:center;gap:16px;padding:14px 20px;
border-bottom:1px solid var(--line);background:var(--panel)}
header h1{font-size:15px;margin:0;font-weight:600;letter-spacing:.3px}
header .sp{flex:1}
main{max-width:1320px;margin:0 auto;padding:20px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:8px;
padding:16px;margin-bottom:16px}
.card h2{margin:0 0 12px;font-size:13px;text-transform:uppercase;
letter-spacing:.6px;color:var(--dim);font-weight:600}
/* Status tiles. Each value gets its own panel so the numbers read as
   separate facts rather than a run-on line. */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
gap:12px}
.tile{background:linear-gradient(180deg,#fbfcfd,#f4f6f8);
border:1px solid var(--line);border-radius:8px;padding:14px 16px;
position:relative;overflow:hidden}
.tile b{display:block;font-size:24px;font-weight:600;letter-spacing:-.5px;
line-height:1.2}
.tile span{color:var(--dim);font-size:11px;text-transform:uppercase;
letter-spacing:.6px}
.tile::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
background:var(--acc)}
.tile.ok::before{background:var(--ok)}
.tile.ok b{color:var(--ok)}
.tile.wide{grid-column:span 2}
.tile.wide b{font-size:19px;font-family:ui-monospace,SFMono-Regular,Menlo,
monospace;letter-spacing:0}
/* Slightly smaller than the surrounding UI: the farm table carries a lot of
   columns, and 0.85em buys the width they need without shrinking the rest of
   the page. */
table{width:100%;border-collapse:collapse;font-size:.85em}
th,td{text-align:left;padding:9px 8px;border-bottom:1px solid var(--line2)}
th{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.5px}
tbody tr:hover{background:#f6f8fa}
td.num{text-align:right;font-variant-numeric:tabular-nums}
.pill{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;
font-weight:600;border:1px solid transparent}
.pill.active{background:#dafbe1;color:var(--ok);border-color:#aceebb}
.pill.disabled{background:#f0f2f4;color:var(--dim);border-color:var(--line)}
.pill.expired,.pill.exhausted{background:#ffebe9;color:var(--bad);
border-color:#ffcecb}
button{font:inherit;padding:6px 12px;border-radius:6px;
border:1px solid var(--line);background:#f6f8fa;color:var(--fg);cursor:pointer}
button:hover{background:#eef1f4;border-color:#b9c0c8}
button.p{background:var(--acc);border-color:var(--acc);color:#fff}
button.p:hover{background:#0860ca}
button.d{color:var(--bad)}
button.d:hover{background:#ffebe9;border-color:#ffcecb}
input,select{font:inherit;padding:6px 10px;border-radius:6px;
border:1px solid var(--line);background:#fff;color:var(--fg)}
input:focus,select:focus{outline:2px solid #b6d4fe;outline-offset:-1px;
border-color:var(--acc)}
input::placeholder{color:#8c959f}
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.bar{height:5px;background:var(--line2);border-radius:3px;overflow:hidden;
margin-top:4px}
.bar i{display:block;height:100%;background:var(--acc)}
.bar i.hi{background:var(--warn)}.bar i.full{background:var(--bad)}
#msg{padding:10px 14px;border-radius:6px;margin-bottom:14px;display:none;
border:1px solid transparent}
#msg.e{background:#ffebe9;color:#82071e;border-color:#ffcecb;display:block}
#msg.s{background:#dafbe1;color:#0a3622;border-color:#aceebb;display:block}
/* Label/value pairs for the farmer portal.
   Replaces the .stat blocks this section used to share with the admin Status
   panel — when that panel was restyled the shared rules went with it, and the
   labels collapsed onto the values with no space between them. Its own
   classes now, so restyling one cannot break the other. */
.facts{margin:0;display:grid;grid-template-columns:auto 1fr;
gap:8px 14px;align-items:baseline}
.facts dt{color:var(--dim);font-size:12px;text-transform:uppercase;
letter-spacing:.5px}
.facts dd{margin:0;font-size:16px;font-weight:600}

#login{max-width:340px;margin:80px auto}
.hide{display:none}

/* A collapsed card is a title bar and nothing else: this content is edited
   rarely and was pushing the farm list off the screen. */
h2.toggle{cursor:pointer;display:flex;align-items:center;gap:8px;
user-select:none;margin-bottom:0}
h2.toggle:hover{color:var(--fg)}
.chev{display:inline-block;transition:transform .15s;font-size:14px;
color:var(--dim)}
.chev.open{transform:rotate(90deg)}
.collapsible h2.toggle+div:not(.hide){margin-top:14px}

textarea{font:inherit;width:100%;padding:8px 10px;border-radius:6px;
border:1px solid var(--line);background:#fff;color:var(--fg);resize:vertical}
textarea:focus{outline:2px solid #b6d4fe;outline-offset:-1px;
border-color:var(--acc)}

/* Persian notices read right to left. */
.rtl{direction:rtl;text-align:right}
#notice{background:#fff8c5;border:1px solid #f0d98c;border-radius:8px;
padding:14px 16px;margin-bottom:16px;white-space:pre-wrap;line-height:1.7}
/* Label/value rows for the farmer's plan. A grid rather than inline spans:
   the values line up in a column, and the gap cannot collapse the way it did
   when these shared the admin panel's stat styling. */
dl.facts{display:grid;grid-template-columns:max-content 1fr;
gap:8px 16px;margin:0}
dl.facts dt{color:var(--dim);font-size:12px;text-transform:uppercase;
letter-spacing:.5px;align-self:center}
dl.facts dd{margin:0;font-size:17px;font-weight:600}
dl.facts dd.ok{color:var(--ok)}
dl.facts dd.bad{color:var(--bad)}
/* Tunnel state. A dot plus a word: colour alone would be unreadable to
   anyone who cannot distinguish red from green. */
.link{display:inline-flex;align-items:center;gap:6px;font-weight:600;
font-size:.95em;white-space:nowrap}
.link i{width:8px;height:8px;border-radius:50%;display:inline-block}
.link.up{color:var(--ok)}
.link.up i{background:var(--ok);box-shadow:0 0 0 3px rgba(26,127,55,.15)}
.link.down{color:var(--bad)}
.link.down i{background:var(--bad)}
.link.na{color:var(--dim)}
/* On the expiry pool: connected, but not on the plan they are paying for. */
.link.grace{color:var(--warn)}
.link.grace i{background:var(--warn);box-shadow:0 0 0 3px rgba(154,103,0,.15)}
/* Plan status in the farmer portal: green when the plan permits a
   connection, red when it does not. */
.state{font-weight:600}
.state.up{color:var(--ok)}
.state.down{color:var(--bad)}
.link.na i{background:var(--line)}

/* Inline editor, opened under the farm it edits. */
td.editbox{background:#f6f8fa;border-left:3px solid var(--acc);padding:16px}
.fld{display:inline-flex;flex-direction:column;gap:4px}
.fld>span{color:var(--dim);font-size:11px;text-transform:uppercase;
letter-spacing:.5px}
.fld input[type=checkbox]{width:16px;height:16px;margin-top:6px}

tr.hit{background:#fff8c5;box-shadow:inset 3px 0 0 var(--warn)}
tr.hit td{font-weight:600}
button.mini{padding:3px 10px;font-size:.95em}
/* Row actions: three per row across many rows, so they are deliberately
   small — they were taking width from the columns being read. */
td button.act{padding:2px 7px;font-size:.9em;margin-right:4px}
td button.act:last-child{margin-right:0}
code{background:var(--line2);padding:2px 6px;border-radius:4px;font-size:12px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;
color:var(--dim)}
.dim{color:var(--dim)}
