/* Polish layer, loaded last. Cross-cutting refinements that are not owned by one component
   file: icon weight, press feedback, popover entrances, AI-working states, the chat and the
   workspace Ask box. Only new rules here (no markup depends on this file), so it merges cleanly
   with work on chat.rs / settings.rs / ws_ai.rs. Every animation below is either feedback (press),
   a state change (popover opens, AI is working) or progress; all of it is switched off under
   prefers-reduced-motion by the global rule in style.css, and the few with layout-visible
   end-states have explicit static fallbacks at the bottom. */

/* ---------- Iconography: one stroke weight ---------- */
/* Icons come from several helpers with stroke widths 1.75 to 2.5; normalise the root weight.
   A child path that sets its own width (the pause bars, the step glyph) keeps it. */
.icon-btn svg, .ws-btn svg, .gc-btn svg, .gc-menu-item svg, .ws-fbtn svg, .btn svg, .link-btn svg { stroke-width: 1.75; }
.send-btn svg { stroke-width: 2; }

/* ---------- Press feedback on compact controls ---------- */
.icon-btn, .ws-btn, .gc-btn, .mode-btn, .ws-seg-btn, .side-tab, .chip-btn, .ws-chip, .ws-swatch, .tbl-btn {
  transition-property: background, color, border-color, box-shadow, transform, filter;
  transition-duration: var(--dur-1);
  transition-timing-function: var(--ease);
}
.icon-btn:active:not(:disabled), .ws-btn:active:not(:disabled), .gc-btn:active:not(:disabled),
.mode-btn:active, .ws-seg-btn:active, .side-tab:active, .chip-btn:active:not(:disabled),
.ws-chip:active, .ws-swatch:active, .send-btn:active:not(:disabled) { transform: var(--press); }

/* ---------- Focus: keep rings visible inside clipped or tight containers ---------- */
.ws-menu-item:focus-visible, .gc-menu-item:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.tbl-cell:focus-visible { outline-offset: -2px; }
.ws-swatch:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 50%; }
.ws-swatch:hover { transform: scale(1.08); }
.ws-swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent); }

/* ---------- Popovers open with a short settle ---------- */
.ws-menu, .ws-settings, .ws-style { animation: pol-pop var(--dur-2) var(--ease-out); transform-origin: top left; }
.ws-menu.right, .ws-row-menu, .ws-settings { transform-origin: top right; }
@keyframes pol-pop { from { opacity: 0; transform: translateY(-4px) scale(0.98); } to { opacity: 1; transform: none; } }
.ws-toast { animation: pol-toast var(--dur-2) var(--ease-out); }
@keyframes pol-toast { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translateX(-50%); } }
.ws-menu-item { display: flex; align-items: center; gap: var(--s-2); }

/* The style popover sits under its row like a sheet of the same paper. */
.ws-style { background: var(--surface); border-color: var(--border-strong); box-shadow: var(--shadow-2); }
.ws-style-sec + .ws-style-sec { padding-top: var(--s-3); border-top: 1px solid var(--border); }
.ws-show { font-size: var(--fs-sm); }

/* ---------- Empty and first-run states ---------- */
.graph-empty > * , .chat-empty > * { animation: pol-rise var(--dur-3) var(--ease-out) both; }
.graph-empty > :nth-child(2), .chat-empty > :nth-child(2) { animation-delay: 60ms; }
.graph-empty > :nth-child(3), .chat-empty > :nth-child(3) { animation-delay: 120ms; }
.graph-empty > :nth-child(n+4), .chat-empty > :nth-child(n+4) { animation-delay: 180ms; }
@keyframes pol-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.graph-empty-title, .chat-empty-title { letter-spacing: -0.005em; text-wrap: balance; }
.graph-empty-sub { text-wrap: pretty; line-height: 1.55; }
.graph-empty .btn { margin-top: var(--s-4); }
/* the empty-state curve draws itself once */
.graph-empty .art-curve { stroke-dasharray: 2 8; }
.chat-empty .art-curve { stroke-dasharray: 160; stroke-dashoffset: 160; animation: pol-draw 900ms var(--ease-out) 150ms forwards; }
@keyframes pol-draw { to { stroke-dashoffset: 0; } }

/* ---------- Chat ---------- */
.chat-empty-sub { max-width: 34ch; line-height: 1.55; }
/* example prompts: the label is a short name, not an eyebrow */
.example { gap: 3px; padding: 11px 14px 12px; }
.example-label { text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); font-weight: 650; color: var(--text); }
.example-text { color: var(--text-2); font-size: var(--fs-sm); line-height: 1.4; }
.example:hover .example-label { color: var(--accent-text); }
.example:active { transform: translateY(0) scale(0.99); }
.msg { line-height: 1.5; }
.msg-assistant { border-color: var(--border); }
.msg-meta { font-variant-numeric: tabular-nums; }

/* The AI is working: the reply bubble gets a moving accent edge and the elapsed time stays steady. */
.generating { position: relative; overflow: hidden; border-color: var(--accent-soft); }
.generating::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(var(--accent), var(--accent-soft), var(--accent)) 0 0 / 100% 200%;
  animation: pol-edge 1.6s linear infinite;
}
@keyframes pol-edge { to { background-position: 0 -200%; } }
.generating-text { font-weight: 600; color: var(--text); }
.elapsed { font-variant-numeric: tabular-nums; color: var(--text-3); }
.progress { height: 4px; border-radius: 2px; }
.progress i { background: linear-gradient(90deg, var(--accent-soft), var(--accent)); border-radius: 2px; }
.dots i { animation-name: pol-dot; animation-duration: 1.2s; animation-timing-function: var(--ease); }
@keyframes pol-dot { 0%, 100% { opacity: 0.35; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }

.composer { padding: var(--s-3) var(--s-3) var(--s-3) var(--s-3); }
.composer-input { transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); }
.composer-input:hover:not(:focus) { border-color: var(--text-3); }
.send-btn:not(:disabled) { box-shadow: 0 2px 6px rgb(42 69 184 / 0.28); }
.suggest .chip-btn, .ws-ask-chips .chip-btn { border-color: transparent; }
.suggest .chip-btn:disabled, .ws-ask-chips .chip-btn:disabled { opacity: 0.5; }

/* ---------- Workspace Ask box ---------- */
.ws-ask { position: relative; gap: var(--s-2); padding-top: var(--s-3); }
.ws-ask-input { border-radius: var(--r-pill); padding-inline: 16px; }
.ws-ask-input:hover:not(:focus) { border-color: var(--text-3); }
.ws-ask-form .btn-primary { border-radius: var(--r-pill); padding-inline: 16px; min-height: 38px; }
.ws-ask-reply { border-radius: var(--r-md); box-shadow: var(--shadow-1); animation: pol-rise var(--dur-2) var(--ease-out); }
.ws-ask-text { line-height: 1.45; }
/* while the model works: an indeterminate accent line runs along the box's top edge, and the
   status line reads as a status, not as body text */
.ws-ask:has(.ws-ask-status)::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent) 40%, var(--accent) 60%, transparent) -40% 0 / 40% 100% no-repeat, var(--accent-soft);
  animation: pol-scan 1.4s var(--ease) infinite;
}
@keyframes pol-scan { to { background-position: 140% 0, 0 0; } }
.ws-ask-status { min-height: 28px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.ws-ask-status .btn { margin-left: auto; }
/* the canvas side shows the same "working" state, so the eye on the graph sees it too */
.app:has(.ws-ask-status) .ws-toolbar { box-shadow: inset 0 -2px 0 var(--accent-soft); }

/* ---------- Settings dialogs (modal shell only; the form content is left alone) ---------- */
.modal { overflow: hidden; }
.modal-head h2 { letter-spacing: -0.005em; }
.ws-settings-head h2 { letter-spacing: -0.005em; }
.ws-settings-sec + .ws-settings-sec { padding-top: var(--s-3); border-top: 1px solid var(--border); }
.ws-win-row .ws-input { font-variant-numeric: tabular-nums; }

/* ---------- Gallery cards ---------- */
.graph-card { transition: box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }
.graph-card-head h3 { letter-spacing: -0.005em; }
.gc-count { font-variant-numeric: tabular-nums; }
.gc-eqs code { box-shadow: inset 0 0 0 1px var(--border); background: var(--bg); }

/* ---------- Header ---------- */
.brand { padding: 2px 4px 2px 2px; transition: background var(--dur-1) var(--ease); }
.brand:hover .logo-tile { filter: brightness(1.08); }
.side-tab { min-width: 4.5rem; }

/* ---------- Static fallbacks for reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .chat-empty .art-curve { stroke-dashoffset: 0; animation: none; }
  .graph-empty > *, .chat-empty > * { animation: none; }
  .ws-ask:has(.ws-ask-status)::before { animation: none; background: var(--accent); }
  .generating::before { animation: none; background: var(--accent); }
  .ws-pending::before { animation: none; background-size: 100% 100%; }
  .vt:has(.vt-status) .vt-grid:empty::before, .vt:has(.vt-status) .vt-grid:empty::after { animation: none; }
  .vt-card.vt-regen .vt-thumb::after { animation: none; background: rgb(255 255 255 / 0.35); }
  .icon-btn:active, .ws-btn:active, .gc-btn:active, .mode-btn:active, .ws-seg-btn:active, .side-tab:active,
  .chip-btn:active, .ws-chip:active, .ws-swatch:active, .send-btn:active, .ws-dot:active, .ws-fbtn:active { transform: none; }
}

/* ---------- Windows high contrast / forced colours ---------- */
@media (forced-colors: active) {
  .ws-dot span { background: CanvasText; }
  .ws-row:focus-within::after { box-shadow: inset 0 0 0 2px Highlight; }
}

/* ---------- Phones: a compact AI footer, so the open sheet keeps room for the rows ---------- */
@media (max-width: 767px) {
  /* quick requests become one scrolling line instead of a wrapping block */
  .ws-ask-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .ws-ask-chips li { flex: 0 0 auto; }
  .ws-ask { padding-top: var(--s-2); gap: var(--s-1); }
  .ws-ask-reply { max-height: 6rem; }
  /* the automatic-change / "no model" notes: smaller, two lines of text at most */
  .pnudge { padding: var(--s-2) var(--s-3); gap: var(--s-1); }
  .pnudge-text {
    font-size: var(--fs-xs); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  }
  /* its buttons stay on one scrolling row; the pill below repeats what the note says, so it hides */
  .pnudge .pactions { gap: var(--s-1); flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .pnudge .pactions .btn { flex: 0 0 auto; white-space: nowrap; min-height: 40px; }
  aside.left:has(.pnudge) .provider-row { display: none; }
  .provider-row { padding-top: 0; }
}
/* Short phones (a browser with toolbars on a small screen): drop the quick-request chips, which
   are suggestions only; the provider pill and the Ask box stay. */
@media (max-width: 767px) and (max-height: 760px) {
  .ws-ask-chips { display: none; }
}

/* ---------- Touch: 44 px hit areas without moving anything ---------- */
@media (pointer: coarse) {
  .ws-dot, .ppill { position: relative; }  /* the grip is already positioned */
  .ws-grip::after, .ws-dot::after, .ppill::after { content: ""; position: absolute; }
  .ws-grip::after { inset: -8px -11px; }
  .ws-dot::after { inset: -6px; }
  .ppill::after { inset: -10px -4px; }
  .ws-ask-form .btn-primary, .ws-ask-form .btn { min-height: var(--touch); }
  .ws-name { min-height: var(--touch); }
  .ppill { min-height: 28px; }
}

/* ---------- Phones: menus open as a scrollable panel above the bottom edge, not clipped by the sheet ---------- */
@media (max-width: 767px) {
  .ws-menu, .ws-menu.right, .ws-row-menu {
    position: fixed; left: var(--s-3); right: var(--s-3); top: auto; bottom: var(--s-3);
    min-width: 0; max-height: 70dvh; overflow-y: auto; overscroll-behavior: contain; transform-origin: bottom center;
  }
}
