/* ==========================================================================
   Global Theme & Color Variables
   ========================================================================== */
:root {
  --primary-color: #E04198;       /* Main brand color (Buttons, Accents) */
  --primary-hover: #1d4ed8;       /* Button hover state */
  --bg-color: #f8fafc;            /* App background color */
  --surface-color: #ffffff;       /* Card and Container background */
  --text-main: #0f172a;           /* Dark body text */
  --text-muted: #64748b;          /* Secondary text & labels */
  --border-color: #e2e8f0;        /* Subtle borders and dividers */
  
  --error-bg: #fef2f2;            /* Alert/Error banner background */
  --error-text: #dc2626;          /* Alert/Error text color */
  --success-bg: #f0fdf4;          /* Success banner background */
  --success-text: #16a34a;        /* Success text color */

  --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  --radius: 8px;
  --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

/* Base Styles */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.link-button {
  background: none;
  border: none;
  color: var(--primary-color);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
  padding: 0;
}

.link-button:hover {
  color: var(--primary-hover);
}

body {
  font-family: var(--font-family);
  background-color: var(--bg-color);
  color: var(--text-main);
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.hidden {
  display: none !important;
}

.version-footer {
  background: transparent;
  color: var(--text-muted);
  text-align: center;
  padding: 0.75rem 0;
  font-size: 0.92rem;
}

/* Footer Links & Separator */
.version-footer .footer-copyright {
  display: block;
  margin-top: 0.35rem;
}

.version-footer .footer-separator {
  margin: 0 0.5rem;
  color: var(--border-color);
}

.version-footer .footer-link {
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s;
}

.version-footer .footer-link:hover {
  color: var(--primary-color);
  text-decoration: underline;
}

.footer-social {
  display: flex;
  justify-content: center;
  gap: 1rem;
  margin-top: 0.6rem;
}

.footer-social-link {
  display: inline-flex;
  color: var(--text-muted);
  transition: color 0.2s;
}

.footer-social-link:hover {
  color: var(--primary-color);
}

.footer-social-link svg {
  width: 18px;
  height: 18px;
}

.footer-version {
  display: block;
  margin-top: 0.6rem;
}

.app-version {
  font-weight: 700;
  color: var(--primary-color);
}

/* ==========================================================================
   Header & Banner
   ========================================================================== */
.site-header {
  background: var(--surface-color);
  border-bottom: 1px solid var(--border-color);
  padding: 1rem 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Header Action Buttons */
.btn-primary-sm {
  display: inline-block;
  font: inherit;
  padding: 0.5rem 1rem;
  background-color: var(--primary-color);
  color: #ffffff;
  border: none;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-primary-sm:hover {
  background-color: var(--primary-hover);
}

.brand-logo,
.brand-logo a {
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--primary-color, #F50B94);
  text-decoration: none;
}

/* Brand Logo & Icon Alignment */
.brand-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--primary-color, #F50B94);
}

.brand-icon {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.brand-icon-svg {
  width: 22px;
  height: 22px;
  stroke: var(--primary-color, #F50B94);
}

#banner {
  padding: 0.75rem 1.5rem;
  margin: 1rem auto;
  max-width: 800px;
  width: 90%;
  border-radius: var(--radius);
  font-weight: 500;
  text-align: center;
}

#banner.info { background: var(--surface-color); border: 1px solid var(--border-color); color: var(--text-main); }
#banner.error { background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-text); }
#banner.success { background: var(--success-bg); color: var(--success-text); border: 1px solid var(--success-text); }

#verifyBanner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.75rem 1.5rem;
  margin: 1rem auto;
  max-width: 800px;
  width: 90%;
  border-radius: var(--radius);
  font-weight: 500;
  text-align: center;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  color: var(--text-main);
}

#verifyBanner button {
  flex-shrink: 0;
}

/* ==========================================================================
   Container & Card Layouts
   ========================================================================== */
.container {
  max-width: 900px;
  width: 90%;
  margin: 2rem auto;
  flex: 1;
}

/* ==========================================================================
   App Shell (persistent left sidebar + full-width main content) - see
   public/js/sidebar.js. Only present on logged-in app pages (dashboard,
   settings, manage/import feed, product pages, pricing) - marketing/auth
   pages keep the plain <main class="container"> layout above untouched.
   .app-shell takes over .container's flex:1 role (filling the remaining
   space between the header and footer in body's column flex layout), with
   .app-main filling the remaining width instead of being capped at 900px.
   ========================================================================== */
.app-shell {
  display: flex;
  align-items: flex-start;
  flex: 1;
  width: 100%;
}

.app-main {
  flex: 1;
  min-width: 0;
  width: 100%;
  padding: 2rem;
}

#sidebarContainer {
  position: relative;
  flex-shrink: 0;
}

.sidebar {
  width: 260px;
  flex-shrink: 0;
  background: var(--surface-color);
  border-right: 1px solid var(--border-color);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  transition: width 0.2s ease;
}

.sidebar-collapsed {
  width: 0;
  border-right: none;
}

.sidebar-collapsed .sidebar-header,
.sidebar-collapsed .sidebar-nav {
  display: none;
}

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  border-bottom: 1px solid var(--border-color);
}

.sidebar-title {
  font-weight: 700;
  color: var(--primary-color);
}

.sidebar-collapse-btn,
.sidebar-expand-tab {
  background: none;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  padding: 0.25rem 0.6rem;
  font-size: 1rem;
  line-height: 1.2;
}

.sidebar-collapse-btn:hover,
.sidebar-expand-tab:hover {
  color: var(--primary-color);
  border-color: var(--primary-color);
}

/* Stays visible (outside .sidebar, which is width:0 when collapsed) so
   there's always a way back in. */
.sidebar-expand-tab {
  position: sticky;
  top: 1rem;
}

.sidebar-nav {
  padding: 0.5rem 0;
}

.sidebar-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  border-top: 1px solid var(--border-color);
  padding: 0.85rem 1rem;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--text-main);
  cursor: pointer;
  text-align: left;
}

.sidebar-section:first-child .sidebar-section-header {
  border-top: none;
}

/* A section header that's a plain link to a whole page (e.g. Settings -
   see sidebarBuildLinkHeader) rather than an accordion toggle - same look,
   but needs the anchor-specific reset/hover a <button> doesn't. */
.sidebar-section-link {
  text-decoration: none;
}

.sidebar-section-link:hover {
  color: var(--primary-color);
  background: var(--bg-color);
}

.sidebar-chevron {
  color: var(--text-muted);
  transition: transform 0.15s ease;
}

.sidebar-section-header.collapsed .sidebar-chevron {
  transform: rotate(-90deg);
}

/* Collapsible card section header (see e.g. manage-feed.html's Data Source
   URL card) - same chevron-rotate behavior as the sidebar's own collapsible
   sections above, reusing .sidebar-chevron rather than a second copy of the
   same transition rule, but its own header class since a card header needs
   different spacing/typography than the sidebar's. */
.card-collapsible-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin-bottom: 0.75rem;
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.card-collapsible-header.collapsed {
  margin-bottom: 0;
}

.card-collapsible-header.collapsed .sidebar-chevron {
  transform: rotate(-90deg);
}

.sidebar-section-body {
  padding: 0 1rem 1rem;
}

.sidebar-group {
  margin-bottom: 1rem;
}

.sidebar-group:last-child {
  margin-bottom: 0;
}

.sidebar-group-label {
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--primary-color);
  margin-bottom: 0.25rem;
}

.sidebar-link {
  display: block;
  padding: 0.35rem 0.5rem;
  margin-left: -0.5rem;
  border-radius: var(--radius);
  color: var(--text-main);
  text-decoration: none;
  font-size: 0.9rem;
}

.sidebar-link:hover {
  background: var(--bg-color);
  color: var(--primary-color);
}

.sidebar-empty-note {
  font-size: 0.85rem;
  margin: 0;
}

.sidebar-add-channel-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.85rem;
}

.sidebar-add-channel-row:last-child {
  border-bottom: none;
}

.sidebar-add-channel-row .btn-primary-sm,
.sidebar-add-channel-row .sidebar-link {
  flex-shrink: 0;
}

@media (max-width: 640px) {
  .app-main {
    padding: 1.25rem;
  }
}

.card {
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 2rem;
  box-shadow: var(--shadow);
}

/* ==========================================================================
   Auth / Login Form
   ========================================================================== */
.auth-card {
  max-width: 420px;
  margin: 4rem auto;
}

/* Register has a longer Terms/Privacy/Refund agreement line than the other
   auth pages - a bit of extra width keeps it from wrapping onto an extra
   line without widening login/forgot/reset/register-success too. */
.auth-card-wide {
  max-width: 520px;
}

.auth-card h1 {
  margin-bottom: 1.5rem;
  font-size: 1.5rem;
  text-align: center;
}

.form-group {
  margin-bottom: 1.25rem;
}

/* Manage Feed's Search + Sort By controls (public/manage-feed.html) sit
   side by side on wide screens, stacking on narrow ones. */
.search-sort-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.search-sort-row .form-group {
  flex: 1;
  min-width: 220px;
}

.form-group label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.form-group-checkbox label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-weight: 400;
  line-height: 1.4;
}

.form-group-checkbox input[type="checkbox"] {
  width: auto;
  margin-top: 0.2rem;
  flex-shrink: 0;
}

input[type="email"],
input[type="password"],
input[type="text"] {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: 1rem;
  outline: none;
  transition: border-color 0.2s;
}

input:focus {
  border-color: var(--primary-color);
}

.btn-primary {
  width: 100%;
  padding: 0.75rem;
  background-color: var(--primary-color);
  color: #ffffff;
  border: none;
  border-radius: var(--radius);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-primary:hover {
  background-color: var(--primary-hover);
}

.btn-secondary {
  display: inline-block;
  font: inherit;
  padding: 0.5rem 1rem;
  background-color: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  cursor: pointer;
}

.btn-secondary:hover {
  background-color: var(--border-color);
  color: var(--text-main);
}

.btn-danger {
  display: inline-block;
  font: inherit;
  padding: 0.5rem 1rem;
  background-color: var(--error-text);
  color: #ffffff;
  border: none;
  border-radius: var(--radius);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-danger:hover {
  opacity: 0.85;
}

.btn-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.error-message {
  color: var(--error-text);
  font-size: 0.875rem;
  margin-top: 1rem;
  text-align: center;
}

/* ==========================================================================
   Dashboard & Licenses List
   ========================================================================== */
.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
}

.feed-switch-link {
  margin: -1rem 0 1rem;
}

.feed-switch-link a {
  color: var(--primary-color);
  text-decoration: none;
  font-size: 0.9rem;
}

.feed-switch-link a:hover {
  text-decoration: underline;
}

/* Chrome extension callout at the top of every Add A Product page (see
   public/product*.html) - same subtle info-banner treatment as #banner.info,
   but its own class since #banner is already used per-page for dynamic
   status messages. */
.extension-promo-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: 0.9rem;
  color: var(--text-main);
}

.extension-promo-banner svg {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--primary-color);
}

.extension-promo-banner a {
  color: var(--primary-color);
  font-weight: 600;
  text-decoration: none;
}

.extension-promo-banner a:hover {
  text-decoration: underline;
}

.checklist-card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
}

.checklist-card h3 {
  margin-top: 0;
}

.checklist-group {
  margin-bottom: 1.5rem;
}

.checklist-group:last-child {
  margin-bottom: 0;
}

.checklist-group h4 {
  margin-bottom: 0.5rem;
}

.checklist-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0;
}

.checklist-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 2px solid var(--border-color);
  flex-shrink: 0;
  font-size: 0.7rem;
  line-height: 1;
  color: transparent;
}

.checklist-item.done .checklist-indicator {
  border-color: var(--primary-color);
  background: var(--primary-color);
  color: #fff;
}

.checklist-item.done .checklist-label {
  text-decoration: line-through;
}

.checklist-action {
  margin: 0 0 0.75rem 1.7rem;
  font-size: 0.9rem;
}

.license-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
  margin-top: 1rem;
}

.license-card {
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.license-card h4 {
  font-size: 1.1rem;
  margin-bottom: 0.5rem;
}

.license-key {
  font-family: monospace;
  background: var(--bg-color);
  padding: 0.5rem;
  border-radius: 4px;
  font-size: 0.9rem;
  color: var(--primary-color);
  word-break: break-all;
  margin: 0.75rem 0;
  border: 1px dashed var(--border-color);
}

/* Feed URL block, rendered inline inside a Subscriptions card (Settings) -
   forced to 100% width within the flex-wrap .settings-row so it wraps onto
   its own line instead of squeezing next to the row's other buttons. */
.feed-credential-block {
  flex: 1 1 100%;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border-color);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.feed-credential-block-label {
  font-weight: 600;
  width: 100%;
}

.feed-credential-block-content {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.feed-credential-details,
.feed-credential-reveal {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.feed-credential-reveal {
  margin-top: 0.5rem;
  padding: 0.75rem;
  background: var(--success-bg);
  border: 1px solid var(--success-text);
  border-radius: var(--radius);
}

/* min-width: 0 lets the license-key box actually shrink inside its flex
   row instead of overflowing - a common flexbox gotcha with long,
   word-break content like these URLs/tokens. */
.inline-row .license-key {
  flex: 1;
  margin: 0;
  min-width: 0;
}

.badge {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
}

.badge-active { background: var(--success-bg); color: var(--success-text); }
.badge-inactive { background: var(--error-bg); color: var(--error-text); }
.badge-warning { background: #fef3c7; color: #92400e; }
.badge-neutral { background: var(--border-color); color: var(--text-muted); }

.subscription-detail {
  display: block;
  width: 100%;
  margin-top: 0.35rem;
  font-size: 0.875rem;
}

/* ==========================================================================
   Pricing Page
   ========================================================================== */
.pricing-hero {
  text-align: center;
  margin-bottom: 2.5rem;
}

.pricing-hero h1 {
  font-size: 2rem;
  margin-bottom: 0.5rem;
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  justify-content: center;
  gap: 2rem;
  max-width: 920px;
  margin: 0 auto;
}

.pricing-card {
  background: var(--surface-color);
  border: 2px solid var(--primary-color);
  border-radius: var(--radius);
  padding: 2.5rem 2rem;
  box-shadow: var(--shadow);
  text-align: center;
  position: relative;
  width: 100%;
}

.pricing-badge {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--primary-color);
  color: #ffffff;
  padding: 0.25rem 0.75rem;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
}

.price-tag {
  font-size: 3rem;
  font-weight: 800;
  color: var(--text-main);
  margin: 1rem 0;
}

.price-tag span {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-muted);
}

.features-list {
  list-style: none;
  padding: 0;
  margin: 1.5rem 0 2rem;
  text-align: left;
}

.features-list li {
  position: relative;
  padding: 0.5rem 0 0.5rem 1.75rem;
  color: var(--text-main);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* Absolutely positioned rather than a flex sibling of the li's text - a flex
   row splits every text run and inline element (e.g. a link mid-sentence,
   like the Chrome extension bullets) into separate flex items instead of
   letting them wrap together as normal text, which broke multi-line bullets
   containing a link. This lets the text flow and wrap normally regardless of
   how many lines it takes, with the checkmark just pinned to the top-left. */
.features-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0.5rem;
  color: var(--primary-color);
  font-weight: bold;
}

.pricing-btn {
  display: block;
  text-decoration: none;
  text-align: center;
  line-height: 1.5;
}

.requirements-box {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
  text-align: left;
}

.requirements-title {
  font-weight: 600;
  color: var(--text-main);
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

.requirements-list {
  margin: 0 0 0.5rem;
  padding-left: 1.25rem;
  font-size: 0.88rem;
  color: var(--text-muted);
}

.requirements-list li {
  margin-bottom: 0.25rem;
}

.requirements-link {
  margin: 0 0 0.75rem;
  font-size: 0.85rem;
}

.requirements-checkbox {
  align-items: flex-start;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--text-main);
}

.requirements-checkbox input {
  margin-top: 0.2rem;
}

/* Pricing page-level Individual Platforms / Bundles switch - same visual
   treatment as .sample-tabs/.sample-tab-btn (public/sample.html), just its
   own class names since it lives above a different grid. */
.pricing-tabs {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 2rem;
}

.pricing-tab-btn {
  padding: 0.6rem 1.25rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--surface-color);
  color: var(--text-muted);
  font-weight: 600;
  cursor: pointer;
}

.pricing-tab-btn.active {
  background: var(--primary-color);
  border-color: var(--primary-color);
  color: #ffffff;
}

/* Manage Feed's per-catalog tab strip (public/js/manage-feed.js's
   renderCatalogTabs) - only shown when the user has more than one active
   product catalog to switch between. Same pill-tab visual language as
   .pricing-tab-btn above, but real <a> links (a normal page navigation to
   ?feed=<slug>, same as every other link in this app) rather than a
   JS-toggled panel switch. */
.catalog-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.catalog-tab {
  padding: 0.5rem 1rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--surface-color);
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
}

.catalog-tab:hover {
  border-color: var(--primary-color);
  color: var(--primary-color);
}

.catalog-tab.active {
  background: var(--primary-color);
  border-color: var(--primary-color);
  color: #ffffff;
  cursor: default;
}

/* public/sample.html's per-tab product name - kept identical to that
   platform's pricing.html card title (see the "Product Catalog Feed
   Builder" h3s there), so a visitor can tell at a glance that a given
   sample tab and pricing card are the same product. */
.sample-product-name {
  text-align: center;
  font-size: 1.4rem;
  margin: 0 0 1.5rem;
}

/* In-card Basic/Enhanced switch - a smaller, more compact segmented control
   than .pricing-tabs since it lives inside a single card rather than above
   the whole grid. Toggles which .tier-panel is visible within its own
   .pricing-card (see initTierToggles in public/js/pricing.js). */
.tier-toggle {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  margin: 0 0 1rem;
}

.tier-toggle-btn {
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: var(--bg-color);
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.82rem;
  cursor: pointer;
}

.tier-toggle-btn.active {
  background: var(--primary-color);
  border-color: var(--primary-color);
  color: #ffffff;
}

/* ==========================================================================
   Text Utilities
   ========================================================================== */
.text-muted {
  color: var(--text-muted);
}

.text-success {
  color: var(--success-text);
}

/* ==========================================================================
   Settings Page
   ========================================================================== */
.settings-section {
  margin-bottom: 1.5rem;
}

.settings-section h3 {
  margin-bottom: 1rem;
}

.settings-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.settings-row + .settings-row {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border-color);
}

.subscription-feature-label {
  width: 100%;
}

/* Catalog Overview's row (public/js/dashboard.js's loadCatalogOverview)
   reuses .settings-row's flex-wrap layout, but needs two specific break
   points: View/Edit pushed to the end of the "Last updated" line, and the
   "Last digested" line forced onto its own line after that rather than
   wrapping wherever it happens to fit. */
.catalog-overview-edit-link {
  margin-left: auto;
}

.catalog-overview-digest-line {
  flex-basis: 100%;
}

/* ==========================================================================
   Status Messages (success/error banners rendered inside page content,
   distinct from the #banner header alert)
   ========================================================================== */
.status-message {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-top: 1rem;
}

.status-success {
  background: var(--success-bg);
  color: var(--success-text);
  border: 1px solid var(--success-text);
}

.status-error {
  background: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.badge-label {
  margin-left: 0.75rem;
}

.action-spacing {
  margin-top: 1rem;
}

.status-row-action {
  margin-left: 1rem;
}

/* ==========================================================================
   Dashboard - Inactive Account Notice
   ========================================================================== */
.inactive-notice {
  font-size: 1.1rem;
  margin-bottom: 1.5rem;
}

.btn-purchase {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  background-color: var(--primary-color);
  color: #ffffff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  text-decoration: none;
}

.btn-purchase:hover {
  background-color: var(--primary-hover);
}

/* ==========================================================================
   Legal Pages (Privacy / Terms / Refund)
   ========================================================================== */
.legal-section {
  margin-bottom: 1.5rem;
}

.legal-notice {
  margin-top: 1.5rem;
}

.pricing-footnote {
  max-width: 920px;
  margin: 2rem auto 0;
  text-align: center;
  color: var(--text-muted);
}

.legal-list {
  margin-left: 1.5rem;
  margin-top: 0.5rem;
  color: var(--text-muted);
}

/* ==========================================================================
   Auth Pages (Login / Register / Forgot / Reset)
   ========================================================================== */
.auth-intro {
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.auth-link-row {
  margin-top: 1rem;
  text-align: center;
}

.auth-link-row-tight {
  margin-top: 0.5rem;
  text-align: center;
}

/* ==========================================================================
   Landing Page
   ========================================================================== */
.requirement-note {
  margin-top: 0.75rem;
}

.landing-container {
  display: flex;
  flex-direction: column;
  gap: 3.5rem;
}

/* Top-of-homepage explainer graphic (Chrome extension/Add a Product/Import
   From File -> Pin Data Connect -> Pinterest/Facebook/Google/Bing). No
   global img{max-width:100%} reset exists in this stylesheet, so this is
   scoped to just this image rather than added globally. */
.hero-diagram {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
  border-radius: 16px;
}

/* Hero */
.hero-section {
  text-align: center;
  padding: 3rem 1.5rem 2.5rem;
  background: linear-gradient(180deg, rgba(224, 65, 152, 0.08) 0%, rgba(224, 65, 152, 0) 100%);
  border-radius: 16px;
}

.hero-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(224, 65, 152, 0.12);
}

.hero-icon svg {
  width: 30px;
  height: 30px;
  stroke: var(--primary-color);
}

.hero-section h1 {
  font-size: 2.5rem;
  line-height: 1.15;
  margin-bottom: 1.25rem;
  color: var(--text-main);
}

.hero-tagline {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--primary-color);
  margin-bottom: 1.5rem;
}

.hero-subtitle {
  max-width: 680px;
  margin: 0 auto 1rem;
  color: var(--text-muted);
  font-size: 1.05rem;
}

.hero-subtitle strong {
  color: var(--text-main);
}

.trust-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 1.75rem;
  margin: 1.5rem 0 2rem;
}

.trust-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
}

.trust-item svg {
  width: 18px;
  height: 18px;
  stroke: var(--primary-color);
  flex-shrink: 0;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
}

.hero-btn {
  width: auto;
  padding: 0.85rem 1.75rem;
  font-size: 1rem;
}

/* Section headings */
.section-heading {
  text-align: center;
  font-size: 1.75rem;
  color: var(--text-main);
  margin-bottom: 0.5rem;
}

.section-subheading {
  text-align: center;
  color: var(--text-muted);
  max-width: 640px;
  margin: 0 auto 1.75rem;
}

/* Feature / step cards (shared with the Pinterest & Facebook landing pages) */
.features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem;
}

.feature-card {
  text-align: left;
  transition: transform 0.2s, box-shadow 0.2s;
}

.feature-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 24px -12px rgba(15, 23, 42, 0.18);
}

.feature-icon {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: rgba(224, 65, 152, 0.12);
  margin-bottom: 1rem;
}

.feature-icon svg {
  width: 22px;
  height: 22px;
  stroke: var(--primary-color);
}

.feature-card h3 {
  margin-bottom: 0.5rem;
  font-size: 1.05rem;
}

/* Platform cards */
.platform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.5rem;
}

.resources-footnote {
  text-align: center;
  margin-top: 2rem;
}

.platform-card {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}

.platform-card:hover {
  transform: translateY(-3px);
  border-color: var(--primary-color);
  box-shadow: 0 12px 24px -12px rgba(224, 65, 152, 0.3);
}

.platform-card h3 {
  margin-bottom: 0.5rem;
  font-size: 1.05rem;
  color: var(--text-main);
}

.platform-card-link {
  display: inline-block;
  margin-top: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--primary-color);
}

/* Combined plans callout */
.combined-callout {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  text-align: left;
}

.combined-callout .feature-icon {
  flex-shrink: 0;
  margin-bottom: 0;
  width: 56px;
  height: 56px;
  border-radius: 14px;
}

.combined-callout .feature-icon svg {
  width: 28px;
  height: 28px;
}

.combined-callout h3 {
  margin-bottom: 0.35rem;
}

/* Disclaimer banner (shared with the Pinterest & Facebook landing pages) */
.disclaimer-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  color: var(--text-muted);
  font-size: 0.875rem;
}

.disclaimer-banner svg {
  width: 20px;
  height: 20px;
  stroke: var(--text-muted);
  flex-shrink: 0;
  margin-top: 0.15rem;
}

.disclaimer-banner strong {
  color: var(--text-main);
}

@media (max-width: 640px) {
  .hero-section h1 {
    font-size: 1.9rem;
  }

  .combined-callout {
    flex-direction: column;
    text-align: center;
  }

  .combined-callout .feature-icon {
    margin: 0 auto;
  }
}

/* ==========================================================================
   Add Product Page
   ========================================================================== */
#status,
#csvFeedStatus,
#categoryStatus,
#submitStatus,
#importStatus,
#ticketStatus {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  font-weight: 500;
  overflow-wrap: break-word;
}
#status.loading, #csvFeedStatus.loading, #categoryStatus.loading, #submitStatus.loading, #importStatus.loading, #ticketStatus.loading { background: var(--surface-color); border: 1px solid var(--border-color); color: var(--text-main); }
#status.error, #csvFeedStatus.error, #categoryStatus.error, #submitStatus.error, #importStatus.error, #ticketStatus.error { background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-text); }
#status.success, #csvFeedStatus.success, #categoryStatus.success, #submitStatus.success, #importStatus.success, #ticketStatus.success { background: var(--success-bg); color: var(--success-text); border: 1px solid var(--success-text); }

select,
textarea {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: 1rem;
  font-family: inherit;
  outline: none;
  transition: border-color 0.2s;
  background: var(--surface-color);
  color: var(--text-main);
}
select:focus,
textarea:focus { border-color: var(--primary-color); }
textarea { resize: vertical; min-height: 5rem; }

input[readonly] {
  background: var(--border-color);
  color: var(--text-muted);
  cursor: not-allowed;
}

.field-hint {
  margin-top: 0.35rem;
  font-size: 0.8rem;
}

/* Spam honeypot (public/contact.html's Get Help form, checked in
   apis/supportApi.js) - hidden with position/size rather than
   display:none or type="hidden", which some spam bots are smart enough to
   skip; a real visitor tabbing through the form never lands on it either,
   since it's pulled out of the layout and off-screen. */
.honeypot-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.card-spaced {
  margin-top: 1.5rem;
}

/* ==========================================================================
   Product Preview (Sample) Page
   ========================================================================== */
.sample-tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.sample-tab-btn {
  padding: 0.6rem 1.25rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--surface-color);
  color: var(--text-muted);
  font-weight: 600;
  cursor: pointer;
}

.sample-tab-btn.active {
  background: var(--primary-color);
  border-color: var(--primary-color);
  color: #ffffff;
}

.csv-preview {
  overflow-x: auto;
  margin-top: 1rem;
  padding: 1rem;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  white-space: pre;
}

/* ==========================================================================
   Pixels Pro/Fine Art America Add Product Page
   ========================================================================== */
.pixels-checklist {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.5rem;
  max-height: 320px;
  overflow-y: auto;
  padding: 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

.pixels-checklist label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 400;
  font-size: 0.9rem;
}

.pixels-checklist input[type="checkbox"] {
  width: auto;
}

.review-item {
  display: grid;
  grid-template-columns: 1.1fr 1.8fr 0.8fr 1.6fr 1.3fr;
  gap: 0.5rem;
  align-items: center;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border-color);
}

/* Pixels-to-Facebook-combo review rows have both a custom label (Pinterest
   side) and a size (Facebook side, see functions/csvFbFunctions.js) column
   on top of the default 5, so they need a 6th column. */
.review-item.review-item-wide {
  grid-template-columns: 1fr 1.6fr 0.7fr 1.3fr 1.1fr 1fr;
}

.review-item:last-child { border-bottom: none; }

.pricing-row {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 0.5rem;
  align-items: center;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border-color);
}

.pricing-row:last-child { border-bottom: none; }

.pricing-row-label {
  font-weight: 600;
  font-size: 0.85rem;
}

.pricing-row input {
  font-size: 0.85rem;
}

.review-item-label {
  font-weight: 600;
  font-size: 0.85rem;
}

.review-item input {
  font-size: 0.85rem;
}

.category-field { position: relative; }

#categoryResults,
.category-results {
  position: absolute;
  z-index: 10;
  top: 100%;
  left: 0;
  right: 0;
  max-height: 280px;
  overflow-y: auto;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-top: 0.25rem;
}

.categoryItem {
  padding: 0.6rem 0.9rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  border-bottom: 1px solid var(--border-color);
}
.categoryItem:last-child { border-bottom: none; }
.categoryItem:hover { background: var(--border-color); }

.categoryPath { font-size: 0.9rem; color: var(--text-main); }
.categoryCode { font-size: 0.75rem; color: var(--text-muted); }

#selectedCategory,
.selected-category {
  margin-top: 0.5rem;
  padding: 0.6rem 0.9rem;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: 0.85rem;
}
#selectedCategory .text-muted,
.selected-category .text-muted { display: block; margin-top: 0.15rem; }

#newCatalogArea {
  margin-top: 0.5rem;
}
#newCatalogArea input { flex: 1; }
.inline-row { display: flex; gap: 0.5rem; align-items: center; }

.category-empty {
  padding: 10px;
}

/* Lets a wide, tall table (e.g. every CSV column across thousands of rows
   on the Manage Feed page) scroll in its own bounded viewport instead of
   overflowing the page. Capping the height (rather than just overflow-x)
   matters once there are enough rows to make the table taller than the
   screen - otherwise the horizontal scrollbar only exists at the very
   bottom of the whole table, which can be thousands of rows down and
   effectively unreachable. Bounding the height keeps both scrollbars (and
   the sticky header/first column below) within the initial viewport. */
.table-scroll {
  overflow: auto;
  max-height: 70vh;
}

/* Manage Feed page shows every CSV column - let the table size itself to
   its content (instead of .submissions-table's width:100% squeezing every
   column, including Actions, to fit) and scroll horizontally via
   .table-scroll above. */
#rowsTable {
  width: auto;
  min-width: 100%;
}

/* Field cells are capped and truncated with an ellipsis rather than
   wrapped - a long, unbroken value (a product URL, an image link) has no
   natural break point, so wrapping it either does nothing or (via
   word-break:break-word) erases the row's minimum content width and lets
   the auto table layout algorithm squeeze every column down to fit the
   container. The full value is still available via the title tooltip
   (see public/js/manage-feed.js) and in the edit panel. */
#rowsTable td {
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Merged Select-All + Actions column (see public/js/manage-feed.js) - one
   column holding both the row checkbox and Edit/Delete (or Save/Cancel)
   buttons, auto-sized to its content rather than a fixed width - a
   separate fixed-width checkbox-only column always left empty space on one
   side or the other, since a header wide enough for "Select All" is wider
   than a lone checkbox, no matter how that checkbox was aligned within it.
   Exempt from the truncation below so Edit/Delete/Save/Cancel render
   normally instead of being clipped. */
#rowsTable td:first-child,
#rowsTable th:first-child {
  max-width: none;
  overflow: visible;
  text-overflow: clip;
}

#rowsTable td:first-child .row-select-checkbox {
  margin-right: 0.5rem;
  vertical-align: middle;
}

.select-all-label {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  white-space: nowrap;
  cursor: pointer;
  font-weight: 600;
}

.select-all-label input[type="checkbox"] {
  width: auto;
}

/* The row currently being edited inline (see public/js/manage-feed.js
   buildInlineEditCell) needs the truncation above reset - otherwise its
   inputs/selects get clipped by the 280px max-width + overflow:hidden meant
   for read-only text, and the Google Product Category widget's dropdown
   (.category-results, position:absolute) would be cut off by its parent
   cell instead of overlaying the table. */
tr.row-editing td {
  max-width: none;
  overflow: visible;
  white-space: normal;
}

tr.row-editing td input,
tr.row-editing td select {
  width: 100%;
  min-width: 160px;
}

/* .btn-primary's width:100% (public/js/manage-feed.js's inline Save
   button reuses this class) is meant for a standalone full-width button -
   inside the actions cell it would fill the whole cell and push Cancel
   onto a wrapped line below it instead of sitting beside it. */
#rowsTable .btn-primary {
  width: auto;
}

/* Smaller than the default textarea size used elsewhere on the site - one
   editing table row with several textarea fields (description,
   description_html, etc. on Pinterest Feed Enhanced) shouldn't blow out
   the table's height. */
.inline-edit-textarea {
  min-width: 220px;
  height: 4.5rem;
}

/* Server-derived inline-edit fields (e.g. Google's product_type, always
   recomputed from google_product_category) - greyed out to signal a typed
   value won't stick, without needing a whole separate read-only cell type. */
.inline-edit-readonly {
  background: var(--bg-color);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* Manage Feed's pagination bar - First/Previous/[page-jump]/Next/Last, plus
   a total-products label. Wraps on narrow screens rather than overflowing,
   since a large catalog's page count can make "Page X of Y" fairly wide. */
.pagination-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

/* Manage Feed's bulk-action bar (public/js/manage-feed.js's
   renderBulkActionBar) - only shown once at least one row checkbox is
   selected. Same flex-wrap row treatment as .pagination-controls above. */
.bulk-action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-bottom: 1rem;
}

.pagination-jump {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
}

/* input[type=number] isn't covered by the site-wide text-input rule, and a
   page-jump field only needs to fit a handful of digits, not the full
   form-field width. */
.pagination-jump-input {
  width: 4.5rem;
  padding: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: 1rem;
  text-align: center;
}

.pagination-jump-input:focus {
  border-color: var(--primary-color);
  outline: none;
}

/* Header row stays pinned to the top of .table-scroll's bounded viewport
   while scrolling down through thousands of rows, and the merged Select-
   All/Actions column stays pinned to the left while scrolling right
   through every field - so a row can always be selected/edited/deleted
   without scrolling back. Both need an explicit opaque background so
   scrolled-past content doesn't show through underneath them. */
#rowsTable thead th {
  position: sticky;
  top: 0;
  background: var(--surface-color);
  z-index: 2;
}

#rowsTable td:first-child,
#rowsTable th:first-child {
  position: sticky;
  left: 0;
  background: var(--surface-color);
  z-index: 2;
}

#rowsTable thead th:first-child {
  z-index: 3;
}

.submissions-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
  font-size: 0.9rem;
}
/* The actions cell mixes .btn-primary (Save) with .btn-secondary (Edit/
   Delete/Cancel) - .btn-primary is width:100% everywhere else on the site
   (a standalone full-width form button), which inside a table cell instead
   stretches it to the cell's full width and pushes the button next to it
   onto its own line. flex + width:auto fixes that, but auto table layout
   still sizes this column from a flex container's shrunk min-content (~one
   button wide), so flex-wrap: wrap would just wrap the second button onto
   its own line again - min-width guarantees room for both buttons
   (nowrap), whichever pair is showing (Edit+Delete or Save+Cancel). */
.submissions-table td:first-child {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.5rem;
  min-width: 10rem;
}
.submissions-table td:first-child .btn-primary,
.submissions-table td:first-child .btn-secondary {
  width: auto;
}
.submissions-table th,
.submissions-table td {
  text-align: left;
  padding: 0.6rem 0.5rem;
  border-bottom: 1px solid var(--border-color);
}
.submissions-table th { color: var(--text-muted); font-weight: 600; font-size: 0.8rem; }

.status-badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}
.status-badge.SUCCESS, .status-badge.COMPLETED { background: var(--success-bg); color: var(--success-text); }
.status-badge.FAILURE, .status-badge.FAILED { background: var(--error-bg); color: var(--error-text); }
.status-badge.PROCESSING { background: var(--surface-color); color: var(--text-muted); border: 1px solid var(--border-color); }

.item-errors {
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--error-text);
}

/* ==========================================================================
   Pinterest Setup Page
   ========================================================================== */
.setup-container {
  max-width: 760px;
  margin: 0 auto;
  padding: 1.25rem;
}
.setup-card {
  background: var(--surface-color);
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: var(--shadow);
  margin-bottom: 1.25rem;
}
.setup-card h2 {
  margin-top: 0;
  color: var(--text-main);
  font-size: 1.6rem;
}
.setup-card h3 {
  margin-top: 1rem;
}
.setup-card p {
  color: var(--text-muted);
  line-height: 1.5;
  margin: 0.6rem 0;
}
.setup-note {
  font-size: 0.9rem;
}
.setup-note-muted {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-top: 0.75rem;
}
.troubleshoot-list {
  color: var(--text-muted);
}
.benefit-list {
  list-style: none;
  padding-left: 0;
  margin: 0.75rem 0;
}
.benefit-list li {
  padding: 0.4rem 0;
  padding-left: 1.5rem;
  position: relative;
  color: #555;
}
.benefit-list li:before {
  content: "✓";
  position: absolute;
  left: 0;
  color: #28a745;
  font-weight: bold;
}
.button-group {
  display: flex;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.25rem;
  flex-wrap: wrap;
}
/* Scoped to .setup-card so these don't collide with the global header's
   Dashboard/Settings/Log Out buttons, which also use .btn-primary/.btn-secondary */
.setup-card .btn-primary {
  flex: 0 1 auto;
  min-width: 200px;
  padding: 1rem 1.5rem;
  font-size: 1rem;
  background: #e60023;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.3s;
}
.setup-card .btn-primary:hover {
  background: #c40019;
}
.setup-card .btn-secondary {
  flex: 1;
  min-width: 200px;
  padding: 1rem 1.5rem;
  font-size: 1rem;
  background: #f0f0f0;
  color: #333;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.3s;
}
.setup-card .btn-secondary:hover {
  background: #e8e8e8;
}
.setup-loading {
  text-align: center;
  padding: 2rem;
}
.setup-spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #e60023;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: setup-spin 1s linear infinite;
  margin: 0 auto 1rem;
}
@keyframes setup-spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* ==========================================================================
   Meet the Founder Page
   ========================================================================== */
.founder-hero {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}

.founder-photo-wrap {
  flex-shrink: 0;
}

.founder-photo {
  display: block;
  width: 260px;
  height: 385px;
  object-fit: cover;
  border-radius: 16px;
  box-shadow: var(--shadow);
}

.founder-intro h1 {
  font-size: 2rem;
  color: var(--text-main);
  margin-bottom: 0.25rem;
}

.founder-role {
  color: var(--primary-color);
  font-weight: 600;
  margin-bottom: 0.85rem;
}

.founder-tagline {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--text-main);
  margin-bottom: 0.85rem;
}

.founder-trust-row {
  justify-content: flex-start;
  margin: 1.25rem 0 0;
}

.founder-thesis {
  text-align: center;
  max-width: 640px;
  margin: 0 auto;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text-main);
}

.founder-paragraph-spaced {
  margin-top: 1rem;
}

.mission-banner {
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  background: rgba(224, 65, 152, 0.08);
  border: 1px solid rgba(224, 65, 152, 0.25);
  border-radius: var(--radius);
  padding: 1.25rem 1.75rem;
  color: var(--text-main);
  font-size: 1.1rem;
  font-weight: 600;
}

.skill-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}

.skill-group h4 {
  margin-bottom: 0.85rem;
  color: var(--text-main);
}

.skill-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.skill-tag {
  background: rgba(224, 65, 152, 0.08);
  color: var(--primary-color);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  white-space: nowrap;
}

.process-steps {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 560px;
  margin: 0 auto 1.5rem;
}

.process-step {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: var(--surface-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 0.85rem 1.25rem;
}

.process-step-number {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--primary-color);
  color: #ffffff;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.process-step-text {
  color: var(--text-main);
  font-weight: 600;
}

.emoji-list {
  list-style: none;
  padding: 0;
  margin: 1.5rem auto;
  max-width: 560px;
  text-align: left;
}

.emoji-list li {
  padding: 0.5rem 0;
  color: var(--text-main);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.95rem;
}

.emoji-list-icon {
  flex-shrink: 0;
  font-size: 1.1rem;
}

.founder-quote {
  max-width: 720px;
  margin: 0 auto;
  border-left: 4px solid var(--primary-color);
  background: var(--surface-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.75rem 2rem;
}

.founder-quote p {
  font-size: 1.1rem;
  font-style: italic;
  color: var(--text-main);
  line-height: 1.6;
}

.founder-quote cite {
  display: block;
  margin-top: 1.25rem;
  font-style: normal;
  font-weight: 600;
  color: var(--primary-color);
  font-size: 0.95rem;
}

@media (max-width: 640px) {
  .founder-hero {
    flex-direction: column;
    text-align: center;
  }

  .founder-photo {
    width: 220px;
    height: 326px;
    margin: 0 auto;
  }

  .founder-trust-row {
    justify-content: center;
  }
}

/* ==========================================================================
   Compare Plans Page
   ========================================================================== */
.compare-container {
  max-width: 1100px;
}

/* Bounded height (not just overflow-x) so the header row's sticky
   positioning below has a scrolling viewport to stick within, and so the
   table doesn't push the rest of the page down as more comparison rows are
   added - same approach as .table-scroll on Manage Feed. */
.compare-scroll {
  overflow: auto;
  max-height: 70vh;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--surface-color);
}

.compare-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.compare-table th,
.compare-table td {
  padding: 0.75rem 1rem;
  text-align: center;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-color);
}

/* Stays pinned to the top of .compare-scroll's bounded viewport while
   scrolling down through the feature rows, so the plan a column belongs to
   is always visible - needs its own opaque background so scrolled-past
   rows don't show through underneath it. */
.compare-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-color);
  color: var(--text-main);
  font-weight: 700;
  vertical-align: bottom;
}

.compare-table thead th a {
  color: var(--text-main);
  text-decoration: none;
}

.compare-table thead th a:hover {
  color: var(--primary-color);
  text-decoration: underline;
}

/* Row-label column stays put while the rest of the table scrolls
   horizontally, so a reader always knows which feature a given column of
   checkmarks refers to - matters here since there are 7 plan columns. */
.compare-row-label,
.compare-table thead th.compare-row-label {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface-color);
  text-align: left;
  white-space: normal;
  min-width: 220px;
  font-weight: 600;
  color: var(--text-main);
}

/* The corner cell is sticky on both axes (left, from the rule above, and
   top, from .compare-table thead th above) - highest z-index so it stays
   above both the sticky header row and the sticky row-label column as the
   table scrolls in either direction. */
.compare-table thead th.compare-row-label {
  background: var(--bg-color);
  z-index: 3;
}

.compare-section-row td {
  background: rgba(224, 65, 152, 0.06);
  color: var(--primary-color);
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  position: sticky;
  left: 0;
}

.compare-yes {
  color: var(--primary-color);
  font-weight: 700;
  font-size: 1.1rem;
}

.compare-no {
  color: var(--border-color);
}

.compare-footnote {
  max-width: 720px;
  margin: 1.5rem auto 0;
  text-align: center;
}

@media (max-width: 640px) {
  .compare-row-label {
    min-width: 160px;
  }
}

/* ==========================================================================
   Cookie Consent Banner (public/js/cookieConsent.js) - GDPR-style opt-in
   gate shown on public marketing/account pages before Google Analytics
   loads. Never present on the logged-in product catalog application, since
   that script is only included on the pages listed in the Privacy Policy's
   Cookies & Analytics section.
   ========================================================================== */
.cookie-consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem;
  background: var(--surface-color);
  border-top: 1px solid var(--border-color);
  box-shadow: var(--shadow);
}

.cookie-consent-message {
  flex: 1 1 320px;
  color: var(--text-main);
  font-size: 0.9rem;
  line-height: 1.5;
}

.cookie-consent-message a {
  color: var(--primary-color);
}

.cookie-consent-actions {
  display: flex;
  gap: 0.75rem;
  flex-shrink: 0;
}

.cookie-consent-actions .btn-primary,
.cookie-consent-actions .btn-secondary {
  width: auto;
  padding: 0.6rem 1.25rem;
}

.cookie-settings-link {
  position: fixed;
  left: 1rem;
  bottom: 1rem;
  z-index: 999;
  padding: 0.4rem 0.85rem;
  background: var(--surface-color);
  color: var(--text-muted);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-size: 0.75rem;
  cursor: pointer;
}

.cookie-settings-link:hover {
  color: var(--text-main);
  border-color: var(--primary-color);
}

/* Lightweight stand-in for Tawk.to's own chat bubble (see
   public/js/cookieConsent.js's showChatLauncher) - costs nothing until
   clicked, unlike loading Tawk.to's real widget eagerly on every page. */
.chat-launcher-btn {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 999;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--primary-color);
  color: #fff;
  border: none;
  box-shadow: var(--shadow);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.chat-launcher-btn:hover {
  background: var(--primary-hover);
}

.chat-launcher-btn svg {
  width: 26px;
  height: 26px;
}

/* ==========================================================================
   Branded Modal (public/js/common.js's confirmModal/alertModal) - replaces
   window.confirm()/window.alert(), which can't be styled at all.
   ========================================================================== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  padding: 1rem;
}

.modal-box {
  background: var(--surface-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  max-width: 420px;
  width: 100%;
  padding: 1.5rem;
}

.modal-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 2px solid var(--primary-color);
}

.modal-icon {
  width: 24px;
  height: 24px;
}

.modal-brand {
  font-weight: 700;
  color: var(--primary-color);
  font-size: 1rem;
}

.modal-message {
  color: var(--text-main);
  line-height: 1.5;
  margin-bottom: 1.5rem;
  white-space: pre-wrap;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
}

.modal-actions .btn-secondary,
.modal-actions .btn-primary-sm,
.modal-actions .btn-danger {
  width: auto;
}

/* Manage Feed's bulk-edit modal (public/js/manage-feed.js's
   openBulkEditModal) reuses the .modal-box/.modal-header/.modal-actions
   structure above, but needs more width than a plain confirm/alert message
   to comfortably fit a field list. */
.modal-box-wide {
  max-width: 520px;
}

.bulk-edit-fields {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.bulk-edit-field-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* Each row's "apply this field" checkbox + label - a field's input/select
   stays disabled (see openBulkEditModal) until this is checked, so an
   unchecked field can never accidentally get overwritten with a blank
   value. Fixed width (not min-width) so every row's checkbox sits in the
   same left-aligned column AND every row's input starts at the same x
   position too - a longer label (e.g. "Custom Label (optional)") used to
   grow past min-width and push just that row's input further right than
   the others. */
.bulk-edit-field-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
  width: 190px;
}

/* flex:none overrides .bulk-edit-field-row input's flex:1 below, which
   otherwise also matches this checkbox (a descendant selector, not scoped
   to just the value input) - without it, flex-basis:0%/flex-grow:1 stretch
   the checkbox's own layout box to fill most of the toggle's width,
   pushing its label text far off to the right. */
.bulk-edit-field-toggle input[type="checkbox"] {
  flex: none;
  width: auto;
}

.bulk-edit-field-row input,
.bulk-edit-field-row select {
  flex: 1;
  width: auto;
}

/* Price's amount input + fixed currency suffix (see openBulkEditModal) -
   the currency itself is never typed, just shown as plain text pulled from
   the seller's own Settings currency, so it lines up next to the amount
   input like a unit label rather than a second editable field. */
.bulk-edit-price-wrap {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 1;
}

.bulk-edit-price-wrap input {
  flex: 1;
  width: auto;
}

.bulk-edit-currency-suffix {
  color: var(--text-muted);
  font-weight: 600;
  flex-shrink: 0;
}

/* Price's format hint (see openBulkEditModal) - indented to start under the
   value input instead of under the checkbox column, matching the toggle's
   fixed width + row gap above exactly. */
.bulk-edit-hint {
  margin-left: calc(190px + 0.75rem);
}

.modal-error {
  color: var(--error-text);
  font-size: 0.875rem;
  margin: -0.5rem 0 1rem;
}

@media (max-width: 640px) {
  .cookie-consent-banner {
    flex-direction: column;
    align-items: stretch;
  }

  .cookie-consent-actions {
    justify-content: flex-end;
  }
}