/* =========================================================================
   Raymon — Design System
   Dark, glass-surfaced, RTL-first. Every screen (site, user panel, admin
   panel) is built from the tokens and primitives defined here.
   ========================================================================= */

/* Self-hosted fonts: this app is entirely Persian-audience, and Google's
   font CDN (fonts.googleapis.com/fonts.gstatic.com) is frequently slow or
   unreachable from Iran. Every page here is a full server-rendered
   navigation (no SPA routing), so a render-blocking <link> to an external,
   unreliable stylesheet meant every single click could hang for seconds —
   this is that exact stylesheet's @font-face rules, vendored locally so
   navigation never depends on a third-party CDN being reachable. Both
   families ship as variable fonts, so one file per script covers every
   weight (400-800 for Vazirmatn, 400-700 for JetBrains Mono) — no per-weight
   files needed. */
@font-face {
  font-family: "Vazirmatn";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/vazirmatn-arabic.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC, U+200C-200E;
}
@font-face {
  font-family: "Vazirmatn";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/vazirmatn-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+2000-206F, U+2122, U+2191, U+2193, U+2212;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+2000-206F, U+2122, U+2191, U+2193, U+2212;
}

:root {
  /* --- Color: base --- */
  --bg: #0b1320;
  --bg-elevated: #0d1424;
  --bg-soft: #111a2e;
  --vignette: linear-gradient(180deg, #17304f 0%, #0d1a2c 32%, var(--bg) 55%);

  --surface: rgba(255, 255, 255, 0.065);
  --surface-2: rgba(255, 255, 255, 0.1);
  --surface-hover: rgba(255, 255, 255, 0.13);
  --border: rgba(255, 255, 255, 0.11);
  --border-strong: rgba(255, 255, 255, 0.2);

  --text: #eef1f8;
  --text-muted: #93a0b8;
  --text-faint: #5c6786;

  /* --- Color: accents --- */
  --accent: #dcb679;         /* warm gold — CTA / highlight copy */
  --accent-soft: rgba(220, 182, 121, 0.14);
  --accent-border: rgba(220, 182, 121, 0.35);
  --accent-ink: #12100a;

  --accent-2: #8bc74b;       /* lime green — active states / secondary accent */
  --accent-2-soft: rgba(139, 199, 75, 0.14);
  --accent-2-border: rgba(139, 199, 75, 0.35);

  --btn-light: #c3c9d9;      /* light lavender-grey — primary CTA fill on the marketing site */
  --btn-light-hover: #d4d9e6;

  --danger: #e08585;

  /* --- Type --- */
  --font-display: "Vazirmatn", system-ui, sans-serif;
  --font-body: "Vazirmatn", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* --- Layout --- */
  --container: 1160px;
  --radius-sm: 10px;
  --radius-md: 16px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  --shadow-soft: 0 20px 60px -25px rgba(0, 0, 0, 0.55);
  --shadow-lift: 0 24px 70px -20px rgba(0, 0, 0, 0.6);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 0.18s;
  --dur: 0.35s;
  --dur-slow: 0.7s;

  --header-h: 104px;
}

/* =========================================================================
   Reset
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  direction: rtl;
  /* Belt-and-suspenders on top of the viewport meta tag: some mobile
     browsers still allow double-tap-to-zoom even with user-scalable=no. */
  touch-action: manipulation;
  /* <body> paints the real gradient, but mobile rubber-band overscroll
     (pulling past the top/bottom edge) reveals whatever's behind it — the
     <html> background, which without this was the browser default (white),
     flashing a mismatched color at the top of the screen. Match the app's
     base tone so an overscroll bounce blends in instead of standing out. */
  background: var(--bg);
}
body {
  background: var(--vignette), var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  overflow-x: hidden;
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4, p { margin: 0; }
::selection { background: var(--accent-soft); color: var(--accent); }

h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 700;
  text-wrap: balance;
}

.ltr { direction: ltr; unicode-bidi: isolate; font-family: var(--font-mono); }

.visually-hidden-focusable {
  position: absolute; right: 12px; top: -60px; z-index: 300;
  background: var(--accent-2); color: var(--accent-ink);
  padding: 10px 18px; border-radius: var(--radius-sm); font-size: 13.5px; font-weight: 600;
  transition: top var(--dur-fast) var(--ease);
}
.visually-hidden-focusable:focus { top: 12px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.idea-error, .field-validation-error { color: var(--danger); font-size: 12.5px; margin-top: 6px; display: block; }
input.input-validation-error, textarea.input-validation-error { border-color: var(--danger) !important; }

/* =========================================================================
   Layout helpers
   ========================================================================= */
.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 20px;
}
.section { padding-top: 10px; padding-bottom: 64px; }
@media (min-width: 768px) { .section { padding-top: 10px; padding-bottom: 96px; } }

/* Neon glow: every marketing-page section title glows in whatever color it
   already is (currentColor), so the plain white headings get a soft white
   halo and the accent-colored ones (e.g. the idea-card title) glow in their
   own brand color — no per-section color bookkeeping needed. Strength is a
   0-1 multiplier the admin controls from /Admin/Settings (inlined as
   --neon-scale by _Layout); the fallback here only applies if that inline
   style is ever missing. */
:root { --neon-scale: 0.4; }
.section-head h2,
.section-head-row h2,
.portfolio-head h2,
.idea-toggle h2 {
  text-shadow:
    0 0 calc(6px * var(--neon-scale)) currentColor,
    0 0 calc(18px * var(--neon-scale)) currentColor,
    0 0 calc(40px * var(--neon-scale)) currentColor;
}

.section-head { text-align: right; margin-bottom: 32px; }
.section-head h2 { font-size: clamp(22px, 3vw, 28px); }
.section-head p { color: var(--text-muted); max-width: 520px; font-size: 15px; }

.section-head-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 24px;
}
.section-head-row h2 { font-size: clamp(22px, 3vw, 28px); }

.portfolio-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px 20px;
  margin-bottom: 24px;
}
.portfolio-head h2 { font-size: clamp(22px, 3vw, 28px); }
.portfolio-head .tabs { min-width: 0; }
.carousel-arrow {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border-strong);
  color: var(--text-muted); cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.carousel-arrow:hover { color: var(--text); border-color: var(--accent-2-border); }
.carousel-arrow svg { width: 18px; height: 18px; }

/* =========================================================================
   Glass primitives
   ========================================================================= */
.glass {
  background: linear-gradient(180deg, var(--surface), rgba(255, 255, 255, 0.015));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(30px) saturate(165%);
  -webkit-backdrop-filter: blur(30px) saturate(165%);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
  /* Safari/WebKit has a long-standing bug where backdrop-filter + overflow:
     hidden + border-radius on the same element stops clipping its content
     (content quietly pokes out past the rounded corners on iOS specifically).
     A no-op mask forces it into a compositing path that clips correctly. */
  -webkit-mask-image: -webkit-radial-gradient(white, black);
}
.glass-interactive:hover {
  border-color: var(--border-strong);
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  background: linear-gradient(180deg, var(--surface-2), rgba(255, 255, 255, 0.02));
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 14.5px;
  padding: 13px 26px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: linear-gradient(135deg, var(--accent-2), #8fbf6a);
  color: var(--accent-ink);
  box-shadow: 0 10px 30px -12px rgba(169, 201, 126, 0.55);
}
.btn-primary:hover { box-shadow: 0 14px 36px -12px rgba(169, 201, 126, 0.7); transform: translateY(-2px); }
.btn-ghost {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-ghost:hover { background: var(--surface-2); border-color: var(--accent-2-border); }
.btn-light {
  background: var(--btn-light);
  color: #16202f;
  box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.5);
}
.btn-light:hover { background: var(--btn-light-hover); transform: translateY(-2px); }
.btn-outline {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.4);
  color: var(--text);
}
.btn-outline:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.6); }
.btn-block { width: 100%; }

/* =========================================================================
   Header — desktop only: a floating centered glass pill mirroring the
   mobile bottom tab bar's visual language (same brand mark, same icon
   items) instead of a traditional full-width bar. Hidden on mobile, where
   the floating bottom tab bar is the sole nav.
   ========================================================================= */
.brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.brand .mark {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--accent-2-soft), var(--accent-soft));
  border: 1px solid var(--border-strong);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent-2);
}

.header-icons { display: flex; align-items: center; gap: 12px; }
.icon-btn {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border);
  backdrop-filter: blur(20px) saturate(150%); -webkit-backdrop-filter: blur(20px) saturate(150%);
  color: var(--text-muted); cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.icon-btn:hover { color: var(--text); border-color: var(--border-strong); }
.icon-btn svg { width: 18px; height: 18px; }

.desktop-topbar { display: none; }
@media (min-width: 900px) {
  .desktop-topbar {
    position: fixed; top: 18px; left: 50%; transform: translateX(-50%);
    z-index: 100;
    display: flex; align-items: center; gap: 6px;
    padding: 8px 8px 8px 20px;
    border-radius: var(--radius-pill);
    background: rgba(17, 26, 46, 0.55);
    border: 1px solid var(--border-strong);
    backdrop-filter: blur(30px) saturate(170%); -webkit-backdrop-filter: blur(30px) saturate(170%);
    box-shadow: var(--shadow-lift);
  }
}
.desktop-topbar-links {
  display: flex; align-items: center; gap: 26px;
  font-size: 14px; color: var(--text-muted);
  padding-inline: 22px;
  border-inline-end: 1px solid var(--border);
}
.desktop-topbar-links a { position: relative; padding: 6px 0; white-space: nowrap; transition: color var(--dur-fast) var(--ease); }
.desktop-topbar-links a:hover, .desktop-topbar-links a.active { color: var(--text); }
.desktop-topbar-links a.active::after {
  content: ""; position: absolute; right: 0; left: 0; bottom: -4px; height: 2px;
  background: var(--accent-2); border-radius: 2px;
}
.desktop-topbar-icons { display: flex; align-items: center; gap: 8px; padding-inline-start: 4px; }

/* Bottom floating pill tab bar (mobile only, app-like primary nav) */
.mobile-tabbar {
  position: fixed;
  left: 16px; right: 16px;
  bottom: calc(14px + env(safe-area-inset-bottom));
  z-index: 90;
  max-width: 220px;
  margin: 0 auto;
  display: flex; align-items: center; justify-content: space-around;
  background: rgba(17, 26, 46, 0.52);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  backdrop-filter: blur(32px) saturate(170%);
  -webkit-backdrop-filter: blur(32px) saturate(170%);
  box-shadow: var(--shadow-lift);
  padding: 8px;
}
.mobile-tabbar.has-4 { max-width: 280px; }
.mobile-tabbar.has-5 { max-width: 340px; }
.mobile-tabbar a {
  flex: 1; display: flex; align-items: center; justify-content: center;
  height: 46px; border: none; background: none;
  color: var(--text-muted); cursor: pointer;
}
.mobile-tabbar a svg { width: 21px; height: 21px; }
.mobile-tabbar a:active .nav-circle { transform: scale(0.88); }
@media (min-width: 900px) { .mobile-tabbar { display: none; } }

/* Shared active-tab indicator: a true circle sized to the icon, not the
   whole (wider) flex cell, so it pops in as a real dot instead of a pill. */
.nav-circle {
  position: relative;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
a.active .nav-circle {
  background: var(--accent-2); color: var(--accent-ink);
  animation: nav-circle-pop 0.35s var(--ease);
}
@keyframes nav-circle-pop {
  from { transform: scale(0.5); opacity: 0.5; }
  to { transform: scale(1); opacity: 1; }
}
@media (max-width: 899px) { body.site-body { padding-bottom: calc(84px + env(safe-area-inset-bottom)); } }

/* =========================================================================
   Hero
   ========================================================================= */
.hero { position: relative; overflow: hidden; text-align: center; }
.hero-img { width: 100%; max-width: 800px; height: auto; display: inline-block; }

@keyframes float-bot { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }

/* =========================================================================
   Services
   ========================================================================= */
.services-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
@media (min-width: 640px) { .services-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 980px) { .services-grid { grid-template-columns: repeat(5, 1fr); gap: 10px; } }

.service-card {
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  cursor: default;
}
/* No card/box behind the icon at all — just the icon itself, bigger, with
   the label sitting close beneath it directly on the page background. */
.service-icon {
  width: 100%;
  aspect-ratio: 1 / 1;
  max-width: 150px;
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--dur) var(--ease);
}
.service-icon img { width: 100%; height: 100%; object-fit: contain; }
.service-card:hover .service-icon { transform: scale(1.05); }
.service-card h3 { font-size: 13.5px; font-weight: 600; }

/* =========================================================================
   CTA banner
   ========================================================================= */
.cta-banner {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  min-height: 260px;
  display: flex;
  align-items: center;
}
.cta-banner .cta-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
}
.cta-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to left, transparent 40%, rgba(6, 10, 20, 0.65) 78%);
}
.cta-content { position: relative; z-index: 2; padding: 40px 32px; max-width: 560px; margin-inline-start: auto; }
.cta-banner h3 {
  font-size: clamp(19px, 2.6vw, 25px);
  color: var(--text);
  margin-bottom: 20px;
}
.cta-actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* The left/right overlay fade is tuned for the wide desktop crop; on a
   narrow banner the see-through zone lands right under the text and the
   art behind it (the swing rope) fights for contrast. Below that width,
   darken the full banner from the bottom instead. */
@media (max-width: 640px) {
  .cta-overlay {
    background: linear-gradient(180deg, rgba(6, 10, 20, 0.12) 0%, rgba(6, 10, 20, 0.58) 42%, rgba(6, 10, 20, 0.88) 74%, rgba(6, 10, 20, 0.94) 100%);
  }
  .cta-content { max-width: 90%; }
}

/* =========================================================================
   Portfolio / Showcase
   ========================================================================= */
.tabs {
  display: flex;
  align-items: center;
  gap: 10px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.tabs::-webkit-scrollbar { display: none; }
.tab-btn {
  flex-shrink: 0;
  padding: 8px 16px;
  font-size: 13.5px;
  color: var(--text-muted);
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.tab-btn:hover { color: var(--text); border-color: var(--accent-2-border); background: var(--surface-2); transform: translateY(-2px); }
.tab-btn:active { transform: scale(0.94); }
.tab-btn.active {
  color: var(--accent-ink); background: var(--accent-2); border-color: var(--accent-2);
  box-shadow: 0 8px 20px -10px rgba(139, 199, 75, 0.55);
}

.portfolio-track {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 20px 2px 8px;
  margin: 0 -2px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.portfolio-track::-webkit-scrollbar { display: none; }

.work-card {
  flex: 0 0 78%;
  scroll-snap-align: start;
  overflow: hidden;
}
@media (min-width: 560px) { .work-card { flex-basis: 46%; } }
@media (min-width: 900px) { .work-card { flex-basis: 23%; } }

.work-thumb {
  aspect-ratio: 4 / 3;
  background: linear-gradient(150deg, var(--bg-soft), var(--bg-elevated));
  position: relative;
  overflow: hidden;
}
.work-thumb svg, .work-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.work-body { padding: 16px 18px 20px; }
.work-body h4 { font-size: 15px; margin-bottom: 6px; }
.work-meta { font-size: 12px; color: var(--text-faint); font-family: var(--font-mono); }

/* =========================================================================
   Tech strip
   ========================================================================= */
.tech-strip {
  overflow-x: auto;
  overflow-y: hidden;
  cursor: grab;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 6%, black 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 6%, black 94%, transparent);
  -webkit-user-select: none;
  user-select: none;
}
.tech-strip::-webkit-scrollbar { display: none; }
.tech-strip.dragging { cursor: grabbing; scroll-behavior: auto; }
.tech-track {
  display: flex;
  width: max-content;
  gap: 10px;
}
.tech-chip {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 18px 9px 9px;
  font-size: 14px; color: var(--text);
  white-space: nowrap;
  flex-shrink: 0;
}
.tech-chip svg { width: 26px; height: 26px; flex-shrink: 0; }

/* =========================================================================
   Idea card
   ========================================================================= */
.idea-card { padding: 34px 26px; }
.idea-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  width: 100%; cursor: pointer; list-style: none;
  background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit; text-align: right;
  -webkit-tap-highlight-color: transparent;
}
.idea-toggle:focus-visible {
  outline: 2px solid var(--accent-2-border); outline-offset: 6px; border-radius: 10px;
}
.idea-toggle h2 { color: var(--accent-2); font-size: clamp(20px, 3vw, 25px); margin: 0; }
.idea-toggle-icon {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border-strong); color: var(--accent-2);
  transition: transform var(--dur) var(--ease), background var(--dur-fast) var(--ease);
}
.idea-toggle-icon svg { width: 18px; height: 18px; }
.idea-toggle:hover .idea-toggle-icon { background: var(--surface-2); }
.idea-toggle[aria-expanded="true"] .idea-toggle-icon { transform: rotate(180deg); }

/* Smooth expand/collapse without native <details> (no reliable open/close
   transition cross-browser) — animate the implicit grid row track instead. */
.idea-collapse {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur) var(--ease);
}
.idea-collapse.open { grid-template-rows: 1fr; }
.idea-collapse-inner { overflow: hidden; min-height: 0; }

/* Same collapse-by-grid-row trick as .idea-collapse above, generically named
   for any "button reveals a form" spot (e.g. the new-ticket form). */
.collapse-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur) var(--ease); }
.collapse-panel.open { grid-template-rows: 1fr; }
.collapse-panel-inner { overflow: hidden; min-height: 0; padding-top: 20px; }

.idea-body { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--border); }
.idea-body > p { color: var(--text-muted); font-size: 14px; max-width: 640px; margin-bottom: 20px; }
.idea-form { display: flex; flex-direction: column; gap: 12px; }

.field { display: flex; flex-direction: column; }
.field textarea, .field input {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  padding: 14px 16px;
  resize: none;
  transition: border-color var(--dur-fast) var(--ease);
}
.field textarea { min-height: 96px; }
.field textarea:focus, .field input:focus { outline: none; border-color: var(--accent-2-border); }

.custom-section-editor {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 1fr);
  gap: 18px;
  margin-top: 16px;
  align-items: start;
}
.custom-section-boxes { display: flex; flex-direction: column; gap: 14px; }
.custom-section-code { font-family: var(--font-mono, monospace); font-size: 13px; min-height: 160px; resize: vertical; }
.custom-section-preview-pane { position: sticky; top: 18px; }
.custom-section-preview-frame {
  width: 100%;
  height: 420px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #fff;
}
@media (max-width: 900px) {
  .custom-section-editor { grid-template-columns: 1fr; }
  .custom-section-preview-pane { position: static; }
}

.field input[type="range"] {
  -webkit-appearance: none; appearance: none;
  background: transparent; border: none; padding: 12px 0; cursor: pointer;
}
.field input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 999px; background: var(--surface-2);
}
.field input[type="range"]::-moz-range-track {
  height: 6px; border-radius: 999px; background: var(--surface-2);
}
.field input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; margin-top: -7px;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent-2); border: 3px solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent-2-border);
}
.field input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%; border: 3px solid var(--bg);
  background: var(--accent-2); box-shadow: 0 0 0 1px var(--accent-2-border);
}

.neon-preview-box {
  margin-top: 18px; padding: 28px; text-align: center;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
}
#neonPreviewTitle {
  color: var(--accent-2); font-size: 22px; font-weight: 800;
  text-shadow:
    0 0 calc(6px * var(--neon-scale, 1)) currentColor,
    0 0 calc(18px * var(--neon-scale, 1)) currentColor,
    0 0 calc(40px * var(--neon-scale, 1)) currentColor;
}
.idea-success { display: none; align-items: center; gap: 10px; color: var(--accent-2); font-size: 13.5px; margin-top: 12px; }
.idea-success.show { display: flex; }

.chat-color-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 14px; }
.chat-color-fields .field label { font-size: 13px; color: var(--text-muted); margin-bottom: 6px; }
.field input[type="color"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 42px; padding: 3px; border-radius: var(--radius-md);
  background: var(--bg); border: 1px solid var(--border); cursor: pointer;
}
.field input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.field input[type="color"]::-webkit-color-swatch { border: none; border-radius: calc(var(--radius-md) - 3px); }
.field input[type="color"]::-moz-color-swatch { border: none; border-radius: calc(var(--radius-md) - 3px); }

.chat-preview-box {
  margin-top: 14px; padding: 20px 16px; display: flex; flex-direction: column; gap: 10px;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.chat-preview-box .chat-bubble { max-width: 78%; border-radius: 16px; padding: 10px 14px; font-size: 14px; transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease); }
.chat-preview-box .chat-bubble p { margin: 0; }

/* =========================================================================
   Magazine carousel
   ========================================================================= */
.mag-track {
  display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x proximity;
  padding: 20px 2px 8px; margin: 0 -2px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.mag-track::-webkit-scrollbar { display: none; }
.mag-card { flex: 0 0 72%; scroll-snap-align: start; overflow: hidden; }
@media (min-width: 560px) { .mag-card { flex-basis: 44%; } }
@media (min-width: 900px) { .mag-card { flex-basis: 23%; } }
.mag-thumb { aspect-ratio: 1/1; background: linear-gradient(160deg, var(--bg-soft), var(--bg-elevated)); position: relative; overflow: hidden; }
.mag-thumb svg, .mag-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mag-body { padding: 14px 16px 18px; font-size: 13.5px; color: var(--text-muted); }

.carousel-nav { display: flex; justify-content: flex-end; gap: 8px; margin-bottom: -6px; }
.carousel-nav .icon-btn { width: 34px; height: 34px; }

/* =========================================================================
   Magazine — standalone list + detail pages
   ========================================================================= */
.magazine-filter { margin-bottom: 24px; }
.magazine-filter .tab-btn { text-decoration: none; }

/* Vertical list of horizontal (landscape) cards on mobile — a compact,
   thumb-left/text-right row like a news-app list; becomes an upright-card
   grid once there's room for it. */
.magazine-grid {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.magazine-card { display: flex; flex-direction: row; overflow: hidden; }
.magazine-card .mag-thumb { flex: 0 0 112px; width: 112px; aspect-ratio: 1/1; align-self: flex-start; }
.magazine-card .mag-body { flex: 1; min-width: 0; padding: 10px 14px 10px 2px; display: flex; flex-direction: column; justify-content: center; }
.magazine-card .mag-body .tag-chip-row { flex-wrap: nowrap; overflow: hidden; margin-top: 2px; }
.magazine-card .mag-body .tag-chip-row .tag-chip { font-size: 10px; padding: 3px 8px; flex-shrink: 0; }
.magazine-card .magazine-card-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.magazine-card .magazine-card-date { margin-bottom: 4px; }
@media (min-width: 640px) {
  .magazine-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
  .magazine-card { flex-direction: column; }
  .magazine-card .mag-thumb { flex-basis: auto; width: auto; align-self: auto; }
  .magazine-card .mag-body { display: block; padding: 14px 16px 18px; }
  .magazine-card .mag-body .tag-chip-row { flex-wrap: wrap; overflow: visible; margin-top: 0; }
  .magazine-card .mag-body .tag-chip-row .tag-chip { font-size: 11px; padding: 4px 10px; }
  .magazine-card .magazine-card-date { margin-bottom: 8px; }
  .magazine-card .magazine-card-title { -webkit-line-clamp: unset; overflow: visible; }
}
@media (min-width: 960px) { .magazine-grid { grid-template-columns: repeat(4, 1fr); } }
.magazine-card-title { font-size: 14.5px; color: var(--text); margin-bottom: 6px; }
.magazine-card-date { display: block; font-size: 11.5px; color: var(--text-faint); margin-bottom: 8px; }

.magazine-back { display: inline-block; margin-bottom: 20px; }

/* Article detail: only the banner image lives in a box — everything else
   (title, meta, body, source) flows in the open like a real editorial page. */
.magazine-article { max-width: 720px; margin: 0 auto; }
.magazine-article-banner {
  aspect-ratio: 16/9; overflow: hidden; margin-bottom: 28px;
  border-radius: var(--radius-lg); border: 1px solid var(--border);
}
.magazine-article-banner img { width: 100%; height: 100%; object-fit: cover; display: block; }
.magazine-article-meta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.magazine-article-meta .magazine-card-date { margin-bottom: 0; }
.magazine-article-title { font-size: clamp(22px, 4vw, 34px); line-height: 1.35; margin-bottom: 28px; }
.magazine-article-content { color: var(--text-muted); font-size: 16px; line-height: 2; }
.magazine-article-content p { margin-bottom: 18px; }
.magazine-article-content p:last-child { margin-bottom: 0; }
.magazine-article-source {
  margin-top: 36px; padding-top: 18px; border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-faint);
}
.magazine-article-source a { color: var(--accent-2); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 480px) {
  .magazine-article-banner { margin-bottom: 20px; border-radius: var(--radius-md); }
  .magazine-article-title { margin-bottom: 20px; }
  .magazine-article-content { font-size: 15px; }
}

/* =========================================================================
   Compact mobile pass — tighter card padding so boxes don't dwarf small
   screens, plus a touch more breathing room from the viewport edge.
   ========================================================================= */
@media (max-width: 480px) {
  .container { padding: 0 18px; }
  .section { padding-top: 44px; padding-bottom: 44px; }
  .services-grid { gap: 8px; }
  .service-card { padding: 0 2px 10px; }
  .cta-banner { min-height: 190px; border-radius: var(--radius-md); }
  .cta-content { max-width: 70%; padding: 20px 16px; }
  .cta-banner h3 { font-size: 15.5px; margin-bottom: 12px; }
  .cta-actions { gap: 8px; }
  .cta-actions .btn { padding: 9px 16px; font-size: 12.5px; }
  .idea-card { padding: 22px 16px; }
  .work-card { flex: 0 0 calc(50% - 8px); }
  .mag-card { flex: 0 0 calc(50% - 8px); }
  .work-body { padding: 12px 14px 16px; }
  .mag-body { padding: 10px 12px 14px; }
  .tech-chip { padding: 8px 14px 8px 8px; font-size: 13px; }
}

/* =========================================================================
   Footer
   ========================================================================= */
.site-footer { border-top: 1px solid var(--border); padding: 56px 0 28px; margin-top: 40px; }
.footer-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px 20px; margin-bottom: 40px; }
.footer-grid .footer-col:first-child { grid-column: 1 / -1; }
@media (min-width: 768px) {
  .footer-grid { grid-template-columns: 1.1fr 1fr 1.3fr; gap: 40px; }
  .footer-grid .footer-col:first-child { grid-column: auto; }
}
.footer-col h5 { font-size: 14px; margin-bottom: 16px; color: var(--text); }
.footer-col ul { display: flex; flex-direction: column; gap: 11px; }
.footer-col a { font-size: 13.5px; color: var(--text-muted); transition: color var(--dur-fast) var(--ease); }
.footer-col a:hover { color: var(--accent-2); }
.footer-col p { font-size: 13.5px; color: var(--text-muted); }

.footer-bottom {
  display: flex; flex-direction: column-reverse; gap: 18px;
  align-items: center; justify-content: space-between;
  padding-top: 24px; border-top: 1px solid var(--border);
  font-size: 12.5px; color: var(--text-faint);
}
@media (min-width: 640px) { .footer-bottom { flex-direction: row; } }
.social-row { display: flex; gap: 10px; }

@media (max-width: 480px) {
  .site-footer { padding: 36px 0 18px; margin-top: 24px; }
  .footer-grid { gap: 20px 14px; margin-bottom: 24px; }
  .footer-col h5 { margin-bottom: 12px; }
  .footer-col ul { gap: 8px; }
  .footer-bottom { padding-top: 18px; gap: 12px; }
}

/* =========================================================================
   Auth pages
   ========================================================================= */
.auth-shell {
  min-height: calc(100vh - var(--header-h));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 20px;
}
.auth-card {
  width: 100%;
  max-width: 420px;
  padding: 36px 30px;
  text-align: center;
}
.auth-mark {
  width: 52px; height: 52px; border-radius: 16px;
  margin: 0 auto 18px;
  background: var(--accent-2-soft);
  border: 1px solid var(--accent-2-border);
  color: var(--accent-2);
  display: flex; align-items: center; justify-content: center;
}
.auth-mark svg { width: 24px; height: 24px; }
.auth-card h1 { font-size: 21px; margin-bottom: 6px; }
.auth-sub { color: var(--text-muted); font-size: 13.5px; margin-bottom: 26px; }
.auth-form { display: flex; flex-direction: column; gap: 14px; text-align: right; }
.auth-form .field label { font-size: 13px; color: var(--text-muted); margin-bottom: 7px; }
.auth-form .field input { min-height: auto; }
.auth-form input.ltr-input { direction: ltr; text-align: left; font-family: var(--font-mono); }
.auth-switch { margin-top: 22px; font-size: 13.5px; color: var(--text-muted); }
.auth-switch a { color: var(--accent-2); font-weight: 600; }
.auth-hint { margin-top: 14px; font-size: 12.5px; color: var(--text-faint); text-align: center; }
.auth-divider { display: flex; align-items: center; gap: 12px; margin: 18px 0; color: var(--text-faint); font-size: 12.5px; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border-strong); }
.btn-google { gap: 10px; }
.auth-error { color: #f2a3a3; font-size: 13.5px; text-align: center; margin: 0 0 14px; }

.checkbox-row { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--text-muted); cursor: pointer; }
.checkbox-row input { width: 17px; height: 17px; accent-color: var(--accent-2); }

.auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.auth-forgot-link { font-size: 12.5px; color: var(--accent-2); font-weight: 600; }

.permission-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px 20px; }
@media (min-width: 640px) { .permission-grid { grid-template-columns: repeat(3, 1fr); } }

.user-role-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.user-role-pill-form { display: inline-block; }
.user-role-assign-form { display: inline-flex; align-items: center; gap: 6px; }
.user-role-assign-form .select-field { width: auto; min-width: 120px; }

/* =========================================================================
   Scroll reveal
   ========================================================================= */
.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.reveal.in { opacity: 1; transform: translateY(0); }

/* =========================================================================
   Panel shell — shared by the user panel and the admin panel
   ========================================================================= */
.panel-body { background: var(--vignette), var(--bg); background-attachment: fixed; }
.panel-shell { display: flex; min-height: 100vh; }

.panel-sidebar {
  width: 260px; flex-shrink: 0;
  background: rgba(13, 20, 36, 0.55);
  backdrop-filter: blur(26px) saturate(150%); -webkit-backdrop-filter: blur(26px) saturate(150%);
  border-inline-end: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 28px;
  padding: 22px 16px;
}
.panel-brand { padding: 0 6px; }
.panel-nav { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.panel-nav a {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; border-radius: 12px;
  color: var(--text-muted); font-size: 14px;
  transition: all var(--dur-fast) var(--ease);
}
.panel-nav a svg { width: 18px; height: 18px; flex-shrink: 0; }
.panel-nav a:hover { background: var(--surface); color: var(--text); }
.panel-nav a.active { background: var(--accent-2-soft); color: var(--accent-2); border: 1px solid var(--accent-2-border); }

.panel-sidebar-footer { display: flex; flex-direction: column; gap: 4px; padding-top: 14px; border-top: 1px solid var(--border); }
.panel-link-muted {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border-radius: 10px; font-size: 13.5px;
  color: var(--text-faint); background: none; border: none; cursor: pointer;
  font-family: inherit; text-align: right;
}
.panel-link-muted svg { width: 16px; height: 16px; }
.panel-link-muted:hover { color: var(--text-muted); background: var(--surface); }

.panel-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.panel-topbar {
  height: 68px; flex-shrink: 0; position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 14px; padding: 0 20px;
  border-bottom: 1px solid var(--border);
  background: rgba(9, 13, 24, 0.48);
  backdrop-filter: blur(22px) saturate(150%); -webkit-backdrop-filter: blur(22px) saturate(150%);
}
.panel-topbar h1 { font-size: 16.5px; flex: 1; }
.panel-drawer-toggle { display: flex; }
.panel-user-chip {
  font-family: var(--font-mono); font-size: 12px; color: var(--text-muted);
  background: var(--surface); border: 1px solid var(--border);
  padding: 6px 12px; border-radius: 999px; max-width: 40vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.panel-content { padding: 22px 16px 32px; flex: 1; }
@media (min-width: 700px) { .panel-content { padding: 30px 32px; } }

.panel-backdrop {
  position: fixed; inset: 0; z-index: 239;
  background: rgba(6, 9, 17, 0.7); backdrop-filter: blur(4px);
  opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease);
}
.panel-backdrop.show { opacity: 1; pointer-events: auto; }

@media (max-width: 959px) {
  .panel-sidebar {
    position: fixed; inset-inline-start: 0; top: 0; bottom: 0; z-index: 240;
    width: min(80vw, 300px);
    transform: translateX(100%);
    transition: transform var(--dur) var(--ease);
  }
  .panel-sidebar.open { transform: translateX(0); }
}
@media (min-width: 960px) {
  .panel-drawer-toggle { display: none; }
  .panel-backdrop { display: none; }
}

/* Bottom app-nav — user panel only. Floating glass pill, matching the
   public site's mobile nav so the whole app feels like one product. */
.panel-bottomnav {
  position: fixed;
  left: 10px; right: 10px;
  bottom: calc(14px + env(safe-area-inset-bottom));
  z-index: 150;
  max-width: 420px;
  margin: 0 auto;
  display: flex;
  background: rgba(17, 26, 46, 0.52);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(32px) saturate(170%); -webkit-backdrop-filter: blur(32px) saturate(170%);
  box-shadow: var(--shadow-lift);
  padding: 8px 4px;
}
.panel-bottomnav a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 4px 2px; color: var(--text-faint); font-size: 9.5px;
}
.panel-bottomnav a svg { width: 18px; height: 18px; }
.panel-bottomnav a .nav-circle { width: 32px; height: 32px; }
.panel-bottomnav a.active { color: var(--accent-2); }
.panel-bottomnav a:active .nav-circle { transform: scale(0.88); }
@media (min-width: 960px) { .panel-bottomnav { display: none; } }
body.has-bottom-nav .panel-content { padding-bottom: 108px; }

/* Section building blocks */
.panel-hello { margin-bottom: 20px; }
.panel-hello h2 { font-size: 19px; margin-bottom: 4px; }
.panel-hello p { color: var(--text-muted); font-size: 13.5px; }

.panel-section { padding: 22px; margin-bottom: 20px; }
.panel-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.panel-section-head h3 { font-size: 15px; }
.panel-link { font-size: 13px; color: var(--accent-2); }

.panel-grid-2 { display: grid; grid-template-columns: 1fr; gap: 20px; }
@media (min-width: 860px) { .panel-grid-2 { grid-template-columns: 1fr 1fr; } }

/* Profile: read-only summary by default, form only appears once the user
   asks to edit — instead of exposed always-editable inputs. */
.profile-edit-toggle summary {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  cursor: pointer; list-style: none; padding: 2px;
  border-radius: 12px; transition: background var(--dur-fast) var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.profile-edit-toggle summary::-webkit-details-marker { display: none; }
.profile-edit-toggle summary::marker { content: ""; }
.profile-edit-toggle summary:hover { background: var(--surface); }
.profile-edit-toggle summary:focus-visible {
  outline: 2px solid var(--accent-2-border); outline-offset: 2px;
}
.profile-summary-info { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.profile-summary-row { display: flex; align-items: baseline; gap: 10px; font-size: 13.5px; }
.profile-summary-row span { color: var(--text-muted); flex-shrink: 0; min-width: 108px; }
.profile-summary-row strong { color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile-summary-edit {
  display: flex; align-items: center; gap: 6px; flex-shrink: 0;
  font-size: 13px; color: var(--accent-2); font-weight: 600;
}
.profile-summary-edit svg { width: 16px; height: 16px; transition: transform var(--dur) var(--ease); }
.profile-edit-toggle[open] .profile-summary-edit svg { transform: rotate(180deg); }
.profile-edit-toggle form { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--border); }

.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 22px; }
@media (min-width: 640px) { .stat-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 960px) { .stat-grid { grid-template-columns: repeat(5, 1fr); } }
.stat-tile { padding: 20px; display: flex; flex-direction: column; gap: 6px; }
.stat-tile.accent { border-color: var(--accent-border); background: linear-gradient(180deg, var(--accent-soft), rgba(255, 255, 255, 0.015)); }
.stat-value { font-family: var(--font-mono); font-size: 25px; font-weight: 700; }
.stat-label { font-size: 12.5px; color: var(--text-muted); }

.wallet-balance-card { text-align: center; padding: 32px 20px; display: flex; flex-direction: column; gap: 10px; align-items: center; margin-bottom: 20px; }
.wallet-balance-amount { font-family: var(--font-mono); font-size: clamp(30px, 6vw, 42px); font-weight: 700; color: var(--accent-2); }
.wallet-balance-amount small { font-size: 14px; font-weight: 500; color: var(--text-muted); margin-inline-start: 6px; }

.empty-state { text-align: center; padding: 34px 12px; display: flex; flex-direction: column; align-items: center; gap: 14px; color: var(--text-muted); font-size: 13.5px; }

.order-list { display: flex; flex-direction: column; }
.order-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 14px 4px; border-bottom: 1px solid var(--border); }
.order-list li:last-child { border-bottom: none; }
.order-list strong { display: block; font-size: 14px; margin-bottom: 3px; }
.order-meta { font-size: 12px; color: var(--text-faint); }

/* A site build in progress (User/Dashboard) — its step ribbon and
   credentials-reveal block always take the full row width, stacked below
   the subdomain/status row above them, never squeezed into it. */
.order-list li > .provision-steps,
.order-list li > .provision-credentials-reveal,
.order-list li > .provision-status-message,
.order-list li > .provision-stats-row {
  flex-basis: 100%;
}

.provision-steps { display: flex; align-items: center; gap: 8px; flex-basis: 100%; margin-top: 4px; }
.provision-step { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-faint); }
.provision-step:not(:last-child)::after {
  content: '';
  width: 20px;
  height: 1px;
  background: var(--border);
  margin-inline-start: 6px;
}
.provision-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); flex-shrink: 0; transition: background var(--dur-fast) var(--ease); }
.provision-step.done { color: var(--text-muted); }
.provision-step.done .provision-dot { background: var(--accent-2); }
.provision-step.active { color: var(--text); font-weight: 600; }
.provision-step.active .provision-dot { background: var(--accent); animation: provisionPulse 1.1s ease-in-out infinite; }

@keyframes provisionPulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); }
  50% { box-shadow: 0 0 0 5px transparent; }
}
.ticket-link { display: block; }

.idea-list { display: flex; flex-direction: column; }
.idea-list li { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 4px; border-bottom: 1px solid var(--border); }
.idea-list li:last-child { border-bottom: none; }
.idea-list li.reviewed { opacity: 0.55; }
.idea-list p { font-size: 13.5px; margin: 0 0 6px; max-width: 520px; }

.ticket-thread { display: flex; flex-direction: column; gap: 12px; max-height: 420px; overflow-y: auto; padding-inline-end: 4px; }
.ticket-message { padding: 12px 16px; border-radius: 14px; max-width: 80%; background: var(--surface); border: 1px solid var(--border); }
.ticket-message.from-user { align-self: flex-start; }
.ticket-message.from-admin { align-self: flex-end; background: var(--accent-2-soft); border-color: var(--accent-2-border); }
.ticket-message-author { font-size: 11.5px; font-weight: 600; color: var(--text-muted); display: block; margin-bottom: 4px; }
.ticket-message p { font-size: 13.5px; margin: 0; }
.ticket-message-time { font-size: 10.5px; color: var(--text-faint); display: block; margin-top: 6px; font-family: var(--font-mono); }

.alert-success { background: var(--accent-2-soft); border: 1px solid var(--accent-2-border); color: var(--accent-2); padding: 12px 18px; border-radius: 12px; font-size: 13.5px; margin-bottom: 18px; }
.alert-warning { background: var(--accent-soft); border: 1px solid var(--accent-border); color: var(--accent); padding: 12px 18px; border-radius: 12px; font-size: 13.5px; margin-bottom: 18px; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.alert-warning form { margin: 0; }

/* Tables */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
thead th { text-align: right; color: var(--text-faint); font-weight: 600; font-size: 12px; padding: 10px 14px; border-bottom: 1px solid var(--border); white-space: nowrap; }
tbody td { padding: 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface); }
.table-subtext { color: var(--text-faint); font-size: 12px; margin: 4px 0 0; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table-actions { display: flex; gap: 8px; }

/* Form controls used in panels */
.select-field {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
  color: var(--text); font-family: var(--font-body); font-size: 13.5px;
  padding: 12px 14px; width: 100%; cursor: pointer;
}
.select-field:focus { outline: none; border-color: var(--accent-2-border); }
.select-sm { padding: 7px 10px; font-size: 12.5px; border-radius: 10px; width: auto; }
.status-form { display: inline-block; }
.field-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 5px; }

/* Admin/DesignPresets/Edit's ListItems/ProductCards repeater rows — plain
   add/remove-a-row rows, no drag-and-drop (matches the "manual SortOrder,
   no reordering UI" convention used everywhere else in this codebase). */
.preview-repeater-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.preview-repeater-row input { flex: 1; min-width: 0; }
.preview-repeater-row-wide input { flex: 1 1 33%; }
.preview-repeater-row .preview-row-remove { flex: 0 0 auto; white-space: nowrap; }

.custom-section-field-row .custom-section-field-key { flex: 1 1 140px; }
.custom-section-field-row select { flex: 1 1 140px; min-width: 0; }
.custom-section-field-row .custom-section-field-default { flex: 2 1 200px; }

.tag-editor { display: flex; flex-direction: column; gap: 10px; }
.tag-editor-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tag-editor-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit; font-size: 12.5px; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 999px; padding: 6px 8px 6px 12px; cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.tag-editor-chip svg { width: 13px; height: 13px; color: var(--text-faint); }
.tag-editor-chip:hover { border-color: var(--danger); color: var(--danger); background: rgba(224, 133, 133, 0.1); }
.tag-editor-chip:hover svg { color: var(--danger); }
.tag-editor-input-row { display: flex; gap: 8px; }
.tag-editor-input-row input { flex: 1; }

.btn-sm { padding: 8px 16px; font-size: 12.5px; }
.btn-danger { color: var(--danger); }
.btn-danger:hover { border-color: rgba(224, 133, 133, 0.5); background: rgba(224, 133, 133, 0.1); }

.pill {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 6px 12px; border-radius: 999px; border: 1px solid transparent;
  white-space: nowrap;
}
.pill-ok { color: var(--accent-2); background: var(--accent-2-soft); border-color: var(--accent-2-border); }
.pill-warn { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-border); }
.pill-info { color: var(--text-muted); background: var(--surface); border-color: var(--border-strong); }
.pill-button {
  cursor: pointer; font-family: inherit; border: 1px solid transparent;
  transition: transform var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease);
}
.pill-button:hover { filter: brightness(1.15); }
.pill-button:active { transform: scale(0.96); }
.pill-danger { color: var(--danger); background: rgba(224, 133, 133, 0.12); border-color: rgba(224, 133, 133, 0.35); }

.text-muted { color: var(--text-muted); font-size: 0.9em; }

.pagination { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 16px; }

.tag-chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-chip {
  display: inline-flex; align-items: center;
  font-size: 11px; color: var(--text-muted); background: var(--surface);
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 10px; white-space: nowrap;
}

.admin-image-preview {
  width: 100%; max-width: 220px; aspect-ratio: 4/3; object-fit: cover;
  border-radius: var(--radius-md); border: 1px solid var(--border); margin-bottom: 10px;
}

/* =========================================================================
   Chat — user-facing widget and admin conversation list/thread
   ========================================================================= */
/* Full-screen Telegram-style chat page — its own minimal layout (_ChatLayout),
   no panel chrome; a slim glass topbar, a scrolling message area that fills
   the rest of the viewport, and a glass input bar pinned to the bottom. */
/* The keyboard-opening bug wasn't really about body's own height — it was
   that html/body still had scrollable overflow available, so the mobile
   browser's "scroll the focused input into view" behavior would scroll the
   whole document, dragging the topbar off the top edge. Nothing above
   .chat-messages is allowed to scroll at all; only that one element is. */
html.chat-page-html {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
body.chat-page-body {
  display: flex; flex-direction: column;
  /* Layered height strategy, safest-first:
     1) 100vh   — universal fallback.
     2) 100svh  — the SMALLEST the viewport can ever be (toolbars fully
        shown). Content sized to this can never be taller than what's
        actually visible, so the input bar can never be pushed off-screen —
        this is the guaranteed floor, not just a nicety.
     3) 100dvh  — adapts to the toolbar hiding for a snugger fit once the
        browser reports it, only ever *shrinking* toward svh or growing
        toward lvh, never breaking the svh guarantee in practice.
     4) --chat-vh — JS-measured visualViewport height, for keyboard-open
        scenarios dvh doesn't always track well. Falls back to svh (not
        dvh) so a stale/late JS read can't regress past the safe floor. */
  height: 100vh;
  height: 100svh;
  height: 100dvh;
  height: var(--chat-vh, 100svh);
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--vignette), var(--bg);
  background-attachment: fixed;
}
.chat-topbar {
  display: flex; align-items: center; gap: 14px; flex-shrink: 0;
  padding: 14px 16px; padding-top: calc(14px + env(safe-area-inset-top));
  border-radius: 0; border-width: 0 0 1px;
  position: relative; z-index: 20;
}
.chat-topbar h1 { font-size: 15.5px; margin: 0; }
.chat-back-btn { flex-shrink: 0; }
.chat-fullscreen { flex: 1; display: flex; flex-direction: column; min-height: 0; }

/* padding-bottom reserves room for .chat-footer, which is pinned with
   position: fixed below (see comment there) and so no longer occupies
   layout space of its own — without this, its last messages would sit
   underneath it. --chat-footer-h is kept in sync with the footer's real,
   possibly-animating height by a ResizeObserver in chat.js; the fallback
   covers the instant before that first measurement lands. */
.chat-messages { flex: 1; overflow-y: auto; padding: 18px 16px; padding-bottom: calc(var(--chat-footer-h, 130px) + 12px); display: flex; flex-direction: column; gap: 10px; }
.chat-bubble-row { display: flex; }
.chat-bubble-row.mine { justify-content: flex-end; }
.chat-bubble-row.theirs { justify-content: flex-start; }
.chat-bubble {
  max-width: 78%;
  background: var(--surface);
  backdrop-filter: blur(26px) saturate(160%);
  -webkit-backdrop-filter: blur(26px) saturate(160%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 10px 14px;
  font-size: 14px;
}
/* Both colors are admin-controlled (/Admin/Settings), inlined per-request
   as CSS variables by _ChatLayout — the fallbacks here are only for the
   (never normally hit) case that style tag is missing. Flat colors, not a
   gradient: a gradient needs a second, hand-picked stop, which would look
   broken the moment the admin picks a color it wasn't tuned for. */
.chat-bubble-row.mine .chat-bubble {
  background: var(--chat-mine-color, #dcb679);
  color: var(--chat-mine-ink, #111111);
  border-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.chat-bubble-row.theirs .chat-bubble {
  background: var(--chat-theirs-color, var(--surface));
  color: var(--chat-theirs-ink, var(--text));
}
.chat-bubble p { margin: 0; white-space: pre-wrap; word-break: break-word; }
.chat-bubble-time { display: flex; align-items: center; gap: 3px; margin-top: 4px; font-size: 10.5px; opacity: 0.65; }
.chat-status { display: inline-flex; }
.chat-status svg { width: 13px; height: 13px; }
.chat-status[data-status="sending"] svg { animation: chat-status-spin 1.4s linear infinite; }
.chat-status[data-status="sent"] svg { animation: chat-status-pop 0.35s var(--ease); }
.chat-status[data-status="failed"] { color: var(--danger); }
@keyframes chat-status-spin { to { transform: rotate(360deg); } }
@keyframes chat-status-pop {
  0% { transform: scale(0.4); opacity: 0; }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); opacity: 1; }
}

/* Every new bubble — mine, theirs, or the FAQ auto-reply — eases in the
   same way, so the chat never "pops" text in abruptly. */
.chat-bubble-enter { animation: chat-bubble-enter 0.32s var(--ease); }
@keyframes chat-bubble-enter {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.chat-attachment-image { display: block; border-radius: 12px; overflow: hidden; margin-bottom: 6px; max-width: 220px; }
.chat-attachment-image img { width: 100%; display: block; }
.chat-attachment-file {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.08); margin-bottom: 6px; color: inherit; text-decoration: none;
}
.chat-attachment-file svg { width: 22px; height: 22px; flex-shrink: 0; }
.chat-attachment-file span { font-size: 13px; word-break: break-all; }

/* Footer: FAQ suggestions + composer, pinned to the real visual viewport
   bottom the same way .mobile-tabbar is (position: fixed + a safe-area-
   aware offset) instead of being laid out as the last flex child of a
   container whose total height is computed from svh/dvh/JS. That total-
   height math is what let the composer drift down past the visible screen
   on some real devices — position: fixed can't drift, it's always relative
   to the actual viewport. --keyboard-offset (set in chat.js from
   visualViewport) lifts it clear of an on-screen keyboard, which otherwise
   covers a plain "bottom: 0" without moving it.
   No background of its own — Telegram-style, only the input pill and the
   round buttons carry their own surface color, so the chat history is
   visible scrolling underneath the bar itself. */
.chat-footer {
  position: fixed; left: 0; right: 0; bottom: var(--keyboard-offset, 0px); z-index: 25;
  display: flex; flex-direction: column;
}
.chat-faq-bar { display: flex; justify-content: center; flex-shrink: 0; }
.chat-faq-bar-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; color: var(--text-faint);
  font-family: inherit; font-size: 12px; cursor: pointer; padding: 8px 10px 2px;
  transition: color var(--dur-fast) var(--ease);
}
.chat-faq-bar-btn:hover, .chat-faq-bar-btn[aria-expanded="true"] { color: var(--accent-2); }
/* Two chevrons nudging upward in sequence — a wordless "there's something
   here, tap it" cue, replacing the old static question-mark icon. */
.chat-faq-nudge { display: inline-flex; flex-direction: column; align-items: center; height: 15px; overflow: hidden; }
.chat-faq-nudge svg { width: 15px; height: 11px; margin-top: -3px; animation: chat-faq-nudge-bounce 1.6s ease-in-out infinite; }
.chat-faq-nudge svg:last-child { margin-top: -7px; animation-delay: 0.18s; }
@keyframes chat-faq-nudge-bounce {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(2px); }
  25% { opacity: 1; transform: translateY(-2px); }
}
.chat-faq-collapse .collapse-panel-inner { padding: 6px 16px 12px; }
.chat-faq-collapse .chat-faq { max-width: none; }

.chat-faq { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; max-width: 420px; }
.chat-faq-chip {
  font-family: inherit; font-size: 12.5px; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 999px; padding: 9px 16px; cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.chat-faq-chip:hover { background: var(--surface-2); border-color: var(--accent-2-border); color: var(--accent-2); }
.chat-faq-chip:active { transform: scale(0.96); }

.chat-input-row {
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
  padding: 12px 16px; padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
.chat-input-row input[type="text"] {
  flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
  color: var(--text); font-family: var(--font-body); font-size: 14px; padding: 11px 16px;
}
.chat-input-row input[type="text"]:focus { outline: none; border-color: var(--accent-2-border); }
.chat-attach-btn {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-muted);
  cursor: pointer; transition: all var(--dur-fast) var(--ease);
}
.chat-attach-btn:hover { color: var(--text); border-color: var(--border-strong); }
.chat-attach-btn:active { transform: scale(0.9); }
.chat-attach-btn svg { width: 18px; height: 18px; }
.chat-send-btn {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-2); color: var(--accent-ink); border: none; cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}
.chat-send-btn svg { width: 19px; height: 19px; }
.chat-send-btn:active { transform: scale(0.9); }

.chat-conv-list { display: flex; flex-direction: column; }
.chat-conv-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 6px; border-bottom: 1px solid var(--border);
  color: var(--text);
}
.chat-conv-row:last-child { border-bottom: none; }
.chat-conv-row:hover { background: var(--surface); }
.chat-conv-row.unread strong { color: var(--accent-2); }
.chat-conv-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.chat-conv-info strong { font-size: 14px; }
.chat-conv-info span { font-size: 12.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60vw; }
.chat-conv-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.chat-conv-meta > span:first-child { font-size: 11px; color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important; transition-delay: 0ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* =========================================================================
   PWA update toast
   ========================================================================= */
.update-toast {
  position: fixed;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom));
  transform: translate(-50%, 20px);
  z-index: 400;
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px 12px 20px;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  max-width: calc(100vw - 32px);
}
.update-toast.show { opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
.update-toast span { font-size: 13.5px; white-space: nowrap; }
.update-toast-btn { padding: 8px 16px; font-size: 12.5px; flex-shrink: 0; }
@media (max-width: 899px) { .update-toast { bottom: calc(86px + env(safe-area-inset-bottom)); } }

/* =========================================================================
   Push permission prompt
   ========================================================================= */
.push-prompt {
  position: fixed;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom));
  transform: translate(-50%, 20px);
  z-index: 401;
  display: flex; align-items: flex-start; gap: 14px;
  padding: 18px;
  width: min(380px, calc(100vw - 32px));
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.push-prompt.show { opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
.push-prompt-icon {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-2-soft); color: var(--accent-2);
}
.push-prompt-icon svg { width: 19px; height: 19px; }
.push-prompt-body strong { display: block; font-size: 14px; margin-bottom: 6px; }
.push-prompt-body p { font-size: 12.5px; color: var(--text-muted); line-height: 1.8; margin-bottom: 14px; }
.push-prompt-actions { display: flex; justify-content: flex-end; gap: 8px; }
@media (max-width: 899px) { .push-prompt { bottom: calc(86px + env(safe-area-inset-bottom)); } }

/* =========================================================================
   Notification bell
   ========================================================================= */
.notif-bell { position: relative; }
.notif-badge {
  position: absolute; top: -2px; left: -2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px;
  background: var(--danger); color: #2a0a0a;
  font-size: 10px; font-weight: 700; line-height: 17px; text-align: center;
  font-family: var(--font-mono);
  border: 2px solid var(--bg);
}
/* position/top/left/right/width are all set inline by JS (see
   site.js) once the dropdown is opened, computed from the bell button's
   actual on-screen position at that moment. It can't be pinned with plain
   CSS: the topbars it lives in (.panel-topbar, .desktop-topbar) use
   backdrop-filter, which — per spec — makes them a new containing block
   for `position: fixed` descendants, silently turning "fixed to the
   viewport" into "fixed to this 68px bar" and sending the dropdown
   off-screen. JS instead moves the element to be a direct child of
   <body>, clear of that trap, and positions it itself. */
.notif-dropdown {
  position: fixed;
  max-height: 70vh; overflow-y: auto;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lift);
  z-index: 300;
  padding: 6px;
}
.notif-dropdown[hidden] { display: none; }
.notif-dropdown-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; font-size: 13.5px; font-weight: 600;
  border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.notif-dropdown-head a { font-size: 12px; font-weight: 500; color: var(--accent-2); }
.notif-dropdown-list { display: flex; flex-direction: column; }
.notif-dropdown-item {
  display: block; padding: 10px; border-radius: 10px;
  transition: background var(--dur-fast) var(--ease);
}
.notif-dropdown-item:hover { background: var(--surface); }
.notif-dropdown-item strong { display: block; font-size: 13px; margin-bottom: 3px; }
.notif-dropdown-item p { font-size: 12px; color: var(--text-muted); margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-dropdown-item span { font-size: 10.5px; color: var(--text-faint); font-family: var(--font-mono); }
.notif-dropdown .empty-state { padding: 24px 12px; }

.notif-page-list { display: flex; flex-direction: column; }
.notif-page-row { border-bottom: 1px solid var(--border); position: relative; }
.notif-page-row:last-child { border-bottom: none; }
.notif-page-row.unread::before {
  content: ""; position: absolute; right: -2px; top: 20px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2);
}
.notif-page-link { display: block; padding: 14px 16px 14px 4px; }
.notif-page-link strong { display: block; font-size: 14px; margin-bottom: 4px; }
.notif-page-link p { font-size: 13px; color: var(--text-muted); margin-bottom: 6px; }

/* =========================================================================
   Accessibility helpers
   ========================================================================= */

/* Visually hidden but still read by screen readers and still indexed —
   used by the homepage <h1>, whose text is baked into the hero artwork.
   The clip-path/1px-box combination (rather than display:none or
   visibility:hidden) is what keeps it in the accessibility tree. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link: off-screen until it takes keyboard focus, then it drops into
   the top-right (RTL) corner as a normal button. Without it, a keyboard
   user had to tab through the entire header on every single page before
   reaching content. */
.skip-link {
  position: absolute;
  top: -100px;
  inset-inline-start: 16px;
  z-index: 999;
  padding: 10px 18px;
  border-radius: 0 0 10px 10px;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus-visible,
.skip-link:focus {
  top: 0;
}

/* <main tabindex="-1"> is only focusable so the skip link can move focus
   into it; it should never draw a focus ring of its own when it does. */
main:focus {
  outline: none;
}
#configurator-root {
  min-height: 100vh;
}

.subdomain-input-row { position: relative; display: flex; align-items: center; }
.subdomain-input-row input { flex: 1; padding-inline-end: 36px; }
.subdomain-status-icon {
  position: absolute;
  inset-inline-end: 12px;
  font-size: 13px;
  pointer-events: none;
}
.subdomain-available .subdomain-status-icon { color: var(--accent-2); }
.subdomain-taken .subdomain-status-icon, .subdomain-invalid .subdomain-status-icon { color: var(--danger); }
.subdomain-checking .subdomain-status-icon { color: var(--text-faint); }

/* site.css hardcodes `html { direction: rtl }` for the rest of the (RTL-only)
   site — this page is the one place that needs to actually flip for English,
   so override it here. Higher specificity than the plain `html` selector,
   so this wins regardless of CSS load order. */
html[dir='ltr'] {
  direction: ltr;
}

.lang-switcher-row {
  text-align: end;
  margin-bottom: 18px;
}

.lang-switcher {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 2px;
}

.lang-switcher button {
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 12px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.lang-switcher button.active {
  background: var(--accent);
  color: var(--accent-ink);
}

:root[dir='ltr'] .auth-form {
  text-align: left;
}

.wizard-stepper {
  display: flex;
  list-style: none;
  gap: 6px;
  margin: 0 0 24px;
  padding: 0;
  overflow-x: auto;
}

.wizard-step {
  flex: 1;
  min-width: 0;
}

.wizard-step-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: none;
  border: none;
  color: var(--text-faint);
  cursor: not-allowed;
  padding: 4px 2px;
  font-family: inherit;
}

.wizard-step:not(.wizard-step-upcoming) .wizard-step-btn {
  cursor: pointer;
  color: var(--text-muted);
}

.wizard-step-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  font-size: 12.5px;
  background: var(--surface);
}

.wizard-step-active .wizard-step-num {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
}

.wizard-step-done .wizard-step-num {
  border-color: var(--accent-2-border);
  color: var(--accent-2);
  background: var(--accent-2-soft);
}

.wizard-step-active .wizard-step-label {
  color: var(--text);
}

.wizard-step-label {
  font-size: 11.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.option-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 640px) {
  .option-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .wizard-main-narrow .option-grid { grid-template-columns: repeat(3, 1fr); }
}

.wizard-step-anim {
  animation: wizardStepIn 0.32s var(--ease);
}

@keyframes wizardStepIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.option-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: right;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  cursor: pointer;
  font-family: inherit;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

.option-card:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

.option-card.selected {
  border-color: var(--accent-border);
  background: var(--accent-soft);
  animation: optionPulse 0.28s var(--ease);
  position: relative;
}

.option-card.selected::after {
  content: '✓';
  position: absolute;
  top: 10px;
  inset-inline-start: 10px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: optionCheckIn 0.22s var(--ease);
}

@keyframes optionPulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.025); }
  100% { transform: scale(1); }
}

@keyframes optionCheckIn {
  from { opacity: 0; transform: scale(0.4); }
  to { opacity: 1; transform: scale(1); }
}

.option-card-title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text);
}

.option-card-desc {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.6;
}

.option-card-disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.option-card-disabled:hover {
  background: var(--surface);
  border-color: var(--border);
}

.option-card-badge {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 600;
}

.feature-group {
  margin-bottom: 22px;
}

.feature-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}

.feature-group-title {
  font-size: 13px;
  color: var(--text-muted);
}

.feature-group-count {
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.feature-card-meta {
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 2px;
}

.feature-default-badge {
  display: inline-block;
  margin-inline-start: 8px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  vertical-align: middle;
}

.feature-header-pills {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* A card starts collapsed to just its title — with 60+ features across a
   dozen categories, every card showing its full description/chips/meta at
   once is what made this step feel endless. The chevron button is a
   separate click target from the card body (which still toggles
   selection), so opening details never accidentally selects/deselects. */
.feature-card-details {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.feature-card-expand-toggle {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 2px 0 0;
  color: var(--text-faint);
  cursor: pointer;
  font-family: inherit;
}

.feature-card-expand-toggle svg {
  transition: transform var(--dur-fast) var(--ease);
}

.feature-card-expand-toggle.expanded svg {
  transform: rotate(180deg);
}

.feature-card-expand-toggle:hover {
  color: var(--text-muted);
}

/* Color language for the feature-relationship tags — each one carries a
   distinct meaning and needs a distinct color, not one green for
   everything: gold = "on by default", grey = neutral prerequisite info,
   green = "something you picked actively needs this" / "this got added
   automatically", red = "this got turned off as a side effect". See the
   in-panel legend (feature-legend-*) for the same mapping spelled out. */
.feature-legend-wrap {
  position: relative;
}

.feature-legend-trigger {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  padding: 6px 12px;
  cursor: pointer;
  font-family: inherit;
}

.feature-legend-trigger:hover {
  background: var(--surface-2);
}

.feature-legend-popover {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-end: 0;
  z-index: 30;
  width: 290px;
  max-width: 82vw;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lift);
  padding: 14px;
  animation: featureAutoNoteIn 0.2s var(--ease);
}

.feature-legend-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  font-size: 13px;
}

.feature-legend-close {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
  padding: 2px;
}

.feature-legend-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.feature-legend-list li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.6;
}

.feature-legend-swatch {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  border-radius: 4px;
  margin-top: 2px;
  border: 1px solid;
}

.feature-legend-swatch-default { background: var(--accent-soft); border-color: var(--accent-border); }
.feature-legend-swatch-requires { background: var(--surface-2); border-color: var(--border-strong); }
.feature-legend-swatch-requiredby { background: var(--accent-2-soft); border-color: var(--accent-2-border); }
.feature-legend-swatch-added { background: var(--accent-2-soft); border-color: var(--accent-2-border); }
.feature-legend-swatch-removed { background: rgba(224, 133, 133, 0.12); border-color: rgba(224, 133, 133, 0.35); }

/* A feature card explains its own dependency chain up front — "requires X"
   before you toggle it on, "needed by X" while it's on and something else
   selected relies on it — instead of the cascade only showing up as a
   silent change elsewhere in the list. Each related feature gets its own
   small chip rather than a comma-joined sentence, so a two- or three-item
   dependency (several catalog rules need more than one feature) stays easy
   to scan instead of running together as prose. */
.feature-relation {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
  font-size: 11px;
  line-height: 1.5;
}

.feature-relation svg {
  flex-shrink: 0;
}

.feature-relation-label {
  color: var(--text-faint);
}

.feature-relation-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid;
  font-weight: 500;
}

.feature-relation-requires svg {
  opacity: 0.8;
  color: var(--text-muted);
}

.feature-relation-requires .feature-relation-chip {
  color: var(--text-muted);
  background: var(--surface-2);
  border-color: var(--border-strong);
}

.feature-relation-required-by svg {
  color: var(--accent-2);
}

.feature-relation-required-by .feature-relation-label {
  color: var(--accent-2);
}

.feature-relation-required-by .feature-relation-chip {
  color: var(--accent-2);
  background: var(--accent-2-soft);
  border-color: var(--accent-2-border);
}

/* Toggling a feature can cascade (auto-add what it needs, auto-drop what
   needed it) — this banner names exactly what changed as a side effect, and
   the matching cards briefly flash so the cascade is visible where it
   happened, not just described in text. */
.feature-auto-note {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  background: var(--accent-2-soft);
  border: 1px solid var(--accent-2-border);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  margin-bottom: 16px;
  animation: featureAutoNoteIn 0.24s var(--ease);
}

/* A single toggle either cascades additions or cascades removals, never
   both at once (resolveDependencies vs. removeWithDependents run
   exclusively) — so the whole banner can safely swap to a "something got
   turned off" tone instead of always reading as the same positive green. */
.feature-auto-note-negative {
  background: rgba(224, 133, 133, 0.12);
  border-color: rgba(224, 133, 133, 0.35);
}

@keyframes featureAutoNoteIn {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

.feature-auto-note-lines {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.feature-auto-note-line {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.6;
}

.feature-auto-note-line svg {
  flex-shrink: 0;
}

.feature-auto-note-added svg {
  color: var(--accent-2);
}

.feature-auto-note-removed svg {
  color: var(--danger);
}

.feature-auto-note-dismiss {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 2px;
}

.feature-card-flash {
  animation: featureCardFlash 1.4s var(--ease);
}

@keyframes featureCardFlash {
  0% { box-shadow: 0 0 0 2px var(--accent-2-border); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.wizard-lead-text {
  color: var(--text-muted);
  font-size: 13.5px;
  line-height: 1.9;
  max-width: 460px;
  margin-left: auto;
  margin-right: auto;
}

.wizard-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 24px;
  gap: 12px;
}

/* ============================= Preview layout ============================= */

.wizard-body {
  display: block;
}

@media (min-width: 980px) {
  .wizard-body.has-preview {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(340px, 440px);
    gap: 28px;
    /* Deliberately no align-items: start here — the preview track is left
       at the default stretch so its box spans the full row height (as
       tall as the feature list next to it) and can paint a background
       that matches the page. Without that, the sticky column's own
       (much shorter) box only covers part of the row, and the empty
       leftover strip shows the glass panel's translucent tint instead
       of the page's solid background — reading as a mismatched color
       block down the left side. */
  }
}

.wizard-main {
  min-width: 0;
}

.preview-backdrop {
  display: none;
}

.preview-mobile-trigger {
  display: none;
}

/* Unwraps on mobile — the sticky trick and its full-height backdrop are
   desktop-only concerns, see the media query below. */
.wizard-preview-track {
  display: contents;
}

.wizard-preview-col {
  display: none;
}

.preview-sheet-close {
  display: none;
}

@media (min-width: 980px) {
  .wizard-body.has-preview .wizard-preview-track {
    display: block;
    background: var(--bg);
  }

  .wizard-body.has-preview .wizard-preview-col {
    display: block;
    position: sticky;
    top: 20px;
    max-height: calc(100vh - 40px);
  }
}

/* Mobile: the preview lives in a full-screen sheet. A sticky bar at the
   very top of the wizard (mirroring the site's own bottom tab bar, just
   flipped to the top since this page only needs one action, not several)
   keeps the trigger reachable at any scroll position instead of a
   floating button that could drift out of thumb reach or get lost behind
   content. */
.preview-mobile-topbar {
  display: none;
}

@media (max-width: 979px) {
  .preview-mobile-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    position: sticky;
    top: 0;
    z-index: 40;
    margin-bottom: 16px;
    padding: 10px 14px;
    background: rgba(17, 26, 46, 0.72);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-pill);
    backdrop-filter: blur(24px) saturate(160%);
    -webkit-backdrop-filter: blur(24px) saturate(160%);
    box-shadow: var(--shadow-lift);
  }

  .preview-mobile-topbar-label {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-muted);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  .preview-mobile-trigger {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--accent);
    color: var(--accent-ink);
    border: none;
    border-radius: var(--radius-pill);
    padding: 8px 14px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
  }

  .preview-backdrop.open {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(5, 8, 16, 0.6);
    z-index: 45;
  }

  /* Full screen, not a partial bottom sheet — no page content is reachable
     (or scrollable) behind it while open; only the preview frame's own
     internal scroll (see .preview-frame) moves. */
  .wizard-preview-col {
    display: block;
    position: fixed;
    inset: 0;
    background: var(--bg-elevated);
    z-index: 50;
    overflow-y: auto;
    padding: calc(14px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));
    transform: translateY(100%);
    transition: transform var(--dur) var(--ease);
  }

  .wizard-preview-col.open {
    transform: translateY(0);
  }

  .preview-sheet-close {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-block-end: 12px;
    margin-inline-start: auto;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    color: var(--text);
    border-radius: var(--radius-pill);
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
  }
}

/* ============================= Preview panel chrome ============================= */

.preview-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  gap: 10px;
}

.preview-panel-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}

.preview-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 0 0 var(--accent-2-soft);
  animation: previewLivePulse 2s infinite;
}

@keyframes previewLivePulse {
  0% { box-shadow: 0 0 0 0 rgba(139, 199, 75, 0.5); }
  70% { box-shadow: 0 0 0 6px rgba(139, 199, 75, 0); }
  100% { box-shadow: 0 0 0 0 rgba(139, 199, 75, 0); }
}

.preview-theme-toggle {
  display: flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 2px;
}

.preview-theme-toggle button {
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 11.5px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.preview-theme-toggle button.active {
  background: var(--accent);
  color: var(--accent-ink);
}

/* ============================= Preview frame + tokens ============================= */

/* Fixed-size "device screen": however many feature-driven sections a
   layout renders, the frame itself never grows — it keeps this exact
   height and only its own inside scrolls, so the panel around it (and the
   page it sits in) never gets pushed out of view. */
.preview-frame {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
  font-family: var(--pv-font, var(--font-body));
  height: min(720px, calc(100vh - 150px));
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--pv-border, rgba(255, 255, 255, 0.25)) transparent;
}

.preview-frame::-webkit-scrollbar {
  width: 6px;
}

.preview-frame::-webkit-scrollbar-track {
  background: transparent;
}

.preview-frame::-webkit-scrollbar-thumb {
  background: var(--pv-border, rgba(255, 255, 255, 0.25));
  border-radius: 999px;
}

.preview-frame[data-theme='dark'], .design-swatch[data-theme='dark'] {
  --pv-bg: #10182a;
  --pv-surface: rgba(255, 255, 255, 0.06);
  --pv-surface-2: rgba(255, 255, 255, 0.1);
  --pv-border: rgba(255, 255, 255, 0.13);
  --pv-text: #eef1f8;
  --pv-text-muted: #93a0b8;
  --pv-danger: #e08585;
}

.preview-frame[data-theme='light'], .design-swatch[data-theme='light'] {
  --pv-bg: #f7f5f1;
  --pv-surface: #ffffff;
  --pv-surface-2: #f0eee9;
  --pv-border: rgba(20, 20, 20, 0.1);
  --pv-text: #17181c;
  --pv-text-muted: #6b6f7a;
  --pv-danger: #c24949;
}

/* Glass preset: a genuine glassmorphism material, not just a palette swap —
   translucent, blurred surfaces instead of the usual flat pv-surface. */
.preview-frame[data-preset='design.glass'] .pv-header,
.preview-frame[data-preset='design.glass'] .pv-footer,
.preview-frame[data-preset='design.glass'] .pv-product-card,
.preview-frame[data-preset='design.glass'] .pv-icon-btn,
.preview-frame[data-preset='design.glass'] .pv-category-chip:not(.active) {
  background: color-mix(in srgb, var(--pv-surface) 55%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--pv-text) 12%, transparent);
}

.design-swatch.design-swatch-glass {
  background: color-mix(in srgb, var(--pv-surface, var(--surface)) 55%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* Creative preset: a two-tone accent gradient instead of a flat fill, to
   match its "expressive" typography personality. */
.preview-frame[data-preset='design.creative'] .pv-hero-cta {
  background: linear-gradient(135deg, var(--pv-accent), var(--pv-accent-2));
}

/* ============================= Design step: swatch cards ============================= */

.design-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 640px) {
  .design-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1040px) {
  .wizard-body:not(.has-preview) .design-grid { grid-template-columns: repeat(3, 1fr); }
}

.design-card-badge {
  margin-inline-start: 8px;
}

.design-swatch {
  height: 78px;
  border-radius: var(--pv-radius);
  background: var(--pv-bg);
  border: 1px solid var(--pv-border);
  box-shadow: var(--pv-shadow);
  padding: 10px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  position: relative;
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease);
}

.option-card:hover .design-swatch {
  transform: scale(1.02);
}

.design-swatch-photo {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: calc(var(--pv-radius) * 0.6);
  background: var(--pv-surface-2);
}

.design-swatch-lines {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.design-swatch-line-heading,
.design-swatch-line-body {
  display: block;
  height: 6px;
  border-radius: 3px;
  background: var(--pv-text);
}

.design-swatch-line-heading {
  width: 70%;
  height: 7px;
  opacity: 0.9;
}

.design-swatch-line-body {
  width: 45%;
  opacity: 0.4;
}

.design-swatch-dot {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--pv-accent);
}

.pv-page {
  background: var(--pv-bg);
  color: var(--pv-text);
}

.pv-header {
  padding: var(--pv-pad);
  border-bottom: 1px solid var(--pv-border);
}

.pv-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.pv-brand {
  font-weight: var(--pv-heading-weight);
  letter-spacing: var(--pv-tracking);
  font-size: 15px;
}

.pv-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pv-icon-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--pv-surface);
  color: var(--pv-text-muted);
  animation: pvFadeIn 0.25s var(--ease);
}

.pv-cart-badge {
  position: absolute;
  top: -4px;
  inset-inline-start: -4px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 50%;
  background: var(--pv-accent);
  color: var(--pv-bg);
  font-size: 9.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pv-category-nav {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  overflow-x: auto;
}

.pv-category-chip {
  flex-shrink: 0;
  padding: 5px 12px;
  border-radius: var(--pv-radius);
  background: var(--pv-surface);
  color: var(--pv-text-muted);
  font-size: 11.5px;
  font-weight: var(--pv-body-weight);
  animation: pvFadeIn 0.25s var(--ease);
}

.pv-category-chip.active {
  background: var(--pv-accent);
  color: var(--pv-bg);
}

.pv-realestate-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pv-realestate-toolbar .pv-category-nav {
  margin-top: 0;
}

.pv-map-toggle {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border-radius: var(--pv-radius);
  border: 1px solid var(--pv-border);
  color: var(--pv-text-muted);
  font-size: 11px;
  font-weight: var(--pv-body-weight);
  white-space: nowrap;
}

.pv-hero {
  padding: calc(var(--pv-pad) * 1.6) var(--pv-pad);
  text-align: center;
}

.pv-hero-image {
  display: block;
  width: 100%;
  max-height: 140px;
  object-fit: cover;
  border-radius: var(--pv-radius);
  margin-bottom: 12px;
}

/* DesignPreset previewContent's Banner/ListItems blocks — only rendered
   when the selected preset actually sets them (see StorefrontLayout.tsx),
   so a preset without them adds zero markup here. */
.pv-banner {
  position: relative;
  margin: 0 var(--pv-pad) var(--pv-pad);
  border-radius: var(--pv-radius);
  overflow: hidden;
  box-shadow: var(--pv-shadow);
}
.pv-banner-image { display: block; width: 100%; height: 90px; object-fit: cover; }
.pv-banner-text {
  position: absolute;
  inset-inline-start: 0;
  bottom: 0;
  padding: 8px var(--pv-pad);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent);
  color: #fff;
  font-size: 12px;
  font-weight: var(--pv-heading-weight);
}

.pv-list-items {
  margin: 0 var(--pv-pad) var(--pv-pad);
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pv-list-item {
  padding: 8px 12px;
  border-radius: var(--pv-radius);
  background: var(--pv-surface);
  color: var(--pv-text);
  font-size: 12px;
  font-weight: var(--pv-body-weight);
}

.pv-hero-title {
  font-weight: var(--pv-heading-weight);
  letter-spacing: var(--pv-tracking);
  font-size: 19px;
  margin: 0 0 6px;
}

.pv-hero-subtitle {
  color: var(--pv-text-muted);
  font-size: 12px;
  font-weight: var(--pv-body-weight);
  margin: 0 0 14px;
}

.pv-hero-cta {
  display: inline-block;
  background: var(--pv-accent);
  color: var(--pv-bg);
  border-radius: var(--pv-radius);
  padding: 8px 18px;
  font-size: 12px;
  font-weight: 700;
}

.pv-generic-note {
  margin: 0 var(--pv-pad) var(--pv-pad);
  padding: 12px;
  border-radius: var(--pv-radius);
  background: var(--pv-surface);
  color: var(--pv-text-muted);
  font-size: 11.5px;
  line-height: 1.8;
}

.pv-product-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--pv-gap);
  padding: 0 var(--pv-pad) var(--pv-pad);
}

.pv-product-card {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  overflow: hidden;
  box-shadow: var(--pv-shadow);
  transform: rotate(var(--pv-card-tilt));
  animation: pvFadeIn 0.3s var(--ease);
  transition: transform var(--dur-fast) var(--ease);
}

.pv-product-card:nth-child(even) {
  transform: rotate(calc(var(--pv-card-tilt) * -1));
}

.pv-product-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--pv-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--pv-text-muted);
}

.pv-product-photo-img { width: 100%; height: 100%; object-fit: cover; }

.pv-wishlist-btn {
  position: absolute;
  top: 8px;
  inset-inline-start: 8px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.85);
  color: #d9527a;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: pvPopIn 0.22s var(--ease);
  cursor: default;
}

.pv-discount-badge {
  position: absolute;
  top: 8px;
  inset-inline-end: 8px;
  background: var(--pv-danger);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: 6px;
  animation: pvPopIn 0.22s var(--ease);
}

.pv-product-body {
  padding: calc(var(--pv-pad) * 0.6);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pv-product-name {
  font-size: 12px;
  font-weight: var(--pv-body-weight);
}

.pv-product-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #e0a83e;
  font-size: 10.5px;
  animation: pvFadeIn 0.25s var(--ease);
}

.pv-product-review-count {
  color: var(--pv-text-muted);
}

.pv-product-price-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 2px;
}

.pv-product-price {
  font-weight: 700;
  font-size: 13px;
}

.pv-product-price-old {
  color: var(--pv-text-muted);
  font-size: 10.5px;
  text-decoration: line-through;
}

.pv-product-price-unit {
  color: var(--pv-text-muted);
  font-size: 10px;
}

.pv-footer {
  padding: var(--pv-pad);
  border-top: 1px solid var(--pv-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--pv-text-muted);
  font-size: 10.5px;
  flex-wrap: wrap;
  gap: 8px;
}

.pv-footer-links {
  display: flex;
  gap: 12px;
}

@keyframes pvFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes pvPopIn {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: scale(1); }
}

/* ============================= Shared: sections + entity grid ============================= */

.pv-section {
  padding: 0 var(--pv-pad) var(--pv-pad);
}

.pv-entity-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--pv-gap);
  padding: 0 var(--pv-pad) var(--pv-pad);
}

.pv-entity-card {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  overflow: hidden;
  box-shadow: var(--pv-shadow);
  animation: pvFadeIn 0.3s var(--ease);
}

.pv-entity-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--pv-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--pv-text-muted);
}

.pv-entity-badge {
  position: absolute;
  top: 8px;
  inset-inline-end: 8px;
  background: var(--pv-accent);
  color: var(--pv-bg);
  font-size: 9.5px;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: 6px;
}

.pv-entity-body {
  padding: calc(var(--pv-pad) * 0.6);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pv-entity-name {
  font-size: 12px;
  font-weight: var(--pv-body-weight);
}

.pv-entity-meta {
  font-size: 10.5px;
  color: var(--pv-text-muted);
}

/* ============================= Location block ============================= */

.pv-location {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: var(--pv-pad);
}

.pv-location-map {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--pv-surface-2);
  color: var(--pv-accent);
  display: flex;
  align-items: center;
  justify-content: center;
}

.pv-location-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11.5px;
}

.pv-location-hours {
  color: var(--pv-text-muted);
  font-size: 10.5px;
}

/* ============================= Booking calendar ============================= */

.pv-booking-calendar {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: var(--pv-pad);
}

.pv-calendar-days {
  display: flex;
  gap: 5px;
  margin-bottom: 10px;
}

.pv-calendar-day {
  flex: 1;
  text-align: center;
  padding: 6px 2px;
  border-radius: calc(var(--pv-radius) * 0.5);
  background: var(--pv-surface-2);
  color: var(--pv-text-muted);
  font-size: 10.5px;
}

.pv-calendar-day.active {
  background: var(--pv-accent);
  color: var(--pv-bg);
  font-weight: 700;
}

.pv-calendar-slots {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.pv-calendar-slot {
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--pv-border);
  color: var(--pv-text-muted);
  font-size: 10.5px;
}

.pv-calendar-slot.active {
  background: var(--pv-accent);
  border-color: transparent;
  color: var(--pv-bg);
  font-weight: 700;
}

/* ============================= Testimonials ============================= */

.pv-testimonials {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--pv-gap);
}

.pv-testimonial-card {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: var(--pv-pad);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pv-testimonial-quote {
  font-size: 11.5px;
  line-height: 1.7;
  margin: 0 0 4px;
}

.pv-testimonial-name {
  font-size: 11px;
  font-weight: var(--pv-heading-weight);
}

.pv-testimonial-role {
  font-size: 10px;
  color: var(--pv-text-muted);
}

/* ============================= Pricing table ============================= */

.pv-pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.pv-pricing-card {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: calc(var(--pv-pad) * 0.8);
  display: flex;
  flex-direction: column;
  gap: 6px;
  border: 1px solid transparent;
}

.pv-pricing-card.highlighted {
  border-color: var(--pv-accent);
}

.pv-pricing-name {
  font-size: 11px;
  color: var(--pv-text-muted);
}

.pv-pricing-price {
  font-size: 13px;
  font-weight: var(--pv-heading-weight);
}

.pv-pricing-features {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 9.5px;
  color: var(--pv-text-muted);
}

/* ============================= FAQ ============================= */

.pv-faq {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pv-faq-item {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: calc(var(--pv-pad) * 0.7);
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pv-faq-q {
  font-size: 11.5px;
  font-weight: var(--pv-body-weight);
}

.pv-faq-a {
  font-size: 10.5px;
  color: var(--pv-text-muted);
}

/* ============================= Contact form ============================= */

.pv-contact-form {
  background: var(--pv-surface);
  border-radius: var(--pv-radius);
  padding: var(--pv-pad);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
}

.pv-contact-title {
  font-size: 13px;
  font-weight: var(--pv-heading-weight);
}

.pv-contact-fields {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.pv-contact-input {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border-radius: calc(var(--pv-radius) * 0.6);
  background: var(--pv-surface-2);
  color: var(--pv-text-muted);
  font-size: 10.5px;
}

.pv-contact-textarea {
  height: 40px;
}

/* ============================= App shell (dashboard / web app) ============================= */

.pv-app-shell {
  display: flex;
  min-height: 320px;
  background: var(--pv-bg);
  color: var(--pv-text);
}

.pv-app-sidebar {
  flex-shrink: 0;
  width: 96px;
  padding: 14px 8px;
  border-inline-end: 1px solid var(--pv-border);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pv-app-brand {
  font-size: 10.5px;
  font-weight: var(--pv-heading-weight);
  color: var(--pv-text-muted);
  padding: 0 4px;
}

.pv-sidebar {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pv-sidebar-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 6px;
  border-radius: calc(var(--pv-radius) * 0.6);
  color: var(--pv-text-muted);
  font-size: 10px;
}

.pv-sidebar-item.active {
  background: var(--pv-accent);
  color: var(--pv-bg);
  font-weight: 700;
}

.pv-sidebar-icon {
  display: flex;
  flex-shrink: 0;
}

.pv-app-main {
  flex: 1;
  min-width: 0;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ============================= KPI grid ============================= */

.pv-kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.pv-kpi-card {
  background: var(--pv-surface);
  border-radius: calc(var(--pv-radius) * 0.7);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pv-kpi-label {
  font-size: 9.5px;
  color: var(--pv-text-muted);
}

.pv-kpi-value {
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 4px;
}

.pv-kpi-trend-up { color: #4ade80; }
.pv-kpi-trend-down { color: #e08585; }

/* ============================= Data table ============================= */

.pv-table-wrap {
  overflow-x: auto;
  background: var(--pv-surface);
  border-radius: calc(var(--pv-radius) * 0.7);
}

.pv-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 10px;
  white-space: nowrap;
}

.pv-table th {
  text-align: start;
  color: var(--pv-text-muted);
  font-weight: 600;
  padding: 8px 10px;
  border-bottom: 1px solid var(--pv-border);
}

.pv-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--pv-border);
}

.pv-table tr:last-child td {
  border-bottom: none;
}

/* ============================= Bar chart ============================= */

.pv-bar-chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 70px;
  background: var(--pv-surface);
  border-radius: calc(var(--pv-radius) * 0.7);
  padding: 10px;
}

.pv-bar-chart-bar {
  flex: 1;
  background: var(--pv-accent);
  border-radius: 3px 3px 0 0;
  min-height: 4px;
  animation: pvBarGrow 0.4s var(--ease);
}

@keyframes pvBarGrow {
  from { transform: scaleY(0); transform-origin: bottom; }
  to { transform: scaleY(1); transform-origin: bottom; }
}

/* ============================= Status chips (web app) ============================= */

.pv-status-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.pv-status-chip {
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  background: var(--pv-surface);
  color: var(--pv-text-muted);
  font-size: 10px;
}

.pv-status-chip::before {
  content: '●';
  color: #4ade80;
  margin-inline-end: 4px;
}
