/* Launch (22 Oct, local): one white card holding two windows in a sliding track (the scan form, then the fix
   form) and the scan helper beside it. Tokens only (css/tokens.css); loaded after css/base.css and css/app.css,
   whose button, label and input rules it narrows inside .launch. The section ground is the page's
   (css/landing.css): the card and the helper sit on it as tone steps, with no shadow, no border and no
   hairline at rest. Type is the text face at weights 400 to 600; the card's one heading takes --font-display
   when the page defines it. */

.launch { padding: var(--s8) 0 0; font-family: var(--font); }
.launch-head { max-width: 640px; margin: 0 auto var(--s6); text-align: center; }
.launch-head h2 { font-family: var(--font-display, var(--font)); font-weight: 600; letter-spacing: -.03em; }
.launch-head p { color: var(--text-dim); font-size: 1.0625rem; max-width: 56ch; margin: 0 auto; }
.launch-grid { display: grid; grid-template-columns: minmax(0, 640px) minmax(300px, 360px); gap: var(--s5); justify-content: center; align-items: stretch; }
.launch-grid > * { min-width: 0; }
.launch-card, .assistant { background: var(--surface); border-radius: 24px; color: var(--text); }
.launch [hidden] { display: none; }

/* ---------- fields and buttons inside the launch block (narrowing css/app.css and css/base.css) ---------- */
.launch label { min-width: 0; gap: 6px; font-size: .875rem; font-weight: 500; color: var(--text-dim); }
.launch label:has(.opt) { grid-template-columns: auto 1fr; column-gap: 8px; align-items: center; }
.launch label:has(.opt) > input, .launch label:has(.opt) > select { grid-column: 1 / -1; }
.launch .opt { font-weight: 400; font-size: .8125rem; color: var(--text-dim); }
.launch input:not([type="checkbox"], [type="radio"], [type="file"]), .launch select {
  width: 100%; min-width: 0; border: 0; border-radius: 14px; padding: 13px 16px; background: var(--bg); color: var(--text);
  font: 400 1rem/1.4 var(--font); transition: background 200ms ease;
}
.launch input:focus, .launch select:focus { outline: none; box-shadow: none; } /* taste-skill-ignore: a reset of css/app.css's focus halo; the ring below replaces it */
.launch input:focus-visible, .launch select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.launch input::placeholder { color: var(--text-dim); opacity: .72; }
.launch input[type="file"] { width: 100%; min-width: 0; border: 0; border-radius: 14px; padding: 8px 10px; background: var(--bg); color: var(--text); font: 400 .9375rem/1.4 var(--font); cursor: pointer; }
.launch input[type="file"]::file-selector-button {
  margin-right: 12px; padding: 8px 14px; border: 0; border-radius: var(--pill); background: var(--surface-2); color: var(--text);
  font: 600 .875rem/1.2 var(--font); letter-spacing: 0; text-transform: none; cursor: pointer;
}
.launch .btn, .launch button { font-weight: 600; }
.launch .btn:not(.ghost), .launch button:not(.ghost, .linkish, .qchip) { color: var(--accent-ink); }
/* a text link in the form, not a pill: no gradient, no sheen */
.launch button.linkish, .launch button.linkish:hover, .launch button.linkish:active {
  display: inline; justify-self: start; overflow: visible; padding: 0; border: 0; border-radius: 4px; background: none; box-shadow: none; transform: none; /* taste-skill-ignore: box-shadow: none resets the pill's inner highlight */
  color: var(--accent); font: 600 .9375rem/1.5 var(--font); letter-spacing: 0; text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px;
}
.launch button.linkish::after { content: none; }

/* ---------- the card: two windows side by side in a track; the card's height is the active window's ---------- */
/* the windows carry the padding, so the card's clip edge is the track's edge and the window that is off never shows */
.launch-card { position: relative; overflow: hidden; overflow: clip; }
.launch-track { position: relative; transition: transform 320ms var(--ease-out); }
.launch-win { width: 100%; display: grid; gap: 18px; align-content: start; padding: 32px; }
.launch-win:focus { outline: none; }
/* the window that is off (inert, aria-hidden) leaves the flow, so the card follows the active one: no height animation */
.launch-card[data-window="scan"] .win-fix { position: absolute; top: 0; left: 100%; }
.launch-card[data-window="fix"] .win-scan { position: absolute; top: 0; left: 0; }
.launch-card[data-window="fix"] .win-fix { margin-left: 100%; }
.launch-card[data-window="fix"] .launch-track { transform: translateX(-100%); }
/* once the slide has ended the window that is off is hidden outright (find-in-page, geometry tools and the clip agree);
   the window coming in is visible at once, since its own state carries no delay */
.launch-card[data-window="scan"] .win-fix, .launch-card[data-window="fix"] .win-scan { visibility: hidden; transition: visibility 0s 320ms; }

/* ---------- the source: a segmented pill, then only the chosen panel ---------- */
.seg { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); padding: 4px; border-radius: var(--pill); background: var(--surface-2); }
.seg::before { content: ""; position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc((100% - 8px) / 3); border-radius: var(--pill); background: var(--grad); transition: transform 280ms var(--ease-out); } /* taste-skill-ignore: the pinned pill gradient on the chosen segment (Nabira, 22 Oct) */
.seg:has(input[value="repo"]:checked)::before { transform: translateX(100%); }
.seg:has(input[value="snapshot"]:checked)::before { transform: translateX(200%); }
.seg-opt {
  position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; min-height: 40px; padding: 8px 10px; border-radius: var(--pill);
  font-size: .9375rem; font-weight: 500; color: var(--text-dim); text-align: center; cursor: pointer; user-select: none; -webkit-user-select: none; transition: color 200ms ease;
}
.seg-opt:has(input:checked) { color: #fff; font-weight: 600; }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) { .seg-opt:not(:has(input:checked)):hover { color: var(--text); } }
/* the real radio and checkbox inputs, kept for the keyboard and screen readers, drawn by their labels */
.seg-opt input, .cchip input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; overflow: hidden; clip: rect(0 0 0 0); pointer-events: none; }
.src-panel { display: grid; gap: var(--s3); }

/* the drop zone: a real one, so the dashed edge stays */
.zone {
  position: relative; display: grid; place-items: center; align-content: center; gap: 4px; min-height: 236px; padding: 28px 20px; text-align: center;
  border: 1.5px dashed var(--line-strong); border-radius: 18px; background: var(--bg); cursor: pointer; transition: border-color 200ms ease, background 200ms ease;
}
.zone.is-over { border-color: var(--accent); background: var(--accent-soft); }
.zone.has-file { border-color: transparent; background: var(--accent-soft); cursor: default; }
.zone-idle, .zone-file { display: grid; place-items: center; gap: 4px; }
.zone-icon { width: 36px; height: 36px; margin-bottom: 6px; color: var(--accent); }
.zone-title { margin: 0; font-size: 1.0625rem; font-weight: 600; color: var(--text); }
.zone-sub { margin: 0; font-size: .875rem; color: var(--text-dim); }
.zone-pick { margin-top: var(--s3); }
.zone-pick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
.zone-name { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.zone-size { font-size: .875rem; color: var(--text-dim); }
.zone-file button { margin-top: var(--s3); }
.source-msg { margin: 0; font-size: .875rem; color: var(--st-bad); }
.source-msg:empty { display: none; }

/* ---------- weakness classes: the legend and three pill toggles on one line ---------- */
.launch-classes { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.launch-classes-label { margin-right: 2px; font-size: .875rem; font-weight: 500; color: var(--text-dim); }
.cchip {
  position: relative; display: inline-flex; align-items: center; min-height: 36px; padding: 6px 14px; border-radius: var(--pill); background: var(--surface-2);
  color: var(--text); font-size: .875rem; font-weight: 500; cursor: pointer; user-select: none; -webkit-user-select: none; transition: background 200ms ease, color 200ms ease;
}
@media (hover: hover) and (pointer: fine) { .cchip:not(:has(input:checked)):hover { background: var(--line); } }
.cchip:has(input:checked) { background: var(--accent); color: var(--accent-ink); }
.cchip span::before { content: ""; display: none; width: 5px; height: 10px; margin: 0 8px 2px 0; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.cchip:has(input:checked) span::before { display: inline-block; }
.cchip:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- the footer row: the text link left, the primary pill right, the hint under ---------- */
.launch-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s4); margin-top: 2px; }
.launch-foot .btn { margin-left: auto; padding: 13px 26px; }
.launch-mock { margin-left: auto; font-size: .8125rem; color: var(--text-dim); text-align: right; }
.launch-mock:not([hidden]) + .btn { margin-left: 0; }
.launch .hint { margin: 0; font-size: .875rem; color: var(--text-dim); }
.launch .hint code { font-size: .8125rem; color: var(--text-dim); }

/* ---------- window 2: the fix form, moved into the card (js/home.js wires it by id) ---------- */
.win-title { margin: 0; font-family: var(--font-display, var(--font)); font-size: 1.625rem; font-weight: 600; letter-spacing: -.025em; line-height: 1.12; color: var(--text); }
.win-lead { margin: 0; max-width: 58ch; font-size: .9375rem; line-height: 1.55; color: var(--text-dim); }
.launch .fixform { display: grid; gap: var(--s4); max-width: none; }
.launch .pair { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; min-width: 0; }
.launch .pair-label { grid-column: 1 / -1; font-size: .875rem; font-weight: 500; color: var(--text-dim); }
.launch .form-msg { font-size: .9375rem; color: var(--text); }
.launch .form-msg ul { display: grid; gap: 4px; margin: 0; padding-left: 1.2em; }
.launch .scope-preview { margin: 0; padding: 12px 14px; border: 0; border-radius: 14px; background: var(--surface-2); font-size: .8125rem; overflow-x: auto; }

/* ---------- the helper: a slim panel, its head and its input row one tone step down ---------- */
.assistant { display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto; min-height: 480px; contain: size; overflow: hidden; overflow: clip; }
.assistant-head { display: flex; align-items: center; gap: 10px; padding: 14px 18px 14px; background: var(--surface-2); }
/* 8 Nov 2026 (Nabira): the monogram and a status in the head */
.assistant-logo { flex: none; width: 28px; height: 28px; border-radius: 8px; }
.assistant-status { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: .75rem; color: var(--text-dim); }
.assistant-status:empty { display: none; }
.assistant-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--st-ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--st-ok) 18%, transparent); }
.assistant-status.off::before { background: var(--st-neutral); box-shadow: none; }
.assistant-name { font-size: .9rem; font-weight: 600; letter-spacing: .16em; padding-left: .16em; color: var(--accent); }
.assistant-sub { font-size: .875rem; color: var(--text-dim); }
.assistant-log { display: flex; flex-direction: column; gap: 10px; min-height: 0; padding: 18px 20px 8px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.msg { max-width: 34ch; padding: 10px 14px; border-radius: 18px; font-size: .9375rem; line-height: 1.5; overflow-wrap: anywhere; }
.msg p { margin: 0; }
.msg p + p { margin-top: 6px; }
.msg.astwa { align-self: flex-start; background: var(--surface-2); border-bottom-left-radius: 6px; }
.msg.you { align-self: flex-end; background: var(--accent); color: var(--accent-ink); border-bottom-right-radius: 6px; }
.msg.pending { color: var(--text-dim); }
/* 8 Nov 2026 (Nabira): rows with avatars; a run from one speaker shows its avatar once, on the last bubble */
.row { display: flex; align-items: flex-end; gap: 8px; max-width: 100%; }
.row.astwa { align-self: flex-start; }
.row.you { align-self: flex-end; flex-direction: row-reverse; }
.row > .msg { align-self: auto; }
.row .av { flex: none; width: 28px; height: 28px; border-radius: 9px; }
.row.astwa:has(+ .row.astwa) .av, .row.you:has(+ .row.you) .av { visibility: hidden; }
.row:has(> .msg.card) { align-self: stretch; }
.row > .msg.card { flex: 1; min-width: 0; }
.you-av { display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); border-radius: 50%; }
.you-av::before {
  content: ""; width: 15px; height: 15px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='8' r='4.2'/%3E%3Cpath d='M3.5 21c.8-4.4 4.2-7 8.5-7s7.7 2.6 8.5 7z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='8' r='4.2'/%3E%3Cpath d='M3.5 21c.8-4.4 4.2-7 8.5-7s7.7 2.6 8.5 7z'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* the typing indicator: three dots */
.msg.typing { display: inline-flex; align-items: center; gap: 4px; padding: 13px 16px; }
.msg.typing .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-dim); opacity: .4; }
.msg.card { width: 100%; max-width: none; padding: 14px 16px; border-radius: 18px; background: var(--bg); }
.msg.card dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; margin: 0 0 var(--s3); }
.msg.card dl > div { display: contents; }
.msg.card dt { color: var(--text-dim); }
.msg.card dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.msg.card.stale { opacity: .55; }
.card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.card-foot .sub { font-size: .8125rem; }
.launch .start-btn { padding: 9px 18px; font-size: .9375rem; }
.scan-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }

/* quick replies and scan links: filled pills, no gradient, no sheen; a pressed one takes the accent */
.launch .qchip, .launch .qchip:hover, .launch .qchip:active {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: var(--pill); background: var(--surface-2); color: var(--text);
  font: 500 .875rem/1.3 var(--font); letter-spacing: 0; text-decoration: none; box-shadow: none; transform: none; cursor: pointer; transition: background 200ms ease, color 200ms ease; /* taste-skill-ignore: box-shadow: none resets the pill's inner highlight */
}
@media (hover: hover) and (pointer: fine) { .launch .qchip:hover { background: var(--line); } }
.launch button.qchip::after { content: none; }
.launch .qchip[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.qchip .st { font-size: .8125rem; font-weight: 600; }
.qchip .st.ok { color: var(--st-ok); } .qchip .st.warn { color: var(--st-warn); } .qchip .st.bad { color: var(--st-bad); }
.qchip .st.info { color: var(--st-info); } .qchip .st.neutral { color: var(--st-neutral); }
/* the offline note (js/home.js, no API on this machine): a slim line above the quick replies, in the panel's own inset */
#assistant-offline { margin: 0; padding: 8px 20px 6px; font-size: .8125rem; line-height: 1.45; color: var(--text-dim); border-top: 1px solid var(--line); }
.assistant-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 6px 20px 12px; }
.assistant-chips:empty { padding: 0; }
.assistant-input { display: flex; gap: 8px; padding: 12px 14px 14px; background: var(--surface-2); }
.assistant-field { flex: 1; display: block; min-width: 0; }
.launch .assistant-input input { padding: 11px 16px; border-radius: var(--pill); background: var(--surface); }
.assistant-input button { flex: none; }

/* a new bubble rises in (a transition from @starting-style; browsers without it show it at once) */
@media (prefers-reduced-motion: no-preference) {
  .assistant-log { scroll-behavior: smooth; }
  .msg { transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out); }
  @starting-style { .msg { opacity: 0; transform: translateY(6px); } }
  /* 8 Nov 2026 (Nabira): the dots rise in turn; quick replies rise in one after another; avatars scale in */
  .msg.typing .dot { animation: astwa-typing 1.05s ease-in-out infinite; }
  .msg.typing .dot:nth-child(2) { animation-delay: .15s; }
  .msg.typing .dot:nth-child(3) { animation-delay: .3s; }
  .row .av { transition: transform 260ms var(--ease-out), opacity 260ms var(--ease-out); }
  @starting-style { .row .av { opacity: 0; transform: scale(.8); } }
  .assistant-chips .qchip { transition: opacity 240ms var(--ease-out), transform 240ms var(--ease-out), background 200ms ease, color 200ms ease; transition-delay: calc(var(--i, 0) * 45ms), calc(var(--i, 0) * 45ms), 0s, 0s; }
  @starting-style { .assistant-chips .qchip { opacity: 0; transform: translateY(6px); } }
}
@keyframes astwa-typing { 0%, 60%, 100% { opacity: .4; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }
/* press feedback on quick replies, for touch and mouse alike */
.launch .assistant-chips .qchip:active { transform: scale(.97); transition-delay: 0s; }
/* reduced motion: the windows swap at once, the segment indicator jumps */
@media (prefers-reduced-motion: reduce) {
  .launch-track, .seg::before, .seg-opt, .cchip, .zone, .msg { transition: none; }
  .launch-card[data-window="scan"] .win-fix, .launch-card[data-window="fix"] .win-scan { transition: none; }
}

/* ---------- narrower screens: the helper under the card; phones: a tighter card, the primary pill full width ---------- */
@media (max-width: 900px) {
  .launch { padding-top: var(--s7); }
  .launch-grid { grid-template-columns: minmax(0, 640px); gap: var(--s4); }
  .assistant { height: 480px; min-height: 0; }
}
@media (max-width: 560px) {
  .row .av, .assistant-logo { width: 24px; height: 24px; }
  .launch { padding-top: var(--s6); }
  .launch-head { margin-bottom: var(--s5); }
  .launch-card { border-radius: 22px; }
  .launch-win { gap: 16px; padding: 24px 18px; }
  .launch-classes-label { flex-basis: 100%; margin: 0; }
  .zone { min-height: 184px; padding: 22px 16px; }
  .seg-opt { padding: 8px 6px; font-size: .875rem; }
  .launch-foot { flex-direction: column-reverse; align-items: stretch; }
  .launch-foot .btn, .launch-mock:not([hidden]) + .btn { width: 100%; min-height: 52px; margin: 0; }
  .launch-foot .linkish, .launch-mock { align-self: center; margin: 0; text-align: center; }
  .launch .pair { grid-template-columns: 1fr; }
  .assistant { height: 440px; }
  .msg { max-width: 88%; }
}
