/* AGS mobile - the ink/paper/brass estate on a phone.
   Palette is the OwnersFirm vault (ink #0B0906, brass #B68B40, paper #F5F1EA)
   crossed with the LIVE wall's visitor classes, so the phone, the wall and the
   vault door all read as one system. */
:root{
  --ink:#0B0906; --ink-2:#100E0A; --ink-3:#171410; --ink-4:#201B15;
  --paper:#F5F1EA;
  --dim:rgba(245,241,234,.62); --faint:rgba(245,241,234,.34); --ghost:rgba(245,241,234,.15);
  --brass:#B68B40; --brass-hi:#D4AF6A; --brass-dim:rgba(182,139,64,.28);
  --line:rgba(182,139,64,.20); --line-2:rgba(245,241,234,.08);
  --human:#63B3ED; --ai:#B678FF; --search:#4FD1A5; --bot:#E6B455;
  --live:#4FD1A5; --red:#E5484D; --amber:#E6B455;
  --r:14px; --r-lg:20px;
  --pad:18px;
  --safe-t:env(safe-area-inset-top,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --tab-h:calc(58px + var(--safe-b));
  --ui:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Inter,system-ui,sans-serif;
  --serif:"EB Garamond",ui-serif,Georgia,"Times New Roman",serif;
  --mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,monospace;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%;overscroll-behavior-y:none}
body{
  background:var(--ink); color:var(--paper); font-family:var(--ui);
  font-size:15px; line-height:1.45; letter-spacing:-.01em;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
/* the estate never sits on flat black: a slow brass bloom from the top */
body::before{
  content:''; position:fixed; inset:0; pointer-events:none; z-index:0;
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(182,139,64,.13), transparent 62%),
    radial-gradient(90% 50% at 50% 108%, rgba(79,209,165,.05), transparent 60%);
}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
a{color:var(--brass-hi);text-decoration:none}

/* ---------- shell ---------- */
#app{position:relative;z-index:1;min-height:100%;display:flex;flex-direction:column}
.scr{
  flex:1; padding:0 var(--pad) calc(var(--tab-h) + 26px);
  animation:rise .32s cubic-bezier(.22,1,.36,1) both;
}
/* The 'to' frame must NOT declare transform.
   animation-fill-mode:both retains the to-frame's declared properties after
   the animation ends, so 'transform:none' persisted as a computed
   matrix(1,0,0,1,0,0) - an identity transform, but still a transform. Any
   transform on an ancestor makes a position:fixed descendant resolve against
   THAT element instead of the viewport, so the Ask composer stopped being
   pinned and scrolled away with the transcript: scroll up to read and the
   input box is gone. Omitting transform here lets it fall back to the base
   value, leaving no containing block behind. */
@keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.scr{animation:none}*{animation-duration:.001ms!important;transition-duration:.001ms!important}}

.chrome{position:sticky;top:0;z-index:30}
.top{
  position:relative; z-index:30; padding:calc(var(--safe-t) + 12px) var(--pad) 11px;
  display:flex; align-items:center; gap:11px;
  background:linear-gradient(var(--ink) 62%, rgba(11,9,6,.86) 88%, transparent);
  backdrop-filter:saturate(150%) blur(14px); -webkit-backdrop-filter:saturate(150%) blur(14px);
}
.mark{
  width:29px;height:29px;border-radius:9px;flex:none;display:grid;place-items:center;
  background:linear-gradient(150deg,var(--brass-hi),var(--brass) 52%,#7C5C24);
  color:#140F06;font-family:var(--serif);font-weight:700;font-size:15px;line-height:1;
  box-shadow:0 2px 12px rgba(182,139,64,.34), inset 0 1px 0 rgba(255,240,205,.5);
}
.top h1{margin:0;font-size:16px;font-weight:600;letter-spacing:-.02em;flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.top .sub{display:block;font-size:11px;font-weight:450;color:var(--faint);letter-spacing:.03em}

.pill{
  display:inline-flex;align-items:center;gap:6px;flex:none;
  padding:6px 11px;border-radius:999px;border:1px solid var(--line);
  background:rgba(182,139,64,.07);font-size:11.5px;font-weight:600;letter-spacing:.02em;
  font-variant-numeric:tabular-nums;
}
.dot{width:6px;height:6px;border-radius:50%;background:var(--live);flex:none}
.dot.on{animation:beat 2.4s ease-in-out infinite;box-shadow:0 0 0 0 rgba(79,209,165,.55)}
@keyframes beat{0%{box-shadow:0 0 0 0 rgba(79,209,165,.5)}70%{box-shadow:0 0 0 7px rgba(79,209,165,0)}100%{box-shadow:0 0 0 0 rgba(79,209,165,0)}}

/* ---------- type ---------- */
.eyebrow{
  font-size:10.5px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  color:var(--brass);margin:26px 0 10px;display:flex;align-items:center;gap:9px;
}
.eyebrow::after{content:'';flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent)}
.eyebrow:first-child{margin-top:14px}
.serif{font-family:var(--serif);font-weight:500;letter-spacing:-.01em}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.03em}
.muted{color:var(--dim)}.faint{color:var(--faint)}

/* ---------- surfaces ---------- */
.card{
  background:linear-gradient(180deg,var(--ink-3),var(--ink-2));
  border:1px solid var(--line-2);border-radius:var(--r);padding:15px;
  box-shadow:0 1px 0 rgba(255,255,255,.03) inset, 0 8px 24px -18px #000;
}
.card + .card{margin-top:10px}
.card.tap{transition:transform .16s cubic-bezier(.22,1,.36,1),border-color .16s}
.card.tap:active{transform:scale(.985);border-color:var(--brass-dim)}
.card.red{border-color:rgba(229,72,77,.34);background:linear-gradient(180deg,rgba(229,72,77,.10),var(--ink-2))}
.card.amber{border-color:rgba(230,180,85,.30);background:linear-gradient(180deg,rgba(230,180,85,.08),var(--ink-2))}

/* headline slab: the one number that matters */
.slab{
  border:1px solid var(--line);border-radius:var(--r-lg);padding:19px 18px;
  background:
    radial-gradient(120% 130% at 0% 0%, rgba(182,139,64,.14), transparent 58%),
    linear-gradient(180deg,var(--ink-3),var(--ink-2));
  position:relative;overflow:hidden;
}
.slab .big{font-family:var(--serif);font-size:34px;line-height:1.1;letter-spacing:-.025em;margin:0 0 6px}
.slab .say{color:var(--dim);font-size:13.5px;margin:0}

/* vitals */
.vitals{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-2);
  border:1px solid var(--line-2);border-radius:var(--r);overflow:hidden}
.vital{background:var(--ink-2);padding:12px 8px;text-align:center}
.vital .v{font-family:var(--mono);font-size:19px;font-weight:600;letter-spacing:-.04em;display:block;line-height:1.15}
.vital .k{font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-top:3px;display:block}
.vital.live .v{color:var(--live)}

/* ---------- canvas heroes ---------- */
.stage{
  position:relative;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  background:radial-gradient(90% 90% at 50% 42%, #0E0C09, #070605 70%, #050403);
}
.stage canvas{display:block;width:100%;touch-action:none}
/* The real engines own their gestures: PMAP pinch-zooms a continuous axis, the
   galaxy pans and pinches, RECON pans and taps. touch-action:pan-y would let
   Safari steal the vertical component of every drag, so the page must not
   scroll while a finger is on a stage. */
.stage-globe canvas{height:58vh;min-height:340px}
/* The galaxy keeps the desktop's gxFit verbatim, and the empire is wider than
   it is tall. A full-height portrait canvas fits to the WIDTH and leaves dead
   space above and below, so the galaxy gets a card-shaped stage instead. */
.stage-card canvas{height:44vh;min-height:300px}
.capline{margin:9px 0 0;font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.stage .cap{
  position:absolute;left:13px;right:13px;bottom:11px;display:flex;align-items:flex-end;
  justify-content:space-between;gap:10px;pointer-events:none;
}
.stage .cap .t{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);font-weight:700}
.legend{display:flex;gap:12px;flex-wrap:wrap;margin-top:11px}
.legend i{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--dim);font-style:normal}
.legend i::before{content:'';width:7px;height:7px;border-radius:50%;background:currentColor;box-shadow:0 0 8px currentColor}
.legend .h{color:var(--human)}.legend .a{color:var(--ai)}.legend .s{color:var(--search)}.legend .b{color:var(--bot)}

/* ---------- rows ---------- */
.row{display:flex;gap:12px;align-items:flex-start}
.row .grow{flex:1;min-width:0}
.ttl{font-size:14.5px;font-weight:600;letter-spacing:-.015em;margin:0 0 3px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sub2{font-size:12.5px;color:var(--dim);margin:0;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.meta{display:flex;gap:8px;flex-wrap:wrap;margin-top:9px;font-size:11px;color:var(--faint)}
.meta b{font-weight:600;color:var(--dim);font-family:var(--mono);font-size:10.5px}
.tag{
  display:inline-block;padding:3px 8px;border-radius:6px;font-size:10px;font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;border:1px solid currentColor;
}
.tag.lead{color:var(--live)}.tag.hot{color:var(--red)}.tag.cold{color:var(--faint)}
.tag.warm{color:var(--amber)}.tag.brass{color:var(--brass)}

/* actions */
.acts{display:flex;gap:9px;margin-top:13px}
.btn{
  flex:1;padding:11px 14px;border-radius:11px;font-size:13.5px;font-weight:600;
  border:1px solid var(--line);background:var(--ink-4);text-align:center;
  transition:transform .14s cubic-bezier(.22,1,.36,1),background .14s;
}
.btn:active{transform:scale(.97)}
.btn.go{background:linear-gradient(180deg,var(--brass-hi),var(--brass));color:#140F06;border-color:transparent;
  box-shadow:0 4px 16px -6px rgba(182,139,64,.7)}
.btn.no{color:var(--dim)}
.btn[disabled]{opacity:.45;pointer-events:none}

/* answering a stuck worker, in place.
   A worker.question row cannot be approved; it is waiting for words. The box
   opens under the card so Jacob never leaves the list to unstick a lane. */
.answerbox{margin-top:11px;display:flex;flex-direction:column;gap:9px}
/* display:flex beats the hidden attribute's UA display:none, so every box
   rendered open. Attribute selectors need to win explicitly. */
.answerbox[hidden]{display:none}
.answerbox textarea{
  width:100%;box-sizing:border-box;resize:vertical;min-height:74px;
  background:var(--ink-4);color:var(--paper);font:inherit;font-size:14px;
  border:1px solid var(--line);border-radius:11px;padding:11px 12px;
  -webkit-appearance:none;
}
.answerbox textarea::placeholder{color:var(--faint)}
.answerbox textarea:focus{outline:none;border-color:var(--brass-dim)}
.answerbox .btn{flex:none}
.whyno{
  align-self:center;font-size:11.5px;color:var(--faint);letter-spacing:.01em;
  padding-left:2px;
}

/* ---------- tab bar ---------- */
.tabs{
  position:fixed;left:0;right:0;bottom:0;z-index:40;
  display:grid;grid-template-columns:repeat(5,1fr);
  padding:7px 6px var(--safe-b);
  background:rgba(13,11,8,.82);backdrop-filter:saturate(180%) blur(22px);
  -webkit-backdrop-filter:saturate(180%) blur(22px);
  border-top:1px solid var(--line-2);
}
.tab{display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 2px 6px;
  color:var(--faint);transition:color .18s;position:relative}
.tab svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.tab span{font-size:9.5px;font-weight:600;letter-spacing:.02em}
.tab.sel{color:var(--brass-hi)}
.tab.sel::before{content:'';position:absolute;top:0;width:20px;height:2px;border-radius:2px;
  background:var(--brass-hi);box-shadow:0 0 10px var(--brass-hi)}
.tab .badge{
  position:absolute;top:2px;right:calc(50% - 19px);min-width:16px;height:16px;padding:0 4px;
  border-radius:9px;background:var(--red);color:#fff;font-size:10px;font-weight:700;
  display:grid;place-items:center;font-variant-numeric:tabular-nums;
  box-shadow:0 0 0 2px rgba(13,11,8,.9);
}

/* ---------- states ---------- */
.skel{background:linear-gradient(90deg,var(--ink-3) 25%,var(--ink-4) 50%,var(--ink-3) 75%);
  background-size:200% 100%;animation:sweep 1.35s ease-in-out infinite;border-radius:8px}
@keyframes sweep{to{background-position:-200% 0}}
.empty{text-align:center;padding:44px 20px;color:var(--faint)}
.empty .g{font-family:var(--serif);font-size:20px;color:var(--dim);margin-bottom:6px}
.err{border:1px solid rgba(229,72,77,.4);background:rgba(229,72,77,.09);border-radius:var(--r);
  padding:13px;font-size:13px;color:#FFC9CB;margin-top:12px}

/* pull to refresh */
#ptr{position:fixed;top:0;left:0;right:0;height:0;z-index:25;display:grid;place-items:end center;
  pointer-events:none;overflow:hidden}
#ptr .ring{width:20px;height:20px;border-radius:50%;border:2px solid var(--brass-dim);
  border-top-color:var(--brass-hi);margin-bottom:7px}
#ptr.spin .ring{animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* toast */
/* translateY alone left the panel peeking above the tab bar, which read as a
   permanent empty box on every screen. Hide it outright when it is down. */
#toast{position:fixed;left:14px;right:14px;bottom:calc(var(--tab-h) + 12px);z-index:60;
  transform:translateY(24px);opacity:0;visibility:hidden;pointer-events:none;
  transition:transform .34s cubic-bezier(.22,1,.36,1),opacity .24s,visibility 0s linear .34s}
#toast.up{transform:none;opacity:1;visibility:visible;transition-delay:0s}
#toast .t{background:var(--ink-4);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;font-size:13px;box-shadow:0 18px 40px -18px #000}
#toast.bad .t{border-color:rgba(229,72,77,.5)}

/* pairing */
.pair{max-width:400px;margin:0 auto;padding-top:9vh}
.pair input{
  width:100%;padding:15px;border-radius:13px;border:1px solid var(--line);
  background:var(--ink-2);color:var(--paper);font-family:var(--mono);font-size:19px;
  text-align:center;letter-spacing:.22em;margin:16px 0 12px;
}
.pair input:focus{outline:none;border-color:var(--brass);box-shadow:0 0 0 3px rgba(182,139,64,.15)}

/* chat */
.msgs{display:flex;flex-direction:column;gap:11px;padding-top:6px}
.msg{max-width:86%;padding:11px 14px;border-radius:16px;font-size:14px;line-height:1.5;
  white-space:pre-wrap;word-break:break-word}
.msg.me{align-self:flex-end;background:linear-gradient(180deg,var(--brass),#96702F);color:#140F06;
  border-bottom-right-radius:5px;font-weight:500}
.msg.ags{align-self:flex-start;background:var(--ink-3);border:1px solid var(--line-2);
  border-bottom-left-radius:5px}
.composer{position:fixed;left:0;right:0;bottom:var(--tab-h);z-index:35;display:flex;gap:9px;
  padding:10px var(--pad) 11px;background:rgba(13,11,8,.9);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);border-top:1px solid var(--line-2)}
.composer textarea{
  flex:1;resize:none;max-height:110px;padding:11px 13px;border-radius:13px;
  border:1px solid var(--line);background:var(--ink-2);color:var(--paper);
  font-family:var(--ui);font-size:15px;line-height:1.4;
}
.composer textarea:focus{outline:none;border-color:var(--brass-dim)}
.composer .send{width:42px;flex:none;border-radius:13px;display:grid;place-items:center;
  background:linear-gradient(180deg,var(--brass-hi),var(--brass));color:#140F06}
.composer .send:active{transform:scale(.94)}
.composer .send[disabled]{opacity:.4}

/* Simple / Satellite, sitting on the globe like the desktop's pair */
.stage-globe{position:relative}
.mapmode{
  position:absolute;top:10px;right:10px;z-index:5;display:flex;gap:6px;
  background:rgba(9,12,20,.62);border:1px solid rgba(150,175,230,.16);
  border-radius:10px;padding:3px;backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
}
.mapmode .mm{
  font-size:10.5px;font-weight:600;letter-spacing:.02em;padding:5px 10px;
  border-radius:7px;color:#8b91ad;
}
.mapmode .mm.on{color:#e8eaf6;background:rgba(120,140,220,.24)}

/* ---------- sub-tab strip ----------
   The desktop shows a group strip under the title; the phone gets the same
   thing, scrolled horizontally. It is sticky UNDER the header, so the section
   you are in stays legible while the list moves. */
.strip{
  position:relative; z-index:29;
  display:flex; gap:7px; overflow-x:auto; overflow-y:hidden;
  padding:2px var(--pad) 11px;
  background:linear-gradient(var(--ink) 72%, rgba(11,9,6,.9) 92%, transparent);
  -webkit-overflow-scrolling:touch; scrollbar-width:none;
}
.strip::-webkit-scrollbar{display:none}
.strip[hidden]{display:none}
.strip .sub{
  flex:none; padding:7px 13px; border-radius:999px; font-size:12.5px; font-weight:600;
  letter-spacing:.01em; color:var(--dim);
  border:1px solid var(--line-2); background:var(--ink-3);
  transition:color .16s, border-color .16s, background .16s;
}
.strip .sub:active{transform:scale(.97)}
.strip .sub.sel{
  color:#140F06; border-color:transparent;
  background:linear-gradient(180deg,var(--brass-hi),var(--brass));
}

/* Ask reserves room for the composer, which is pinned outside .scr */
.scr.chat{padding-bottom:calc(var(--tab-h) + 96px)}
.msg.ags code{
  font-family:var(--mono,ui-monospace,SFMono-Regular,Menlo,monospace);
  font-size:12.5px;background:var(--ink-4);border:1px solid var(--line-2);
  border-radius:6px;padding:1px 5px;
}
.msg.ags b{color:var(--brass-hi);font-weight:650}

/* Receipt: what you already did to this row, and whether it moved.
   A worker that answers and asks a FOLLOW-UP renders an almost identical card,
   so without this a working loop is indistinguishable from a dead button. */
.receipt{
  margin-top:9px;padding:7px 10px;border-radius:9px;font-size:12px;line-height:1.4;
  color:var(--dim);background:var(--ink-4);border:1px solid var(--line-2);
}
.receipt.moved{
  color:#F2E4C4;border-color:rgba(182,139,64,.42);
  background:linear-gradient(180deg,rgba(182,139,64,.16),rgba(182,139,64,.06));
}
