/* Stage styles. Ported from ep-persona-v0.html. */
:root{
  --ink:#0a0c0f;
  --ink-lift:#11151a;
  --glow-warm:#2f9c6e;
  --glow-cool:#4a58d8;
  --speech:#eef1f2;
  --ahead:#6f7880;
  --quiet:#79838c;
  --faint:#454d55;
  --line:#1d232a;
  --card:#141920;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--ink);
  color:var(--speech);
  font-family:"IBM Plex Sans",system-ui,-apple-system,sans-serif;
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
  cursor:default;
}
[hidden]{display:none!important}
/* The end screen is the one thing a visitor keeps: once it is up, the page scrolls. */
body.reading{overflow-y:auto;-webkit-overflow-scrolling:touch}

/* The keyboard is up on a phone (stage.js, body.keyboard): his question stays in view right
   above what they're typing into. The browser shrinks the visible area and pans to the input;
   the question, mid-screen, went off the top and people answered a question they could no
   longer see (Danny, 2026-09-18). The stage covers exactly the visible area (--vv-top and
   --vv-h from the visual viewport), the figure gets small but keeps its states, and his words
   sit at the bottom of the column, over the box or the typed line. */
body.keyboard #stage{
  position:fixed;left:0;right:0;top:var(--vv-top,0px);height:var(--vv-h,100%);
  padding:10px 16px calc(8px + env(safe-area-inset-bottom));
  grid-template-rows:minmax(0,1fr) auto;
}
/* Pushed down by an auto margin, not end-aligned: when the column is too short, end-aligned
   content goes off the top out of reach; this way it overflows downward and scrolls. Nothing in
   it shrinks: the question once collapsed to nothing and its words ran under the box. */
body.keyboard #left{justify-content:flex-start;overflow-y:auto;min-height:0}
body.keyboard #left > *{flex-shrink:0}
body.keyboard #left > :first-child{margin-top:auto}
/* A scrolling column clips whatever reaches past its edges, and his glow reaches a third of
   his size past him: at the column's edge it was cut off on the left and showed as a box
   (Danny's iPhone, 2026-09-18). The column runs to the screen's edges with the stage's
   gutter as its own padding, so the glow has room inside it. */
body.keyboard #left{margin:0 -16px;padding:22px 16px 0}
body.keyboard #figure{width:34px;height:54px;margin-bottom:10px;margin-left:12px}
body.keyboard #figure .veil{inset:-30%}
body.keyboard #speech{min-height:0;font-size:19px;line-height:1.38}
body.keyboard #trust,body.keyboard #shelf,body.keyboard #mute-voice{display:none}
/* Typing into a box: the typed line under it is disabled anyway, and the room goes to the box. */
body.keyboard.in-box:has(#field-capture) #floor{display:none}
body.keyboard #field-capture{margin-top:12px}
body.keyboard #typed{margin-top:8px;padding-top:10px}

/* the room: light falls from him */
#room{
  position:fixed;inset:0;
  background:
    radial-gradient(60% 50% at 38% 42%, rgba(47,156,110,.13), transparent 70%),
    radial-gradient(45% 40% at 42% 38%, rgba(74,88,216,.10), transparent 70%),
    var(--ink);
  transition:background 1.4s ease;
}
#stage{
  position:relative;height:100%;
  display:grid;
  grid-template-columns:1fr minmax(0,420px);
  grid-template-rows:1fr auto;
  gap:0 48px;
  padding:clamp(20px,4vw,56px);
  max-width:1380px;margin:0 auto;
}
#left{
  grid-column:1;grid-row:1;
  display:flex;flex-direction:column;justify-content:center;
  min-width:0;
  transition:transform .9s cubic-bezier(.2,.7,.2,1);
}

/* him */
#figure{
  margin-left:10px;  /* room for the listening ring at narrow widths */
  width:clamp(92px,11vw,132px);
  height:clamp(150px,18vw,214px);
  margin-bottom:clamp(28px,4vh,48px);
  position:relative;
  opacity:0;
  animation:wake 2.6s cubic-bezier(.2,.7,.2,1) .25s forwards;
}
@keyframes wake{to{opacity:1}}
#figure .core{
  position:absolute;inset:0;
  border-radius:48% 48% 44% 44% / 62% 62% 38% 38%;
  background:linear-gradient(168deg,rgba(90,214,163,.92),rgba(47,156,110,.6) 42%,rgba(74,88,216,.5));
  filter:blur(13px);
  transform-origin:50% 88%;
  animation:breathe 6.5s ease-in-out infinite;
}
#figure .veil{
  position:absolute;inset:-34%;
  border-radius:50%;
  background:radial-gradient(circle at 50% 42%,rgba(90,214,163,.2),transparent 62%);
  filter:blur(22px);
  animation:breathe 6.5s ease-in-out infinite reverse;
}
@keyframes breathe{
  0%,100%{transform:scaleY(1) scaleX(1);opacity:.92}
  50%{transform:scaleY(1.045) scaleX(.985);opacity:1}
}

/* his three states, carried in the figure alone (build order §5 Beat 0, rule 9) */

/* idle: small, dim, asleep */
#figure .core{transition:filter .25s ease,opacity .25s ease,transform .25s ease}
#figure:not(.listening):not(.speaking):not(.working) .core{opacity:.55;transform:scale(.9);filter:blur(16px)}
#figure:not(.listening):not(.speaking):not(.working) .veil{opacity:.3}

/* speaking: big, bright, moving */
#figure.speaking .core{animation:speak 1.15s ease-in-out infinite;filter:blur(9px);opacity:1}
#figure.speaking .veil{animation:speak 1.15s ease-in-out infinite reverse;opacity:1;transform:scale(1.1)}
@keyframes speak{
  0%,100%{transform:scaleY(1) scaleX(1);opacity:.9}
  50%{transform:scaleY(1.16) scaleX(.95);opacity:1}
}

/* listening: sharp, wide open, and it answers the visitor's voice (--voice, 0 to 1).
   The ring is the tell: it exists in no other state, and it breathes with them. */
#figure.listening .core{
  animation:none;
  filter:blur(6px);
  transform:scale(calc(1.06 + var(--voice,0) * .12));
  opacity:1;
  transition:transform .08s ease-out,opacity .08s ease-out;
}
#figure.listening .veil{
  animation:none;
  background:radial-gradient(circle at 50% 42%,rgba(110,236,183,.42),transparent 62%);
  transform:scale(calc(1.2 + var(--voice,0) * .34));
  opacity:calc(.7 + var(--voice,0) * .3);
  transition:transform .08s ease-out,opacity .08s ease-out;
}
#figure.listening::after{
  content:"";
  position:absolute;inset:-30%;
  border-radius:50%;
  border:1px solid rgba(110,236,183,calc(.12 + var(--voice,0) * .26));
  box-shadow:0 0 30px rgba(90,214,163,calc(.04 + var(--voice,0) * .12)) inset;
  transform:scale(calc(.98 + var(--voice,0) * .1));
  transition:transform .08s ease-out,border-color .08s ease-out;
}

/* working: he turns inward — the light goes cool and circles */
#figure.working .core{animation:breathe 3.4s ease-in-out infinite;filter:blur(18px);opacity:.5;
  background:linear-gradient(168deg,rgba(120,140,240,.85),rgba(74,88,216,.55) 45%,rgba(47,156,110,.35))}
#figure.working .veil{
  animation:circle 2.6s linear infinite;opacity:.9;
  background:conic-gradient(from 0deg,rgba(120,140,240,.5),transparent 42%,transparent 70%,rgba(120,140,240,.5));
}
@keyframes circle{
  0%{transform:rotate(0deg) scale(1.02)}
  50%{transform:rotate(180deg) scale(1.12)}
  100%{transform:rotate(360deg) scale(1.02)}
}

@media (prefers-reduced-motion:reduce){
  #figure .core,#figure .veil{animation:none!important;transition:none!important}
  #figure{animation:none;opacity:1}
  /* the states still have to be distinguishable without motion */
  #figure.listening .veil{opacity:1;transform:scale(1.4)}
  #figure.listening::after{transform:scale(1.05)}
  #figure.speaking .core{filter:blur(9px);transform:scale(1.12)}
  #figure.working .core{opacity:.55}
  #figure.working .veil{opacity:.4;transform:scale(.9)}
}

/* his words: what he has said is bright, what he is about to say waits in grey */
#speech{
  font-family:"Newsreader",Georgia,serif;
  font-optical-sizing:auto;
  font-weight:300;
  font-size:clamp(21px,2.7vw,34px);
  line-height:1.42;
  letter-spacing:-.01em;
  max-width:19em;
  min-height:4.4em;
  color:var(--speech);
}
#speech .said{display:block;color:#5d666e;font-size:.62em;line-height:1.5;margin-bottom:.9em;max-width:26em}
#speech .ahead{color:var(--ahead)}

/* the quiet lines under his words */
#go-ahead{
  align-self:flex-start;
  margin-top:26px;
  background:transparent;
  border:1px solid #47515b;
  border-radius:999px;
  color:var(--speech);
  cursor:pointer;
  font-family:"IBM Plex Sans",sans-serif;font-size:16px;letter-spacing:.01em;
  padding:13px 26px;
}
#go-ahead:hover{border-color:#6c7883;background:rgba(255,255,255,.03)}
#go-ahead:focus-visible{outline:2px solid var(--glow-warm);outline-offset:3px}
#trust{
  font-family:"IBM Plex Sans",sans-serif;font-size:13px;letter-spacing:.01em;
  color:var(--quiet);margin-top:14px;max-width:34em;
}
#prefer-type,#mute-voice,#end-here{
  align-self:flex-start;
  background:none;border:none;padding:4px 0;
  margin-top:18px;
  color:var(--quiet);
  cursor:pointer;
  font-family:"IBM Plex Sans",sans-serif;font-size:14px;letter-spacing:.01em;
}
#mute-voice{margin-top:10px}
#end-here{margin-top:8px}
#prefer-type:hover,#prefer-type:focus-visible,
#mute-voice:hover,#mute-voice:focus-visible,
#end-here:hover,#end-here:focus-visible{color:var(--speech);outline:none}
#prefer-type:focus-visible,#mute-voice:focus-visible,#end-here:focus-visible{text-decoration:underline}

/* what he shows */
#shelf{
  grid-column:2;grid-row:1;
  display:flex;flex-direction:column;justify-content:flex-start;gap:16px;
  overflow-y:auto;
  padding:8px 0;
}
/* Centred when it fits, top-aligned when it doesn't: plain centring pushed the top of a tall
   card above the scroll origin, out of reach (the end screen's heading at 1280x720). */
#shelf > :first-child{margin-top:auto}
#shelf > :last-child{margin-bottom:auto}
.card{
  background:var(--card);
  border:1px solid var(--line);
  border-left:2px solid var(--glow-warm);
  border-radius:3px;
  padding:20px 22px;
  box-shadow:0 0 44px rgba(47,156,110,.07);
  animation:rise .7s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.card h3{
  font-family:"IBM Plex Sans",sans-serif;
  font-size:12px;font-weight:500;letter-spacing:.02em;
  color:var(--glow-warm);margin-bottom:10px;
}
.card p{font-family:"Newsreader",Georgia,serif;font-weight:300;font-size:16.5px;line-height:1.58;color:#c3cbd1}
.card.insight{border-left-color:var(--glow-cool);box-shadow:0 0 44px rgba(74,88,216,.09)}
.card.insight h3{color:#8f9bf0}
.card.insight ol{list-style:none;counter-reset:b}
.card.insight li{
  font-family:"Newsreader",Georgia,serif;font-weight:300;font-size:16.5px;line-height:1.55;
  color:#c3cbd1;padding-left:22px;position:relative;margin-bottom:11px;
}
.card.insight li:last-child{margin-bottom:0}
.card.insight li::before{
  counter-increment:b;content:counter(b);
  position:absolute;left:0;top:.18em;
  font-family:"IBM Plex Sans",sans-serif;font-size:11px;color:#6470d4;
}

/* the end: their own words, as the person who reads this will see them */
.card.summary .label{
  font-family:"IBM Plex Sans",sans-serif;font-size:12px;letter-spacing:.02em;
  color:#9aa4ad;margin-bottom:6px;
}
.card.summary .words{font-size:18px;line-height:1.55;color:var(--speech)}
.card.summary .words + .label{margin-top:16px}
.card.summary .words.next{font-family:"IBM Plex Sans",sans-serif;font-size:14px;color:#c3cbd1}
.card.summary .frame{font-family:"IBM Plex Sans",sans-serif;font-size:13px;color:#9aa4ad;margin-right:4px}
.card.summary .built-from{font-family:"IBM Plex Sans",sans-serif;font-size:13px;color:#9aa4ad;margin:10px 0 4px}
.card.summary .built-from .site{color:#c3cbd1}
.card.summary .evidence{list-style:none;margin:0 0 6px;padding:0 0 0 12px;border-left:1px solid #2a3238}
.card.summary .evidence li{font-family:"IBM Plex Sans",sans-serif;font-size:14px;line-height:1.5;color:#c3cbd1;margin:0 0 6px}

/* the typed path: only exists when rule 7c applies */
#floor{grid-column:1 / -1;grid-row:2}
/* a targeted field (rule 11): raised under his words, because this is where they commit.
   The close's pair sits in one frame, and Send stays asleep until both are filled. */
#field-capture{
  margin-top:24px;
  max-width:30em;
  background:var(--card);
  border:1px solid #2c343d;
  border-radius:12px;
  padding:4px 20px 16px;
  box-shadow:0 0 44px rgba(47,156,110,.08);
  animation:rise .7s cubic-bezier(.2,.7,.2,1) both;
}
.field-row{
  display:flex;align-items:baseline;gap:14px;
  border-bottom:1px solid #262d35;
  transition:border-color .2s ease;
}
.field-row:focus-within{border-bottom-color:var(--glow-warm)}
.field-row label{
  flex:none;width:4.2em;
  font-family:"IBM Plex Sans",sans-serif;font-size:13px;letter-spacing:.02em;
  color:#9aa4ad;
}
.field-row input{
  flex:1;min-width:0;background:transparent;border:none;outline:none;
  color:var(--speech);
  font-family:"Newsreader",Georgia,serif;font-weight:300;
  font-size:clamp(18px,1.7vw,21px);
  padding:14px 2px 12px;
}
.field-foot{
  display:flex;align-items:center;justify-content:flex-end;gap:16px;
  margin-top:16px;
}
.field-note{
  margin-right:auto;
  font-family:"IBM Plex Sans",sans-serif;font-size:13px;color:#9aa4ad;
}
#field-capture button{
  background:rgba(47,156,110,.12);
  border:1px solid var(--glow-warm);
  border-radius:999px;
  color:var(--speech);
  cursor:pointer;
  font-family:"IBM Plex Sans",sans-serif;font-size:15px;letter-spacing:.01em;
  padding:10px 24px;
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
#field-capture button:hover{background:rgba(47,156,110,.22)}
#field-capture button:focus-visible{outline:2px solid var(--glow-warm);outline-offset:3px}
#field-capture button:disabled{
  background:transparent;border-color:#333b44;color:#5d666e;cursor:default;
}
#typed{
  border-top:1px solid var(--line);
  padding-top:16px;margin-top:20px;
  display:flex;align-items:center;gap:14px;
  animation:rise .7s cubic-bezier(.2,.7,.2,1) both;
}
#reply{
  flex:1;background:transparent;border:none;outline:none;
  color:var(--speech);
  font-family:"Newsreader",Georgia,serif;font-weight:300;
  font-size:clamp(16px,1.5vw,19px);
  padding:10px 2px;
}
#reply::placeholder{color:#4e575f}
#reply:focus-visible{box-shadow:0 2px 0 var(--glow-warm)}
#send{
  background:transparent;border:1px solid var(--line);color:var(--quiet);
  border-radius:999px;width:38px;height:38px;cursor:pointer;flex:none;
  font-size:16px;line-height:1;
}
#send:hover{border-color:#3a4049;color:#aab3ba}

@media (max-width:880px){
  #stage{grid-template-columns:1fr;gap:0;padding:18px}
  #left{grid-row:1}
  #shelf{grid-column:1;grid-row:2;max-height:34vh;justify-content:flex-start}
  /* At the end there is nothing else on screen, so their words get the room they need, and
     the page itself scrolls to them: the card runs well past the fold on a phone, and with the
     stage locked to the screen's height half of it was unreachable (Danny, 2026-09-18). */
  body.reading #shelf{max-height:none;overflow:visible}
  body.reading #stage{height:auto;min-height:100%;padding-bottom:calc(32px + env(safe-area-inset-bottom))}
  #floor{grid-row:3}
  #speech{min-height:3.4em}
  #figure{margin-bottom:20px}
}
