/* portal.css — DistroDesigner developer portal. White, minimal, burgundy. */

:root{
  --paper:#ffffff;
  --ink:#1c1518;
  --muted:#8a7d81;
  --hair:#ece7e8;
  --tint:#faf6f7;
  --accent:#7a0d2b;
  --accent-dark:#5e0a21;
  --fail:#b3261e;
  --display:"Jost","Futura","Century Gothic","Avenir Next",system-ui,sans-serif;
  --body:"Source Sans 3","Source Sans Pro","Segoe UI",Helvetica,Arial,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{color-scheme:light}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font:16px/1.55 var(--body);
  -webkit-font-smoothing:antialiased;
}
[hidden]{display:none!important}
img{max-width:100%}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

@keyframes rise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.rise{animation:rise 240ms ease both}
@media (prefers-reduced-motion:reduce){
  .rise{animation:none}
  *{transition:none!important}
}

/* ---------- topbar: wordmark left, AMPOWER right, always showing ---------- */
.topbar{
  position:sticky;top:0;z-index:40;background:var(--paper);
  border-bottom:1px solid var(--hair);
}
.topbar-inner{
  max-width:1080px;margin-inline:auto;padding:0 24px;height:58px;
  display:flex;align-items:center;gap:22px;
}
.wordmark{
  font-family:var(--display);font-weight:500;font-size:19px;
  letter-spacing:.02em;color:var(--ink);text-decoration:none;
}
.wordmark:hover{text-decoration:none}
.wordmark b{color:var(--accent);font-weight:500}
.topbar .grow{flex:1}
.toplogo{height:36px;display:block}
.tabs{display:flex;gap:4px}
.tab{
  font-family:var(--display);font-weight:400;font-size:15px;
  color:var(--muted);background:none;border:0;padding:8px 10px;cursor:pointer;
  border-bottom:2px solid transparent;transition:color 140ms ease;
}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--ink);border-bottom-color:var(--accent)}
/* A page whose content is wide (New Project, the owner's console) has a bar
   as wide as its content, so the logo stands over the content's left edge. */
.topbar.wide .topbar-inner{max-width:1360px}
/* A phone. The bar's parts do not fit on one line of 390 px, and a bar that
   does not wrap makes the whole page scroll sideways. So it wraps: the logo,
   the wordmark and Sign out on the first line, the tabs and New project on
   the second. It also stops following the page down, because two lines of
   bar are too much of a small screen to keep. */
@media (max-width:720px){
  .topbar{position:static}
  .topbar-inner{height:auto;min-height:58px;flex-wrap:wrap;
    gap:4px 10px;padding:10px 16px}
  .toplogo{height:24px}
  .topbar .wordmark{font-size:17px}
  .topbar .grow{order:1;min-width:0}
  .topbar #logout{order:2;margin-left:auto}
  .topbar .tabs{order:3;margin-left:-10px}
  .topbar a.btn{order:4;margin-left:auto}
  .topbar .btn{padding:7px 10px;font-size:14px}
  .topbar .tab{font-size:14px;padding:8px 9px}
}

/* ---------- buttons ---------- */
/* An <a class="btn"> is inline by default, so "View report" broke across two
   lines in the narrow actions column and its baseline drifted away from the
   status badge beside it. nowrap + inline-block keeps every button one line
   tall and lets the row centre it. */
.btn{
  font-family:var(--display);font-weight:500;font-size:15px;
  border:1px solid var(--hair);background:var(--paper);color:var(--ink);
  padding:8px 16px;border-radius:6px;cursor:pointer;
  white-space:nowrap;display:inline-block;line-height:1.2;
  transition:background 140ms ease,border-color 140ms ease,color 140ms ease;
}
.btn:hover{border-color:var(--muted)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{background:var(--accent-dark);border-color:var(--accent-dark)}
.btn.quiet{border-color:transparent;color:var(--accent)}
.btn.quiet:hover{background:var(--tint)}
.btn:disabled{opacity:.45;cursor:default}

/* ---------- layout ---------- */
.wrap{max-width:1080px;margin-inline:auto;padding:28px 24px 64px}
@media (max-width:720px){.wrap{padding:20px 16px 48px}}
.narrow{max-width:660px}
h1{font-family:var(--display);font-weight:500;font-size:24px;margin:0 0 18px}
h2{font-family:var(--display);font-weight:500;font-size:18px;margin:26px 0 10px}
/* A second heading of the page's first rank (Accounts, on the owner's
   console) stands clear of the table above it. */
main > h1:not(:first-child){margin-top:40px}
.sub{color:var(--muted);font-size:14px}
.right{text-align:right}
.mono{font-variant-numeric:tabular-nums}

/* ---------- table ---------- */
table{width:100%;border-collapse:collapse}
th{
  text-align:left;font-family:var(--display);font-weight:500;font-size:12px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
  padding:6px 10px;border-bottom:1px solid var(--hair);
}
td{padding:12px 10px;border-bottom:1px solid var(--hair);vertical-align:middle}
tr.row{cursor:pointer;transition:background 140ms ease}
tr.row:hover{background:var(--tint)}
td.addr{font-weight:600}
/* The actions column has an empty header, so the browser hands it the least
   width it can and wrapped the buttons inside it. width:1% asks for the
   narrowest column that still fits its content on one line; the table sits in
   .tablewrap{overflow-x:auto}, so nowrap here cannot scroll the page. */
td.actions{white-space:nowrap;width:1%}
.btn.quiet + .btn.quiet{margin-left:4px}
.tablewrap{overflow-x:auto}
/* The buttons of one order on the owner's console, one under another: side
   by side they made the table wider than the page and the last of them could
   only be reached by scrolling the table sideways. */
td.rowacts{width:1%;white-space:nowrap}
td.rowacts .btn,td.rowacts .pill{display:block;margin:2px 0 2px auto;width:max-content}
td.rowacts .btn.quiet + .btn.quiet{margin-left:auto}

/* A table drawn as blocks on a phone (every table of the portal): the
   header row is put away, each row is a block, and a cell that needs its
   column's name says it (`data-label`). Nothing has to be scrolled sideways
   to reach a button. */
@media (max-width:720px){
  table.stack thead{display:none}
  table.stack,table.stack tbody,table.stack tfoot,table.stack tr,
  table.stack td{display:block;width:auto}
  table.stack tr{padding:10px 0;border-bottom:1px solid var(--hair)}
  table.stack td{border:0;padding:3px 6px;text-align:left}
  table.stack td[data-label]::before{content:attr(data-label) ": ";
    color:var(--muted);font-size:13px}
  table.stack td:empty{display:none}
  table.stack td.billaddr{font-weight:600}
  table.stack td.actions{white-space:normal;padding-top:8px}
  table.stack tr.detail,table.stack tr.confirmrow,
  table.stack tr.prpanel{padding:0}
  table.stack tr.detail td{padding:14px 12px}
  table.stack tr.confirmrow td{padding:10px 12px}
  table.stack tr.prpanel td{padding:6px 6px 10px}
  table.stack .engines{flex-wrap:wrap;row-gap:8px;margin-top:4px}
  table.stack .inlinegrant{display:inline-flex;vertical-align:middle}
  table.stack td.rowacts{white-space:normal;padding-top:6px}
  table.stack td.rowacts .btn,table.stack td.rowacts .pill{
    display:inline-block;margin:2px 4px 2px 0}
  table.stack td .btn.quiet{padding-left:8px;padding-right:8px}
}

/* status */
.st{font-family:var(--display);font-size:14px;color:var(--muted);white-space:nowrap}
.st.complete{color:var(--ink)}
.st.failed{color:var(--fail)}
.st .dot{
  display:inline-block;width:7px;height:7px;border-radius:50%;
  margin-right:7px;background:var(--hair);vertical-align:1px;
}
.st.in_progress .dot{background:var(--accent);animation:pulse 1.6s ease infinite}
.st.complete .dot{background:var(--accent)}
.st.failed .dot{background:var(--fail)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.st .dot{animation:none}}

/* engine progress: six named segments */
.engines{display:flex;gap:5px;align-items:center}
.eng{display:flex;flex-direction:column;gap:3px;align-items:center}
.eng .bar{
  width:44px;height:5px;border-radius:3px;background:var(--hair);
  transition:background 300ms ease;
}
.eng.done .bar{background:var(--accent)}
/* `blocked` (design_refused) reads as work in progress, not a failure: the
   run happened and the report is being finished, not a broken order. Same
   paint as `running` — an owner is already on it. */
.eng.running .bar,.eng.blocked .bar{background:var(--accent);opacity:.45;animation:pulse 1.6s ease infinite}
.eng .lbl{font-size:10.5px;letter-spacing:.04em;color:var(--muted);
  font-family:var(--display)}
.outstanding{font-size:13px;color:var(--muted);margin-top:5px}

/* detail row */
tr.detail td{background:var(--tint);padding:16px 14px}
.kv{display:grid;grid-template-columns:max-content 1fr;gap:4px 22px;font-size:14px}
.kv dt{color:var(--muted)}
.kv dd{margin:0}
/* On a phone the name of each detail stands over its value: side by side,
   a long name left the value a few characters wide. */
@media (max-width:720px){
  .kv{grid-template-columns:minmax(0,1fr);gap:0}
  .kv dt{margin-top:8px}
  .kv dt:empty{display:none}
}

/* ---------- forms ---------- */
label{
  display:block;font-family:var(--display);font-weight:500;font-size:13px;
  letter-spacing:.03em;margin:16px 0 5px;
}
label .opt{color:var(--muted);font-weight:400;letter-spacing:0}
input[type=text],input[type=password],input[type=number],input[type=email],
input[type=search],
select,textarea{
  width:100%;font:15px/1.4 var(--body);color:var(--ink);
  background:var(--paper);border:1px solid var(--hair);border-radius:6px;
  padding:9px 11px;transition:border-color 140ms ease;
}
input:focus,select:focus,textarea:focus{border-color:var(--accent);outline:none}
textarea{resize:vertical}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 20px}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:0 20px}
@media (max-width:640px){.grid2,.grid3{grid-template-columns:1fr}}
.err{color:var(--fail);font-size:14px;margin-top:12px}
.ok{color:var(--accent);font-size:14px;margin-top:12px}

/* ---------- login ---------- */
/* The DistroDesigner wordmark leads the page, large, above the form; the
   AMPOWER logo stands at the bottom of the page, under everything else. */
.login{
  min-height:100vh;display:flex;align-items:center;
  flex-direction:column;padding:24px;
}
.login-main{
  flex:1;width:100%;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:34px;
}
.login-card{width:100%;max-width:340px}
.login-brand{max-width:none;text-align:center}
.login-card .wordmark{font-size:clamp(38px,11vw,56px);line-height:1.1}
/* "Developer" on a line of its own under the wordmark, centred on the same
   axis, so the wordmark stays centred as it was (portal #12). It stands
   14px under the wordmark's line, so its text box starts below the
   wordmark's, which reaches about 10px under that line at 56px. */
.login-brand .edition{display:block;margin-top:14px;font-family:var(--display);
  font-weight:400;font-size:24px;line-height:1.2;letter-spacing:.04em;
  color:var(--muted)}
.login-foot{padding:32px 0 8px}
.login-logo{height:44px;display:block}
.login-logo-link{display:block;border-radius:4px}
.login-logo-link:focus-visible{outline:2px solid currentColor;outline-offset:6px}
.login .btn{width:100%;margin-top:20px}
.login .contact{margin-top:26px;font-size:14px;color:var(--muted);text-align:center}

/* ---------- map (new project) ---------- */
#map{height:420px;border:1px solid var(--hair);border-radius:6px}
.maptools{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
.maptools .btn{font-size:13.5px;padding:6px 12px}
.maptools .btn.on{background:var(--accent);border-color:var(--accent);color:#fff}
.aclist{position:relative}
/* Hangs BELOW the input, not over it: top:2px pinned the list to the top of
   the wrapper, which is the input itself, so the six suggestions covered the
   address you were still typing. top:100% is the input's bottom edge; the
   max-height keeps six rows from running off a phone. */
.aclist .list{
  position:absolute;left:0;right:0;top:100%;margin-top:4px;
  max-height:240px;overflow-y:auto;
  z-index:30;background:var(--paper);
  border:1px solid var(--hair);border-radius:6px;box-shadow:0 6px 18px rgba(28,21,24,.08);
}
.aclist .list div{padding:8px 11px;cursor:pointer;font-size:14px}
.aclist .list div:hover{background:var(--tint)}

/* ---------- admin ---------- */
.pill{
  font-family:var(--display);font-size:12px;padding:2px 9px;border-radius:99px;
  border:1px solid var(--hair);color:var(--muted);
  /* One line: a pill that wrapped ("Awaiting your / review") drew its
     border across two lines of text. */
  white-space:nowrap;display:inline-block;line-height:1.5;
}
.pill.off{color:var(--fail);border-color:var(--fail)}
.inlinegrant{display:flex;gap:6px;align-items:center}
.inlinegrant input{width:70px;padding:5px 8px;font-size:14px}
label.check{display:inline-flex;align-items:center;gap:7px;margin:0;
  font-family:var(--body);font-weight:400;font-size:14px;letter-spacing:0}
label.check input{width:auto;margin:0}
label.check + label.check{margin-left:22px}
.btn.quiet.danger{color:var(--fail)}
.btn.danger{border-color:var(--fail);color:var(--fail)}

/* The inline confirmation under an account on /admin ("Delete account"). */
tr.confirmrow > td{background:var(--tint);border-top:none}
tr.confirmrow p{margin:6px 0}

/* "Revise this report", under an order's details on the projects page. */
.reviserow{margin:16px 0 4px}
.reviserow .sub{margin-left:10px}
@media (max-width:720px){.reviserow .sub{display:block;margin:8px 0 0}}
.revisenote{max-width:860px}

/* ------------------------------- the pole requests, owner-side (P-W5)
   A row under each order: what a blind reader made of the developer's own
   notes, and the one button that turns a reading into a requirement on the
   engine. Developers never see this — it is rendered only on /admin, from
   keys the API adds only for an owner. */
tr.prpanel > td { padding-top:0; border-top:none; }
.prrow { border-left:3px solid var(--line, #d7dade); padding:.35rem .6rem;
         margin:.3rem 0; }
.prrow .words { font-size:.92rem; }
.prrow.unread { opacity:.75; }

/* ------------------------- the pole-request pins, developer-side (W3 D12)
   The same panel as /admin, plus the map the intake console has always had
   and the portal never did: /admin could show a pin the engine guessed and
   could not move it, so a row the engine pinned to nothing was a dead end
   that read "open the operator console". The developer is the person who
   knows which pole they meant, so the map is on their page. */
.prmap { height:260px; margin:.5rem 0; border:1px solid var(--hair);
         border-radius:6px; }
.prrow.on { border-left-color:var(--accent); background:var(--tint); }
.prrow .chip {
  font-family:var(--display); font-size:12px; padding:2px 9px;
  border-radius:99px; border:1px solid var(--hair); color:var(--muted);
  margin-right:5px;
}
.prrow .pin { font-size:.88rem; color:var(--muted); margin:.25rem 0; }
.prrow.confirmed { border-left-color:var(--ok, #2e7d32); }
.pacts { display:flex; gap:6px; flex-wrap:wrap; margin-top:.35rem; }
.pacts .btn { font-size:13px; padding:5px 10px; }

/* ---------- new project: the address fields to the LEFT of the map ----------
   Two columns on a wide screen, the fields first; one column, fields above
   the map, on a narrow one. The page is wider than the others so the map
   keeps its size with the fields beside it. */
.wrap.wide{max-width:1360px}
.newsplit{display:grid;grid-template-columns:minmax(260px,340px) minmax(0,1fr);
  gap:0 34px;align-items:start}
@media (max-width:900px){.newsplit{grid-template-columns:minmax(0,1fr)}}
.drawerrow{margin:10px 0}
.drawerrow .btn[aria-expanded="true"]{
  background:var(--accent);border-color:var(--accent);color:#fff}

/* ---------- pole marks (plan v4 P2): the pole tools drawer ----------
   Closed, the map has the whole column. Open, the drawer (the pole tools,
   the Street View pane and the list of marks) stands beside the map on a
   wide screen and under it on a narrow one. */
.mapsplit{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;
  align-items:start}
.mapsplit #map{height:460px}
.poledrawer{border:1px solid var(--hair);border-radius:6px;padding:12px 14px;
  min-width:0}
.poledrawer h2{margin:0 0 6px;font-size:17px}
.poledrawer h2:focus{outline:none}
.poledrawer h2:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.poledrawer .maptools{margin:6px 0}
.svpane{
  height:300px;border:1px solid var(--hair);border-radius:6px;
  background:var(--tint);padding:14px;overflow:hidden;
}
.svpane p{margin:0 0 10px}
@media (min-width:1180px){
  .mapsplit.open{grid-template-columns:minmax(0,3fr) minmax(300px,2fr)}
}
.pm-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  padding:6px 0;border-bottom:1px solid var(--hair)}
.pm-row input{flex:1;min-width:200px;margin:0}
.pm-row .btn{font-size:13px;padding:5px 10px}
.pm-label{
  background:#b3261e;color:#fff;border-radius:9px;font:600 11px/18px var(--body);
  text-align:center;box-shadow:0 0 0 2px #fff;
}
.formhead{font-size:17px;margin:26px 0 4px}
.pmcard{display:flex;gap:14px;align-items:flex-start;padding:10px 0;
  border-top:1px solid var(--hair)}
.pmcard img{width:220px;max-width:40vw;border-radius:6px;border:1px solid var(--hair)}
.pmcands{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}
.pmcand{border:1px solid var(--hair);border-radius:6px;padding:8px;width:240px}
.pmcand.on{border-color:var(--accent)}
.pmcand img{width:100%;border-radius:4px}
