﻿/* Luxemora prototype v4.3 — the guide chat. Loaded after styles.css; the plane's own artwork and size rules in styles.css are unchanged.
   Focus rings come from the site-wide :focus-visible rule (magenta). */

/* ------------------------------------------------------------ the plane: a click target for the G-PILOT launcher */
/* v4.4: the plane carries a transparent, non-focusable click target (#assistant-plane) that opens the SAME launcher (#assistant-toggle, below). It moves with the plane
   and takes no pointer taps while the plane is flying (a moving target). Keyboard and screen-reader users use the G-PILOT launcher: one control, one tab stop. */
.glider__hit {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border-radius: 50%; cursor: pointer; pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}
.glider.is-flying .glider__hit { pointer-events: none; }
.glider svg { transition: filter 160ms var(--ease); }
.glider:has(.glider__hit:hover) svg,
body:has(.gpilot__btn:hover) .glider.is-parked svg,
body:has(.gpilot__btn:focus-visible) .glider.is-parked svg { filter: drop-shadow(0 0 7px rgba(55, 220, 233, 0.55)); }

/* ------------------------------------------------------------ G-PILOT launcher (v4.4)
   One real button. Name in Manrope, help text in Inter (the site's own fonts, no new download), on a solid dark backing so the moving code field behind it never touches the text.
   Desktop: left of the plane's dock, a fixed width (--gp-w) so the space the page keeps clear for it (--dock-clear) is exact. It is only shown while the plane rests on its dock:
   during welcome and route flights it is hidden (it would be detached from the plane) and it returns when the plane has parked. Its space is reserved either way.
   Phones and tablets: inside the header (see the max-width rules below). There is no animation on it except a quiet fade; nothing pulses or bounces. */
:root { --gp-w: 156px; --gp-gap: 8px; --gp-band: 0px; }
.gpilot {
  position: fixed; z-index: 54; right: var(--dock-r); bottom: var(--dock-b);
  height: var(--glider-size); padding-right: calc(var(--glider-size) + var(--gp-gap));
  display: flex; align-items: center; pointer-events: none;
  opacity: 0;                                          /* plane away (welcome, a flight): the launcher steps aside at once, but stays in the keyboard order and the accessibility tree */
}
body:has(.glider.is-visible.is-parked) .gpilot { opacity: 1; transition: opacity 180ms var(--ease); }   /* it fades back in when the plane has parked */
.gpilot:focus-within { opacity: 1; }                   /* a keyboard user who reaches it while the plane is away still sees it and its focus ring */
.gpilot__btn {
  pointer-events: none; display: block; width: var(--gp-w); margin: 0; padding: 8px 12px 9px; text-align: left; cursor: pointer;
  color: var(--text); background: #070d1c; border: 1px solid var(--line-cyan); border-radius: 2px;
  box-shadow: 0 10px 28px -14px rgba(0, 0, 0, 0.95);
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
  -webkit-tap-highlight-color: transparent;
}
body:has(.glider.is-visible.is-parked) .gpilot__btn { pointer-events: auto; }   /* a click can only land on it while it is shown next to the parked plane */
/* v4.4.1: a browser without :has() cannot see the plane's state, so there the launcher is simply always shown AND clickable. This block must come AFTER .gpilot__btn (and its pointer-events: none): equal specificity, the later rule wins. In v4.4 it sat above it and lost, so the visible launcher ignored the pointer. Verified with a forced-branch simulation in Chrome (suite_r4r5.mjs), not in an old browser. */
@supports not selector(:has(*)) { .gpilot { opacity: 1; } .gpilot__btn { pointer-events: auto; } }
.gpilot__btn:hover { border-color: var(--cyan); background: #0a1428; }
.gpilot__name { display: block; font-family: var(--font-display); font-weight: 700; font-size: 0.9375rem; line-height: 1.25; letter-spacing: 0.06em; color: var(--text); }
.gpilot__help { display: block; margin-top: 2px; font-family: var(--font-body); font-weight: 500; font-size: 0.875rem; line-height: 1.35; color: var(--muted); white-space: nowrap; }
.gpilot__role, .gpilot__ask { display: block; }
.gpilot__sep { display: none; }
.gpilot__ask { color: var(--cyan); font-weight: 600; }
@media (min-width: 881px) {
  :root { --dock-clear: calc(var(--dock-r) + var(--glider-size) + var(--gp-gap) + var(--gp-w) + 16px); }   /* the page keeps this column clear: the plane, the gap and the launcher */
}
/* The reserved column narrows the page copy on desktops under about 1140 px. The three-column stage lists of the Process page need more than that, and would run under the launcher
   (measured at 881 px), so there they stack in one column. */
@media (min-width: 881px) and (max-width: 1140px) { .stage__grid { grid-template-columns: 1fr; gap: 16px; } }
/* A short desktop screen: the open chat moves beside the plane and would cover the launcher, so the launcher steps aside while it is open (the chat heading carries the name). */
@media (min-width: 881px) and (max-height: 600px) { body.assistant-open .gpilot { visibility: hidden; } }

/* Phones and tablets (880 px and narrower): the header gets a second, reserved band for the launcher: one 44 px line under the logo row, full width, one tap target. The logo row, the
   plane's header slot and the menu button stay exactly where they were (the plane's docking is unchanged). --header-h grows by the band, and everything that is laid out from it
   (page tops, anchors, the menu, the chat sheet, the greeting) follows. The header is solid from the top so the band never sits half over the scene behind it. */
@media (max-width: 880px) {
  :root { --gp-band: 44px; --header-h: calc(60px + var(--gp-band)); }
  .site-header { background: rgba(5, 9, 20, 0.94); border-bottom: 1px solid var(--line); }
  .site-header__inner { height: 60px; }                  /* the logo row keeps its 60 px; the band below it is the launcher's */
  .gpilot { top: 60px; left: 0; right: 0; bottom: auto; z-index: 51; height: var(--gp-band); padding-right: 0; opacity: 1; }   /* the band is part of the header: always shown, also while the plane flies */
  .gpilot__btn { pointer-events: auto; width: 100%; height: 100%; display: flex; align-items: center; gap: 10px; padding: 0 var(--gutter); border-width: 1px 0 0; border-radius: 0; background: #070d1c; box-shadow: none; }
  .gpilot__btn:hover { background: #0a1428; }
  .gpilot__role, .gpilot__ask { display: inline; }
  .gpilot__sep { display: inline; color: var(--dim); }
  .gpilot__help { margin-top: 0; }
  .gpilot__btn:focus-visible { outline-offset: -3px; }
  /* While the chat sheet is open (the phone menu closed) the header is just the logo row: the sheet starts right under it, exactly as in v4.3.x, and its own heading G-PILOT carries the name,
     so the band steps aside. --header-h (what the page below is laid out from) does not change, so nothing under the sheet moves; the band is back the moment the chat closes. */
  body.assistant-open:not(.menu-open) .site-header { height: 60px; }
  body.assistant-open:not(.menu-open) .gpilot { visibility: hidden; }
  /* The header is taller by the band; the first screen of Home keeps its old proportions (the call-to-action stays where it was, so the plane's arrival anchor next to it stays clear of the copy). */
  .hero__content { padding-top: max(0px, calc(min(30vh, 280px) - var(--gp-band))); }
}

/* The greeting card in "push" mode (no clear space beside the page copy) must be tall enough to hold the plane: on a wide screen the one-line card was 60 px high and the 80 px plane stuck out.
   The G-PILOT launcher's reserved column makes that fallback more likely on narrow desktops, so the card now keeps at least plane height plus 8 px when the plane is in it. */
.greeting.has-plane .greeting__body { min-height: calc(var(--glider-size) + 8px); }

/* ------------------------------------------------------------ panel */
.assistant {
  position: fixed; z-index: 55;
  display: flex; flex-direction: column;
  right: var(--dock-r); bottom: calc(var(--dock-b) + var(--glider-size) + 12px);
  width: min(380px, calc(100vw - 32px));
  height: min(540px, calc(100vh - var(--dock-b) - var(--glider-size) - 12px - var(--header-h) - 16px));
  /* v4.3.1: no min-height. The v4.3 value of 300px overrode this height on short screens and pushed the heading and Close above the top of the page. */
  background: linear-gradient(165deg, rgba(16, 28, 52, 0.97), rgba(7, 12, 26, 0.98));
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--line-cyan); border-radius: 2px;
  box-shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.95);
  animation: assistant-in 200ms var(--ease) both;
}
.assistant[hidden] { display: none; }
.assistant > :not(.assistant__log) { flex-shrink: 0; }   /* only the conversation gives way when space is short */
@keyframes assistant-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
body.menu-open .assistant { z-index: 49; }

.assistant__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 8px 10px 14px; border-bottom: 1px solid var(--line); }
.assistant__id { flex: 1 1 0; min-width: 0; }          /* the subtitle wraps on the narrowest phones instead of squeezing New chat and Close */
.assistant__tools { flex: 0 0 auto; }
.assistant__title { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 1rem; line-height: 1.25; letter-spacing: 0.06em; }
.assistant__sub { margin: 1px 0 0; font-size: 0.875rem; line-height: 1.35; color: var(--muted); }
.assistant__tools { display: flex; align-items: center; gap: 4px; }
.assistant__btn {
  display: inline-grid; place-items: center; min-height: 34px; padding: 0 10px;
  background: none; border: 1px solid transparent; border-radius: 2px; color: var(--muted); cursor: pointer; font-size: 0.8125rem;
}
.assistant__btn:hover { color: var(--text); border-color: var(--line-mid); }
.assistant__btn--icon { width: 34px; padding: 0; }
.assistant__btn--icon svg { width: 14px; height: 14px; }

.assistant__status { margin: 0; padding: 6px 14px; font-size: 0.75rem; line-height: 1.4; color: var(--dim); border-bottom: 1px solid var(--line); }
.assistant__status.is-off { color: var(--muted); }

.assistant__log { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.assistant__log:focus-visible { outline-offset: -3px; }
.msg { max-width: 92%; font-size: 0.875rem; line-height: 1.5; }
.msg p { margin: 0 0 0.6em; overflow-wrap: anywhere; }
.msg p:last-child { margin-bottom: 0; }
.msg__body { padding: 8px 11px; border-radius: 2px; }
.msg--bot .msg__body { background: var(--surface-2); border-left: 2px solid var(--cyan); }
.msg--user { align-self: flex-end; }
.msg--user .msg__body { background: var(--cyan-soft); border: 1px solid var(--line-cyan); }
.msg--note { align-self: stretch; max-width: 100%; }
.msg--note .msg__body { padding: 4px 2px; color: var(--muted); font-size: 0.8125rem; background: none; border-left: 2px solid var(--violet); padding-left: 10px; }
.msg--typing { color: var(--dim); font-size: 0.8125rem; padding-left: 4px; }
.msg__src { margin: 3px 0 0 2px; font-family: var(--font-mono); font-size: 0.6875rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dim); }
.msg__summary {
  margin: 6px 0 0; padding: 8px 10px; white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--font-mono); font-size: 0.75rem; line-height: 1.5;
  background: var(--bg); border: 1px solid var(--line-mid); border-radius: 2px; max-height: 190px; overflow: auto;
}
.msg__actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

.assistant__chips { display: flex; gap: 6px; padding: 8px 14px; overflow-x: auto; white-space: nowrap; border-top: 1px solid var(--line); scrollbar-width: thin; }
.chip {
  flex: 0 0 auto; min-height: 34px; padding: 0 11px;
  background: rgba(5, 9, 20, 0.5); border: 1px solid var(--line-mid); border-radius: 2px; color: var(--text); cursor: pointer; font-size: 0.8125rem;
}
.chip:hover { border-color: var(--cyan); color: var(--cyan); }
.chip--action { white-space: normal; text-align: left; border-color: var(--line-cyan); }

.assistant__form { display: flex; gap: 6px; padding: 8px 14px 8px; border-top: 1px solid var(--line); }
.assistant__input { flex: 1 1 auto; min-width: 0; min-height: 40px; padding: 0 10px; font-size: 0.9375rem; background: var(--bg); border: 1px solid var(--line-mid); border-radius: 2px; color: var(--text); }
.assistant__input::placeholder { color: var(--dim); }
.assistant__input:focus { border-color: var(--cyan); }
.assistant__send { flex: 0 0 auto; min-height: 40px; padding: 0 16px; background: var(--cyan); color: #04101c; font-weight: 600; border: 0; border-radius: 2px; cursor: pointer; }
.assistant__send[aria-disabled="true"] { opacity: 0.55; cursor: progress; }
.assistant__note { margin: 0; padding: 0 14px 10px; font-size: 0.6875rem; line-height: 1.45; color: var(--dim); }

/* ------------------------------------------------------------ short desktop-width screens (v4.3.1)
   When the dock (plane) plus a usable panel no longer fit above each other, the panel moves BESIDE the plane: from just under the header to 8px above the bottom,
   its right edge left of the plane. The plane stays visible and clickable, the heading, New chat, Close, field and Send stay on screen, and the conversation scrolls. */
@media (min-width: 881px) and (max-height: 600px) {
  .assistant {
    top: calc(var(--as-top, var(--header-h)) + 8px); bottom: 8px; height: auto;
    right: calc(var(--dock-r) + var(--glider-size) + 12px);
    width: min(380px, calc(100vw - var(--dock-r) - var(--glider-size) - 28px));
  }
}

/* ------------------------------------------------------------ phones and tablets: a sheet under the header, above the on-screen keyboard */
@media (max-width: 880px) {
  .assistant {
    left: 0; right: 0; width: auto; top: var(--as-top, var(--header-h));
    bottom: var(--as-kb, 0px); height: auto; min-height: 0;
    border-left: 0; border-right: 0; border-bottom: 0;
  }
  .assistant__input { font-size: 16px; min-height: 44px; }
  .assistant__send, .chip, .assistant__btn { min-height: 44px; }
  .assistant__btn--icon { width: 44px; }
  .msg { max-width: 94%; }
  .assistant__note { padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
}
/* A short visible screen (on-screen keyboard open, or a phone held sideways): give the conversation the room. The disclosure note stays; the status line goes
   (the same news is in the conversation as a notice), and the quick choices step aside while the question field has focus. */
@media (max-height: 420px) {
  .assistant__chips { padding-top: 4px; padding-bottom: 4px; }
  .assistant .chip { min-height: 36px; }
  .assistant__form { padding-top: 6px; padding-bottom: 4px; }
  .assistant__note { padding-bottom: 6px; }
}

@media (max-height: 560px) {
  .assistant__status { display: none; }
  .assistant__head { padding-top: 4px; padding-bottom: 4px; }
  .assistant__chips { padding-top: 6px; padding-bottom: 6px; }
  .assistant:has(.assistant__input:focus) .assistant__chips { display: none; }
}

/* A narrow phone held very short, or with the on-screen keyboard open (v4.4): the subtitle steps aside; the name G-PILOT stays in the heading. */
@media (max-width: 599px) and (max-height: 420px) { .assistant__sub { display: none; } }



