/* frontend/components/lo-window.css  Spec: [TBLT-LO-08]
 *
 * The Lo conversation window. Anchored INSIDE .world (playbook rule: no
 * position:fixed for in-world Lo mounts) so it travels with the centred
 * phone shell and never covers the whole viewport. Colors come from the
 * canonical DS bundle (frontend/loka-ds/ds-tokens.css); no bare hex here --
 * the LOKA-02 gate greps for it and the DS contract spec re-checks.
 */
lo-window {
  /* Covers .world so the open window can blur the scene behind it; the
   * frame itself sits inside, anchored above Lo's corner. */
  position: absolute;
  inset: 0;
  /* Above the scene + HUD band (60), below the task layer (91). */
  z-index: 66;
  pointer-events: none;
  font-family: var(--loka-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--loka-text-pixel-lg, 11px);
  color: var(--loka-ink);
}

lo-window[data-open="true"] { pointer-events: auto; }

/* While the window is open the learner's whole attention is Lo's: the scene
 * behind blurs and dims. A tap on it folds the window (app.js). */
lo-window[data-open="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  -webkit-backdrop-filter: blur(6px) brightness(0.55);
  backdrop-filter: blur(6px) brightness(0.55);
}

lo-window .lo-window__frame {
  display: none;
  flex-direction: column;
  position: absolute;
  left: var(--loka-space-3, 12px);
  right: var(--loka-space-3, 12px);
  /* Clears Lo's corner mount so the window folds back into it visually, and
   * sits above the software keyboard when one is up ([ONBOARD-97] F5:
   * --lo-kb-inset is the visual viewport's missing height, 0 otherwise). */
  bottom: calc(var(--loka-space-10, 96px) + var(--lo-kb-inset, 0px));
  /* About four fifths of the world's height, so a visit's thread is readable
   * without scrolling every other bubble; capped so it never overruns the top. */
  height: min(80%, calc(100% - var(--loka-space-10, 96px) - var(--loka-space-3, 12px) - var(--lo-kb-inset, 0px)));
  width: min(100%, 360px);
  background: var(--loka-cream);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  box-shadow: 0 6px 0 rgba(0, 0, 0, 0.25);
  /* The fold shrinks the frame toward the point the corner vector is
   * measured from, so the two agree: frame centre to Lo's centre. */
  transform-origin: center;
  /* Nothing inside paints past the frame: with the keyboard up the thread
   * used to overflow it and its pill row painted over the composer
   * (UAT 2026-09-17, issue 3). */
  overflow: hidden;
}

/* [ONBOARD-97] F5: with the keyboard up the window is the only thing on
 * screen -- Lo's corner is behind it and the learner is typing, so the frame
 * takes the space above the keyboard instead of keeping her 96px clearance.
 * Without this the send button sits under the keyboard on a 667px handset. */
lo-window[data-keyboard] .lo-window__frame {
  bottom: calc(var(--loka-space-2, 8px) + var(--lo-kb-inset, 0px));
  height: calc(100% - var(--lo-kb-inset, 0px) - var(--loka-space-2, 8px) - var(--loka-space-3, 12px));
}

/* With the keyboard up the frame can be under 350px tall (Chrome on iOS
 * shrinks the layout viewport itself, so 100% is already the space above the
 * keyboard). The thread's 160px floor plus four pills no longer fit beside
 * the composer: the thread gives up its floor and clips, and the pill row
 * scrolls inside a cap instead of pushing the composer out of the frame
 * (UAT 2026-09-17, issue 3: the fourth pill painted over the field). */
lo-window[data-keyboard] .lo-window__thread {
  min-height: 0;
  overflow: hidden;
}
lo-window[data-keyboard] .lo-choices {
  max-height: 132px;
  overflow-y: auto;
}

lo-window[data-open="true"] .lo-window__frame {
  display: flex;
  animation: lo-window-pop 320ms cubic-bezier(.2,.8,.2,1) both;
}

/* Comes out of Lo's corner: the exact reverse of the fold below -- the same
 * vector, the same twelfth-of-itself, the same easing family -- so open and
 * fold read as one paired motion (Spec: [TBLT-LO-16]). [ONBOARD-89] F4: the
 * window grows out of her rather than sliding in from beside her, which is
 * what a translate on its own looked like (UAT 2026-09-16).
 *
 * The scale() here was once avoided: a scaled frame shrinks the *rendered*
 * box getBoundingClientRect() reports for its descendants, and the DS
 * contract spec's tap-target check read that box shortly after open(). That
 * spec now waits for the frame's animationend before it measures, so the
 * mid-animation box is never what it reads.
 *
 * The 24px fallbacks only apply on a page where _aimAtCorner() could not
 * measure; the real vector is set on the host. */
@keyframes lo-window-pop {
  from {
    transform: translate(var(--lo-corner-dx, 24px), var(--lo-corner-dy, 24px)) scale(0.12);
    opacity: 0;
  }
  to   { transform: none; opacity: 1; }
}

/* Folding back into Lo's corner: the frame travels the corner vector while
 * it shrinks to a twelfth of itself, landing on Lo, and then leaves the
 * layout (lo-window.js flips data-open after the animation). scale() is
 * written after translate() so it applies first, about the frame's centre:
 * the frame shrinks in place, then its centre moves onto Lo's centre. */
lo-window[data-closing="true"] .lo-window__frame {
  animation: lo-window-fold 280ms ease-in forwards;
}

@keyframes lo-window-fold {
  from { transform: none; opacity: 1; }
  to   {
    transform: translate(var(--lo-corner-dx, 24px), var(--lo-corner-dy, 24px)) scale(0.12);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  lo-window[data-open="true"] .lo-window__frame,
  lo-window[data-closing="true"] .lo-window__frame { animation: none; }
}

lo-window .lo-window__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--loka-space-1, 4px) var(--loka-space-2, 8px);
  border-bottom: 1px solid var(--loka-rule-dark);
}

lo-window .lo-window__title {
  font-family: var(--loka-font-pixel, var(--loka-font-mono, monospace));
  font-size: var(--loka-text-pixel-lg, 11px);
  letter-spacing: var(--loka-track-pixel-lg, 0.18em);
  text-transform: uppercase;
  color: var(--loka-terracotta-deep);
}

/* The voice switch sits between the title and the close control; margin-auto
   pushes it right so the close button keeps the corner. Spec: [TBLT-LO-17]. */
lo-window .lo-voice {
  margin-left: auto;
  margin-right: var(--loka-space-2, 8px);
  min-height: 32px;
  padding: 0 var(--loka-space-2, 8px);
  font: inherit;
  font-size: var(--loka-text-note, 13px);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

lo-window[data-voice="off"] .lo-voice { opacity: 0.7; }

/* [ONBOARD-89] D-15 the ordinary touch-target convention, applied to shared
 * chrome: the box grows to the floor via flex centering, the painted glyph
 * (the times character) keeps its own font-size. */
lo-window .lo-close {
  min-height: var(--loka-tap-min, 44px);
  min-width: var(--loka-tap-min, 44px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-sizing: border-box;
  background: none;
  border: 0;
  color: inherit;
  font-size: var(--loka-text-sm, 16px);
  line-height: 1;
  cursor: pointer;
}

/* The wrapped thread sets position:absolute; inset:0 on its own :host (it is
 * built as a full-screen FoF surface). Outer-tree rules win over :host, so
 * these three lines are what make it a flex row of this frame instead. */
lo-window .lo-window__thread {
  position: relative;
  inset: auto;
  flex: 1 1 auto;
  min-height: 160px;
}

/* The pill rides the thread's `above-ptt` slot, so it sits directly above the
 * hold-to-speak bar in voice mode and above the typed field in text mode; the
 * bottom padding keeps it off the bar's 2px rule. Spec: [TBLT-LO-15]. */
lo-window .lo-suggestion {
  flex: none;
  display: flex;
  justify-content: flex-start;
  padding: var(--loka-space-1, 4px) var(--loka-space-2, 8px);
}

lo-window .lo-suggestion button {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--loka-space-3, 12px);
  font-family: inherit;
  font-size: var(--loka-text-note, 13px);
  line-height: 1;
  color: var(--loka-cream);
  background: var(--loka-terracotta-deep);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  border-radius: 999px;
  cursor: pointer;
}

lo-window .lo-suggestion[hidden] { display: none; }

/* Choice pills: Lo offered two or three next steps; a tap is the reply.
 * Rides the thread's `above-ptt` slot ahead of `.lo-suggestion` (same reason:
 * a pill placed after `<volley-chat-thread>` lands under the hold-to-speak
 * bar in voice mode), so the choices row sits above the plan pill, which
 * sits directly above the bar. Spec: [TBLT-LO-15]. */
lo-window .lo-choices {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--loka-space-1, 4px);
  padding: var(--loka-space-2, 8px) var(--loka-space-2, 8px) 0;
}

lo-window .lo-choices__kind {
  flex: 0 0 100%;
  font-family: var(--loka-font-pixel, inherit);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--loka-ink-mute);
}

lo-window .lo-choice {
  min-height: 36px;
  padding: var(--loka-space-1, 4px) var(--loka-space-3, 12px);
  font-family: inherit;
  font-size: var(--loka-text-note, 13px);
  color: var(--loka-ink);
  background: var(--loka-cream);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  border-radius: 999px;
  cursor: pointer;
}

lo-window .lo-choices[hidden],
lo-window[data-visit="true"] .lo-choices { display: none; }

/* [ONBOARD-81] The onboarding action button: the arrival's "next", the
 * microphone's "turn it on". One button, the width of the row, so the tap is
 * unmissable on a phone. Gold follows the fof-transition precedent for the one
 * thing to tap in a named Lo moment; it is not decoration.
 * [ONBOARD-89] The microphone ask carries a second pill (spec section 6,
 * "WHY?"): it shares the row, but plain -- gold stays reserved for the one
 * tap that actually grants, so the two are never visually equal. */
lo-window .lo-action {
  flex: none;
  display: flex;
  gap: var(--loka-space-2, 8px);
  padding: var(--loka-space-2, 8px) var(--loka-space-2, 8px) 0;
}

lo-window .lo-action__btn {
  flex: 1;
  justify-content: center;
  font-weight: 600;
  background: var(--loka-gold, var(--loka-cream));
}

lo-window .lo-action__btn--secondary {
  flex: none;
  min-width: 44px;
  font-weight: 500;
  background: var(--loka-cream);
}

lo-window .lo-action[hidden] { display: none; }

/* [ONBOARD-79] The rung ladder: six stacked rows, the number in the pixel
 * face, the plain-words label in the middle, the target-language tag right.
 * Rows, not pills: the learner reads all six before tapping one. */
/* The ladder is a sibling of the thread, not a slot inside it: slotted into
   `above-ptt` its height resolved against the thread's own box and only three of
   six rows were readable at 390x844 (walkthrough 2026-09-11). Out here the
   thread gives way instead, because while the ladder is up the ladder IS the
   turn -- [ONBOARD-83] F6: the typed row and the thread's hold-to-speak bar
   fold away with it, and the six rows take everything the thread does not need
   (UAT 2026-09-16: the ladder sat under "Hold to speak", half of it off the
   bottom of the frame). */
lo-window .lo-ladder {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--loka-space-1, 4px);
  padding: var(--loka-space-2, 8px);
  overflow-y: auto;
}

/* The thread is capped rather than floored while the rungs are up: it keeps
   the sentence they answer on screen and gives every pixel below it to the
   ladder, so all six rows fit at 375x667 (screens 2026-09-16: sharing the
   space evenly cut the sixth row in half). */
lo-window[data-ladder] .lo-window__thread {
  flex: 0 1 auto;
  min-height: 0;
  max-height: 150px;
}
lo-window[data-ladder] .lo-window__input { display: none; }

lo-window .lo-ladder__row {
  display: flex;
  align-items: center;
  gap: var(--loka-space-2, 8px);
  min-height: var(--loka-space-8, 48px);
  padding: var(--loka-space-1, 4px) var(--loka-space-2, 8px);
  text-align: left;
  font-family: inherit;
  font-size: var(--loka-text-note, 13px);
  color: var(--loka-ink);
  background: var(--loka-cream);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  box-shadow: var(--loka-card-shadow-sm);
  cursor: pointer;
}

lo-window .lo-ladder__n {
  font-family: var(--loka-font-pixel);
  /* [UI-PRIN-40] the legibility floor: the pixel face never goes under 9px */
  font-size: var(--loka-text-pixel-sm, 9px);
  color: var(--loka-ink-soft);
}

lo-window .lo-ladder__label { flex: 1; font-style: italic; }

lo-window .lo-ladder__tag {
  font-size: var(--loka-text-note, 13px);
  color: var(--loka-ink-soft);
}

lo-window .lo-ladder[hidden] { display: none; }

/* [ONBOARD-81] Locked: onboarding is waiting on the learner, so the fold
 * control is inert rather than absent (the frame keeps its shape). */
lo-window[data-locked="true"] .lo-close {
  opacity: 0.35;
  pointer-events: none;
}

lo-window .lo-window__input {
  flex: none;
  display: flex;
  gap: var(--loka-space-1, 4px);
  padding: var(--loka-space-2, 8px);
  border-top: 1px solid var(--loka-rule-dark);
}

lo-window .lo-window__input input {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--loka-space-1, 4px);
  font-family: inherit;
  /* 16px keeps iOS Safari from zooming the shell on focus. */
  font-size: var(--loka-text-sm, 16px);
  color: var(--loka-ink);
  background: var(--loka-cream);
  border: 1px solid var(--loka-rule-dark);
}

/* [ONBOARD-89] D-15 the ordinary touch-target convention: the box grows via
 * flex centering to the floor, the "Send" glyph keeps its own font-size. */
lo-window .lo-window__input button[type="submit"] {
  min-height: var(--loka-tap-min, 44px);
  min-width: var(--loka-tap-min, 44px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--loka-space-2, 8px);
  box-sizing: border-box;
  font-family: inherit;
  font-size: var(--loka-text-pixel-md, 10px);
  letter-spacing: var(--loka-track-pixel-md, 0.16em);
  text-transform: uppercase;
  color: var(--loka-cream);
  background: var(--loka-ink);
  border: 0;
  cursor: pointer;
}

lo-window.is-busy .lo-window__input button[type="submit"] {
  opacity: 0.5;
  pointer-events: none;
}

/* One input method at a time: the typed row hides in voice mode (the
 * thread's hold-to-speak bar shows instead, with the "Aa" switch slotted
 * into it), and the hold bar hides in text mode (thread.setPttVisible). */
lo-window[data-input="voice"] .lo-window__input { display: none; }

/* [ONBOARD-89] D-15 the ordinary touch-target convention: raised from 40px
 * to the shared floor. Covers both the mic-toggle (data-testid="lo-mic",
 * shown in text-input mode) and its "Aa" counterpart slotted into the
 * hold-to-speak bar in voice mode -- one rule, one convention, both modes. */
lo-window .lo-mode {
  flex: none;
  min-width: var(--loka-tap-min, 44px);
  min-height: var(--loka-tap-min, 44px);
  box-sizing: border-box;
  padding: 0;
  font-family: var(--loka-font-pixel, var(--loka-font-mono, monospace));
  font-size: var(--loka-text-pixel-lg, 11px);
  letter-spacing: 0;
  color: var(--loka-ink);
  background: var(--loka-cream);
  border: var(--loka-border-2, 2px solid);
  border-color: var(--loka-rule-dark);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* A coach visit is spoken from end to end ([TBLT-LO-18], PO ruling
 * 2026-09-15): the way to typing is closed for the whole visit, not only
 * while a card waits. The window applies voice for the same span, so the
 * hold-to-speak bar is what is left on screen. */
lo-window[data-visit="true"] .lo-mode { display: none; }

/* Small mic glyph, same construction as the thread's PTT mic, ink on cream. */
lo-window .lo-mode__mic {
  position: relative;
  width: 10px;
  height: 14px;
  background: var(--loka-ink);
  border: 2px solid var(--loka-rule-dark);
  border-radius: 4px 4px 2px 2px;
  box-shadow: 0 5px 0 -2px var(--loka-rule-dark);
}

/* A tutoring visit is running in the thread ([TBLT-LO-06]): it owns the turn,
 * so the tap-through left over from the conversation folds away until it
 * ends. Typed input stays -- the learner answers the coach in whichever
 * input method is theirs ([TBLT-LO-18]). The close control stays too (it
 * leaves the visit through the same confirm as the coach's own exit). */
lo-window[data-visit="true"] .lo-suggestion {
  display: none;
}

/* The window's answer when a typed line could not be taken ([TBLT-LO-18]):
 * one quiet line under the input bar, up for 2s. `hidden` is left to the UA
 * default -- no author-origin `display` here to defeat it. */
lo-window .lo-hint {
  font-size: var(--loka-text-note, 13px);
  color: var(--loka-ink-soft);
  padding: 0 var(--loka-space-2, 8px) var(--loka-space-1, 4px);
}

/* [LESSON-10] the lesson chip in the window head while a lesson runs */
.lo-window__lesson {
  font-size: 9px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.8;
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 999px;
  max-width: 40%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* [LESSON-10] The window says a lesson is running, in colour as well as in
 * words. The chip alone was 9px in the corner of a window that looked exactly
 * like an ordinary chat, so nothing but the text said the mode had changed
 * (PO 2026-09-20). The frame warms to terracotta and the head takes the gold
 * band the chip sits on: the edge catches the eye, the band says what it is.
 * Colour only -- no layout moves, so nothing here can shift a tap target. */
lo-window[data-lesson="true"] .lo-window__frame {
  border-color: var(--loka-terracotta-deep);
}

lo-window[data-lesson="true"] .lo-window__head {
  background: var(--loka-cream-gold);
  border-bottom-color: var(--loka-terracotta-deep);
}

lo-window[data-lesson="true"] .lo-window__lesson {
  background: var(--loka-gold);
  border-color: var(--loka-rule-dark);
  opacity: 1;
}
