/* ============================================================================
 * chat.css — the chat: thread, answer text, composer dock, welcome screen and
 * the ☰ drawer's history rows. Loaded after styles.css (tokens + base) and
 * styles/screens.css (shell + shared components). Compose the tokens; never
 * redefine them here.
 *
 * Everything lives in #view / #msgs / #drawer / #appsheet, so a rule here
 * always outranks the shared components in screens.css — no !important and
 * no glass-gate specificity fights.
 *
 *   1. Inline primitives (citation pills, device tags)
 *   2. Thread (user bubble, the plain assistant answer, markdown body,
 *      isolation checklist, status line, refusal, error, sheets + feedback)
 *   3. Sheet list (bottom sheet rows)
 *   4. Composer dock
 *   5. Welcome screen, crane divider, crane picker
 *   6. History list (drawer)
 *   7. Modes: high contrast, reduced motion, responsive
 * ==========================================================================*/

/* ======================================================= 1. INLINE PRIMITIVES */
html{scroll-padding-bottom:calc(var(--dock-h,120px) + var(--kb,0px) + 24px)}
/* One device-token treatment everywhere: <b> = mono 600 tabular. */
.msg.ai b{font-family:var(--f-mono);font-weight:600;font-variant-numeric:tabular-nums;
  letter-spacing:-.01em}
/* Citation pills (render-time restyle of [CCx INST shS pP]; the stored tuple is
 * untouched and stays the link's accessible name). */
.citelink{position:relative;display:inline-flex;align-items:baseline;gap:2px;
  vertical-align:baseline;padding:3px 6px;margin:-3px 0;
  border-radius:var(--r-xs);border:1px solid color-mix(in srgb,var(--acc) 55%,transparent);
  background:color-mix(in srgb,var(--acc) 10%,transparent);
  color:var(--acc-ink);font-family:var(--f-mono);font-size:var(--fs-12);font-weight:700;
  font-variant-numeric:tabular-nums;text-decoration:none;text-underline-offset:2px;
  white-space:nowrap;overflow-wrap:anywhere;
  transition:background var(--dur-1) var(--ease-out),transform var(--dur-1) var(--spring)}
/* Inline pills cannot be 44px tall without wrecking the paragraph line box:
 * an invisible pseudo hit-area gives a 44px touch target instead (WCAG 2.5.8
 * exempts inline links; this is better than the exemption). */
.citelink::before{content:"";position:absolute;left:-4px;right:-4px;top:-11px;bottom:-11px;
  border-radius:var(--r-xs)}
.citelink:active{transform:scale(.96);background:var(--acc-weak)}
.cite{font-family:var(--f-mono);font-size:var(--fs-12);color:var(--mut);
  font-variant-numeric:tabular-nums}

/* ================================================================= 2. THREAD */
/* Thread: user = grey bubble right, assistant = plain full-width text.
 * --dock-h is measured by chat.js. */
#msgs{display:flex;flex-direction:column;gap:var(--s5);
  padding:0 0 calc(var(--dock-h) + var(--sp4))}
#msgs:empty{display:none}
/* Content rise: 4px, on real content only. */
.msg{overflow-wrap:break-word;animation:fadeup var(--dur-3) var(--ease-out) both;
  animation-delay:calc(var(--i,0) * 24ms)}
#msgs .msg{font-size:var(--fs-17);line-height:1.5}
/* User bubbles stay grey, right-aligned, iMessage-shaped. --me-mix is 7% light /
 * 16% dark and is mixed HERE, so high contrast (which re-values --txt/--bg on
 * body) still gets a dark bubble. */
#msgs .msg.me{align-self:flex-end;max-width:78%;border:0;border-radius:20px 20px 6px 20px;
  padding:10px 15px;line-height:1.4;box-shadow:none;text-align:left;
  background:color-mix(in srgb,var(--txt) var(--me-mix),var(--bg))}
#msgs .msg.me .mtxt{overflow-wrap:anywhere}
#msgs .msg.me .thumb{display:block;max-width:220px;border-radius:var(--r-sm);
  margin-bottom:var(--s2)}

/* The assistant message is plain full-width text — no card, border, shadow or
 * coloured edge. Parts in order: markdown body -> (isolation) step checkboxes ->
 * ONE slim status line -> "N sheets ›" pill + 👍/👎/copy row (newest answer only). */
#msgs .msg.ai.amsg{position:relative;background:transparent;border:0;border-radius:0;
  box-shadow:none;padding:0;margin:0;max-width:100%;align-self:stretch;
  font-size:var(--fs-17);line-height:1.55;color:var(--txt);overflow-wrap:anywhere}
@media (min-width:700px){#msgs .msg.ai.amsg{max-width:70ch}}
#msgs .amsg .cite{font-size:.8em;padding:1px 5px;border-radius:5px;
  background:color-mix(in srgb,var(--txt) 6%,transparent);color:var(--mut);white-space:nowrap}

/* ---- markdown body */
#msgs .amsg .md>:first-child{margin-top:0}
#msgs .amsg .md>:last-child{margin-bottom:0}
#msgs .amsg .md p{margin:0 0 .6em}
#msgs .amsg .md strong{font-weight:650}
#msgs .amsg .md em{font-style:italic}
#msgs .amsg .md code{font-family:var(--f-mono);font-size:.86em;padding:1px 5px;
  border-radius:5px;background:var(--surface-2);border:1px solid var(--hair);white-space:nowrap}
#msgs .amsg .md code.wrap{white-space:normal;overflow-wrap:anywhere}
/* device tags (-Q4, XE1:7): mono so they read as labels, but sized and weighted to sit IN the
 * sentence (the card era's heavy mono shouted over the prose) */
#msgs .amsg .md b{font-family:var(--f-mono);font-size:.92em;font-weight:600;letter-spacing:-.01em}
#msgs .amsg .md .md-h{font-size:var(--fs-17);line-height:1.4;font-weight:700;
  margin:1.1em 0 .35em;letter-spacing:-.01em}
#msgs .amsg .md ul.md-l,#msgs .amsg .md ol.md-l{margin:0 0 .7em;padding-left:1.45em}
#msgs .amsg .md li{margin:.28em 0;padding-left:.15em}
#msgs .amsg .md li>ul.md-l,#msgs .amsg .md li>ol.md-l{margin:.25em 0 .1em}
#msgs .amsg .md ol.md-l>li::marker{font-variant-numeric:tabular-nums;color:var(--mut);font-weight:600}
#msgs .amsg .md ul.md-l>li::marker{color:var(--mut)}
#msgs .amsg .md blockquote{margin:0 0 .7em;padding:0 0 0 12px;border-left:3px solid var(--line);
  color:var(--mut)}
#msgs .amsg .md hr{border:0;border-top:1px solid var(--hair);margin:1em 0}
#msgs .amsg .md .md-tw{overflow-x:auto;margin:0 0 .8em;-webkit-overflow-scrolling:touch}
#msgs .amsg .md table.md-t{border-collapse:collapse;font-size:var(--fs-15);min-width:60%}
#msgs .amsg .md table.md-t th,#msgs .amsg .md table.md-t td{text-align:left;
  padding:6px 10px;border-bottom:1px solid var(--hair);vertical-align:top}
#msgs .amsg .md table.md-t th{font-weight:650;color:var(--mut);font-size:var(--fs-13)}

/* ---- isolation steps: the numbered list itself becomes a checklist */
#msgs .amsg .md ol.md-l.chk{list-style:none;padding-left:0}
#msgs .amsg .md ol.md-l.chk>li{display:flex;align-items:flex-start;gap:12px;margin:.5em 0;padding:0}
#msgs .amsg .md .stepchk{flex:none;appearance:none;-webkit-appearance:none;margin:0;
  width:24px;height:24px;border:2px solid var(--line);border-radius:7px;background:var(--surface);
  position:relative;cursor:pointer;top:1px;
  /* 44px touch target without changing the line box */
  box-shadow:0 0 0 10px transparent}
#msgs .amsg .md .stepchk::after{content:"";position:absolute;inset:-10px}
#msgs .amsg .md .stepchk:checked{background:var(--ok,#2E7D32);border-color:var(--ok,#2E7D32)}
#msgs .amsg .md .stepchk:checked::before{content:"";position:absolute;left:7px;top:3px;width:6px;height:11px;
  border:solid #fff;border-width:0 2.5px 2.5px 0;transform:rotate(45deg)}
/* a ticked step greys out but stays readable (no strike-through over device tags) */
#msgs .amsg .md .stepchk:checked+.li-t{color:var(--mut)}
#msgs .amsg .md .stepchk:focus-visible{outline:2px solid var(--acc);outline-offset:2px}

/* ---- the one status line (kind = isolation | shared | stale | unverified | …) */
#msgs .amsg .status{display:flex;align-items:flex-start;gap:8px;margin:.55em 0 0;
  font-size:var(--fs-15);line-height:1.4;font-weight:500;color:var(--mut)}
#msgs .amsg .status .sdot{flex:none;width:8px;height:8px;border-radius:50%;margin-top:.45em;
  background:var(--mut)}
#msgs .amsg .status.s-isolation,#msgs .amsg .status.s-shared{color:var(--warn-ink,#8A5A00)}
#msgs .amsg .status.s-isolation .sdot,#msgs .amsg .status.s-shared .sdot{background:var(--warn,#E0A100)}
#msgs .amsg .status.s-stale,#msgs .amsg .status.s-unverified{color:var(--danger-ink)}
#msgs .amsg .status.s-stale .sdot,#msgs .amsg .status.s-unverified .sdot{background:var(--danger)}

/* ---- refusal: one red-tinted line + reason */
#msgs .msg.ai.amsg.refused .refline{margin:0;padding:10px 14px;border-radius:14px;
  background:color-mix(in srgb,var(--danger) 9%,transparent);color:var(--txt);
  font-size:var(--fs-15);line-height:1.45}
#msgs .msg.ai.amsg.refused .refline strong{color:var(--danger-ink);font-weight:700}

/* ---- error: one line + Retry */
#msgs .amsg.ecard .errline{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;
  font-size:var(--fs-15);color:var(--mut)}
#msgs .amsg.ecard .etxt{flex:1 1 auto;min-width:0}
#msgs .amsg.ecard .retrybtn{flex:none;min-height:44px;padding:0 18px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface);color:var(--txt);
  font-size:var(--fs-15);font-weight:600;cursor:pointer}
#msgs .amsg.ecard .errx{flex:none;width:44px;height:44px;border:0;background:transparent;
  color:var(--mut);font-size:22px;line-height:1;cursor:pointer;border-radius:50%}

/* ---- sheets pill + feedback icons */
#msgs .amsg .arow{display:flex;align-items:center;gap:var(--s1);margin:.5em 0 0;min-height:0}
#msgs .amsg .arow:empty{display:none}
#msgs .amsg .sheetspill{display:inline-flex;align-items:center;gap:4px;min-height:44px;
  padding:0 14px;margin-right:auto;border-radius:var(--r-pill);border:1px solid var(--hair);
  background:var(--surface-2);color:var(--txt);font-size:var(--fs-15);font-weight:500;
  font-variant-numeric:tabular-nums;cursor:pointer;
  transition:transform var(--dur-1) var(--spring),background var(--dur-1) var(--ease-out)}
#msgs .amsg .sheetspill .chev{font-size:20px;line-height:1;color:var(--mut);margin-left:2px}
#msgs .amsg .sheetspill:active{transform:scale(.97);background:var(--surface-3,var(--surface-2))}
#msgs .amsg .fb{display:inline-flex;gap:0;margin-left:auto}
#msgs .amsg .fb .fbbtn{flex:none;width:44px;height:44px;min-height:44px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:50%;
  background:transparent;color:var(--mut);box-shadow:none;
  font-size:var(--fs-13);line-height:18px;font-weight:600;white-space:nowrap;cursor:pointer;
  transition:transform var(--dur-1) var(--spring),background var(--dur-1) var(--ease-out)}
#msgs .amsg .fb .fbbtn svg{width:19px;height:19px}
#msgs .amsg .fb .fbbtn:active{background:var(--surface-2);color:var(--txt);transform:scale(.92)}
#msgs .amsg .fb .fbbtn[aria-pressed="true"]{color:var(--acc-ink)}
/* feedback shows under the newest answer only (older ones stay clean) */
#msgs>.msg.ai:not(:last-child) .fb,#msgs>.msg.ai.pending .fb{display:none}
/* 👎 opens a one-line "what fixed it" box under the answer. */
#msgs .fbfix{margin-top:var(--s2)}
#msgs .fbfix label{display:block;font-size:var(--fs-13);font-weight:600;color:var(--mut);
  margin-bottom:var(--s1)}
#msgs .fbfix .row{display:flex;gap:var(--s2);margin-top:var(--s2)}
#msgs .fbfix .fixin{width:100%;min-height:48px;padding:0 var(--s3);
  background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);
  color:var(--txt);font-size:var(--fs-17);font-family:inherit}
#msgs .fbfix .hint{font-size:var(--fs-12);color:var(--mut);margin-top:var(--s1)}

/* ---- streaming: typing dots until the first token */
#msgs .amsg.pending{min-height:28px}
#msgs .amsg .typing{display:inline-flex;align-items:center;gap:5px;height:24px}
#msgs .amsg .typing i{width:8px;height:8px;border-radius:50%;background:var(--mut);opacity:.35;
  animation:typing-dot 1.2s ease-in-out infinite}
#msgs .amsg .typing i:nth-child(2){animation-delay:.15s}
#msgs .amsg .typing i:nth-child(3){animation-delay:.3s}
@keyframes typing-dot{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:.9;transform:translateY(-3px)}}

/* ---- "New answer ↓" pill */
#newpill{position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(var(--dock-h,120px) + 12px + var(--kb,0px) + env(safe-area-inset-bottom));
  z-index:35;min-height:44px;padding:0 var(--s4);border:0;border-radius:var(--r-pill);
  background:var(--acc);color:var(--acc-t);font-size:var(--fs-15);font-weight:700;
  box-shadow:var(--e3);cursor:pointer;animation:pill-in var(--dur-3) var(--spring) both}
@keyframes pill-in{from{opacity:0;transform:translate(-50%,10px)}
  to{opacity:1;transform:translate(-50%,0)}}

/* ---- "Fixed on CCx" resurfacing card */
.card.fixedcard.resurf{border-left:3px solid var(--ok-ink)}
#view .fixedcard{display:flex;align-items:center;gap:var(--s3);width:100%;
  min-height:56px;margin:0 0 var(--s2);padding:var(--s3) var(--s4);text-align:left;
  background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-md);
  box-shadow:var(--e1);color:var(--txt);cursor:pointer}
#view .fixedcard:active{transform:scale(.985)}

/* ============================================================= 3. SHEET LIST */
/* "N sheets ›" opens the rows in the app's bottom sheet (#appsheet); a page
 * without the app shell expands the same rows inline under the pill. */
#msgs .amsg .sheetlist{margin-top:var(--s2)}
.refcard{min-height:56px}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard{display:grid;grid-template-columns:1fr auto;
  column-gap:var(--s3);row-gap:1px;align-items:center;margin:0 0 var(--s2);padding:11px 14px;
  border-radius:var(--r-sm);background:var(--surface);border:1px solid var(--hair);box-shadow:none;
  color:var(--txt);text-decoration:none;min-height:56px}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .tag{grid-column:1;grid-row:1;
  font-family:var(--f-mono);font-size:var(--fs-17);font-weight:700;color:var(--txt);margin:0;letter-spacing:-.02em}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .t{grid-column:1;grid-row:2;
  font-size:var(--fs-13);font-weight:500;color:var(--mut);line-height:1.35}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .t b{font-family:var(--f-mono);font-weight:700;color:var(--txt)}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .m{grid-column:1;grid-row:3;
  font-size:var(--fs-12);color:var(--mut);font-family:var(--f-mono)}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard::after{content:"\203A";
  grid-column:2;grid-row:1/span 3;align-self:center;color:var(--mut);font-size:22px;line-height:1}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .why{display:block;grid-column:1/span 2;grid-row:5;
  color:var(--mut);font-size:var(--fs-13)}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard :is(.sibbadge,.unverbanner){grid-column:1/span 2;grid-row:4;
  margin-top:var(--s2);padding:5px 9px;border-radius:var(--r-xs);font-size:var(--fs-12);font-weight:700}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .sibbadge{color:var(--acc-ink);background:var(--acc-weak)}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard .unverbanner{color:var(--danger-ink);
  background:color-mix(in srgb,var(--danger) 12%,var(--surface))}
:is(#appsheet .sheetrefs,#msgs .amsg .sheetlist) .refcard.ref-stale{opacity:.72}
/* Rails: a sibling-crane sheet is dashed amber, an unverified one solid red. */
.sibbadge{font-size:13px;font-weight:600;color:var(--acc-ink);margin-top:var(--s1)}
.unverbanner{font-size:14px;font-weight:700;color:var(--danger-ink);margin-top:var(--s1)}
.ref-sib{border-style:dashed;border-color:var(--acc)}
.ref-unver{background:color-mix(in srgb,var(--danger) 8%,var(--surface));border-color:var(--danger)}
.ref-stale{opacity:.6}

/* ========================================================== 4. COMPOSER DOCK */
/* The dock is the bottom-most element of a chat route: status + composer. */
.dock{position:fixed;left:50%;transform:translateX(-50%);width:100%;max-width:760px;
  bottom:0;z-index:30;background:var(--surface);border-top:1px solid var(--hair)}
/* bottom rides the on-screen keyboard (--kb, measured by chat.js) */
#view .dock{background:var(--surface);border-top:1px solid var(--hair);bottom:var(--kb,0px);
  padding:var(--s2) var(--s4) calc(var(--s2) + env(safe-area-inset-bottom))}
#view .dock .composer{display:flex;align-items:flex-end;gap:var(--s2);
  width:100%;box-sizing:border-box;min-height:0;padding:6px;
  background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-lg);
  box-shadow:none;
  transition:border-color var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out),
    transform var(--dur-1) var(--spring)}
#view .dock .composer:focus-within{border-color:color-mix(in srgb,var(--acc) 60%,var(--line));
  box-shadow:0 0 0 3px var(--acc-weak)}
#view .dock .composer.sending{transform:scale(.995)}
#view .dock .composer .cwrap{flex:1 1 auto;min-width:0;display:flex;align-items:center}
#view .dock .composer #qin{flex:1 1 auto;min-width:0;width:100%;box-sizing:border-box;
  resize:none;overflow-y:auto;min-height:46px;max-height:120px;padding:10px var(--s1);
  border:0;outline:0;background:transparent;color:var(--txt);
  font-family:inherit;font-size:var(--fs-17);line-height:24px}
#view .dock .composer #qin::placeholder{color:var(--mut)}
#view .dock .composer #qin:focus-visible{outline:none}
#view .dock .composer .cbtn{flex:none;width:44px;height:44px;min-width:44px;min-height:44px;
  border-radius:50%;border:0;background:transparent;color:var(--mut);
  display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;
  transition:background var(--dur-1) var(--ease-out),transform var(--dur-1) var(--spring)}
#view .dock .composer .cbtn svg{width:22px;height:22px}
#view .dock .composer .cbtn:active{transform:scale(.92);background:var(--surface-3)}
#view .dock .composer #qsend{flex:none;width:44px;height:44px;min-width:44px;min-height:44px;
  padding:0;border:0;border-radius:50%;background:var(--acc);color:var(--acc-t);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  font-size:var(--fs-15);font-weight:600;
  transition:transform var(--dur-1) var(--spring),filter var(--dur-1) var(--ease-out)}
#view .dock .composer #qsend svg{width:21px;height:21px}
#view .dock .composer #qsend:active{transform:scale(.9);filter:brightness(.95)}
#view .dock .composer #qsend:disabled{opacity:.45;cursor:default}
/* Send ⇄ Stop while an answer streams. */
#view .dock .composer #qsend.stop{background:var(--txt);color:var(--surface)}
#view .dock .composer #qsend.stop svg{width:16px;height:16px}
/* Staged-send status line above the composer (pulsing dot + elapsed + Cancel). */
#view .dock #sendstate{display:flex;align-items:center;gap:var(--s2);
  font-size:var(--fs-13);line-height:18px;font-weight:600;color:var(--mut);margin:0 0 var(--s2);min-height:0}
#view .dock #sendstate:empty{display:none;margin:0;padding:0}
#sendstate:not(:empty)::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;
  background:var(--ok-ink);animation:chatsendpulse 1.2s ease-in-out infinite}
@keyframes chatsendpulse{0%,100%{opacity:.4}50%{opacity:1}}
#view .dock #photoprev{margin:0 0 var(--s2)}
#view .dock #photoprev:not(:empty){display:flex;align-items:center;gap:var(--s2)}
#view .dock #photoprev .thumb{max-width:120px;border-radius:var(--r-sm);vertical-align:middle}

/* ============================================= 5. WELCOME + CRANE SWITCHING */
/* The welcome screen: one line + at most four chips, sitting directly above the
 * composer — thumb reach, and nothing to scroll past. It fills the space above the dock and
 * bottom-aligns, so its last chip always clears the dock's measured top edge. */
#view #zerostarters.welcome{display:flex;flex-direction:column;justify-content:flex-end;
  box-sizing:border-box;
  min-height:calc(100dvh - var(--topbar-h) - env(safe-area-inset-top) - var(--offbar-h,0px) - var(--s3) - var(--kb,0px));
  padding-bottom:calc(var(--dock-h,120px) + var(--s3))}
/* An empty thread is a welcome screen too, but in flow: reserve the dock below it. */
#msgs:empty + #zerostarters{padding-bottom:calc(var(--dock-h,120px) + var(--s3))}
#view .welcomeline{margin:0 2px var(--s3);font-size:var(--fs-17);line-height:1.4;
  font-weight:600;color:var(--txt);max-width:46ch}
#view .chips{margin:var(--s1) 0 var(--s2)}
#view .starterbank{gap:4px;margin:0}
#view .starterbank .chip{text-align:left;white-space:normal;line-height:1.3;
  min-height:44px;height:auto;padding:8px var(--s3)}
#view .welcome .starterbank,#msgs:empty + #zerostarters .starterbank{display:flex;
  flex-direction:column;align-items:stretch;gap:var(--s2);margin:0}
/* "Now on CC4": the crane switch inside a chat. Everything above it is history the model
 * no longer sees. */
#msgs .crdiv{display:flex;align-items:center;gap:var(--s3);margin:var(--s1) 0;
  color:var(--mut);font-family:var(--f-mono);font-size:var(--fs-13);font-weight:700;
  font-variant-numeric:tabular-nums;letter-spacing:.02em}
#msgs .crdiv::before,#msgs .crdiv::after{content:"";flex:1 1 0;height:1px;background:var(--hair)}
/* The crane picker (bottom sheet opened from the title). */
#appsheet .cranepick{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s2);
  margin:var(--s2) 0 var(--s3)}
#appsheet .cranepick .chip{min-height:48px;justify-content:center;font-family:var(--f-mono);
  font-weight:700}
#appsheet .cranepick .chip[aria-pressed="true"]{background:var(--acc);color:var(--acc-t);
  border-color:transparent}

/* =========================================================== 6. HISTORY LIST */
#drawer #chatlist .sec{margin:var(--s3) var(--s4) var(--s1)}
:is(#view,#drawer) #chatlist .sec:first-child{margin-top:var(--s2)}
:is(#view,#drawer) .listbar{margin:0 0 var(--s3)}
:is(#view,#drawer) .listbar input{width:100%;box-sizing:border-box;min-height:44px;
  padding:0 var(--s3);border-radius:var(--r-sm);background:var(--surface);
  border:1px solid var(--hair);color:var(--txt);font-size:var(--fs-17);
  font-family:inherit;box-shadow:var(--e1);-webkit-appearance:none;appearance:none}
:is(#view,#drawer) .listbar input:focus{border-color:var(--acc);outline:none;box-shadow:var(--e2)}
:is(#view,#drawer) .listbar input::-webkit-search-cancel-button{-webkit-appearance:none}
:is(#view,#drawer) .listhint{margin:0 2px var(--s2);font-size:var(--fs-12);color:var(--mut)}
#drawer .listbar{margin:0 var(--s3) var(--s2)}
#drawer .listhint{margin:0 var(--s4) var(--s2)}
/* Swipe-to-archive row. */
:is(#view,#drawer) .swipe{position:relative;overflow:hidden;border-radius:0;
  border-bottom:1px solid var(--hair);background:var(--surface)}
:is(#view,#drawer) .swipe:first-child{border-top:1px solid var(--hair)}
:is(#view,#drawer) .swipe .stray{position:absolute;top:0;right:0;bottom:0;display:flex;z-index:0;
  touch-action:pan-y}
:is(#view,#drawer) .swipe .sact{width:80px;min-height:44px;border:0;color:#fff;
  font-size:var(--fs-13);font-weight:700;cursor:pointer}
:is(#view,#drawer) .swipe .sact.arch{background:var(--n-600)}
/* Destructive tray: --danger-solid is a deeper red in dark mode (white on the
 * dark --danger #ff453a measured 3.41:1), so the label stays >=4.5:1. */
:is(#view,#drawer) .swipe .sact.del{background:var(--danger-solid)}
:is(#view,#drawer) .swipe .chatrow{position:relative;z-index:1;touch-action:pan-y;
  -webkit-user-drag:none;user-select:none;display:grid;
  grid-template-columns:1fr auto;column-gap:var(--s3);row-gap:2px;
  min-height:76px;padding:12px var(--s4) 12px var(--gutter);
  background:var(--surface);color:var(--txt);text-decoration:none;
  border-radius:0;transition:transform var(--dur-3) var(--ease)}
:is(#view,#drawer) .swipe .chatrow:active{background:var(--surface-2)}
#drawer .swipe .chatrow[aria-current="page"]{background:var(--surface-2)}
/* the reveal is class-driven: focus-driven opening must stay animated so a
 * plain mouse click still lands on the link (critic P1) */
:is(#view,#drawer) .swipe.open .chatrow{transform:translateX(-160px)}
:is(#view,#drawer) .swipe .chatrow .ct{grid-column:1;grid-row:1;font-size:var(--fs-17);
  font-weight:600;letter-spacing:-.015em;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
:is(#view,#drawer) .swipe .chatrow .cm{grid-column:1;grid-row:2;display:flex;align-items:center;
  gap:0;font-size:var(--fs-12);color:var(--mut);font-variant-numeric:tabular-nums}
/* separators are pseudo-elements: a real text node here fails the contrast
 * gate (the dot colour is a hairline, not text). */
:is(#view,#drawer) .swipe .chatrow .cm > * + *::before{content:"·";color:var(--mut);
  margin:0 6px;font-weight:600}
:is(#view,#drawer) .swipe .chatrow .cm .casset{font-family:var(--f-mono);font-weight:700;color:var(--acc-ink)}
:is(#view,#drawer) .swipe .chatrow .qpill{background:var(--acc-weak);color:var(--acc-ink);
  border-radius:var(--r-xs);padding:0 6px;font-weight:700;font-size:var(--fs-12)}
:is(#view,#drawer) .swipe .chatrow .cp{grid-column:1;grid-row:3;font-size:var(--fs-13);color:var(--mut);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:is(#view,#drawer) .swipe .chatrow .cgo{grid-column:2;grid-row:1/span 3;align-self:center;
  color:var(--mut);font-size:22px;line-height:1}

/* ==================================================================== 7. MODES */
/* High contrast (body.contrast) is opaque black/white/yellow. */
body.contrast #msgs .msg.ai.amsg{background:#000;border:0;color:#fff}
body.contrast #msgs .amsg .sheetspill,body.contrast #msgs .amsg.ecard .retrybtn{background:#000;color:#fff;border-color:#fff}
body.contrast #msgs .amsg .status{color:#ff0}
body.contrast #msgs .amsg .status .sdot{background:#ff0}
body.contrast #msgs .msg.ai.amsg.refused .refline{background:#000;border:1px solid #ff0;color:#fff}
body.contrast #msgs .citelink{color:#ff0;border-color:#ff0;background:transparent}
body.contrast #msgs .crdiv{color:#fff}
body.contrast :is(#view,#drawer) .swipe .chatrow,
body.contrast #view .fixedcard,
body.contrast #view .dock .composer{background:#000;color:#fff;border-color:#fff}
body.contrast :is(#view,#drawer) .swipe .sact.arch,body.contrast :is(#view,#drawer) .swipe .sact.del{
  background:#fff;color:#000}
body.contrast #newpill{background:#ff0;color:#000}
/* Reduced motion: no pill spring, no pulsing or bouncing dots. */
@media (prefers-reduced-motion:reduce){
  #newpill{animation:none}
  #sendstate:not(:empty)::before{animation:none;opacity:.8}
  #msgs .amsg .typing i{animation:none;opacity:.6}
}
/* Short viewport (keyboard / landscape): compact but never below the 44px
 * target floor. */
@media (max-height:520px){
  #view .dock{padding:var(--s1) var(--s3) calc(var(--s1) + env(safe-area-inset-bottom))}
  #view .dock .composer #qin{min-height:44px}
}
/* Landscape phones/tablets (>=600px wide, short): the composer moves into a
 * right-hand rail so the thread keeps full height. */
@media (min-width:600px) and (max-height:520px){
  .dock{left:auto;right:0;transform:none;width:340px;top:var(--topbar-h);
    border-left:1px solid var(--hair);
    display:flex;flex-direction:column;justify-content:flex-end;gap:var(--s2)}
  #msgs{padding-bottom:var(--s4)}
  #view .dock .composer{border-radius:var(--r-md)}
}
@media (max-width:359px){
  #msgs .msg.me{max-width:92%}
  #view .dock .composer{padding:4px}
  #view .dock .composer #qin{font-size:16px}
}
@media (min-width:900px){
  .dock{max-width:920px}
}
