/* =========================================================================
   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;
}
