/* ==========================================================================
   Instagram Bot — "Signal Panel" design system
   Dark control-room surface. Every state (connected / pending / error) reads
   as a literal signal light. Money and identifiers are set in monospace to
   read as data, not prose.
   ========================================================================== */

/* Self-hosted (wwwroot/fonts/) rather than loaded from Google's CDN: this
   app's own infra (Ollama, Postgres, Redis) is fully self-hosted per
   docker-compose.yml, so an outbound font dependency would be the only
   external network call the admin UI makes, and would hard-fail rendering
   in an offline/air-gapped deployment. Latin + Cyrillic subsets only (the
   UI's only scripts); Greek/Vietnamese subsets from the source webfont are
   dropped. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-400-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-400-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/inter-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/inter-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/inter-500-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/inter-500-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/inter-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/inter-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/inter-600-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/inter-600-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jbmono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jbmono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jbmono-400-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jbmono-400-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jbmono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jbmono-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jbmono-500-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jbmono-500-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/jbmono-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/jbmono-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/jbmono-600-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/jbmono-600-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Space Grotesk ships no dedicated Cyrillic subset upstream — Ukrainian
   headings fall back to Inter (below) via the --font-display stack, which
   is why --font-display lists both. Latin-script headings use Space
   Grotesk; Cyrillic ones render in Inter at the same weight. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/spacegrotesk-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/spacegrotesk-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/spacegrotesk-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/spacegrotesk-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/spacegrotesk-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/spacegrotesk-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --ink: #16151a;
  --ink-raised: #1c1b21;
  --ink-line: #2a2933;
  --paper: #f5f3ee;
  --paper-dim: #a9a6b3;
  --paper-faint: #6f6c7a;
  --signal: #ff4b4b;
  --signal-dim: #7a2e2e;
  --ok: #34d399;
  --ok-dim: #1c4a3a;
  --wait: #f5a623;
  --wait-dim: #4a3a1c;

  --font-display: 'Space Grotesk', 'Inter', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Segoe UI', sans-serif;
  --font-data: 'JetBrains Mono', 'Consolas', monospace;

  --radius: 3px;
  --gap: 1.5rem;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--paper);
  text-decoration-color: var(--signal-dim);
  text-underline-offset: 3px;
}

a:hover {
  text-decoration-color: var(--signal);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 0.5rem;
  color: var(--paper);
}

p {
  margin: 0 0 0.75rem;
  color: var(--paper-dim);
}

/* -------------------------------------------------------------------------
   Shell — header bar + content column, shared by every authenticated page
   ------------------------------------------------------------------------- */

.shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.shell-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.75rem;
  border-bottom: 1px solid var(--ink-line);
  flex-wrap: wrap;
}

.shell-brand {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--paper);
  text-decoration: none;
}

.shell-brand::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 3px var(--signal-dim);
  flex-shrink: 0;
}

.shell-nav {
  display: flex;
  gap: 1.5rem;
  font-size: 0.85rem;
}

.shell-nav a {
  color: var(--paper-dim);
  text-decoration: none;
  font-weight: 500;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}

.shell-nav a:hover,
.shell-nav a.active {
  color: var(--paper);
  border-bottom-color: var(--signal);
}

.shell-main {
  flex: 1;
  width: 100%;
  max-width: 780px;
  margin: 0 auto;
  padding: 2.5rem 1.75rem 4rem;
}

/* Wider column for pages whose content is inherently horizontal — the
   catalog's photo-led product grid needs more than a single reading
   column's width to breathe. */
.shell-main.is-wide {
  max-width: 1180px;
}

.shell-eyebrow {
  font-family: var(--font-data);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper-faint);
  margin: 0 0 0.4rem;
}

.shell-main h1 {
  font-size: 1.6rem;
  margin-bottom: 2rem;
}

/* Auth/onboarding pages get a centered card instead of the app shell */

.auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.auth-card {
  width: 100%;
  max-width: 380px;
  text-align: center;
}

.auth-card .shell-brand {
  justify-content: center;
  margin-bottom: 2rem;
  font-size: 1.2rem;
}

.auth-card h1 {
  font-size: 1.4rem;
  margin-bottom: 0.6rem;
}

.auth-card p {
  margin-bottom: 1.75rem;
}

.auth-card.is-wide {
  max-width: 420px;
  text-align: left;
}

.auth-card.is-wide .shell-brand {
  justify-content: flex-start;
}

/* -------------------------------------------------------------------------
   Panels — the section block used throughout Panel/Usage/Admin pages
   ------------------------------------------------------------------------- */

.panel {
  background: var(--ink-raised);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  padding: 1.5rem 1.75rem;
  margin-bottom: var(--gap);
}

.panel h2 {
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--paper-dim);
  margin-bottom: 1.1rem;
}

.panel + .panel {
  margin-top: 0;
}

/* -------------------------------------------------------------------------
   Status — the signature element. A dot + label pair used for connection
   state, subscription state, and any other binary/tri-state system health.
   ------------------------------------------------------------------------- */

.status-line {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-data);
  font-size: 0.9rem;
}

.status-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}

.status-dot.is-ok { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-dim); }
.status-dot.is-wait { background: var(--wait); box-shadow: 0 0 0 3px var(--wait-dim); }
.status-dot.is-off { background: var(--paper-faint); box-shadow: 0 0 0 3px var(--ink-line); }

.status-label.is-ok { color: var(--ok); }
.status-label.is-wait { color: var(--wait); }
.status-label.is-off { color: var(--paper-faint); }

.status-meta {
  color: var(--paper-faint);
  font-family: var(--font-body);
  font-size: 0.85rem;
}

/* -------------------------------------------------------------------------
   Forms
   ------------------------------------------------------------------------- */

label {
  display: block;
  font-size: 0.85rem;
  color: var(--paper-dim);
  margin-bottom: 0.4rem;
}

input[type="text"],
input[type="number"],
input:not([type]),
textarea {
  width: 100%;
  background: var(--ink);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 0.92rem;
  padding: 0.65rem 0.8rem;
}

textarea {
  font-family: var(--font-data);
  font-size: 0.85rem;
  resize: vertical;
}

input[type="text"]:focus,
input[type="number"]:focus,
input:not([type]):focus,
textarea:focus {
  border-color: var(--signal);
}

button,
.btn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.85rem;
  background: var(--signal);
  color: #1a0d0d;
  border: none;
  border-radius: var(--radius);
  padding: 0.65rem 1.1rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

button:hover,
.btn:hover {
  background: #ff6363;
}

button.btn-secondary,
.btn.btn-secondary {
  background: transparent;
  color: var(--paper);
  border: 1px solid var(--ink-line);
}

button.btn-secondary:hover,
.btn.btn-secondary:hover {
  border-color: var(--paper-faint);
  background: var(--ink-line);
}

.field {
  margin-bottom: 1.1rem;
}

.field-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.6rem;
}

.status-message {
  font-size: 0.85rem;
  color: var(--paper-dim);
  margin-top: 0.75rem;
  margin-bottom: 0;
}

.status-message.is-error {
  color: var(--signal);
}

/* -------------------------------------------------------------------------
   Tier selector — radio group styled as a row of toggles
   ------------------------------------------------------------------------- */

.tier-options {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.tier-option {
  position: relative;
}

.tier-option input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.tier-option label {
  display: block;
  margin: 0;
  padding: 0.6rem 1rem;
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  font-family: var(--font-data);
  font-size: 0.85rem;
  color: var(--paper-dim);
  cursor: pointer;
}

.tier-option input:checked + label {
  border-color: var(--signal);
  color: var(--paper);
  background: rgba(255, 75, 75, 0.08);
}

.tier-option input:focus-visible + label {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

/* -------------------------------------------------------------------------
   Tables — usage/pricing/tenant lists. Figures set in monospace and
   right-aligned so numbers stack for scanning, like a statement.
   ------------------------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

th {
  text-align: left;
  font-family: var(--font-data);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper-faint);
  font-weight: 500;
  padding: 0 0.5rem 0.6rem;
  border-bottom: 1px solid var(--ink-line);
}

td {
  padding: 0.65rem 0.5rem;
  border-bottom: 1px solid var(--ink-line);
  color: var(--paper);
}

tbody tr:last-child td {
  border-bottom: none;
}

th:nth-child(n+2),
td:nth-child(n+2) {
  text-align: right;
  font-family: var(--font-data);
}

tfoot td {
  border-bottom: none;
  border-top: 1px solid var(--ink-line);
  padding-top: 0.9rem;
  font-family: var(--font-data);
  font-weight: 600;
}

.price-input {
  width: 8rem;
  text-align: right;
}

.field-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.field-hint {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 50%;
  border: 1px solid var(--ink-line);
  color: var(--paper-dim);
  font-size: 0.7rem;
  font-style: italic;
  font-family: Georgia, "Times New Roman", serif;
  cursor: help;
  user-select: none;
}

/* CSS-only tooltip, not the native `title` attribute — `title` waits ~1s before showing and is
   easy to miss/dismiss by accident, which is why the field-hint icons alone were visible without
   their explanation reliably appearing. This shows immediately on hover/focus (keyboard-reachable
   via tabindex) and stays open long enough to read the (longer, impact-focused) explanations. */
.field-hint::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%) translateY(0.25rem);
  width: max-content;
  max-width: 22rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius);
  border: 1px solid var(--ink-line);
  background: var(--ink-raised);
  color: var(--paper);
  font-size: 0.8rem;
  font-style: normal;
  font-family: var(--font-body, inherit);
  line-height: 1.4;
  text-align: left;
  white-space: normal;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.35);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 20;
}

.field-hint:hover::after,
.field-hint:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

/* -------------------------------------------------------------------------
   Catalog grid — product cards, not a spreadsheet. Catalog rows carry
   arbitrary tenant-defined columns (color, size, category...) plus a photo,
   so a table forces either horizontal scroll or wrapped mush; a photo-led
   card is the shape this content actually has. Availability reuses the
   app's existing status-dot language (in stock / low / out) rather than
   inventing a new state indicator.
   ------------------------------------------------------------------------- */

.catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.1rem;
}

.catalog-card {
  background: var(--ink);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease;
}

.catalog-card:hover {
  border-color: var(--paper-faint);
}

.catalog-card.is-expanded {
  border-color: var(--signal);
  grid-column: 1 / -1;
}

.catalog-card-photo {
  aspect-ratio: 4 / 5;
  background: var(--ink-raised);
  overflow: hidden;
}

.catalog-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.catalog-card-photo.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--paper-faint);
  font-size: 0.75rem;
}

.catalog-card-body {
  padding: 0.9rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 1;
}

.catalog-card-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--paper);
  line-height: 1.3;
}

.catalog-card-price {
  font-family: var(--font-data);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--paper);
}

.catalog-card-attrs {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.8rem;
  color: var(--paper-dim);
  margin-top: 0.2rem;
}

.catalog-card-attrs span {
  color: var(--paper-faint);
  font-family: var(--font-data);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-right: 0.4rem;
}

.catalog-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 0.6rem;
}

.catalog-card-photo-count {
  font-family: var(--font-data);
  font-size: 0.75rem;
  color: var(--paper-faint);
}

/* -------------------------------------------------------------------------
   Catalog detail — expanded card content: full attribute list, photo
   gallery with reorder/delete, raw-row inspector, danger action.
   ------------------------------------------------------------------------- */

.catalog-detail {
  padding: 0 1rem 1.25rem;
  border-top: 1px solid var(--ink-line);
  margin-top: 0.5rem;
  padding-top: 1rem;
}

.catalog-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.6rem 1.5rem;
  margin-bottom: 1.25rem;
}

.catalog-detail-attr {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.catalog-detail-attr dt {
  font-family: var(--font-data);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--paper-faint);
}

.catalog-detail-attr dd {
  margin: 0;
  font-size: 0.9rem;
  color: var(--paper);
}

.catalog-detail h4 {
  font-family: var(--font-display);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--paper-dim);
  margin: 0 0 0.6rem;
}

.photo-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.photo-gallery-item {
  width: 120px;
}

.photo-gallery-item img {
  width: 120px;
  height: 150px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--ink-line);
  display: block;
}

.photo-gallery-actions {
  display: flex;
  gap: 0.3rem;
  margin-top: 0.4rem;
}

.photo-gallery-actions button {
  flex: 1;
  padding: 0.3rem 0.4rem;
  font-size: 0.72rem;
}

.catalog-availability {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
}

/* -------------------------------------------------------------------------
   Pending-deletion confirm banner
   ------------------------------------------------------------------------- */

.import-confirm {
  margin-top: 1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--wait-dim);
  background: rgba(245, 166, 35, 0.08);
  border-radius: var(--radius);
}

.import-confirm p {
  color: var(--paper);
  margin-bottom: 0.75rem;
}

.import-confirm .field-row {
  display: flex;
  gap: 0.6rem;
  margin-bottom: 0;
}

@media (max-width: 640px) {
  .catalog-grid {
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 0.75rem;
  }
}

/* -------------------------------------------------------------------------
   LLM health table — mixed text (model/status) and numeric (success/failure
   count) columns, unlike the statement-style tables above where every column
   past the first is a right-aligned figure — so alignment is set per-column
   here instead of by nth-child.
   ------------------------------------------------------------------------- */

.llm-health-table th,
.llm-health-table td {
  text-align: left;
  font-family: var(--font-body);
}

.llm-health-table th:nth-child(3),
.llm-health-table td:nth-child(3),
.llm-health-table th:nth-child(4),
.llm-health-table td:nth-child(4) {
  text-align: right;
  font-family: var(--font-data);
}

/* -------------------------------------------------------------------------
   Admin tabs — per-tier switch on the LLM health page. Same underline-active
   language as .shell-nav, but as buttons (client-side tab switch, not a
   route change) rather than links.
   ------------------------------------------------------------------------- */

.admin-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 1.25rem 0;
}

.admin-tabs {
  display: flex;
  gap: 1.5rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--ink-line);
}

.admin-tabs button {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 0 0 0.75rem;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--paper-dim);
  cursor: pointer;
}

.admin-tabs button:hover {
  color: var(--paper);
}

.admin-tabs button.is-active {
  color: var(--paper);
  border-bottom-color: var(--signal);
}

/* -------------------------------------------------------------------------
   Metric row — used at the top of the usage page for the month's headline
   numbers, set as a lit dashboard readout.
   ------------------------------------------------------------------------- */

.metric-row {
  display: flex;
  gap: 2.25rem;
  flex-wrap: wrap;
}

.metric {
  min-width: 140px;
}

.metric-value {
  font-family: var(--font-data);
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--paper);
  line-height: 1.2;
}

.metric-value.is-accent {
  color: var(--signal);
}

.metric-label {
  font-size: 0.78rem;
  color: var(--paper-faint);
  margin-top: 0.3rem;
}

/* -------------------------------------------------------------------------
   Page list (connect-instagram page picker)
   ------------------------------------------------------------------------- */

.pick-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.pick-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
}

.pick-row span {
  font-weight: 500;
}

.choice-row {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

/* -------------------------------------------------------------------------
   Prompt builder (/panel/prompt) — answers on the left, the composed prompt
   on the right. The preview is the signature: the tenant watches their
   answers compile into the literal text the model receives, which is what
   makes a form feel like it hasn't taken the prompt away from them. It is a
   <pre>, not a styled paragraph, precisely because it IS the artifact.
   ------------------------------------------------------------------------- */

.builder-lede {
  max-width: 52ch;
  margin-top: -1.25rem;
  margin-bottom: 2rem;
}

.builder {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
  align-items: start;
  gap: var(--gap);
}

.builder-form .panel:last-child {
  margin-bottom: 0;
}

.builder-preview-sticky {
  position: sticky;
  top: 1.5rem;
  background: var(--ink-raised);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  padding: 1.5rem 1.6rem;
}

.builder-preview-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.builder-preview-head h2 {
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--paper-dim);
  margin: 0;
}

.builder-preview-count {
  font-family: var(--font-data);
  font-size: 0.72rem;
  color: var(--paper-faint);
  white-space: nowrap;
}

.builder-preview-body {
  margin: 0;
  padding: 1rem;
  max-height: 26rem;
  overflow-y: auto;
  background: var(--ink);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  font-family: var(--font-data);
  font-size: 0.78rem;
  line-height: 1.65;
  color: var(--paper);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.builder-preview-empty {
  margin: 0;
  padding: 1rem;
  border: 1px dashed var(--ink-line);
  border-radius: var(--radius);
  font-size: 0.83rem;
  color: var(--paper-faint);
}

.builder-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.25rem;
}

/* Sits above the first section, so it reads as a shortcut into the form rather
   than one more field inside it. */
.builder-actions-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 0.9rem;
  margin-bottom: var(--gap);
}

.builder-actions-hint {
  font-size: 0.8rem;
  color: var(--paper-faint);
}

.builder-actions-warning {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.85rem;
  color: var(--wait);
}

.field-note {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  color: var(--paper-faint);
}

/* The builder's answers are prose the tenant writes, not data — so they get the
   body face, overriding the global monospace `textarea` rule that makes an empty
   field's placeholder read as pre-filled content. */
.builder-form textarea {
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.5;
}

/* Placeholders must never be mistakable for a filled-in value: dimmer than the
   real text and italic, so "empty" is legible at a glance. */
.builder-form input::placeholder,
.builder-form textarea::placeholder {
  color: var(--paper-faint);
  font-style: italic;
  opacity: 0.75;
}

/* A field the tenant has actually filled in reads brighter than its neighbours. */
.builder-form input:not(:placeholder-shown),
.builder-form textarea:not(:placeholder-shown) {
  border-color: #3a3945;
  color: var(--paper);
}

/* Excerpt of the saved prompt on /panel — clamped, since the panel only needs
   to answer "is this filled in", not to be read. */
.prompt-preview {
  font-family: var(--font-data);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--paper-dim);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0;
}

@media (max-width: 900px) {
  .builder {
    grid-template-columns: 1fr;
  }
  .builder-preview-sticky {
    position: static;
  }
}

/* -------------------------------------------------------------------------
   Utility
   ------------------------------------------------------------------------- */

.muted {
  color: var(--paper-faint);
}

/* Collapsed Telegram group setup guide: long enough to need hiding by default,
   but the first thing a tenant looks for when topics are not working. */
.tg-guide {
  border: 1px solid var(--ink-line);
  border-radius: 8px;
  padding: 0.75rem 1rem;
}

.tg-guide > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--paper);
}

.tg-guide[open] > summary {
  margin-bottom: 0.75rem;
}

.tg-steps {
  margin: 0.5rem 0 0.75rem;
  padding-left: 1.25rem;
  line-height: 1.65;
}

.tg-steps li + li {
  margin-top: 0.6rem;
}

.tg-note {
  display: block;
  font-size: 0.85rem;
  color: var(--paper-faint);
}

.tg-cmd {
  display: inline-block;
  margin-top: 0.35rem;
  word-break: break-all;
}

.mt-lg {
  margin-top: var(--gap);
}

@media (max-width: 640px) {
  .shell-header {
    padding: 1rem;
  }
  .shell-main {
    padding: 1.75rem 1rem 3rem;
  }
  .metric-row {
    gap: 1.5rem;
  }
}

/* ==========================================================================
   Landing page ("/") — a distinct system from the admin Signal Panel above.
   The pitch IS the product: the hero is a live Instagram DM thread, not a
   headline-over-gradient. Warm serif display against a near-black chat UI,
   indigo for the bot's own accent (deliberately not Instagram's own
   pink/orange, so this never reads as impersonating the Instagram brand).
   Fraunces loaded from Google Fonts (this page only, via HeadContent) — an
   explicit, scoped exception to the rest of the app's self-hosted-fonts
   policy, accepted for this one warm display face.
   ========================================================================== */

.ig {
  --ig-ink: #faf7f2;
  --ig-surface: #ffffff;
  --ig-surface-raised: #f0ece4;
  --ig-line: #e4ded2;
  --ig-paper: #211f1c;
  --ig-paper-dim: #5c584f;
  --ig-paper-faint: #8c877b;
  --ig-accent: #4b4fd6;
  --ig-accent-dim: #dcdcfb;
  --ig-live: #1f9c76;

  --ig-font-display: 'Fraunces', 'Space Grotesk', 'Inter', 'Segoe UI', sans-serif;
  --ig-font-body: 'Inter', 'Segoe UI', sans-serif;
  --ig-font-data: 'JetBrains Mono', 'Consolas', monospace;

  background: var(--ig-ink);
  color: var(--ig-paper);
  min-height: 100vh;
  font-family: var(--ig-font-body);
}

.ig h1, .ig h2 {
  font-family: var(--ig-font-display);
  color: var(--ig-paper);
  margin: 0 0 0.6rem;
  letter-spacing: -0.01em;
}

.ig p {
  color: var(--ig-paper-dim);
  margin: 0 0 0.9rem;
  line-height: 1.6;
}

.ig a {
  color: inherit;
}

/* -------------------------------------------------------------------------
   Nav
   ------------------------------------------------------------------------- */

.ig-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 1.75rem;
}

.ig-wordmark {
  font-family: var(--ig-font-display);
  font-weight: 600;
  font-size: 1.05rem;
  text-decoration: none;
  color: var(--ig-paper);
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.ig-wordmark::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ig-accent);
  box-shadow: 0 0 0 3px var(--ig-accent-dim);
}

/* -------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------- */

.ig-btn {
  font-family: var(--ig-font-body);
  font-weight: 600;
  font-size: 0.88rem;
  border-radius: 999px;
  padding: 0.7rem 1.35rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid transparent;
}

.ig-btn-primary {
  background: var(--ig-accent);
  color: #fff;
}

.ig-btn-primary:hover {
  background: #6d70f4;
}

.ig-btn-ghost {
  background: transparent;
  color: var(--ig-paper);
  border-color: var(--ig-line);
}

.ig-btn-ghost:hover {
  border-color: var(--ig-paper-faint);
}

/* -------------------------------------------------------------------------
   Hero — copy on the left, live DM thread on the right (stacks on mobile,
   thread first since it's the whole point).
   ------------------------------------------------------------------------- */

.ig-hero {
  max-width: 1120px;
  margin: 0 auto;
  padding: 2.5rem 1.75rem 1.25rem;
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 3.5rem;
  align-items: center;
}

.ig-eyebrow {
  font-family: var(--ig-font-data);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ig-live);
  margin: 0 0 0.75rem;
}

.ig-hero h1 {
  font-size: 2.5rem;
  font-weight: 600;
  line-height: 1.18;
  margin-bottom: 1.2rem;
}

.ig-lede {
  font-size: 1.05rem;
  max-width: 480px;
  margin-bottom: 1.75rem;
}

.ig-cta-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* -------------------------------------------------------------------------
   The phone — the signature element. A DM thread, not a card.
   ------------------------------------------------------------------------- */

.ig-phone {
  background: var(--ig-surface);
  border: 1px solid var(--ig-line);
  border-radius: 22px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 48px -20px rgba(33, 31, 28, 0.18);
}

.ig-phone-header {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--ig-line);
}

.ig-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--ig-accent), #8b5ef0 60%, #e0538a);
}

.ig-phone-header-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.ig-phone-header-text strong {
  font-size: 0.88rem;
  color: var(--ig-paper);
}

.ig-status {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.75rem;
  color: var(--ig-live);
}

.ig-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ig-live);
}

.ig-thread {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  min-height: 160px;
  max-height: 360px;
  overflow-y: auto;
}

.ig-day-divider {
  text-align: center;
  font-size: 0.68rem;
  color: var(--ig-paper-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 0.4rem;
}

.ig-bubble {
  max-width: 82%;
  padding: 0.55rem 0.85rem;
  border-radius: 16px;
  font-size: 0.88rem;
  line-height: 1.4;
}

.ig-bubble span {
  color: inherit;
}

.ig-bubble.is-user {
  align-self: flex-end;
  background: var(--ig-accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.ig-bubble.is-bot {
  align-self: flex-start;
  background: var(--ig-surface-raised);
  color: var(--ig-paper);
  border-bottom-left-radius: 4px;
}

.ig-typing-dots {
  display: inline-flex;
  gap: 3px;
  padding: 0.15rem 0;
}

.ig-typing-dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ig-paper-faint);
  animation: ig-typing-bounce 1.1s infinite ease-in-out;
}

.ig-typing-dots i:nth-child(2) { animation-delay: 0.15s; }
.ig-typing-dots i:nth-child(3) { animation-delay: 0.3s; }

@keyframes ig-typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-3px); opacity: 1; }
}

.ig-composer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem;
  border-top: 1px solid var(--ig-line);
}

.ig-composer input {
  flex: 1;
  background: var(--ig-ink);
  border: 1px solid var(--ig-line);
  border-radius: 999px;
  color: var(--ig-paper);
  font-family: var(--ig-font-body);
  font-size: 0.85rem;
  padding: 0.6rem 1rem;
}

.ig-composer input:focus {
  outline: none;
  border-color: var(--ig-accent);
}

.ig-composer button {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--ig-accent);
  color: #fff;
  font-size: 0.95rem;
  cursor: pointer;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ig-composer button:hover:not(:disabled) {
  background: #6d70f4;
}

.ig-composer button:disabled {
  background: var(--ig-surface-raised);
  color: var(--ig-paper-faint);
  cursor: not-allowed;
}

.ig-inline-error {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 1.75rem;
  color: #f28b8b;
  font-size: 0.85rem;
}

.ig-demo-caption {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 1.75rem;
  font-size: 0.78rem;
  color: var(--ig-paper-faint);
}

/* -------------------------------------------------------------------------
   Steps — a real ordered sequence (connect → configure → run), so numbering
   here encodes true information rather than decorating a grid of three.
   ------------------------------------------------------------------------- */

.ig-section {
  max-width: 1120px;
  margin: 0 auto;
  padding: 2.75rem 1.75rem;
}

.ig-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--ig-line);
  border: 1px solid var(--ig-line);
  border-radius: 14px;
  overflow: hidden;
}

.ig-step {
  background: var(--ig-surface);
  padding: 1.75rem 1.6rem;
}

.ig-step-mark {
  display: block;
  font-family: var(--ig-font-data);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ig-accent);
  margin-bottom: 0.9rem;
}

.ig-step h2 {
  font-size: 1.15rem;
}

.ig-step p {
  margin-bottom: 0;
  font-size: 0.9rem;
}

/* -------------------------------------------------------------------------
   Pricing — plain rows, not cards. The pitch is "pay for use," not "pick a
   glossy tier," so the presentation stays unglamorous on purpose.
   ------------------------------------------------------------------------- */

.ig-section-title {
  font-size: 1.7rem;
  max-width: 640px;
}

.ig-lede-sm {
  max-width: 620px;
  margin-bottom: 2rem;
}

/* -------------------------------------------------------------------------
   Pricing calculator — the answer to "how much will this cost me a month".
   Two inputs (message volume, tier), one output. No submit, no server call:
   pure client-visible arithmetic against illustrative per-message rates.
   ------------------------------------------------------------------------- */

.ig-calc {
  background: var(--ig-surface);
  border: 1px solid var(--ig-line);
  border-radius: 14px;
  padding: 1.75rem 1.85rem;
  margin-bottom: 2rem;
}

.ig-calc-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.ig-calc-row label {
  font-size: 0.9rem;
  color: var(--ig-paper-dim);
}

.ig-calc-count {
  font-family: var(--ig-font-data);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ig-paper);
}

.ig-calc-slider {
  width: 100%;
  appearance: none;
  height: 4px;
  border-radius: 999px;
  background: var(--ig-line);
  margin: 0.3rem 0 1.5rem;
}

.ig-calc-slider::-webkit-slider-thumb {
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--ig-accent);
  cursor: pointer;
  border: 3px solid var(--ig-surface);
  box-shadow: 0 0 0 1px var(--ig-line);
}

.ig-calc-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--ig-accent);
  cursor: pointer;
  border: 3px solid var(--ig-surface);
  box-shadow: 0 0 0 1px var(--ig-line);
}

.ig-calc-tiers {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

.ig-calc-tier {
  font-family: var(--ig-font-body);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ig-paper-dim);
  background: transparent;
  border: 1px solid var(--ig-line);
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  cursor: pointer;
}

.ig-calc-tier:hover {
  border-color: var(--ig-paper-faint);
}

.ig-calc-tier.is-active {
  background: var(--ig-accent);
  border-color: var(--ig-accent);
  color: #fff;
}

.ig-calc-result {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--ig-line);
}

.ig-calc-result-value {
  font-family: var(--ig-font-display);
  font-weight: 600;
  font-size: 2rem;
  color: var(--ig-paper);
}

.ig-calc-result-label {
  font-size: 0.85rem;
  color: var(--ig-paper-faint);
}

.ig-price-rows {
  border-top: 1px solid var(--ig-line);
}

.ig-price-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--ig-line);
}

.ig-price-name {
  font-family: var(--ig-font-display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ig-paper);
}

.ig-price-row p {
  margin: 0 0 0.3rem;
  font-size: 0.92rem;
}

.ig-price-per-message {
  font-family: var(--ig-font-data);
  font-size: 0.78rem;
  color: var(--ig-paper-faint);
}

.ig-note {
  margin-top: 1.5rem;
  font-size: 0.9rem;
}

.ig-note a {
  color: var(--ig-accent);
  text-decoration-color: var(--ig-accent-dim);
}

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */

.ig-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 1120px;
  margin: 0 auto;
  padding: 2rem 1.75rem 3.5rem;
  border-top: 1px solid var(--ig-line);
  color: var(--ig-paper-faint);
  font-size: 0.85rem;
}

.ig-footer a {
  color: var(--ig-paper-dim);
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  .ig-typing-dots i {
    animation: none;
  }
}

@media (max-width: 860px) {
  .ig-hero {
    grid-template-columns: 1fr;
    padding-top: 1.5rem;
  }
  .ig-hero h1 {
    font-size: 2rem;
  }
  .ig-steps {
    grid-template-columns: 1fr;
  }
  .ig-price-row {
    grid-template-columns: 1fr;
    gap: 0.35rem;
  }
}

/* ==========================================================================
   Test chat (/panel/chat) — the bot preview, full-screen, shaped like an
   Instagram Direct thread rather than a widget inside a panel. It borrows the
   landing page's light chat palette (--ig-*) instead of the admin's dark
   Signal Panel, because the tenant is here to judge how a reply will look to a
   customer, and a customer sees it on Instagram's own light thread.

   Deliberately NOT Instagram's pink/orange brand gradient anywhere except the
   avatar: same reasoning as the landing page — this is a preview of a bot, and
   it must never read as impersonating the Instagram product itself.

   Three fixed rows (topbar / scrolling thread / composer) on a dvh height, so
   the composer stays reachable on mobile where the URL bar steals vh.
   ========================================================================== */

.dm {
  --dm-ink: #faf7f2;
  --dm-surface: #ffffff;
  --dm-raised: #f0ece4;
  --dm-line: #e4ded2;
  --dm-paper: #211f1c;
  --dm-paper-dim: #5c584f;
  --dm-paper-faint: #8c877b;
  --dm-accent: #4b4fd6;
  --dm-danger: #b3261e;

  --dm-font-display: 'Fraunces', 'Space Grotesk', 'Inter', 'Segoe UI', sans-serif;
  --dm-font-body: 'Inter', 'Segoe UI', sans-serif;

  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--dm-surface);
  color: var(--dm-paper);
  font-family: var(--dm-font-body);
}

/* --- Topbar --------------------------------------------------------------- */

.dm-topbar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--dm-line);
  background: var(--dm-surface);
}

.dm-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  border-radius: 50%;
  color: var(--dm-paper);
  text-decoration: none;
}

.dm-back svg {
  width: 1.35rem;
  height: 1.35rem;
}

.dm-back:hover {
  background: var(--dm-raised);
}

.dm-identity {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
  flex: 1;
}

.dm-avatar {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--dm-accent), #8b5ef0 60%, #e0538a);
}

.dm-avatar-lg {
  width: 4.5rem;
  height: 4.5rem;
}

.dm-identity-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.dm-identity-text strong {
  font-size: 0.92rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dm-identity-sub {
  font-size: 0.75rem;
  color: var(--dm-paper-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dm-reset {
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--dm-line);
  border-radius: 999px;
  color: var(--dm-paper-dim);
  font-family: var(--dm-font-body);
  font-weight: 500;
  font-size: 0.8rem;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
}

.dm-reset:hover:not(:disabled) {
  border-color: var(--dm-paper-faint);
  color: var(--dm-paper);
}

.dm-reset:disabled {
  opacity: 0.45;
  cursor: default;
}

/* --- Thread --------------------------------------------------------------- */

.dm-thread {
  overflow-y: auto;
  background: var(--dm-ink);
}

.dm-thread-inner {
  max-width: 46rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* Empty state as an invitation: the account card a real Direct thread opens
   with, plus three real questions the tenant's customers actually ask. */
.dm-intro {
  text-align: center;
  padding: 2.5rem 1rem 1rem;
}

.dm-intro .dm-avatar-lg {
  display: inline-block;
  margin-bottom: 0.9rem;
}

.dm-intro-name {
  font-family: var(--dm-font-display);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--dm-paper);
  margin: 0 0 0.5rem;
}

.dm-intro-note {
  max-width: 34rem;
  margin: 0 auto 1.75rem;
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--dm-paper-dim);
}

.dm-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
}

.dm-suggestion {
  background: var(--dm-surface);
  border: 1px solid var(--dm-line);
  border-radius: 999px;
  color: var(--dm-paper);
  font-family: var(--dm-font-body);
  font-size: 0.85rem;
  padding: 0.5rem 1.05rem;
  cursor: pointer;
}

.dm-suggestion:hover {
  border-color: var(--dm-accent);
  color: var(--dm-accent);
}

.dm-row {
  display: flex;
}

.dm-row.is-user {
  justify-content: flex-end;
}

.dm-row.is-bot {
  justify-content: flex-start;
}

/* Consecutive bubbles from one side tuck together, and only the last of a run
   keeps its outer tail — the grouping a real DM thread has. */
.dm-row + .dm-row.is-user,
.dm-row + .dm-row.is-bot {
  margin-top: 0.1rem;
}

.dm-bubble {
  max-width: min(82%, 34rem);
  padding: 0.55rem 0.9rem;
  border-radius: 18px;
  font-size: 0.9rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.dm-row.is-user .dm-bubble {
  background: var(--dm-accent);
  color: #fff;
  border-bottom-right-radius: 5px;
}

.dm-row.is-bot .dm-bubble {
  background: var(--dm-raised);
  color: var(--dm-paper);
  border-bottom-left-radius: 5px;
}

.dm-row.is-bot .dm-bubble.is-error {
  background: #fdecea;
  color: var(--dm-danger);
}

.dm-bubble.is-photo {
  padding: 0.3rem;
  background: var(--dm-raised);
}

.dm-bubble.is-photo img {
  display: block;
  max-width: 100%;
  max-height: 20rem;
  border-radius: 14px;
  object-fit: cover;
}

.dm-bubble.is-typing {
  padding: 0.7rem 0.95rem;
}

.dm-dots {
  display: inline-flex;
  gap: 4px;
}

.dm-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dm-paper-faint);
  animation: dm-typing 1.1s infinite ease-in-out;
}

.dm-dots i:nth-child(2) { animation-delay: 0.15s; }
.dm-dots i:nth-child(3) { animation-delay: 0.3s; }

@keyframes dm-typing {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-3px); opacity: 1; }
}

/* --- Composer ------------------------------------------------------------- */

.dm-composer {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 46rem;
  width: 100%;
  margin: 0 auto;
  padding: 0.85rem 1rem calc(0.85rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--dm-line);
  background: var(--dm-surface);
}

/* Overrides the app-wide dark input styling, which would otherwise paint an
   --ink field into this light thread. */
.dm-composer input[type="text"] {
  flex: 1;
  min-width: 0;
  background: var(--dm-ink);
  border: 1px solid var(--dm-line);
  border-radius: 999px;
  color: var(--dm-paper);
  font-family: var(--dm-font-body);
  font-size: 0.9rem;
  padding: 0.65rem 1.1rem;
}

.dm-composer input[type="text"]::placeholder {
  color: var(--dm-paper-faint);
}

.dm-composer input[type="text"]:focus {
  border-color: var(--dm-accent);
}

.dm-composer input[type="text"]:focus-visible,
.dm-composer button:focus-visible,
.dm-suggestion:focus-visible,
.dm-reset:focus-visible,
.dm-back:focus-visible {
  outline: 2px solid var(--dm-accent);
  outline-offset: 2px;
}

.dm-composer button {
  width: 2.5rem;
  height: 2.5rem;
  flex-shrink: 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--dm-accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.dm-composer button svg {
  width: 1.15rem;
  height: 1.15rem;
}

.dm-composer button:hover:not(:disabled) {
  background: #6d70f4;
}

.dm-composer button:disabled {
  background: var(--dm-raised);
  color: var(--dm-paper-faint);
  cursor: default;
}

@media (max-width: 640px) {
  .dm-topbar {
    padding: 0.6rem 0.75rem;
  }
  .dm-reset {
    font-size: 0.75rem;
    padding: 0.35rem 0.7rem;
  }
  .dm-thread-inner {
    padding: 1rem 0.75rem 1.5rem;
  }
  .dm-bubble {
    max-width: 88%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dm-dots i {
    animation: none;
  }
}
