/* Design by Kai — Shopper Widget Styles (M · Tight)
 *
 * Layout: 1fr viewer column + ~34% form column (1fr 0.515fr grid).
 * Form column scrolls internally; viewer column is fixed.
 * Component classes are prefixed `kw-` (kai-widget).
 *
 * Loaded from public/index.html on /?token=<embed_token>.
 * Design tokens, animations, and tile patterns ported from the
 * design_handoff_kai_widget bundle (kai-tight.jsx + kai-shared.jsx +
 * kai-hybrid-palettes.jsx). Keep this file in sync with the bundle
 * if you make visual changes here. */

/* ──────────────────────────────── tokens ─── */
:root {
  --bg:          #f4eee9;
  --panel:       #fefaf5;
  --panel-2:     #ebe2da;
  --ink-1:       #2a2520;
  --ink-2:       #5e564f;
  --ink-3:       #9a8f85;
  --line:        #d9cfc4;
  --accent:      #6a4d8a;
  --accent-soft: #efe6f5;
  --accent-ink:  #4a3360;
  --ok:          #5b8a4e;
  --serif: 'Newsreader', Georgia, serif;
  --sans:  'Geist', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --mono:  'Geist Mono', ui-monospace, monospace;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink-1);
  font-size: 13px;
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; }

/* ─────────────────────────────── root ────── */
.kw-root {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background: var(--bg);
}

/* ───────────────────────────── header ────── */
.kw-header {
  height: 52px;
  padding: 0 22px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.kw-brand { display: flex; align-items: center; gap: 10px; }
.kw-brand-mark {
  width: 26px; height: 26px; border-radius: 6px;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-weight: 600; font-style: italic; font-size: 16px;
}
.kw-brand-name {
  font-family: var(--serif);
  font-size: 18px; font-weight: 500;
  color: var(--ink-1);
}
.kw-brand-name em { font-style: italic; color: var(--accent); }
.kw-ai-badge {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--ink-2);
  display: flex; align-items: center; gap: 6px;
}
.kw-ai-badge-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); display: inline-block;
}

/* ───────────────────────── body grid ─────── */
.kw-body {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 0.515fr;
  overflow: hidden;
  min-height: 0;
}

/* ──────────────────────── viewer column ─── */
.kw-viewer-col {
  position: relative;
  background: linear-gradient(180deg, #f4eee9 0%, #e8ddd1 100%);
  border-right: 1px solid var(--line);
  overflow: hidden;
}
#viewer-container { width: 100%; height: 100%; }
.kw-viewer-topbar {
  position: absolute;
  top: 16px; left: 16px; right: 16px;
  z-index: 3;
  display: flex; justify-content: space-between; align-items: center;
  pointer-events: none;
}
.kw-viewer-topbar > * { pointer-events: auto; }
.kw-viewer-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-ink);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.6px; text-transform: uppercase;
  font-family: var(--sans);
  border: 1px solid rgba(106, 77, 138, 0.18);
}
.kw-viewer-badge-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(106, 77, 138, 0.18);
  display: inline-block;
}
.kw-viewer-hide {
  padding: 6px 12px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--line); color: var(--ink-1);
  font-size: 12px; font-weight: 500; cursor: pointer;
  font-family: var(--sans);
}
.kw-viewer-placeholder {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  height: 100%;
  color: var(--ink-3); gap: 10px;
  font-family: var(--serif); font-style: italic; font-size: 14px;
  text-align: center; padding: 0 24px;
}
.kw-viewer-placeholder svg {
  width: 64px; height: 64px; opacity: 0.25; stroke: var(--ink-3);
}

/* Richer empty-state placeholder used before any template is loaded.
 * Mirrors design_handoff_kai_widget/kai-shared.jsx ViewerStage: wooden
 * floor + standing banner that sways gently via kaiBannerSway. Sits
 * inside #viewer-container until KaiViewer creates its Three.js canvas. */
.kw-viewer-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.kw-stage-floor {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 28%;
  background: repeating-linear-gradient(90deg, #b8997a 0 38px, #ad8e6e 38px 78px);
  box-shadow: inset 0 12px 24px rgba(0, 0, 0, 0.15);
  transform-origin: center bottom;
  transform: perspective(420px) rotateX(56deg);
  opacity: 0.55;
}
.kw-stage-banner {
  position: absolute;
  left: 50%; bottom: 12%;
  transform: translateX(-50%);
  width: 34%;
  aspect-ratio: 31.5 / 80;
  max-height: 78%;
  animation: kaiBannerSway 8s ease-in-out infinite;
}
.kw-stage-banner-face {
  position: absolute;
  inset: 0;
  background: var(--panel);
  border-radius: 2px 2px 0 0;
  box-shadow: 0 18px 36px rgba(0, 0, 0, 0.18), 0 2px 0 rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
  border: 1px solid var(--line);
}
.kw-stage-banner-mark {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(13px, 1.5cqi + 8px, 18px);
  color: var(--ink-2);
  line-height: 1.2;
}
.kw-stage-banner-sub {
  font-family: var(--sans);
  font-size: clamp(10px, 1cqi + 6px, 12px);
  color: var(--ink-3);
  margin-top: 4px;
  line-height: 1.3;
}
.kw-stage-stand-bar {
  position: absolute;
  bottom: -10px; left: -8%; right: -8%;
  height: 8px;
  background: #bdbdbd;
  border-radius: 2px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.kw-stage-stand-foot {
  position: absolute;
  bottom: -16px;
  width: 28px; height: 8px;
  background: #9c9c9c;
  border-radius: 2px;
}
.kw-stage-stand-foot--l { left: -14%; }
.kw-stage-stand-foot--r { right: -14%; }
.kw-stage-hint {
  position: absolute;
  bottom: 12px; left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-2);
  z-index: 3;
}
.kw-stage-hint-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #5fbf7f;
  box-shadow: 0 0 8px rgba(95, 191, 127, 0.6);
  animation: kaiPulse 1.6s ease-in-out infinite;
}

/* ────────────────────────── form column ─── */
.kw-form-col {
  padding: 14px 18px 18px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 12px;
  min-height: 0;
  background: var(--bg);
}

/* ───────────────── template selector pill ── */
.kw-tpl {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px 8px 12px;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.kw-tpl-label {
  font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--ink-2); flex-shrink: 0;
}
.kw-tpl-button {
  flex: 1; min-width: 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 6px 12px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-1); cursor: pointer;
  font-family: var(--sans);
  transition: border-color .12s;
}
.kw-tpl-button:hover { border-color: var(--ink-3); }
.kw-tpl-button:disabled { cursor: default; color: var(--ink-3); }
.kw-tpl-button.kw-empty { color: var(--accent); font-style: italic; }
.kw-tpl-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1; text-align: left;
}
.kw-tpl-caret { color: var(--ink-3); font-size: 9px; flex-shrink: 0; }
.kw-tpl-menu {
  position: absolute;
  top: calc(100% + 4px); left: 0; right: 0;
  z-index: 100;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  max-height: 280px; overflow-y: auto;
  animation: kaiFadeUp .18s cubic-bezier(.2, .7, .3, 1) both;
}
.kw-tpl-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px;
  background: #fff; border: none;
  border-bottom: 1px solid var(--line);
  text-align: left; cursor: pointer;
  font-family: var(--sans); font-size: 13px;
}
.kw-tpl-item:last-child { border-bottom: none; }
.kw-tpl-item:hover { background: var(--bg); }
.kw-tpl-item.kw-on { background: var(--accent-soft); color: var(--accent-ink); }
.kw-tpl-item-thumb {
  width: 32px; height: 32px; border-radius: 6px;
  background: var(--panel-2);
  flex-shrink: 0;
  object-fit: cover;
}
.kw-tpl-item-info { flex: 1; min-width: 0; }
.kw-tpl-item-name {
  font-size: 13px; font-weight: 500; color: var(--ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kw-tpl-item-meta {
  font-size: 10px; color: var(--ink-2); font-family: var(--mono); margin-top: 2px;
}

/* ───────────────────────────── chips ────── */
.kw-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.kw-chips-empty {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  border: 1px dashed var(--line);
  font-size: 12px; color: var(--ink-2);
  font-style: italic; font-family: var(--serif);
}
.kw-chips-empty-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ink-3);
}
.kw-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: #fff;
  border: 1px solid var(--line);
  font-family: var(--sans); font-size: 12px;
  color: var(--ink-1); cursor: pointer;
  transition: all .12s;
  max-width: 100%;
}
.kw-chip:hover { border-color: var(--ink-3); transform: translateY(-1px); }
.kw-chip-label { font-weight: 600; color: var(--ink-2); }
.kw-chip-divider { color: var(--ink-3); }
.kw-chip-value {
  color: var(--ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 120px;
}
.kw-chip-pencil { color: var(--ink-3); font-size: 10px; margin-left: 2px; }
.kw-chip-prev-logo {
  width: 16px; height: 16px; border-radius: 3px; flex-shrink: 0;
  background: var(--panel-2) center/contain no-repeat;
}
.kw-chip-prev-colors {
  display: inline-flex; border-radius: 3px; overflow: hidden;
  height: 14px; width: 28px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
}
.kw-chip-prev-colors > span { flex: 1; display: block; }
.kw-chip-prev-style {
  position: relative; width: 20px; height: 14px; border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  overflow: hidden; flex-shrink: 0;
  background: linear-gradient(135deg, #b8a190, #6e5e52);
}

/* ─────────────────────── active card ────── */
.kw-active-card {
  background: var(--panel);
  border-radius: 14px;
  padding: 16px 18px 14px;
  border: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
}
.kw-counter {
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.5px; color: var(--ink-2);
  text-transform: uppercase;
}
.kw-counter-text { font-weight: 600; color: var(--accent); }
.kw-ai-tag {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent); text-transform: none;
  font-size: 10px; font-family: var(--sans); font-style: italic;
}
.kw-ai-tag-dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(106, 77, 138, 0.18);
}
.kw-question {
  font-family: var(--serif); font-weight: 500;
  font-size: 22px; line-height: 1.2;
  margin: 8px 0 4px;
  color: var(--ink-1);
  text-wrap: pretty;
}
.kw-helper {
  font-family: var(--sans); font-size: 12.5px;
  color: var(--ink-2); line-height: 1.45;
}
.kw-input-area { margin-top: 16px; }

/* text / textarea */
.kw-text, .kw-textarea {
  width: 100%;
  padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--line);
  background: #fff;
  font-family: var(--sans); font-size: 15px;
  color: var(--ink-1); outline: none;
  resize: none; line-height: 1.5;
  transition: border-color .15s, box-shadow .15s;
}
.kw-text::placeholder, .kw-textarea::placeholder { color: var(--ink-3); }
.kw-text:focus, .kw-textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(106, 77, 138, 0.12);
}
.kw-input-actions {
  margin-top: 16px;
  display: flex; justify-content: flex-end; gap: 8px;
}

/* logo checkbox + dropzone */
.kw-logo-check {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer;
  padding: 14px 16px; border-radius: 12px;
  background: #fff; border: 1px solid var(--line);
  transition: border-color .15s;
}
.kw-logo-check:hover { border-color: var(--ink-3); }
.kw-logo-check input { display: none; }
.kw-logo-check-box {
  position: relative; width: 22px; height: 22px;
  border-radius: 6px;
  border: 1.5px solid var(--ink-3);
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: all .15s;
  flex-shrink: 0;
}
.kw-logo-check.kw-on .kw-logo-check-box {
  border-color: var(--accent); background: var(--accent);
}
.kw-logo-check-tick { color: #fff; font-size: 14px; line-height: 1; display: none; }
.kw-logo-check.kw-on .kw-logo-check-tick { display: inline; }
.kw-logo-check-label { font-size: 15px; color: var(--ink-1); }

.kw-logo-drop-wrap {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .35s cubic-bezier(.2, .7, .3, 1),
              opacity .25s,
              margin-top .25s;
}
.kw-logo-drop-wrap.kw-open {
  max-height: 280px; opacity: 1; margin-top: 12px;
}
.kw-logo-drop {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 20px 16px; border-radius: 12px;
  border: 1.5px dashed var(--ink-3);
  background: rgba(255, 255, 255, 0.6);
  cursor: pointer; transition: all .15s;
  text-align: center; gap: 6px;
}
.kw-logo-drop.kw-drag {
  border-color: var(--accent);
  background: rgba(106, 77, 138, 0.04);
}
.kw-logo-drop-icon {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--panel-2);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-2); font-size: 18px;
}
.kw-logo-drop-text { font-size: 13px; color: var(--ink-1); font-weight: 500; }
.kw-logo-drop-text a { color: var(--accent); text-decoration: underline; cursor: pointer; }
.kw-logo-drop-fine { font-size: 11px; color: var(--ink-3); font-family: var(--mono); }
.kw-logo-preview {
  display: flex; align-items: center; gap: 12px;
  padding: 12px; border-radius: 12px;
  background: #fff; border: 1px solid var(--line);
}
.kw-logo-preview-thumb {
  width: 56px; height: 56px; border-radius: 8px;
  background: var(--bg) center/contain no-repeat;
  border: 1px solid var(--line);
  flex-shrink: 0;
}
.kw-logo-preview-info { flex: 1; min-width: 0; }
.kw-logo-preview-name {
  font-size: 13px; font-weight: 600; color: var(--ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kw-logo-preview-meta {
  font-size: 11px; color: var(--ink-2);
  font-family: var(--mono); margin-top: 2px;
}
.kw-link-btn {
  background: transparent; border: none; cursor: pointer;
  font-size: 13px; color: var(--ink-2);
  font-family: var(--sans); text-decoration: underline; padding: 4px;
}
.kw-link-btn-sm { font-size: 12px; }
.kw-logo-actions {
  margin-top: 16px;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}

/* palette / graphic-style tile grids */
.kw-tile-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 6px;
}
.kw-palette-tile, .kw-style-tile {
  position: relative;
  display: flex; flex-direction: column;
  background: #fff;
  border: none; border-radius: 8px;
  overflow: hidden;
  padding: 0; cursor: pointer; text-align: left;
  transition: all .12s;
  box-shadow: 0 0 0 1px var(--line), 0 1px 2px rgba(0, 0, 0, 0.04);
}
.kw-palette-tile.kw-on {
  box-shadow: 0 0 0 2.5px var(--accent), 0 4px 12px rgba(0, 0, 0, 0.10);
  transform: translateY(-1px);
}
.kw-style-tile.kw-on {
  box-shadow: 0 0 0 2.5px var(--accent), 0 6px 16px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}
.kw-palette-swatch-row { display: flex; height: 36px; }
.kw-palette-swatch-row > span { flex: 1; display: block; }
.kw-style-art {
  position: relative;
  aspect-ratio: 5 / 4;
  overflow: hidden;
  /* container-type lets nested type scale to tile width via cqi units, so
     "Roam", "Travel", and the eyebrow lines all stay proportional whether
     the form column is 380px wide or 480px wide. */
  container-type: inline-size;
  /* Fallback for unknown style names (shouldn't trigger in practice — the
     four .kw-style-art--Name rules below cover all curated styles). */
  background: linear-gradient(135deg, #ebe2da 0%, #d9cfc4 100%);
}
.kw-tile-foot { padding: 7px 10px 9px; }
.kw-tile-name {
  font-family: var(--serif); font-size: 14px;
  font-weight: 600; color: var(--ink-1); line-height: 1.1;
}
.kw-tile-note {
  font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.5px; color: var(--ink-2); margin-top: 3px;
}
.kw-tile-check {
  position: absolute;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700;
}
.kw-palette-tile .kw-tile-check { top: 6px; right: 6px; }
.kw-style-tile .kw-tile-check { top: 8px; right: 8px; width: 22px; height: 22px; font-size: 12px; }

/* "Or describe your own" custom row */
.kw-custom-row {
  margin-top: 8px;
  display: flex; align-items: center;
  background: rgba(255, 255, 255, 0.5);
  border: 1.5px dashed var(--ink-3);
  border-radius: 8px;
  padding: 0 10px;
  height: 40px;
}
.kw-custom-star {
  font-family: var(--mono); font-size: 13px;
  color: var(--accent);
  flex-shrink: 0; margin-right: 8px;
}
.kw-custom-input {
  flex: 1; border: none; background: transparent; outline: none;
  font-family: var(--sans); font-size: 12.5px;
  color: var(--ink-1); min-width: 0;
}
.kw-custom-input::placeholder { color: var(--ink-3); }

/* ───────────────────────── buttons ──────── */
.kw-btn {
  font-family: var(--sans);
  font-size: 14px; font-weight: 600;
  padding: 12px 22px; border-radius: 999px;
  cursor: pointer; border: none;
  transition: transform .12s, box-shadow .15s, background .12s;
  letter-spacing: 0.1px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.kw-btn-primary {
  background: var(--accent); color: #fff;
  box-shadow: 0 6px 14px rgba(106, 77, 138, 0.25);
}
.kw-btn-primary:hover { transform: translateY(-1px); }
.kw-btn-primary:disabled {
  background: #cbbfb4; box-shadow: none;
  cursor: not-allowed; transform: none;
}
.kw-btn-ghost {
  background: transparent; color: var(--ink-1);
  border: 1px solid var(--line);
}
.kw-btn-ghost:hover { transform: translateY(-1px); background: rgba(255, 255, 255, 0.6); }

/* ──────────────────────── card footer ─── */
.kw-card-footer {
  margin-top: 14px; padding-top: 10px;
  border-top: 1px dashed var(--line);
  display: flex; justify-content: space-between; align-items: center;
}
.kw-back-btn {
  background: transparent; border: none;
  color: var(--ink-2); font-size: 12px;
  font-family: var(--sans); font-weight: 500;
  cursor: pointer; padding: 4px 8px;
}
.kw-back-btn:disabled { color: var(--ink-3); cursor: default; }
.kw-enter-hint { font-size: 11px; color: var(--ink-3); font-family: var(--mono); }
.kw-kbd {
  font-family: var(--mono); font-size: 9px;
  padding: 1px 5px; border-radius: 3px;
  border: 1px solid var(--line); background: #fff;
  color: var(--ink-2);
}
.kw-escape {
  margin-top: 10px; text-align: center;
  font-size: 11px; color: var(--ink-2);
  font-style: italic; font-family: var(--serif);
}
.kw-escape a {
  color: var(--accent-ink); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}

/* ───────────────────────── Kai thinking ─── */
.kw-thinking {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-radius: 12px;
  background: var(--accent-soft); color: var(--accent-ink);
  font-family: var(--serif); font-size: 14px; font-style: italic;
  animation: kaiFadeIn .35s ease-out both;
}
.kw-thinking-spinner {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: kaiSpin .9s linear infinite;
}

/* ─────────────────────── celebrate ─────── */
.kw-celebrate {
  background: var(--panel);
  border-radius: 14px;
  padding: 18px 18px 16px;
  border: 1px solid var(--line);
  background-image: radial-gradient(circle at 90% -10%, rgba(106, 77, 138, 0.06), transparent 50%);
}
.kw-celebrate-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-ink);
  font-size: 10px; font-weight: 600;
  font-family: var(--sans);
  letter-spacing: 0.4px; text-transform: uppercase;
}
.kw-celebrate-badge-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}
.kw-celebrate-title {
  font-family: var(--serif); font-weight: 500;
  font-size: 24px; line-height: 1.15;
  margin: 8px 0 4px;
  color: var(--ink-1);
}
.kw-celebrate-title em { font-style: italic; color: var(--accent-ink); }
.kw-celebrate-sub { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }

.kw-review {
  margin-top: 12px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.kw-review-row {
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
}
.kw-review-row:last-child { border-bottom: none; }
.kw-review-label {
  font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--ink-2);
}
.kw-review-value {
  font-size: 12.5px; color: var(--ink-1);
  min-width: 0; overflow: hidden;
}
.kw-review-edit {
  background: transparent; border: none; cursor: pointer;
  color: var(--accent); font-size: 11px;
  font-family: var(--sans); font-weight: 600;
}
.kw-celebrate-meta {
  margin-top: 10px; text-align: center;
  font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.3px; color: var(--ink-3);
}

.kw-sticky-generate {
  position: sticky; bottom: -18px;
  margin: 12px -18px -18px;
  padding: 14px 18px 18px;
  background: var(--bg);
  box-shadow: 0 -8px 14px -6px rgba(0, 0, 0, 0.08);
  z-index: 5;
}

/* Progress bar shown while /generate-from-brief is in flight. GPT Image 2
 * doesn't stream progress, so we run a fake-progress animation: fills
 * smoothly from 0 -> 90% over ~18s (the typical generation duration),
 * then snaps to 100% on real completion. A continuous shimmer slides
 * across the filled portion so the bar feels alive even between width
 * updates. */
.kw-progress {
  position: relative;
  margin-top: 12px;
  height: 6px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.kw-progress-bar {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0;
  border-radius: 999px;
  background:
    linear-gradient(90deg,
      rgba(255,255,255,0) 0%,
      rgba(255,255,255,0.45) 50%,
      rgba(255,255,255,0) 100%) 0 0 / 35% 100% no-repeat,
    linear-gradient(90deg, var(--accent), #8c6db0, var(--accent));
  animation: kaiProgressShimmer 1.6s linear infinite;
  box-shadow: 0 0 8px rgba(106, 77, 138, 0.35);
}
.kw-progress.kw-active .kw-progress-bar {
  width: 90%;
  transition: width 18s cubic-bezier(.2, .7, .3, 1);
}
.kw-progress.kw-complete .kw-progress-bar {
  width: 100%;
  transition: width .25s ease-out;
}
@keyframes kaiProgressShimmer {
  from { background-position: -35% 0, 0 0; }
  to   { background-position: 135% 0, 0 0; }
}

/* Inline error banner used by the celebrate / post-gen cards when
 * generate / regenerate / approve fails. Replaces the old alert() popups
 * — gentler, dismissable, doesn't block the page. */
.kw-error {
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(180, 60, 60, 0.07);
  border: 1px solid rgba(180, 60, 60, 0.25);
  border-radius: 10px;
  color: #7c2424;
  font-size: 12.5px;
  line-height: 1.4;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}
.kw-error-text { flex: 1; min-width: 0; }
.kw-error-dismiss {
  background: transparent;
  border: none;
  cursor: pointer;
  color: #7c2424;
  font-size: 11px;
  font-family: var(--sans);
  text-decoration: underline;
  padding: 2px 4px;
  flex-shrink: 0;
}

/* ─────────────────────────── animations ─── */
@keyframes kaiBannerSway {
  0%, 100% { transform: translateX(-50%) rotate(-0.5deg); }
  50%      { transform: translateX(-50%) rotate(0.5deg); }
}
@keyframes kaiFadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes kaiFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes kaiSpin {
  to { transform: rotate(360deg); }
}
@keyframes kaiPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(1.05); }
}
.kw-fade-up { animation: kaiFadeUp .4s cubic-bezier(.2, .7, .3, 1) both; }
.kw-fade-in { animation: kaiFadeIn .35s ease-out both; }

/* ──────────────────────── misc atoms ────── */
.kw-spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%;
  animation: kaiSpin 0.8s linear infinite;
  display: inline-block;
}

/* ────────────────── graphic-style mini-banner art ─── */
/* Each curated style has hand-rendered art that mirrors
 * kai-hybrid-palettes.jsx's GRAPHIC_STYLES from the bundle. Used in two
 * places: full-size inside Q4's tile picker (.kw-style-art--Name) and
 * shrunken into the style chip preview (.kw-chip-prev-style--Name).
 * Inner element positioning uses % of the .kw-style-art bounds; font
 * sizes use cqi units (% of container width) so type stays proportional
 * to the tile size on any viewport. */

/* — Photographic: sunset gradient, soft sun, diamond palms, "Travel" — */
.kw-style-art--Photographic {
  background: linear-gradient(180deg, #f7c594 0%, #e89679 50%, #3d6f8c 100%);
}
.kw-style-art--Photographic .kw-art-sun {
  position: absolute;
  top: 14%; left: 50%; transform: translateX(-50%);
  width: 46%; aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle, #ffd9a8 0%, transparent 70%);
}
.kw-style-art--Photographic .kw-art-dot {
  position: absolute;
  bottom: 22%;
  width: 3cqi; height: 3cqi;
  min-width: 2px; min-height: 2px;
  background: #2a4a5a; opacity: 0.6;
  transform: rotate(45deg);
}
.kw-style-art--Photographic .kw-art-label {
  position: absolute;
  bottom: 6%; left: 0; right: 0;
  text-align: center;
  font-family: var(--serif);
  font-size: 13cqi;
  color: #fef9f1; font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  line-height: 1;
}

/* — Illustrated: diagonal stripes + cream card + italic Roam + waves — */
.kw-style-art--Illustrated {
  background: repeating-linear-gradient(45deg, #f4d0a4 0 6px, #e8b585 6px 12px);
}
.kw-style-art--Illustrated .kw-art-card {
  position: absolute;
  inset: 12% 14% 14%;
  background: #fef9f1;
  border-radius: 3px;
  border: 2px solid #c8744a;
}
.kw-style-art--Illustrated .kw-art-roam {
  position: absolute;
  top: 34%; left: 0; right: 0;
  text-align: center;
  font-family: var(--serif);
  font-size: 18cqi;
  font-weight: 700; font-style: italic;
  color: #3d6f8c;
  line-height: 1;
}
.kw-style-art--Illustrated .kw-art-wave {
  position: absolute;
  height: 2px;
  background: #3d6f8c;
  border-radius: 99px;
}
.kw-style-art--Illustrated .kw-art-wave-1 { top: 62%; left: 22%; right: 22%; opacity: 0.7; }
.kw-style-art--Illustrated .kw-art-wave-2 { top: 70%; left: 28%; right: 28%; opacity: 0.5; }

/* — Minimal: paper-white background, thin rules, serif type stack — */
.kw-style-art--Minimal { background: #fef9f1; }
.kw-style-art--Minimal .kw-art-rule-top {
  position: absolute;
  top: 12%; left: 14%;
  width: 3px; height: 10%;
  background: #2a2520;
}
.kw-style-art--Minimal .kw-art-stack {
  position: absolute;
  top: 36%; left: 14%; right: 14%;
  text-align: left;
  font-family: var(--serif);
  color: #2a2520;
}
.kw-style-art--Minimal .kw-art-stack > div {
  font-size: 15cqi;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.5px;
}
.kw-style-art--Minimal .kw-art-stack > div + div {
  margin-top: 8%;
  font-style: italic;
}
.kw-style-art--Minimal .kw-art-rule-bottom {
  position: absolute;
  bottom: 12%; left: 14%; right: 14%;
  height: 1px;
  background: #2a2520;
}

/* — Vintage: aged gradient, scanline grain, letterpress type — */
.kw-style-art--Vintage {
  background: linear-gradient(135deg, #d4a373 0%, #8b6b4a 50%, #5a3f2a 100%);
}
.kw-style-art--Vintage .kw-art-grain {
  position: absolute;
  inset: 0;
  opacity: 0.4;
  mix-blend-mode: multiply;
  background: repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.08) 2px 3px);
}
.kw-style-art--Vintage .kw-art-top-label {
  position: absolute;
  top: 15%; left: 0; right: 0;
  text-align: center;
  font-family: var(--serif);
  font-size: 8cqi;
  letter-spacing: 4px;
  font-weight: 500;
  color: #f4d0a4;
}
.kw-style-art--Vintage .kw-art-roam {
  position: absolute;
  top: 36%; left: 0; right: 0;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  color: #fef9f1;
  font-size: 22cqi;
  font-weight: 700;
  line-height: 0.95;
}
.kw-style-art--Vintage .kw-art-bottom-label {
  position: absolute;
  bottom: 14%; left: 0; right: 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 7cqi;
  letter-spacing: 2px;
  color: #fef9f1;
}

/* — Chip-strip style preview (20×14px). Reuses just the style backgrounds
     for visual identity — the inner content gets dropped because no detail
     would be legible at this size anyway. — */
.kw-chip-prev-style {
  background: linear-gradient(135deg, #b8a190, #6e5e52);  /* fallback */
}
.kw-chip-prev-style.kw-chip-prev-style--Photographic {
  background: linear-gradient(180deg, #f7c594 0%, #e89679 55%, #3d6f8c 100%);
}
.kw-chip-prev-style.kw-chip-prev-style--Illustrated {
  background: repeating-linear-gradient(45deg, #f4d0a4 0 3px, #e8b585 3px 6px);
}
.kw-chip-prev-style.kw-chip-prev-style--Minimal {
  background: #fef9f1;
  border-color: rgba(42, 37, 32, 0.3);
}
.kw-chip-prev-style.kw-chip-prev-style--Vintage {
  background: linear-gradient(135deg, #d4a373 0%, #8b6b4a 50%, #5a3f2a 100%);
}

/* ────────────────── post-gen variant strip ─────── */
/* 3-up grid of mini banner thumbnails. Clicking a thumb selects that
 * variant: outlines it in accent, swaps the 3D viewer's texture to that
 * design, and updates the action bar's "Use Draft 0X" label. Mirrors
 * kai-postgen.jsx's K2 thumb strip from the design bundle. */
.kw-variant-strip {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}
.kw-variant-thumb {
  position: relative;
  aspect-ratio: 3 / 4;
  background: #fff;
  border: none;
  border-radius: 8px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: transform .12s, box-shadow .15s;
  outline: 1px solid var(--line);
  outline-offset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-color: var(--panel-2);
}
.kw-variant-thumb:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
}
.kw-variant-thumb.kw-on {
  outline: 2.5px solid var(--accent);
  outline-offset: 1px;
  box-shadow: 0 6px 16px rgba(106, 77, 138, 0.18);
}
.kw-variant-label {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 3px 6px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--ink-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.kw-variant-live {
  color: var(--accent);
  font-weight: 600;
}

/* ────────────────── draft preview + lightbox ─────── */
/* In post-gen, fill the form column with a flat thumbnail of the
 * generated design beneath the Draft 01 card. The 3D viewer renders
 * the banner at small scale + tall aspect, which hides typography.
 * This flat view lets the shopper actually read what's on the banner,
 * and clicking opens a full-screen lightbox. */
.kw-draft-preview {
  margin-top: 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  cursor: zoom-in;
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  transition: transform .15s, box-shadow .2s;
}
.kw-draft-preview:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.10);
}
.kw-draft-preview img {
  display: block;
  width: 100%;
  height: auto;
  background: var(--panel-2);
}
.kw-draft-preview-hint {
  position: absolute;
  top: 8px; right: 8px;
  padding: 4px 10px;
  background: rgba(20, 16, 14, 0.55);
  color: #fff;
  font-size: 9px; font-family: var(--mono);
  letter-spacing: 0.6px; text-transform: uppercase;
  font-weight: 500;
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.kw-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(20, 16, 14, 0.88);
  z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
  cursor: zoom-out;
  animation: kaiFadeIn .15s ease-out;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.kw-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
  animation: kaiLightboxIn .25s cubic-bezier(.2, .7, .3, 1) both;
}
@keyframes kaiLightboxIn {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}
.kw-lightbox-close {
  position: absolute;
  top: 18px; right: 18px;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  font-size: 18px; line-height: 1;
  font-family: var(--sans);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, transform .12s;
}
.kw-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.28);
  transform: scale(1.05);
}

/* ────────────────── chat-as-escape modal ─────── */
/* Floating modal that exposes the conversational /chat endpoint for
 * shoppers who prefer back-and-forth dialogue over the question form.
 * Opens from the 'Prefer free-form? Talk to Kai instead →' link below
 * the active question card. Form state persists in the background —
 * closing the modal returns to whatever question or post-gen state
 * was active before. */
.kw-chat-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 16, 14, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: kaiFadeIn .2s ease-out;
}
.kw-chat-modal {
  width: 100%;
  max-width: 480px;
  max-height: 80vh;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: kaiChatSlideIn .25s cubic-bezier(.2, .7, .3, 1) both;
}
@keyframes kaiChatSlideIn {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.kw-chat-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.kw-chat-title {
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 500;
  color: var(--ink-1);
  display: flex; align-items: center; gap: 8px;
}
.kw-chat-title em { font-style: italic; color: var(--accent); }
.kw-chat-title-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  animation: kaiPulse 1.6s ease-in-out infinite;
}
.kw-chat-close {
  background: transparent; border: none;
  color: var(--ink-2);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  padding: 6px;
  border-radius: 999px;
  transition: background .12s, color .12s;
}
.kw-chat-close:hover {
  background: var(--panel-2);
  color: var(--ink-1);
}
.kw-chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 200px;
  background: var(--bg);
}
.kw-chat-msg {
  display: flex;
  animation: kaiFadeUp .3s cubic-bezier(.2, .7, .3, 1) both;
}
.kw-chat-msg.kw-kai { justify-content: flex-start; }
.kw-chat-msg.kw-user { justify-content: flex-end; }
.kw-chat-bubble {
  max-width: 80%;
  padding: 10px 14px;
  border-radius: 14px;
  font-size: 13.5px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.kw-chat-msg.kw-kai .kw-chat-bubble {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-family: var(--serif);
  font-style: italic;
  border-bottom-left-radius: 4px;
}
.kw-chat-msg.kw-user .kw-chat-bubble {
  background: var(--accent);
  color: #fff;
  font-family: var(--sans);
  border-bottom-right-radius: 4px;
}
.kw-chat-msg.kw-thinking .kw-chat-bubble {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-family: var(--serif);
  font-style: italic;
  border-bottom-left-radius: 4px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.kw-chat-typing {
  display: inline-flex;
  gap: 3px;
}
.kw-chat-typing span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.6;
  animation: kaiChatTyping 1.2s infinite ease-in-out;
}
.kw-chat-typing span:nth-child(2) { animation-delay: 0.15s; }
.kw-chat-typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes kaiChatTyping {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%           { transform: translateY(-4px); opacity: 1; }
}
.kw-chat-input-row {
  display: flex;
  gap: 8px;
  padding: 12px 18px 16px;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.kw-chat-input {
  flex: 1;
  min-width: 0;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13.5px;
  font-family: var(--sans);
  color: var(--ink-1);
  background: #fff;
  outline: none;
  resize: none;
  line-height: 1.4;
  max-height: 96px;
  transition: border-color .15s, box-shadow .15s;
}
.kw-chat-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(106, 77, 138, 0.12);
}
.kw-chat-send {
  flex-shrink: 0;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  border: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .12s, transform .12s;
}
.kw-chat-send:hover { transform: translateY(-1px); }
.kw-chat-send:disabled {
  background: #cbbfb4;
  cursor: not-allowed;
  transform: none;
}

/* ──────────────────────── responsive ────── */
@media (max-width: 768px) {
  .kw-body { grid-template-columns: 1fr; grid-template-rows: 280px 1fr; }
  .kw-viewer-col {
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
}
