/* Colours and shapes follow Mokkup's extension style guide (from mokkup.ai, 5 Nov 2026): one brand indigo
   for actions, links and focus; indigo tints for surfaces; green, red and amber only for what they mean
   (ready / reachable, errors, warnings); the violet gradient only on the AI actions (Send, Build). One light
   theme, as the guide's components are all set on white and Tableau's own panes are light. Its "medium" weight is
   600 here: Segoe UI, the Windows font of Tableau's stack, has no 500 and would show it as regular. */
:root {
  --ink: #212529;
  --ink-soft: #5e5e5e;
  --line: #e6e7e9;
  --line-strong: #cdd0d5;
  --surface: #f7f6fd;          /* brand at 4% on white */
  --bg: #ffffff;
  --brand: #342bc2;            /* text, links, borders, focus */
  --brand-fill: #342bc2;       /* filled buttons and bubbles, white text on it */
  --brand-hover: #2a22a3;
  --brand-tint: #f7f6fd;       /* brand 4% */
  --brand-line: #ebeaf9;       /* brand 10% */
  --brand-half: rgba(52, 43, 194, 0.5);
  --brand-ring: rgba(52, 43, 194, 0.12);
  --ai: linear-gradient(180deg, #744efd, #8872f3);
  --ok: #1b7a57;
  --ok-fill: #22946b;
  --ok-tint: #edf6f3;
  --ok-line: #cde7dc;
  --red: #dc2626;
  --red-tint: #fef0f0;
  --red-line: #f7c9c9;
  --amber: #b45309;
  --amber-tint: #fff7ee;
  --amber-line: #ffd9ab;
  --disabled: #9ca4b2;
  --disabled-fill: #e6e7e9;
  --shadow: rgba(0, 0, 0, 0.18);
  /* A drawn tick: the ✓ character renders as a square root (√) in Tableau's font */
  --tick-white: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --tick-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%231b7a57' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --tick-brand: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23342bc2' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --prompt-glow: 6px 6px 20px rgba(52, 43, 194, 0.06), -6px -6px 20px rgba(52, 43, 194, 0.06), 2px 7px 12.3px rgba(116, 78, 253, 0.06), -2px -4px 4px rgba(216, 224, 247, 0.5);
  color-scheme: light;
}
* { box-sizing: border-box; }
html, body { width: 100%; margin: 0; }
body {
  padding: clamp(8px, 5%, 16px);
  font-family: "Benton Sans", "BentonSans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;   /* Tableau UI font stack */
  font-size: clamp(11px, 3vw, 13px);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.4;
}
[hidden] { display: none !important; }
.muted { color: var(--ink-soft); margin: 0 0 8px; }
.small { font-size: 0.85em; }
.label { font-size: 0.92em; font-weight: 600; color: var(--ink); margin: 10px 0 4px; }   /* label: 12px, medium */
strong, b { font-weight: 600; }
button { font-family: inherit; }
a { color: var(--brand); }
/* Keyboard focus is always visible; mouse clicks don't draw it. */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }

/* Header */
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
/* The connection badge: checking (grey), connected (green), a problem (red); a click opens the check */
.net-badge { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; font: inherit; font-size: 0.85em; font-weight: 600; white-space: nowrap; cursor: pointer;
  color: var(--ink-soft); background: var(--bg); border: 1px solid var(--line); border-radius: 999px; transition: border-color 0.12s ease; }
.net-badge:hover { border-color: var(--line-strong); }
.net-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--disabled); }
.net-badge[data-state="ok"] { color: var(--ok); background: var(--ok-tint); border-color: var(--ok-line); }
.net-badge[data-state="ok"] .dot { background: var(--ok-fill); }
.net-badge[data-state="bad"] { color: var(--red); background: var(--red-tint); border-color: var(--red-line); }
.net-badge[data-state="bad"] .dot { background: var(--red); }
.net-badge[data-state="checking"] .dot { animation: blink 1.2s infinite ease-in-out; }
@media (prefers-reduced-motion: reduce) { .net-badge[data-state="checking"] .dot { animation: none; } }
.brand { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 1.15em; }
.brand-logo { display: block; width: auto; height: 20px; flex: none; }   /* the Mokkup.ai wordmark (mokkup-logo.png) */
.account { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 0.85em; color: var(--ink-soft); padding-bottom: 8px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
.account span { margin-right: auto; overflow-wrap: anywhere; }
.avatar { display: inline-grid; place-items: center; width: 20px; height: 20px; margin-right: 6px; vertical-align: middle; border-radius: 50%; background: var(--brand-fill); color: white; font-size: 0.85em; font-weight: 700; }
/* Coins: the balance under the account line; orange when low, and a box with where to get more when out */
.coin-bar { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0 0 8px; padding: 7px 10px; border-radius: 10px; background: var(--surface); border: 1px solid var(--brand-line); }
.coin-bar.low { border-color: var(--amber-line); background: var(--amber-tint); }
.coin-low { color: var(--amber); font-weight: 600; }
.coin-nudge { margin: 0 0 8px; padding: 9px 10px; border-radius: 10px; background: var(--amber-tint); border: 1px solid var(--amber-line); }
.coin-nudge p { margin: 3px 0 8px; color: var(--ink-soft); }
.coin-nudge-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.coin-nudge a.btn-primary { display: inline-block; width: auto; padding: 6px 14px; text-decoration: none; }
.link-btn { background: none; border: none; padding: 0; color: var(--brand); text-decoration: none; cursor: pointer; font: inherit; font-weight: 600; }
.link-btn:hover:not(:disabled) { text-decoration: underline; }
.link-btn:disabled { color: var(--disabled); text-decoration: none; cursor: not-allowed; }

/* Buttons */
.btn-primary {
  background: var(--brand-fill); color: white; border: none;
  font-size: 1.08em; font-weight: 400; border-radius: 2px; cursor: pointer;
  min-height: 32px; padding: 6px 14px; width: 100%;
  transition: background 0.15s ease, transform 0.05s ease;
}
.btn-primary:hover { background: var(--brand-hover); }
.btn-primary:active { transform: translateY(1px); }
.btn-primary:disabled { background: var(--disabled-fill); color: var(--disabled); cursor: not-allowed; }

.btn-secondary {
  background: var(--bg); color: var(--brand); border: 1px solid var(--brand);
  font-size: 1.08em; font-weight: 400; border-radius: 2px; cursor: pointer;
  min-height: 32px; padding: 5px 12px; width: 100%;
  transition: background 0.15s ease, border-color 0.15s ease;
}
a.btn-secondary { display: block; text-align: center; text-decoration: none; }
.btn-secondary:hover { background: var(--brand-tint); border-color: var(--brand-hover); }
.btn-secondary:disabled { opacity: 0.55; cursor: not-allowed; }
.chip-btn { font: inherit; font-size: 0.9em; border: 1px solid var(--line); background: var(--brand-tint); border-radius: 4px; padding: 3px 10px; cursor: pointer; color: var(--ink-soft); }
.chip-btn:hover { border-color: var(--brand-half); color: var(--brand); }
.chip-btn:disabled { opacity: 0.55; cursor: not-allowed; }

.card {
  background: var(--surface); border: 1px solid var(--brand-line); border-radius: 10px;
  padding: clamp(8px, 2vw, 12px); margin-bottom: 8px;
}

/* Status: hidden when empty; errors get a box so they read as errors, not as captions */
.status { margin: 0 0 8px; font-size: 0.9em; color: var(--ink-soft); }
.status:empty { display: none; }
.status.error { color: var(--red); background: var(--red-tint); border: 1px solid var(--red-line); border-radius: 10px; padding: 7px 10px; }
/* An error as a card (showError): calm amber, a plain title, what to do, one button, and the reference
   folded under "Details". The plain red line above stays for the few messages written directly. */
.status.error:has(.err-card) { color: var(--ink); background: var(--amber-tint); border-color: var(--amber-line); padding: 10px 12px; }
.err-card .err-title { display: block; font-weight: 600; color: var(--ink); }
.err-card .err-text { margin: 3px 0 0; color: var(--ink-soft); }
.err-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 8px; }
.err-actions .btn-primary, .err-actions .btn-secondary { width: auto; font-size: 0.95em; min-height: 28px; padding: 4px 12px; }
.err-details { margin-left: auto; font-size: 0.85em; color: var(--ink-soft); }
.err-details summary { cursor: pointer; color: var(--ink-soft); }
.err-details[open] { flex-basis: 100%; margin-left: 0; }
.err-details span { word-break: break-word; }

/* Login form */
label { display: block; font-size: 0.92em; font-weight: 600; margin: 8px 0 3px; }   /* field label: 12px, medium */
input[type=email], input[type=password], #verify_code {
  width: 100%; min-height: 32px; padding: 6px 10px; font: inherit; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 4px; margin-bottom: 4px;
}
input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); }
form .btn-primary { margin-top: 8px; }
#login_status { margin-top: 10px; }
/* Login steps: the email being used (with a way back), the sign-up/forgot links, the terms line */
.login-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0 0 4px; overflow-wrap: anywhere; }
.login-links { margin: 10px 0 0; }
.login-links .sep { margin: 0 4px; }
.login-links a { color: var(--brand); font-weight: 600; text-decoration: none; }   /* like the ghost buttons beside it */
.login-links a:hover { text-decoration: underline; }
.terms { margin: 8px 0 0; }
.or-line { display: flex; align-items: center; gap: 8px; margin: 12px 0 8px; }
.or-line::before, .or-line::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.google-wait { margin: 12px 0 0; }
/* The login page's look: a centred column (full width in a narrow panel), a title, roomier fields and buttons */
#panel_login { max-width: 400px; margin: clamp(4px, 4vh, 28px) auto 0; }
.login-title { font-size: 1.3em; font-weight: 600; margin: 0 0 4px; }
#panel_login input[type=email], #panel_login input[type=password], #panel_login #verify_code {
  padding: 6px 10px; border-radius: 4px; transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
#panel_login input:hover { border-color: var(--line-strong); }
#panel_login input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); }
#panel_login input::placeholder { color: var(--disabled); }
#panel_login .btn-primary, #panel_login .btn-secondary { border-radius: 2px; }
.google-btn { color: var(--ink); border-color: var(--line); display: flex; align-items: center; justify-content: center; gap: 10px; font-weight: 500; padding: 5px 12px; }
.google-g { width: 18px; height: 18px; flex: none; }
#panel_login .login-links, #panel_login .terms { text-align: center; }
/* The browser tab Google comes back to: one card, a spinner while signing in, then a tick or a "!" */
.done-card {
  max-width: 380px; margin: clamp(16px, 10vh, 90px) auto 0; padding: 28px 24px; text-align: center;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 0 35px rgba(0, 0, 0, 0.25);
}
.done-icon {
  width: 56px; height: 56px; margin: 0 auto 14px; border-radius: 50%; display: grid; place-items: center;
  font-size: 28px; font-weight: 700; line-height: 1;
}
.done-card[data-state="working"] .done-icon { border: 4px solid var(--brand-line); border-top-color: var(--brand); animation: done-spin 0.9s linear infinite; }
.done-card[data-state="ok"] .done-icon { background: var(--ok-tint) var(--tick-ok) center / 30px no-repeat; color: var(--ok); border: 1px solid var(--ok-line); }
.done-card[data-state="fail"] .done-icon { background: var(--red-tint); color: var(--red); border: 1px solid var(--red-line); }
@keyframes done-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .done-card[data-state="working"] .done-icon { animation: none; } }
.done-title { font-size: 1.3em; font-weight: 600; margin: 0 0 6px; }
.done-email { font-weight: 600; margin: 0 0 12px; overflow-wrap: anywhere; }
.done-text { color: var(--ink-soft); margin: 0 0 10px; }
.done-note { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); }
#panel_login #login_status:not(.error) { text-align: center; font-size: 0.82em; color: var(--ink-soft); margin-top: 16px; }
#verify_code { letter-spacing: 0.3em; font-size: 1.1em; }

/* Workbook data: folds to one line, opens to the controls */
.data-bar { border: 1px solid var(--brand-line); border-radius: 10px; padding: 6px 10px; margin: 8px 0 4px; }
.data-head { display: flex; align-items: center; gap: 8px; }
.data-chip { flex: 1; min-width: 0; font-weight: 600; font-size: 0.92em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.data-chip.sent::before { content: ""; display: inline-block; width: 1em; height: 1em; margin-right: 5px; vertical-align: -0.15em; background: var(--tick-ok) center / contain no-repeat; }
#data_body { margin-top: 6px; }
.data-bar .check { display: flex; align-items: center; gap: 6px; margin: 0; font-weight: 600; }
.data-bar .check.share { font-weight: 500; margin: 6px 0 2px; }
.data-bar select { width: 100%; min-height: 32px; margin: 6px 0 4px; padding: 5px 6px; font: inherit; color: var(--ink); border: 1px solid var(--line); border-radius: 4px; background: var(--bg); }
.data-bar select:disabled { color: var(--ink-soft); background: var(--surface); }
.data-bar p { margin: 0; }
.data-links { margin: 2px 0 6px; }
.data-links .label { font-size: 0.8em; font-weight: 600; color: var(--ink-soft); margin: 2px 0; }
/* The tables as a tree under the main one: Suppliers sits under Products, which sits under Orders. */
.data-links .link-root { font-weight: 600; margin: 2px 0; }
.data-links .link-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 2px 0; padding-left: calc(var(--depth, 1) * 14px); position: relative; }
.data-links .link-row::before { content: "└"; position: absolute; top: 2px; left: calc(var(--depth, 1) * 14px - 12px); color: var(--line-strong); }
.data-links .link-row .check { font-weight: 500; margin: 0; }
.data-links .link-on { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.data-links .link-manual { margin: 2px 0 8px 22px; padding: 6px 8px; border-left: 2px solid var(--line); }
.data-links .link-suggest, .data-links .link-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 2px 0 4px; }
.data-links .link-pick select { width: auto; max-width: 100%; margin: 0; padding: 2px 4px; }
.data-links .chip-btn { font-size: 0.95em; border-radius: 4px; padding: 1px 8px; }
.data-links .link-rate { color: var(--ink-soft); }
.data-links .link-rate.warn { color: var(--red); }
/* Where the links come from (the workbook file, or matched from the data), and why a file's link wasn't used. */
.data-links .link-source { color: var(--ink-soft); margin: 0 0 4px; }
.data-links .link-file { flex-basis: 100%; padding-left: 22px; }

/* Opening screen */
.welcome { margin: 8px 0 4px; }

/* Chat */
.chat { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 8px; }
.msg { padding: 8px 11px; border-radius: 12px; font-size: 0.95em; white-space: pre-wrap; overflow-wrap: anywhere; max-width: 92%; }
.msg.you { background: var(--brand-fill); color: #fff; align-self: flex-end; border-bottom-right-radius: 4px; }
.msg.you.edited { opacity: 0.55; text-decoration: line-through; }
.msg.note { align-self: center; color: var(--ink-soft); font-size: 0.82em; padding: 2px 8px; }
.msg.ai { background: var(--surface); border: 1px solid var(--brand-line); align-self: flex-start; border-bottom-left-radius: 4px; }
.msg-edit { align-self: flex-end; margin-top: -4px; }
.msg.working { display: flex; align-items: flex-start; gap: 9px; color: var(--ink-soft); white-space: normal; }
.msg.working strong { color: var(--ink); font-weight: 600; }
.quick { display: flex; flex-wrap: wrap; gap: 5px; margin: -2px 0 8px; }
.dots { display: inline-flex; gap: 4px; padding: 4px 2px; }
.dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-soft); animation: blink 1.2s infinite ease-in-out; }
.dots i:nth-child(2) { animation-delay: 0.15s; }
.dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes blink { 0%, 80%, 100% { opacity: 0.25; } 40% { opacity: 1; } }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .dots i { animation: none; } }

.examples { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.examples .label { margin-top: 0; }
.example {
  text-align: left; font: inherit; font-size: 0.92em; color: var(--ink); cursor: pointer;
  background: var(--bg); border: 1px dashed var(--line-strong); border-radius: 4px; padding: 7px 10px;
}
.example:hover { border-color: var(--brand); background: var(--brand-tint); }

/* Composer: stays at the bottom of the pane while the conversation scrolls */
.composer-wrap { position: sticky; bottom: 0; background: var(--bg); padding: 8px 0 2px; }
.composer {
  display: flex; align-items: flex-end; gap: 6px; padding: 6px;
  border: 1px solid var(--brand-half); border-radius: 12px; background: var(--bg); box-shadow: var(--prompt-glow);   /* Mokkup's prompt box */
}
.composer:focus-within { border-color: var(--brand); box-shadow: var(--prompt-glow), 0 0 0 3px var(--brand-ring); }
.composer textarea {
  flex: 1; min-width: 0; resize: none; border: none; outline: none; background: transparent;
  font: inherit; color: inherit; line-height: 1.4; padding: 5px 4px; max-height: 160px;
  min-height: calc(1.4em + 10px);   /* always one full line, so the placeholder is never clipped */
  overflow-y: hidden;               /* no scrollbar arrows until the text is taller than the box (see grow()) */
}
.composer textarea:disabled { color: var(--ink-soft); }
.btn-send {
  flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 32px; background: var(--ai); color: #fff; border: none; border-radius: 4px;
  font-weight: 600; font-size: 1.08em; padding: 0 14px; cursor: pointer;
}
.btn-send .sparkle { width: 14px; height: 14px; flex: none; }
.btn-send:hover { filter: brightness(1.06); }
.btn-send:disabled { background: var(--disabled-fill); color: var(--disabled); filter: none; cursor: not-allowed; }
.hint { font-size: 0.85em; color: var(--ink-soft); margin: 4px 2px 0; }   /* caption: 11px */
.build-bar { background: var(--brand-tint); border: 1px solid var(--brand-line); border-radius: 10px; padding: 10px; margin-bottom: 8px; }
.build-bar p { margin: 6px 0 0; }
.hint .link-btn { color: inherit; }
.build-confirm p { margin: 0 0 6px; }
.build-confirm .actions { margin: 0 0 6px; }

/* Result */
/* Mokkup dashboards are often taller than wide: fill the width so text stays readable, and
   scroll inside a fixed window rather than shrinking the whole page to fit. */
.result .preview-frame {
  margin-top: 8px; max-height: min(70vh, 640px); overflow-x: hidden; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 4px; background: #fff;
}
.preview-btn { display: block; width: 100%; padding: 0; border: none; background: none; cursor: zoom-in; }
.preview-frame img { width: 100%; height: auto; display: block; }
.preview-frame p { margin: 0; padding: 48px 12px; text-align: center; color: #5e5e5e; }
.preview-actions { display: flex; justify-content: space-between; gap: 8px; margin-top: 4px; }
.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip { font-size: 0.82em; color: var(--ink-soft); background: var(--brand-tint); border: 1px solid var(--line); border-radius: 4px; padding: 2px 9px; }
.chip[title] { cursor: help; border-style: dashed; }
.actions { display: flex; gap: 6px; margin: 12px 0 8px; }
.actions > * { flex: 1; }

/* Screens: a tab per screen (two or more), "Add another screen", the download's cost */
.screen-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.screen-tab { font: inherit; font-size: 0.85em; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-soft); background: var(--bg); border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px; cursor: pointer; }
.screen-tab:hover:not(:disabled) { border-color: var(--brand-half); }
.screen-tab.active { color: var(--brand); background: var(--brand-tint); border-color: var(--brand); font-weight: 600; }
.screen-tab.new { border-style: dashed; }
.screen-tab:disabled { cursor: not-allowed; opacity: 0.6; }
.screen-actions { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.screen-actions:empty, .screen-actions:not(:has(button:not([hidden]))) { display: none; }
.download-cost { margin: 0 0 6px; }

/* The download's file name, just above Download: a light brand card (as the chat's cards), a document icon,
   "FILE NAME" over the name in bold, and a soft "✎ Change" button. Changing it turns the name into a box with
   ".twbx" fixed after it. A long name ends in "…" (the full one is its tooltip). */
.save-name { display: flex; align-items: center; gap: 10px; margin: 14px 0 0; padding: 8px 10px 8px 12px;
  background: var(--bg); border: 1px solid var(--brand-line); border-radius: 10px; transition: border-color 0.15s ease; }
.save-name.editing { border-color: var(--brand-half); }
.save-name + .actions { margin-top: 8px; }
.save-name-icon { flex: none; width: 22px; height: 26px; border-radius: 3px 8px 3px 3px; background: var(--bg); border: 1.5px solid var(--brand);
  position: relative; box-shadow: inset 0 -7px 0 var(--brand-line); }
.save-name-icon::after { content: ""; position: absolute; top: -1.5px; right: -1.5px; width: 8px; height: 8px; border-left: 1.5px solid var(--brand);
  border-bottom: 1.5px solid var(--brand); border-radius: 0 7px 0 3px; background: var(--brand-tint); }
.save-name-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.save-name-label { font-size: 0.72em; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); }
.save-name-text { color: var(--ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.save-name-box { display: flex; align-items: center; gap: 3px; }
.save-name-box input { flex: 1; min-width: 0; font: inherit; font-weight: 600; color: var(--ink); padding: 3px 7px;
  border: 1px solid var(--line-strong); border-radius: 6px; background: var(--bg); }
.save-name-box input:focus { outline: 2px solid var(--brand-ring); border-color: var(--brand); }
.save-name-ext { flex: none; color: var(--ink-soft); font-weight: 600; }
.save-name-edit { flex: none; font: inherit; font-size: 0.9em; font-weight: 600; color: var(--brand); background: var(--brand-tint);
  border: 1px solid var(--brand-line); border-radius: 999px; padding: 4px 12px; cursor: pointer; white-space: nowrap;
  transition: border-color 0.12s ease, background 0.12s ease; }
.save-name-edit:hover { border-color: var(--brand-half); background: var(--brand-line); }
.save-name-edit:focus-visible { outline: 2px solid var(--brand-ring); outline-offset: 1px; }
.screen-note { margin: 4px 0 0; }

/* Mokkup said "built" but saved nothing: what it said, and two ways on */
.msg.unsaved { border-color: var(--amber-line); background: var(--amber-tint); }
.msg.unsaved p { margin: 6px 0 0; }
.unsaved-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.unsaved-actions button { width: auto; font-size: 0.95em; min-height: 28px; padding: 4px 12px; }
#redownload_btn { margin-bottom: 8px; }

/* My dashboards */
.history-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.history-list { display: flex; flex-direction: column; gap: 8px; }
.history-item { display: flex; gap: 10px; padding: 8px; border: 1px solid var(--brand-line); border-radius: 10px; background: var(--surface); }
.history-item img { flex: none; width: 96px; height: 64px; object-fit: cover; object-position: top; border-radius: 4px; border: 1px solid var(--line); background: #fff; }
.history-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.history-body strong { overflow-wrap: anywhere; }
.history-typed { font-style: italic; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }   /* what the user typed, under the name */
.history-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
/* "Open" (a button) and "Open in Mokkup" (a link) the same size, their words centred */
.history-actions .btn-secondary { display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: auto; height: 30px; padding: 0 12px; font-size: 0.9em; line-height: 1; text-decoration: none; }
/* "Remove": a quiet link at the row's far end, red on hover */
.history-actions .history-remove { margin-left: auto; font-weight: 400; color: var(--ink-soft); }
.history-actions .history-remove:hover { color: var(--red); }
/* Connection check: the verdict, then one row per address (✓ reachable / ✕ blocked) */
.net-state { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; margin: 8px 0; border: 1px solid var(--brand-line); border-radius: 10px; background: var(--surface); }
.net-state p { margin: 4px 0 0; }
.net-icon { flex: none; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; }
.net-state[data-state="checking"] .net-icon { border: 3px solid var(--brand-line); border-top-color: var(--brand); animation: done-spin 0.9s linear infinite; }
.net-state[data-state="ok"] { background: var(--ok-tint); border-color: var(--ok-line); }
.net-state[data-state="ok"] .net-icon { background: var(--tick-ok) center / 20px no-repeat; }
.net-state[data-state="bad"] { background: var(--red-tint); border-color: var(--red-line); }
.net-state[data-state="bad"] .net-icon::before { content: "!"; color: var(--red); }
@media (prefers-reduced-motion: reduce) { .net-state[data-state="checking"] .net-icon { animation: none; } }
.net-list { list-style: none; padding: 0; margin: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.net-list li { display: flex; gap: 8px; align-items: baseline; padding: 8px 12px; border-top: 1px solid var(--line); }
.net-list li:first-child { border-top: none; }
.net-list .mark { flex: none; width: 1.2em; font-weight: 700; }
.net-list .ok .mark { align-self: center; height: 1em; background: var(--tick-ok) left center / 1em no-repeat; }
.net-list .bad .mark { color: var(--red); }
.net-list .addr { font-weight: 600; overflow-wrap: anywhere; }
.net-list .what { flex: 1; color: var(--ink-soft); font-size: 0.85em; }
.net-list .bad .what { color: var(--red); }
.net-msg { width: 100%; box-sizing: border-box; margin: 0 0 8px; font-family: inherit; color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: 4px; padding: 8px; resize: vertical; }
/* Mokkup projects: limit meter, Made in Studio tag, inline delete confirmation */
.meter { position: relative; height: 22px; margin: 8px 0; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); overflow: hidden; }
.meter > span { display: block; height: 100%; width: 0; background: var(--brand-line); transition: width 0.4s ease; }
.meter.full > span { background: var(--red-line); }
.meter::after { content: attr(data-label); position: absolute; inset: 0; display: flex; align-items: center; padding: 0 8px; font-size: 0.85em; }
.tag { display: inline-block; padding: 1px 6px; border-radius: 999px; font-size: 0.75em; font-weight: 600; vertical-align: middle; color: var(--brand); background: var(--brand-tint); border: 1px solid var(--brand-line); }
.confirm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.btn-danger { width: auto; padding: 4px 10px; font-size: 0.9em; border-radius: 2px; cursor: pointer; color: #fff; background: var(--red); border: 1px solid var(--red); }
.btn-danger:disabled { opacity: 0.6; cursor: default; }
.project-item { transition: transform 0.25s ease; }
.project-item.gone { transform: translateX(110%); }
@media (prefers-reduced-motion: reduce) { .meter > span, .project-item { transition: none; } }

/* Full-size preview */
.lightbox { position: fixed; inset: 0; z-index: 10; display: flex; flex-direction: column; background: var(--bg); box-shadow: 0 0 0 100vmax var(--shadow); }
.lightbox-bar { display: flex; gap: 6px; padding: 8px; border-bottom: 1px solid var(--line); }
.lightbox-bar .btn-secondary { width: auto; padding: 5px 12px; }
.lightbox-bar #zoom_close { margin-left: auto; }
.lightbox-body { flex: 1; overflow: auto; padding: 8px; background: var(--surface); }
.lightbox-body img { display: block; height: auto; margin: 0 auto; background: #fff; }


/* Proposal card: what Mokkup will build, as chips you can drop */
/* Cards in the chat (proposal, questions, options) are white, so the guide's tinted chips stand out on them */
.msg.proposal { max-width: 100%; width: 100%; padding: 10px 12px; border-color: var(--brand-line); border-radius: 10px; background: var(--bg); white-space: normal; }
.proposal-head { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.proposal-mark { color: var(--brand); }
.proposal-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.proposal-chip {
  font: inherit; font-size: 0.86em; color: var(--ink-soft); background: var(--brand-tint); border: 1px solid var(--line); border-radius: 4px;
  padding: 3px 10px; cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease, opacity 0.12s ease;
}
.proposal-chip:hover:not(:disabled) { border-color: var(--brand-half); color: var(--brand); transform: translateY(-1px); }
.proposal-chip:disabled { cursor: default; }
.proposal-chip:not(:disabled):hover::after { content: " ✕"; color: var(--red); }
.proposal-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.proposal-actions .btn-primary, .proposal-actions .btn-secondary { width: auto; padding: 7px 14px; }
/* Question card (Mokkup's newer AI): each question, its options as chips, "Other…" opens a text field */
.questions .q-text { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin: 14px 0 6px; font-weight: 600; color: var(--ink); }
.questions .proposal-head + .q-text { margin-top: 4px; }
.questions .q-hint { flex: none; font-size: 0.85em; font-weight: 400; color: var(--ink-soft); }
.choices .proposal-head .q-hint { flex: none; margin-left: auto; padding-left: 8px; font-size: 0.85em; font-weight: 400; color: var(--ink-soft); }   /* the option card's "Pick one", as on the question card */
.choices .proposal-head { align-items: baseline; }   /* a title over several lines: the mark and "Pick one" stay level with its first line */
.choices .choices-own { margin: 10px 0 0; }   /* the line under the options ("Or pick Create Custom…"), clear of them */
.questions .q-chip[aria-pressed="true"] { background: var(--brand-line); border-color: var(--brand); color: var(--brand); font-weight: 600; }
.questions .q-chip:hover:not(:disabled) { border-color: var(--brand-half); }
.questions .q-chip:disabled { cursor: default; }   /* an answered card keeps the guide's chip colours */
.questions .q-chip::after { content: none !important; }   /* not the proposal card's "drop it" mark */
.questions .q-chip[aria-pressed="true"]:disabled { opacity: 1; }
.q-other { width: 100%; margin: 6px 0 0; padding: 6px 10px; font: inherit; color: var(--ink); background: var(--bg); border: 1px solid var(--line); border-radius: 4px; }
.q-other:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); }
/* Option card: colour palettes as swatch cards (like Mokkup's theme picker), other lists as chips */
.palette-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; margin-top: 6px; padding: 3px; }
.choices .show-all { display: block; margin-top: 8px; }
/* Each option reads as a button: a clear border, a lift and an indigo ring on hover; the one picked has a
   2px indigo border (an inset ring, so nothing moves), a tint, an indigo name and a ✓ badge in its corner. */
.palette-card { position: relative; display: block; padding: 8px; font: inherit; text-align: left; color: var(--ink); cursor: pointer;
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: 6px; transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease; }
.palette-card:hover:not(:disabled) { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); transform: translateY(-1px); }
.palette-card[aria-pressed="true"] { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); background: var(--brand-tint); }
.palette-card[aria-pressed="true"] .palette-name { color: var(--brand); font-weight: 600; }
.palette-card[aria-pressed="true"]::after { content: ""; position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--brand-fill) var(--tick-white) center / 11px no-repeat; box-shadow: 0 0 0 2px var(--bg); }
.palette-card:disabled { cursor: default; }
.palette-card[aria-pressed="true"]:disabled { opacity: 1; }
.palette-card .swatches { display: block; height: 20px; border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08); }
@media (prefers-reduced-motion: reduce) { .palette-card { transition: none; } .palette-card:hover:not(:disabled) { transform: none; } }
.palette-card .swatches.none { border: 1px dashed var(--line-strong); }
/* Element styles (KPI, header, filter, chart): Mokkup's picture of each, on white like its own picker */
.palette-card .widget-img { display: block; width: 100%; height: 64px; object-fit: contain; background: #fff; border: 1px solid var(--line); border-radius: 2px; }
.palette-card .widget-img.none { background: var(--surface); border-style: dashed; }
.palette-card .palette-name { display: block; margin-top: 6px; font-size: 0.92em; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.choices .q-chip::after { content: none !important; }
.choices .q-chip[aria-pressed="true"] { background: var(--brand-line); border-color: var(--brand); color: var(--brand); font-weight: 600; }

/* Motion: messages slide in, the result card pops in with its check, Build pulses once it's ready */
/* Movement only, never transparency: a panel Tableau keeps off screen may not run animations, and
   content must be readable even if one never plays. */
.msg { animation: msg-in 0.22s ease-out; }
@keyframes msg-in { from { transform: translateY(6px); } to { transform: none; } }
.result-head { display: flex; align-items: center; gap: 8px; }
.result-head .check { display: block; flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--ok-fill) var(--tick-white) center / 14px no-repeat; }
.result.reveal { animation: reveal 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2); }
.result.reveal .check { animation: pop 0.5s 0.15s cubic-bezier(0.2, 0.9, 0.3, 1.4); }
@keyframes reveal { from { transform: translateY(10px) scale(0.98); } to { transform: none; } }
@keyframes pop { 0% { transform: scale(0.4); } 100% { transform: scale(1); } }
#build_btn.ready { animation: pulse 2s ease-in-out 3; }
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(52, 43, 194, 0.35); } 50% { box-shadow: 0 0 0 6px rgba(52, 43, 194, 0); } }
.example { transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease; }
.example:hover { transform: translateY(-1px); }
.chip-btn { transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease; }
.chip-btn:hover { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) {
  .msg, .result.reveal, .result.reveal .check, #build_btn.ready { animation: none !important; }
  .example:hover, .chip-btn:hover, .proposal-chip:hover { transform: none; }
}

/* Narrow dashboard zones: stack side-by-side controls so nothing is squeezed */
@media (max-width: 360px) {
  body { padding: 8px; }
  .actions { flex-direction: column; }
  .account { gap: 4px 10px; }
  .data-links .link-row { padding-left: calc(var(--depth, 1) * 10px); }
  .data-links .link-row::before { left: calc(var(--depth, 1) * 10px - 10px); }
  .data-links .link-manual { margin-left: 10px; }
  .history-item { flex-direction: column; }
  .history-item img { width: 100%; height: 90px; }
  .msg { max-width: 100%; }
}

/* Live progress of a chat turn */
.working .live { margin-top: 6px; }
.working .live-text { margin-top: 4px; white-space: pre-wrap; }
/* Redesign this dashboard */
/* Opening screen: three ready-made designs as compact rows, then a quiet redesign link */
.more-ways { margin: 10px 0 4px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.more-ways .link-btn { padding: 0; margin: 0; vertical-align: baseline; }
.design-list { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.design-row { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); transition: border-color 0.12s ease; }
.design-row:hover, .design-row:focus-visible { border-color: var(--brand); }
.design-row strong { font-size: 0.92em; }
.design-sum { font-size: 0.82em; color: var(--ink-soft); }
.warn-line { margin: 6px 0 0; padding: 6px 10px; border-radius: 10px; color: var(--red); background: var(--red-tint); border: 1px solid var(--red-line); }
.download-report { margin-top: 8px; }
.download-report .ok-line { margin: 0; color: var(--ok); }
.download-report .ok-line::before { content: ""; display: inline-block; width: 1em; height: 1em; margin-right: 5px; vertical-align: -0.15em; background: var(--tick-ok) center / contain no-repeat; }
/* "Updated: the preview shows the change", after the newer AI edits the dashboard */
.msg.updated::before { content: ""; display: inline-block; width: 16px; height: 16px; margin-right: 7px; vertical-align: -3px; border-radius: 50%; background: var(--ok-fill) var(--tick-white) center / 10px no-repeat; }
.download-report details { margin-top: 4px; }
.download-report summary { cursor: pointer; color: var(--brand); }
.download-report ul { margin: 4px 0 0; padding-left: 18px; }
.download-report li { margin: 2px 0; overflow-wrap: anywhere; }
.download-report .warn-line p { margin: 0; font-weight: 600; }
/* What the download's check couldn't handle by itself: a calm amber note, not an alarm (red is for failures) */
.notice-line { margin: 6px 0 0; padding: 6px 10px; border-radius: 10px; color: var(--amber); background: var(--amber-tint); border: 1px solid var(--amber-line); }
.download-report .notice-line p { margin: 0; font-weight: 600; }
/* The main-table question, only on a close call */
.main-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.main-ask .chip-btn { border-style: solid; }
.main-ask .chip-btn.chosen { border-color: var(--brand); background: var(--brand-tint); }
#pick_table { display: block; margin: 4px 0; }
