/* ==========================================================================
   EVAL · ask.css — the assistant surface (panel on iPad, full page on phone).
   Owner: ask agent. Tokens from tokens.css, primitives from components.css
   (.card.panel, .pill, .chip, .tile, .inputpill, .num, .empty).
   Every value is a token: ink on the purple gradient is var(--onGrad), the same
   one components.css uses for .btn-primary, .pill.solid and .avatar.
   ========================================================================== */

/* ---------- the surface ------------------------------------------------- */
.ask {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.ask.ask-panel {
  height: 100%;
  flex: 1;
  padding: 18px;
}
.ask.ask-page {
  padding: 6px 0 0;
}

/* ---------- head: mark + name + path pill, then the greeting ------------ */
/* Two rows, on every frame: who is speaking and which path she is answering on
   the first, the greeting on its own below it. One row cannot hold a mark, a
   name tag, a 22px greeting and a status pill at 1024px without ellipsising the
   GM's own name — and the greeting is the line this panel exists for. */
.ask-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 11px;
  row-gap: 9px;
  flex: 0 0 auto;
  min-width: 0;
  transition: opacity .18s ease, transform .18s ease;
}
/* reading down the thread: the head folds away and the thread takes its height;
   the fold is a switch (no height animation, laws §3), the fade is the motion */
.ask.headhide .ask-head { height: 0; min-height: 0; overflow: hidden; opacity: 0; transform: translateY(-8px); margin: 0; pointer-events: none; }
/* the mark itself is .gmark in components.css — one shape for every surface
   the assistant heads; this file only says where it sits. .ask-name is the one
   place Val's own name sits: the lavender chip the top bar also uses, never a
   caption — but set in the APP'S OWN TYPE, not --font-mono.

   It was mono, to match the "AI" tag beside the EVAL wordmark. The round-2
   integration pass had already moved the assistant's "Read from" receipt off
   mono for the reason that applies twice as hard here — monospace reads as debug
   output in a product whose voice is otherwise plain prose — and this was the
   one place the assistant is NAMED, wearing the identical chip to a product
   mark two inches away. Val came out as a variable rather than as the person the
   GM is about to talk to. Mono is the product mark's alone now; the chip, its
   colour and its size are unchanged, so nothing else about the head moves. */
.ask-name {
  font-family: var(--font-head); font-size: var(--fs-pill); font-weight: 700;
  letter-spacing: .2px; color: var(--purInk); background: var(--lav);
  border-radius: var(--r-xs); padding: 3px 7px; line-height: 1; flex: 0 0 auto;
}
.ask-head h1 {
  order: 3;
  flex: 1 0 100%;
  min-width: 0;
  font-family: var(--font-head);
  font-size: var(--fs-h1);
  font-weight: 800;
  letter-spacing: var(--ls-tight);
  color: var(--ink);
  line-height: var(--lh-tight);
  overflow: hidden;
}
/* The head's one pill: which path answered (Connected to the model on the
   store's own server, or Local — the reports on this device). It is a real
   control, because "why is it local this morning" is a single fact and a
   pop-up is where a single fact lives. The dot is chrome; the word is the
   status, so nothing here is told in colour alone (laws §5). The date used to
   sit in this slot and the top bar carries it two inches above — home.css was
   already dropping this second copy below 1180px for that reason. */
.ask-net {
  flex: 0 0 auto;
  margin-left: auto;
  background: var(--card);
  color: var(--ink2);
  border: 1px solid var(--line);
  padding: 6px 10px 6px 11px;
}
.ask-net i {
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--muted2);
  display: block;
  flex: 0 0 auto;
}
.ask-net.live i { background: var(--goodInk); }

/* ---------- the conversation -------------------------------------------- */
.ask-thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 15px 2px 4px;
  margin: 0 -2px;
}
.ask-page .ask-thread { padding-top: 13px; }
/* BOTH edges get the same care, and the depth is a number rather than three
   copies of a gradient. The foot was reasoned out first — 38px, deeper than one
   line of body type (22px), so a cut never lands mid-letter at full ink — and
   the top was left at 20px, which is LESS than one line. Measured at 1180 with
   the thread scrolled: a 16px tile label straddled the top edge by 8px and drew
   at 40-80% ink directly under "Good morning, Quinn.", and an answer's ALL-CAPS
   head came through the same ramp with its capitals cut square. One line of the
   scrolled conversation read as broken rendering on every scroll, on the surface
   Quinn calls his favourite. The top is now the foot's own depth.

   Three depths, declared once and used by all three states, because the mask was
   being restated as a whole gradient every time one surface wanted a different
   number — and home.css was restating it a fourth time for the panel, which is
   how the top edge kept its 20px there after this rule gave it 38. A surface
   that wants a deeper dissolve sets the NUMBER now:
     --askFadeTop       how far the top ramps up to full ink
     --askFadeFoot      the same at the foot
     --askFadeFootFlat  how much of the foot is clear BEFORE the ramp starts, for
                        a box tall enough to afford it (the Home panel: a cut can
                        land anywhere inside a line, so the deepest part of one is
                        fully gone and full ink is two lines up) */
.ask-thread { --askFadeTop: 38px; --askFadeFoot: 38px; --askFadeFootFlat: 0px; }
.ask-thread.sc {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--askFadeTop));
  mask-image: linear-gradient(to bottom, transparent 0, black var(--askFadeTop));
}
.ask-thread.more {
  -webkit-mask-image: linear-gradient(to top, transparent 0, transparent var(--askFadeFootFlat), black var(--askFadeFoot));
  mask-image: linear-gradient(to top, transparent 0, transparent var(--askFadeFootFlat), black var(--askFadeFoot));
}
.ask-thread.sc.more {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--askFadeTop), black calc(100% - var(--askFadeFoot)), transparent calc(100% - var(--askFadeFootFlat)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black var(--askFadeTop), black calc(100% - var(--askFadeFoot)), transparent calc(100% - var(--askFadeFootFlat)), transparent 100%);
}

/* ---------- bubbles ------------------------------------------------------ */
/* One content width for the whole thread. The answer card, the question bubble,
   the suggested chips and the input pill all flush to the same left and right
   inset; the only floating edge in the column is the question bubble's LEFT one,
   because that bubble is the one thing hung off the right. Before this the answer
   card stopped 47px short of the column on the iPad and 22px short on the phone,
   so a 505px column carried three different right edges. */
.ask-b {
  padding: 14px 16px;
  border-radius: var(--r) var(--r) var(--r) var(--r-xs);
  flex: 0 0 auto;
}
.ask-b.a {
  align-self: stretch;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}
.ask-b.u {
  align-self: flex-end;
  max-width: 82%;
  background: var(--grad);
  border-radius: var(--r) var(--r) var(--r-xs) var(--r);
  box-shadow: var(--glow);
}
.ask-b p {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 450;
  color: var(--ink2);
}
.ask-b p + p { margin-top: 9px; }
/* a figure is one object: never let "−$26.1K" break after the minus sign */
.ask-b .num, .ask-tiles .tile b { white-space: nowrap; }
.ask-b.u p { color: var(--onGrad); font-weight: 500; }
/* the thinking bubble is a placeholder, not content: it holds three dots, so it
   stays the size of three dots rather than opening a card-wide empty rectangle */
.ask-b.a.dots { align-self: flex-start; padding: 15px 18px; }

/* word-tick reveal (24ms a word; reduced motion lands them all at once) */
.ask-b .w { opacity: 0; transition: opacity 110ms linear; }
.ask-b .w.on { opacity: 1; }
.ask-b.open .w { opacity: 1; }

/* ---------- typing dots -------------------------------------------------- */
.ask-dots { display: inline-flex; align-items: center; gap: 6px; height: 14px; }
.ask-dots i {
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--muted2);
  animation: askDot 1.05s var(--ease) infinite;
}
.ask-dots i:nth-child(2) { animation-delay: .15s; }
.ask-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes askDot {
  0%, 60%, 100% { opacity: .32; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}
/* base.css shortens every animation to 1ms under reduced motion, which stops a
   one-shot but makes an INFINITE one restart a thousand times a second — the
   dots strobed at the display's refresh rate instead of going still, the one
   thing reduced motion exists to prevent. The loop is switched off here, and the
   dots hold the resting state the keyframes start from. Any future infinite
   animation in this app needs the same override. */
@media (prefers-reduced-motion: reduce) {
  .ask-dots i { animation: none; opacity: .6; transform: none; }
}

/* ---------- the answer's blocks ----------------------------------------- */
/* The pictures are EVAL.viz's (css/viz.css): the ring an answer draws is the
   Pace curtain's ring. The tile grid inside a `kpis` block also carries
   .ask-tiles, because that is the name the answer column is measured by
   (tests/suites/11b-ask-column.cjs) — the geometry below is the same grid
   viz.css gives .viz-grid, and it is what draws the grid in the one case viz is
   not on the page at all.
   No half-empty rows and no trailing tile at double the area of its siblings:
   one tile fills the width, two pair up, three run across in one row on BOTH
   frames, four make the 2x2. A third tile spanning the pair was an orphan that
   read as a layout which ran out of items; three even columns hold the widest
   figure these answers print (81.4% is 67px in a 78px column) without shrinking
   the type, so the figures stay the same size they are everywhere else. */
.ask-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
/* only when the grid IS the block, drawn straight into the bubble: inside a
   viz stack the stack already carries the gap above it */
.ask-b > .ask-tiles { margin-top: 13px; }
.ask-tiles .tile { background: var(--surf2); border-color: var(--line2); }
.ask-tiles .tile b { font-size: var(--fs-d3); letter-spacing: -.7px; }
/* a figure that does not fit its column steps down the type scale instead of
   being cut (the walk prints "1,632 vs 380" into a slot sized for "81.4%") */
.ask-tiles .tile.fit b { font-size: var(--fs-h2); letter-spacing: -.3px; }
.ask-tiles .tile.fit2 b { font-size: var(--fs-row); letter-spacing: -.1px; }
/* the last step is the family's floor: nothing in EVAL is set under 11px, so a
   figure that will not fit at 12px keeps its size and the column gives way */
.ask-tiles .tile.fit3 b { font-size: var(--fs-pill); letter-spacing: 0; }
.ask-tiles[data-n="1"] { grid-template-columns: minmax(0, 1fr); }
.ask-tiles[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* ---------- what the answer lets you DO --------------------------------- */
/* The action row: a task on today's walk, that task handed to someone, or the
   curtain the answer came out of. Buttons, not chips — a chip in EVAL is a
   question you can ask, and these are things that happen. */
.ask-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 13px;
}
.ask-acts .btn { padding: 0 15px; }
.ask-acts .btn svg { color: var(--muted2); }
/* one gradient in the row — the thing the answer is FOR (hand it to someone, put
   it on the walk). Its glyph rides on the gradient, so it cannot stay muted. */
.ask-acts .btn-primary svg { color: currentColor; opacity: .9; }

/* ---------- the Read from line ------------------------------------------ */
/* The receipt under an answer, set in the app's own type. In monospace it read
   as debug output printed under the reply rather than as the reports the GM
   knows by name. */
.ask-src {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--line2);
  font-size: var(--fs-pill);
  line-height: 1.35;
}
.ask-src .lb { color: var(--muted2); font-weight: 600; letter-spacing: .2px; }
.ask-src .dv { color: var(--line3); }
.ask-src b { font-family: var(--font-head); color: var(--ink2); font-weight: 700; letter-spacing: -.1px; }

/* ---------- the "add as today's task" pop-up ---------------------------- */
/* One decision: what goes on the walk, what will prove it, and who owns it.
   The owner is picked here because a pop-up opens nothing (laws §1). */
.ask-cf {
  font-family: var(--font-head);
  font-size: var(--fs-h2);
  font-weight: 700;
  letter-spacing: var(--ls-head);
  color: var(--ink);
  line-height: var(--lh-tight);
  margin-bottom: 12px;
}
.popup-body .ask-cf + .kv { border-top: 1px solid var(--line2); }
/* the picker scrolls, not the whole pop-up: what is being added and what will
   prove it stay on screen while the GM looks for a name. 168px is three whole
   rows and half of the fourth — the cut is where it says "there are more", not
   wherever 46vh happened to land. */
/* A WHOLE NUMBER OF ROWS, never a pixel count that happens to land mid-name. The
   box was 168px against 44px rows and a 7px gap, so three rows (146px) fitted and
   15px of the fourth showed under them: on the iPad the OWNER grid drew Daina
   Dzenkovska / Nana Prempeh intact and Harrison England / Ryker Stokes sliced
   horizontally through the x-height, directly above the Add button, which reads as a
   rendering failure rather than as "there is more". 44*3 + 7*2 = 146 exactly, so the
   fade can only ever land in a gutter. */
.ask-pick {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin-top: 6px;
  max-height: 144px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.ask-pick-row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding: 0 9px;
  border-radius: var(--r-sm);
  background: var(--surf2);
  border: 1px solid var(--line2);
  text-align: left;
  transition: transform var(--dur-liftUp) var(--ease), background-color var(--dur-pill) var(--ease);
}
.ask-pick-row .nm {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-row);
  font-weight: 600;
  color: var(--ink2);
  letter-spacing: -.1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ask-pick-row.on { background: var(--lav); border-color: var(--line3); }
.ask-pick-row.on .nm { color: var(--purInk); }

/* ---------- suggested questions + the input pill ------------------------ */
.ask-foot { flex: 0 0 auto; display: flex; flex-direction: column; gap: 12px; padding-top: 12px; }
.ask-chips { display: flex; flex-direction: column; gap: 8px; }
.ask.no-chips .ask-chips { display: none; }
.ask.kb .ask-chips { display: none; }

.ask .inputpill { gap: 8px; padding-right: 7px; }
.ask-in { height: 46px; min-width: 0; }
/* transform stays in the list: a rule that declares its own transition replaces
   the family's, and the tap lift (laws §3) would snap without it */
.ask .inputpill .mic { transition: transform var(--dur-liftUp) var(--ease), background-color 200ms var(--ease), color 200ms var(--ease); }
.ask .inputpill .mic.on { background: var(--lav); border-color: var(--line3); color: var(--pur); }

/* ---------- phone ------------------------------------------------------- */
@media (max-width: 999px) {
  .ask.ask-page {
    height: calc(100vh - var(--sat) - var(--sab) - 178px);
    min-height: 360px;
  }
}
@supports (height: 100dvh) {
  @media (max-width: 999px) {
    .ask.ask-page { height: calc(100dvh - var(--sat) - var(--sab) - 178px); }
  }
}
@media (max-width: 999px) {
  .ask-head h1 { font-size: 20px; }
  /* 88vw of a phone leaves 150px a cell: every second name ellipsised, so the
     picker takes one column and the names print whole */
  /* one column here, and the same whole-row arithmetic: three rows, no fourth cut */
  .ask-pick { grid-template-columns: minmax(0, 1fr); max-height: 144px; }
  .ask-b { padding: 13px 15px; }
  .ask-b.u { max-width: 86%; }
  .ask-foot { gap: 10px; padding-top: 10px; }
  /* a GM's question is longer than 393px: the chip grows rather than swallowing
     the end of it in an ellipsis */
  .ask-chips .chip { height: auto; min-height: 52px; padding-top: 9px; padding-bottom: 9px; }
  .ask-chips .chip .lb { white-space: normal; overflow: visible; line-height: 1.32; }
}
