/* Adhook design tokens (docs/FRONTEND.md section 2). CSS variables only, no hardcoded colors. */

/* Self-hosted fonts (no third-party CDN). Sentient = display (variable 200-700 + italic),
   Inter = UI/body, JetBrains Mono = mono. Inter/JBM are split into latin + latin-ext subsets. */
@font-face {
  font-family: "Sentient";
  src: url("/static/fonts/sentient-variable.woff2") format("woff2");
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Sentient";
  src: url("/static/fonts/sentient-italic-variable.woff2") format("woff2");
  font-weight: 200 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/inter-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/inter-latin-ext.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/jbm-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/jbm-latin-ext.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Palette - warm charcoal base (visual refresh 2026-07-14). RGB triplets below let rgba()
     compose from the same source of truth. */
  --bg: #100e0b;
  --bg-2: #15120d;
  --surface: #1b1712;
  --surface-2: #231e17;
  --line: rgba(255, 255, 255, 0.08);
  --line-2: rgba(255, 255, 255, 0.14);
  --tx: #f7f3ec;
  --tx-2: #b3aa99;
  --tx-3: #7c7365;
  --lime: #d4f84b;
  --lime-hover: #e1ff5c;
  --lime-dim: rgba(212, 248, 75, 0.3);
  --lime-tint: rgba(212, 248, 75, 0.07);
  --on-lime: #000000;
  --good: #9be37a;
  --good-dim: rgba(155, 227, 122, 0.3);
  --good-tint: rgba(155, 227, 122, 0.07);
  --warn: #e8c45a;
  --warn-dim: rgba(232, 196, 90, 0.3);
  --warn-tint: rgba(232, 196, 90, 0.07);
  --bad: #ff8080;
  --bad-dim: rgba(255, 128, 128, 0.3);
  --bad-tint: rgba(255, 128, 128, 0.07);

  /* Accents split out of lime's overloaded roles: focus + secondary/data-viz get their own. */
  --violet: #8b7dff;
  --focus: #a99bff;
  --glass: rgba(255, 255, 255, 0.05);
  --glass-line: rgba(255, 255, 255, 0.13);
  --bg-rgb: 16, 14, 11;
  --lime-rgb: 212, 248, 75;
  --violet-rgb: 139, 125, 255;

  /* Self-hosted faces (see @font-face above). Sentient = display, Inter = UI, JetBrains = mono. */
  --font-display: "Sentient", Georgia, serif;
  --font-ui: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  --r-control: 11px;
  --r-card: 16px;
  --h-control: 40px;

  /* Scales (intent, not one-off literals). */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 6px 20px rgba(0, 0, 0, 0.4);
  --shadow-3: 0 20px 50px rgba(0, 0, 0, 0.5);
  --z-base: 1;
  --z-dropdown: 20;
  --z-sticky: 30;
  --z-scrim: 40;
  --z-modal: 50;
  --z-toast: 60;
  --dur-fast: 0.12s;
  --dur-base: 0.18s;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
}

.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(60% 60% at 50% 0%, var(--bg-2), var(--bg));
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 32px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 24px;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--lime);
  color: var(--on-lime);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
}

.brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--tx);
}

.auth-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 24px;
  margin: 0 0 6px;
}

.auth-sub {
  color: var(--tx-2);
  font-size: 14px;
  margin: 0 0 24px;
}

.policy-list {
  margin: 0 0 20px;
  padding-left: 20px;
  color: var(--tx);
  font-size: 14px;
  line-height: 1.6;
}
.policy-list li {
  margin-bottom: 6px;
}
.policy-note {
  color: var(--tx-2);
  font-size: 12.5px;
  line-height: 1.5;
  margin: 0 0 20px;
  padding-top: 14px;
  border-top: 1px solid var(--line-2);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.field-label {
  font-size: 13px;
  color: var(--tx-2);
}

/* Required-field marker next to the label (decorative; the input carries `required`). */
.field-label .req {
  color: var(--tx-3);
  margin-left: 3px;
}

.input {
  height: var(--h-control);
  padding: 0 13px;
  border-radius: var(--r-control);
  border: 1px solid var(--line-2);
  background: var(--surface-2);
  color: var(--tx);
  font-family: var(--font-ui);
  font-size: 14px;
}

.input:focus {
  outline: none;
  border-color: var(--lime);
}

.btn {
  height: var(--h-control);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 18px;
  border-radius: var(--r-control);
  border: 1px solid transparent;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease),
    border-color var(--dur-base) var(--ease),
    color var(--dur-base) var(--ease);
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

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

.btn-ghost {
  background: transparent;
  border-color: var(--line-2);
  color: var(--tx);
}
.btn-ghost:hover {
  background: var(--surface-2);
  border-color: var(--tx-3);
}

/* Destructive actions (sign out everywhere, delete, etc.). Tinted-red so it reads as danger without
   shouting on the dark theme; fills in on hover. */
.btn-danger {
  background: var(--bad-tint);
  border-color: var(--bad);
  color: var(--bad);
}
.btn-danger:hover {
  background: var(--bad-dim);
  color: var(--tx);
}

/* A form submit that reads as a plain text link (no button chrome) - for low-emphasis actions like
   a routine single-device sign out. */
.btn-textlink {
  background: none;
  border: none;
  padding: 0;
  height: auto;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--tx-2);
  text-decoration: underline;
  cursor: pointer;
}
.btn-textlink:hover {
  color: var(--tx);
}

.auth-foot {
  margin: 22px 0 0;
  font-size: 13px;
  color: var(--tx-3);
  text-align: center;
}
.auth-foot a {
  color: var(--tx-2);
  text-decoration: none;
  font-weight: 500;
  transition: 0.12s;
}
.auth-foot a:hover {
  color: var(--lime);
}

.alert {
  border-radius: var(--r-control);
  padding: 11px 13px;
  font-size: 13px;
  margin-bottom: 16px;
  border: 1px solid var(--line-2);
}

.alert-bad {
  color: var(--bad);
  border-color: var(--bad);
  background: rgba(255, 128, 128, 0.08);
}

.alert-warn {
  color: var(--warn);
  border-color: var(--warn);
  background: rgba(232, 196, 90, 0.08);
}

.alert-good {
  color: var(--good);
  border-color: var(--good);
  background: var(--good-tint);
}

/* "or" divider + full-width Google button on the sign-in page. */
.auth-or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0;
  color: var(--tx-3);
  font-size: 13px;
}
.auth-or::before,
.auth-or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line-2);
}
.btn-google {
  width: 100%;
}

[x-cloak] {
  display: none !important;
}

/* ---------- authenticated app shell (create-workspace, docs/FRONTEND.md section 3) ---------- */
.app {
  display: grid;
  grid-template-columns: 240px 1fr;
  /* The document itself is the scroller (so the wheel works everywhere, no dead zones); the sidebar
     and topbar are pinned with position:sticky. min-height (not height) keeps the shell full-viewport
     on short pages while still letting the grid row grow with content. */
  min-height: 100vh;
}

.side {
  background: var(--bg-2);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 18px 14px;
  gap: 4px;
  /* Pinned as a full-height rail while the document scrolls (a wheel over it scrolls the document).
     overflow-y:auto lets a long nav scroll internally on a short viewport; the margin-top:auto footer
     stays pinned. The mobile @media override (position:fixed drawer) wins by source order. */
  position: sticky;
  top: 0;
  height: 100vh;
  align-self: start;
  overflow-y: auto;
}

.side .brand {
  margin-bottom: 12px;
  padding: 6px 8px;
}

.brand-block {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.brand-tag {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
}

.nav-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--tx-3);
  padding: 12px 10px 6px;
  font-weight: 600;
}

.nav-item {
  display: flex;
  align-items: center;
  padding: 9px 10px;
  border-radius: 10px;
  color: var(--tx-2);
  font-weight: 500;
  font-size: 14px;
  text-decoration: none;
  transition: 0.15s;
}

.nav-item:hover {
  background: var(--surface);
  color: var(--tx);
}

.nav-item.active {
  background: var(--surface);
  color: var(--tx);
}

.nav-item.is-disabled {
  color: var(--tx-3);
  pointer-events: none;
  opacity: 0.5;
}

.nav-gap {
  height: 14px;
}

.side-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.credits {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px;
}

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

.credits-lab {
  font-size: 11px;
  color: var(--tx-3);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.credits-n {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 16px;
  color: var(--tx-2);
}

.bar-mini {
  height: 4px;
  border-radius: 3px;
  background: var(--surface-2);
  margin-top: 9px;
  overflow: hidden;
}

.bar-mini i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--lime);
}

.profile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}

.profile:hover {
  background: var(--surface);
}

.ava {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--lime), var(--good));
  flex: none;
}

.profile-text {
  min-width: 0;
}

.profile-n {
  font-weight: 500;
  font-size: 12px;
  color: var(--tx);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 150px;
}

.profile-m {
  font-size: 11px;
  color: var(--tx-3);
}

.main {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background:
    radial-gradient(1200px 600px at 70% -10%, rgba(212, 248, 75, 0.05), transparent 60%),
    var(--bg);
}

.top {
  height: 60px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  padding: 0 24px;
  flex: none;
  /* Pinned to the viewport top; opaque so the document scrolls under it. */
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--bg);
}

/* App-open greeting (F5-2b): in the empty-state hero of the tool pages, replacing the heading. Two
   lines; punch words pop lime. Hides for free with the hero via #grid:not(:empty) ~ #empty. */
.greet {
  max-width: 540px;
  margin: 0 auto;
}

.greet .greet-1 {
  display: block;
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(30px, 1.9vw, 44px);
  font-weight: 700;
  color: var(--tx);
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.greet .greet-2 {
  display: block;
  font-size: clamp(16px, 1vw, 22px);
  color: var(--tx-2);
  line-height: 1.4;
  margin-top: 8px;
}

.g-pop {
  color: var(--lime);
  font-weight: 700;
}

.g-shout {
  color: var(--lime);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.top-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: 0.3px;
}

.top-sub {
  font-size: 12px;
  color: var(--tx-3);
}

.content {
  flex: 1;
  position: relative;
  min-height: 0;
}

/* The document (shell pages) is the scroller, but its scrollbar is hidden - scroll still works via
   trackpad/wheel/keyboard. Scoped to shell pages via :has(.app) so landing/auth keep their normal
   scrollbar. */
html:has(.app) {
  scrollbar-width: none;
}
html:has(.app)::-webkit-scrollbar {
  display: none;
}

/* The few elements that still scroll internally (sidebar on a short viewport, drawer body) also hide
   their scrollbar for consistency. */
.side,
.dr-body {
  scrollbar-width: none;
}
.side::-webkit-scrollbar,
.dr-body::-webkit-scrollbar {
  display: none;
}

.canvas {
  padding: 28px 28px 192px;
}

.empty-state {
  /* Exactly the free band between the sticky topbar (60px) and the fixed composer clearance (the
     canvas paddings, 28 + 192), so an EMPTY tool page never scrolls - the document is precisely one
     viewport tall. The hero centers in that band; the bottom padding biases it ~30px above the
     geometric center (optical centering, Aljaz 2026-07-16). Media blocks mirror the canvas paddings. */
  min-height: calc(100vh - 60px - 28px - 192px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 12px;
  padding-bottom: 60px;
}

/* Empty-slot frame holding the Adhook brand mark (replaced the four-point star, which read as the
   Gemini logo). */
.empty-mark {
  width: 76px;
  height: 76px;
  border-radius: 22px;
  border: 1px dashed var(--line-2);
  display: grid;
  place-items: center;
}

.empty-mark .em-a {
  width: 46px;
  height: 46px;
  border-radius: 13px;
  background: var(--lime);
  color: var(--on-lime);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 26px;
  line-height: 1;
}

.empty-state h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  margin: 0;
}

.empty-state p {
  color: var(--tx-3);
  max-width: 340px;
  line-height: 1.5;
  margin: 0;
}

/* ---------- generate bar (visual; Generate enabled in a later step) ---------- */
.gbar-wrap {
  /* Docked to the viewport bottom (fixed) while the document scrolls, offset by the sidebar width so
     it aligns with the content column. left becomes 0 when the sidebar is collapsed (desktop) or an
     overlay (mobile) - see the media rules by the responsive shell block. */
  position: fixed;
  left: 240px;
  right: 0;
  bottom: 0;
  z-index: var(--z-sticky);
  /* Generous bottom padding lifts the bar off the viewport edge (Aljaz 2026-07-16). */
  padding: 16px 28px 38px;
  background: linear-gradient(transparent, var(--bg) 44%);
  pointer-events: none;
}

.gbar {
  pointer-events: auto;
  max-width: 880px;
  margin: 0 auto;
  background: rgba(20, 20, 23, 0.9);
  border: 1px solid var(--line-2);
  border-radius: 16px;
  padding: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.prod-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  height: var(--h-control);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  padding: 0 12px 0 8px;
  cursor: pointer;
  flex: none;
  color: var(--tx);
}

.prod-chip:hover {
  border-color: var(--line-2);
}

.prod-thumb {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px dashed var(--line-2);
  color: var(--tx-3);
  flex: none;
  overflow: hidden;
  font-size: 12px;
  font-weight: 600;
}

.prod-thumb.has-img {
  border-style: solid;
}

.prod-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pc-text {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: left;
}

.pc-name {
  font-weight: 500;
  font-size: 13px;
}

.pc-sub {
  font-size: 10px;
  color: var(--tx-3);
}

/* Ad Reference upload control in the generate bar (F3-B) */
.upload-chip {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--h-control);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  padding: 0 12px;
  cursor: pointer;
  flex: none;
  color: var(--tx-2);
  font-size: 12.5px;
}

.upload-chip:hover {
  border-color: var(--line-2);
}

.upload-chip.has-file {
  color: var(--tx);
  border-color: var(--lime);
}

/* Visually hidden, NOT display:none - the input stays keyboard-focusable so a keyboard user
   can Tab to the chip and open the file picker (focus ring via :focus-within below). */
.upload-chip input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

.upload-chip:focus-within {
  border-color: var(--lime);
}

.uc-ic {
  width: 14px;
  height: 14px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.uc-lab {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 130px;
}

.describe {
  flex: 1;
  min-width: 0;
}

.describe input {
  width: 100%;
  height: var(--h-control);
  background: transparent;
  border: none;
  outline: none;
  color: var(--tx);
  font-size: 14px;
  font-family: inherit;
}

.describe input::placeholder {
  color: var(--tx-3);
}

.fmt-wrap {
  position: relative;
  flex: none;
}

.seg {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--h-control);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0 12px;
  flex: none;
  cursor: pointer;
  transition: border-color 0.15s;
}

.seg:hover {
  border-color: var(--line-2);
}

.seg-ic {
  width: 11px;
  height: 15px;
  border-radius: 3px;
  border: 1.5px solid var(--tx-3);
  flex: none;
}

.seg-lab {
  font-weight: 500;
  font-size: 12.5px;
  color: var(--tx-2);
}

.seg-caret {
  display: inline-flex;
  align-items: center;
  color: var(--tx-3);
}

.fmt-pop {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  width: 230px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 14px;
  padding: 7px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
  display: none;
  z-index: 5;
}

.fmt-pop.show {
  display: block;
}

.fmt-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 12px;
  border: none;
  background: transparent;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.12s;
}

.fmt-opt:hover {
  background: var(--surface-2);
}

.fmt-opt.on {
  background: var(--surface-2);
}

.fmt-opt .fo-l {
  display: flex;
  align-items: center;
  gap: 10px;
}

.fmt-opt .fo-ic {
  width: 16px;
  height: 22px;
  border-radius: 3px;
  border: 1.5px solid var(--tx-3);
}

.fmt-opt .fo-ic.feed {
  width: 20px;
  height: 18px;
}

.fmt-opt .fo-ic.both {
  width: 20px;
  height: 20px;
  border-style: dashed;
}

.fmt-opt.on .fo-ic {
  border-color: var(--lime);
}

.fmt-opt .fo-n {
  font-weight: 500;
  font-size: 13px;
  color: var(--tx-2);
}

.fmt-opt .fo-c {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--tx-3);
}

.fmt-opt.on .fo-c {
  color: var(--lime);
}

.gen-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  height: var(--h-control);
  background: var(--lime);
  color: var(--on-lime);
  font-weight: 600;
  font-family: var(--font-display);
  font-size: 14.5px;
  padding: 0 18px;
  border: none;
  border-radius: var(--r-control);
  flex: none;
  cursor: pointer;
}

.gen-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---------- modal ---------- */
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(3px);
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 20px;
  width: 560px;
  max-width: 100%;
  max-height: 88vh;
  overflow: auto;
}

.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 22px 22px 12px;
  /* The modal itself scrolls; keep the title + close reachable on long forms. */
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

/* Scroll anchors inside the modal (htmx show:top targets) must clear the sticky head. */
#entity-msg,
#prod-edit {
  scroll-margin-top: 110px;
}

.modal-head h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  margin: 0;
}

.modal-head p {
  color: var(--tx-3);
  font-size: 13px;
  margin: 5px 0 0;
  line-height: 1.5;
  max-width: 360px;
}

.x {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  color: var(--tx-3);
  border: 1px solid var(--line);
  background: transparent;
  cursor: pointer;
  flex: none;
}

.x:hover {
  color: var(--tx);
  border-color: var(--line-2);
}

/* Corner close on the creative detail modal (replaces the old footer Close button). */
.detail-x {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 5;
  background: rgba(var(--bg-rgb), 0.55);
  backdrop-filter: blur(6px);
}

.modal-body {
  padding: 16px 22px 22px;
}

.url-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.url-input {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  padding: 0 13px;
  height: var(--h-control);
}

.url-input input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  color: var(--tx);
  font-size: 13.5px;
  font-family: inherit;
}

.url-input input::placeholder {
  color: var(--tx-3);
}

.htmx-indicator {
  display: none;
}

.htmx-request .htmx-indicator {
  display: inline;
}

/* small in-button spinner, shown while its button's request is in flight */
.spinner-sm {
  display: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(0, 0, 0, 0.25);
  border-top-color: currentColor;
  animation: rot 0.7s linear infinite;
  vertical-align: -2px;
  margin-right: 6px;
}
.htmx-request .spinner-sm,
.htmx-request.spinner-sm {
  display: inline-block;
}

/* generic disabled state (buttons disabled while a request is in flight, hx-disabled-elt) */
.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.saved-lab {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--tx-3);
  font-weight: 600;
  margin: 22px 0 11px;
}

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

.saved {
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-2);
  text-align: left;
  cursor: pointer;
  color: var(--tx);
  display: flex;
  flex-direction: column;
}

.saved:hover {
  border-color: var(--lime);
}

.sv-img {
  position: relative;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--surface-2), var(--surface));
  color: rgba(255, 255, 255, 0.92);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  text-transform: uppercase;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.sv-img img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sv-n {
  padding: 8px 10px 2px;
  font-size: 12px;
  color: var(--tx);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sv-b {
  padding: 0 10px 8px;
  font-size: 10.5px;
  color: var(--tx-3);
}

.saved-empty {
  color: var(--tx-3);
  font-size: 13px;
  grid-column: 1 / -1;
  margin: 0;
}

.saved-count {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--tx-3);
  margin: 0 0 2px;
}

/* kind badge + delete overlay on a saved card (F3-A) */
.sv-kind {
  position: absolute;
  top: 6px;
  left: 6px;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  color: rgba(255, 255, 255, 0.92);
  padding: 2px 6px;
  border-radius: 6px;
  text-shadow: none;
}

.sv-del {
  position: absolute;
  top: 5px;
  right: 5px;
  /* 24px minimum tap target: always visible (and tappable) on touch devices. */
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  line-height: 1;
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.saved:hover .sv-del {
  opacity: 1;
}

/* Pencil twin of the delete button, sitting to its left. */
.sv-edit {
  position: absolute;
  top: 5px;
  right: 33px;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  line-height: 1;
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.saved:hover .sv-edit {
  opacity: 1;
}

.sv-edit:hover {
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
}

/* No hover on touch devices: keep edit + delete reachable. */
@media (hover: none) {
  .sv-del,
  .sv-edit {
    opacity: 1;
  }
}

.sv-del:hover {
  background: var(--bad);
  color: var(--on-lime);
}

/* Armed state of the two-step delete: widens into a red "Delete?" pill until confirmed. */
.sv-del.arm {
  width: auto;
  padding: 0 9px;
  background: var(--bad);
  color: #fff;
  opacity: 1;
}

.sv-del-lab {
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* product/service toggle in the add modal (F3-A) */
.kind-toggle {
  display: inline-flex;
  gap: 4px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 3px;
  margin-bottom: 12px;
}

.kt-opt {
  border: none;
  background: transparent;
  color: var(--tx-2);
  padding: 6px 18px;
  border-radius: 8px;
  font-size: 12.5px;
  cursor: pointer;
}

.kt-opt.on {
  background: var(--lime);
  color: #0d0d0d;
  font-weight: 600;
}

/* enrichment images: removable candidate thumbs + upload tile (F3-A) */
.field-hint {
  color: var(--tx-3);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  margin-left: 6px;
  font-size: 10.5px;
}

.img-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.img-cell {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 9px;
  overflow: hidden;
  border: 1px solid var(--line-2);
}

.img-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.img-x {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  cursor: pointer;
  font-size: 10px;
  display: grid;
  place-items: center;
}

.img-upload {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 9px;
  border: 1px dashed var(--line-2);
  display: grid;
  place-items: center;
  align-content: center;
  cursor: pointer;
  text-align: center;
  color: var(--tx-3);
  gap: 2px;
}

.img-upload input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

.img-upload:focus-within {
  border-color: var(--lime);
}

.img-upload-plus {
  display: inline-flex;
  line-height: 0;
}

.img-upload-lab {
  font-size: 8.5px;
  padding: 0 4px;
}

/* ---------- editable scraped fields ---------- */
.scraped {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.scraped-note {
  font-size: 11.5px;
  color: var(--tx-3);
  background: rgba(212, 248, 75, 0.06);
  border: 1px solid rgba(212, 248, 75, 0.18);
  border-radius: 10px;
  padding: 9px 11px;
  line-height: 1.5;
}

.textarea {
  height: auto;
  padding: 10px 12px;
  line-height: 1.5;
  resize: vertical;
}

.swatches {
  display: flex;
  gap: 8px;
}

.sw {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  border: 1px solid var(--line-2);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 2px;
}

/* ---------- generation batch + cards (F1 step 3) ---------- */
.batch-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 18px;
}
.batch-head h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
}
.grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-content: flex-start;
}
/* empty state hides once the batch has any card */
#grid:not(:empty) ~ #empty {
  display: none;
}
.card {
  width: 208px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  position: relative;
  transition: 0.18s;
}
.card.story {
  aspect-ratio: 9 / 16;
}
.card.done {
  cursor: pointer;
}
.card.done:hover {
  border-color: var(--line-2);
  transform: translateY(-3px);
}
.card .fmt-badge {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 3;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  padding: 3px 8px;
  border-radius: 7px;
  color: var(--tx-2);
}
/* generating */
.card.gen .shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(212, 248, 75, 0.07) 50%,
    transparent 70%
  );
  background-size: 220% 100%;
  animation: sweep 1.7s linear infinite;
}
@keyframes sweep {
  0% {
    background-position: 130% 0;
  }
  100% {
    background-position: -130% 0;
  }
}
.gen-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--tx-3);
}
.spin {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2.5px solid var(--surface-2);
  border-top-color: var(--lime);
  animation: rot 0.8s linear infinite;
}
@keyframes rot {
  to {
    transform: rotate(360deg);
  }
}
.gen-step {
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.3px;
}
.gen-sub {
  margin-top: 6px;
  font-size: 11.5px;
}
.gen-sub a {
  color: inherit;
  text-decoration: underline;
}
.gen-prog {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  height: 3px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.gen-prog i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--lime);
  transition: width 0.4s;
}
.card.failed .gen-center {
  color: var(--bad);
}
.fail-mark {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid var(--bad);
  display: grid;
  place-items: center;
}

/* Corner dismiss on a failed card: removes the card from the batch view (the job row stays). */
.card-dismiss {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 3;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  display: grid;
  place-items: center;
}

.card-dismiss:hover {
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
}
/* done creative */
.card .art {
  position: absolute;
  inset: 0;
  animation: reveal 0.5s ease both;
}
.card .art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@keyframes reveal {
  from {
    opacity: 0;
    transform: scale(1.03);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.card .quick {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 3;
  display: flex;
  gap: 6px;
  opacity: 0;
  transition: 0.15s;
  transform: translateY(-3px);
}
.card.done:hover .quick {
  opacity: 1;
  transform: none;
}
.qbtn {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  display: grid;
  place-items: center;
  color: #fff;
  border: 1px solid var(--line);
}
.qbtn:hover {
  background: rgba(0, 0, 0, 0.8);
}
/* generate error chip */
.gen-error {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  background: rgba(255, 128, 128, 0.08);
  border: 1px solid rgba(255, 128, 128, 0.35);
  color: var(--bad);
  border-radius: 12px;
  padding: 11px 14px;
  font-size: 13px;
}
.gen-error button {
  color: var(--bad);
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
/* ---------- detail popup ---------- */
.detail {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 20px;
  width: 920px;
  max-width: 100%;
  max-height: 90vh;
  display: grid;
  grid-template-columns: 1fr 360px;
  overflow: hidden;
  animation: pop 0.2s ease both;
}
.detail-art {
  background: var(--bg-2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  position: relative;
}
.detail-canvas {
  width: 280px;
  max-width: 100%;
  aspect-ratio: 9 / 16;
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
}
.detail-canvas[data-fmt="feed"] {
  aspect-ratio: 4 / 5;
}
.detail-tabs {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 3px;
}
.detail-tabs button {
  padding: 6px 14px;
  border: none;
  background: none;
  border-radius: 7px;
  color: var(--tx-3);
  font-weight: 500;
  font-size: 12.5px;
  font-family: inherit;
  cursor: pointer;
  transition: 0.12s;
}
.detail-tabs button.on {
  background: var(--surface-2);
  color: var(--tx);
}
.detail-side {
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  overflow: auto;
}
.detail-side-head {
  padding: 18px 48px 6px 18px;
}
.detail-side-head .nm {
  font-weight: 600;
  font-size: 13.5px;
}
.detail-side-head .dt {
  font-size: 11px;
  color: var(--tx-3);
}
.copy-sec {
  padding: 14px 18px;
  position: relative;
}
.copy-sec-lab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.copy-sec-lab span {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--tx-3);
  font-weight: 600;
}
.copy-val {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 11px 12px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--tx);
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease);
}
.copy-val:hover {
  border-color: var(--line-2);
}
.copy-tools {
  display: flex;
  gap: 6px;
}
.copy-tools button {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  color: var(--tx-3);
  background: transparent;
  border: 1px solid var(--line);
  cursor: pointer;
  transition:
    color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease);
}
.copy-tools button:hover {
  color: var(--lime);
  border-color: var(--line-2);
}
/* colored "Copied" confirmation pill, pops over the field for ~1s */
.copied-pill {
  position: absolute;
  left: 50%;
  top: calc(50% + 10px);
  z-index: 3;
  background: var(--lime);
  color: var(--on-lime);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 5px 12px;
  border-radius: 100px;
  box-shadow: 0 6px 18px rgba(var(--lime-rgb), 0.4);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.9);
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease);
}
.copy-sec.copied .copied-pill {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.copy-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.copy-edit textarea,
.cta-select {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 11px;
  padding: 10px 12px;
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
  color: var(--tx);
  resize: vertical;
}
.copy-edit textarea:focus,
.cta-select:focus {
  outline: none;
  border-color: var(--lime);
  box-shadow: 0 0 0 2px rgba(var(--lime-rgb), 0.22);
}
.cta-select {
  resize: none;
  cursor: pointer;
}
.edit-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.counter {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--tx-3);
}
.edit-actions {
  display: flex;
  gap: 8px;
}
.copy-edit .btn {
  height: 32px;
  padding: 0 14px;
  font-size: 13px;
}
.copy-err {
  margin: 0 18px 4px;
  color: var(--bad);
  background: var(--bad-tint);
  border: 1px solid var(--bad-dim);
  border-radius: 9px;
  padding: 8px 11px;
  font-size: 12.5px;
}
@media (prefers-reduced-motion: reduce) {
  .copied-pill {
    transition-duration: 0.01ms;
    transform: translate(-50%, -50%);
  }
}
.cta-pill {
  display: inline-block;
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  padding: 5px 11px;
  font-weight: 600;
  font-size: 12.5px;
}
.variants {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.variant {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 11px;
  font-size: 12.5px;
  color: var(--tx-2);
}
.variant button {
  font-size: 11px;
  color: var(--tx-3);
}
.variant button:hover {
  color: var(--lime);
}
.detail-foot {
  margin-top: auto;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 9px;
  position: sticky;
  bottom: 0;
  background: var(--surface);
}
.foot-row {
  display: flex;
  gap: 9px;
}
.btn-lime {
  flex: 1;
  background: var(--lime);
  color: var(--on-lime);
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 11px;
  border-radius: 11px;
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.btn-lime:hover {
  background: var(--lime-hover);
}
.btn-line {
  flex: 1;
  background: transparent;
  border: 1px solid var(--line-2);
  color: var(--tx-2);
  font-family: var(--font-ui);
  font-weight: 600;
  padding: 11px;
  border-radius: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  transition:
    color var(--dur-base) var(--ease),
    border-color var(--dur-base) var(--ease);
}
.btn-line:hover {
  color: var(--tx);
  border-color: var(--tx-3);
}
.gen-btn .gc {
  display: flex;
  align-items: center;
  gap: 3px;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 12px;
  background: rgba(0, 0, 0, 0.16);
  padding: 2px 7px;
  border-radius: 6px;
}
@media (max-width: 720px) {
  .detail {
    grid-template-columns: 1fr;
  }
}

/* ---------- billing page (redesigned onto the design system) ---------- */
.billing {
  padding: 24px 28px 48px;
  max-width: 1080px;
  margin-inline: auto;
}

.billing .bill-top {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  align-items: stretch;
}

.billing .bill-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
}

.billing .bill-lab {
  font-family: var(--font-ui);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  font-weight: 600;
  margin: 0 0 var(--space-3);
}

.billing .bill-plan-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(26px, 1.4vw, 34px);
  line-height: 1.1;
  color: var(--tx);
}

.billing .bill-plan-sub {
  color: var(--tx-2);
  font-size: 13.5px;
  margin-top: 4px;
}

.billing .muted {
  color: var(--tx-3);
  font-size: 12.5px;
  margin-top: var(--space-3);
}

/* Actions pinned to the card bottom so the two top cards line up regardless of body length. */
.billing .bill-actions {
  margin-top: auto;
  padding-top: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.billing .bill-credits {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(32px, 1.8vw, 44px);
  color: var(--lime);
  line-height: 1;
}

.billing .bill-credits-u {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--tx-3);
  font-weight: 500;
  margin-left: 8px;
}

.billing .ubar {
  height: 8px;
  border-radius: 5px;
  background: var(--surface-2);
  margin: var(--space-4) 0 var(--space-2);
  overflow: hidden;
}

.billing .ubar i {
  display: block;
  height: 100%;
  background: var(--lime);
  border-radius: 5px;
}

.billing .bill-usage-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 12.5px;
  color: var(--tx-3);
}

.billing .sec-lab {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--tx-3);
  font-weight: 600;
  margin: var(--space-8) 0 var(--space-3);
  scroll-margin-top: 16px;
}

.billing .plans {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  align-items: stretch;
}

.billing .topup {
  display: flex;
  flex-direction: column;
}
.billing .topup-readout {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
.billing .tu-credits {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(30px, 1.56vw, 40px);
}
.billing .tu-unit {
  font-size: 14px;
  color: var(--tx-3);
  font-weight: 600;
}
.billing .tu-rate {
  font-size: 12.5px;
  color: var(--tx-3);
  margin-top: 5px;
}
.billing .tu-price {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(30px, 1.56vw, 40px);
  color: var(--lime);
}
.billing .tu-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 5px;
  background: var(--surface-2);
  outline: none;
  margin: 18px 0 8px;
  cursor: pointer;
}
.billing .tu-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--lime);
  border: 3px solid var(--bg-2);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.billing .tu-slider::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--lime);
  border: 3px solid var(--bg-2);
  cursor: pointer;
}
.billing .tu-ticks {
  display: flex;
  justify-content: space-between;
}
.billing .tu-tick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  color: var(--tx-3);
  font-weight: 600;
  background: none;
  border: none;
  cursor: pointer;
  transition: 0.12s;
}
.billing .tu-tick:hover {
  color: var(--tx-2);
}
.billing .tu-tick span {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
}
.billing .tu-tick.on span {
  color: var(--lime);
}
.billing .tu-tick.on {
  color: var(--lime);
}
.billing .tu-buy {
  margin-top: 18px;
  width: 100%;
  justify-content: center;
  display: flex;
}
.billing .tu-buy:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.billing .plan {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
}

.billing .plan.current {
  border-color: rgba(var(--lime-rgb), 0.4);
  box-shadow: 0 0 0 1px rgba(var(--lime-rgb), 0.2);
}

.billing .plan.pop {
  border-color: rgba(var(--lime-rgb), 0.45);
  box-shadow: 0 0 0 1px rgba(var(--lime-rgb), 0.25);
}

.billing .plan-ribbon {
  position: absolute;
  top: -10px;
  right: var(--space-4);
  background: var(--lime);
  color: var(--on-lime);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 3px 9px;
  border-radius: 999px;
}

.billing .pn {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  color: var(--tx);
}

.billing .pp {
  font-family: var(--font-display);
  font-size: clamp(24px, 1.3vw, 30px);
  font-weight: 500;
  color: var(--tx);
  margin-top: var(--space-2);
}

.billing .pp-u {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  color: var(--tx-3);
}

.billing .pc {
  font-size: 12.5px;
  color: var(--tx-2);
  margin-top: 4px;
}

.billing .pu {
  font-size: 11px;
  color: var(--tx-3);
  margin-top: 4px;
}

/* A fixed gap ABOVE the CTA - as a margin, never padding on the pill/button, so the pill keeps its
   h-control height and its label stays vertically centered. Plan cards are uniform, so the CTAs
   still line up across the grid. */
.billing .plan form,
.billing .plan > .pbtn,
.billing .plan > .pbtn-static {
  margin-top: var(--space-5);
}

.billing .plan form {
  display: flex;
}

.billing .plan .pbtn {
  width: 100%;
}

.billing .pbtn-static {
  width: 100%;
  height: var(--h-control);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-control);
  color: var(--tx-3);
  font-size: 14px;
  font-weight: 600;
}

/* Downgrade confirm modal (single instance, Alpine-toggled). */
.billing .bill-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
}

.billing .bill-modal-scrim {
  position: absolute;
  inset: 0;
  background: rgba(var(--bg-rgb), 0.72);
}

.billing .bill-modal-box {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  padding: var(--space-6);
  box-shadow: var(--shadow-2);
}

.billing .bill-modal-t {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  margin: 0 0 var(--space-3);
}

.billing .bill-modal-p {
  font-size: 13.5px;
  color: var(--tx-2);
  line-height: 1.5;
  margin: 0 0 var(--space-5);
}

.billing .bill-modal-p b {
  color: var(--tx);
}

.billing .bill-modal-acts {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}

/* Skeleton for the lazy-loaded billing history. */
.billing .bill-skel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.billing .bill-skel span {
  height: 44px;
  border-radius: var(--r-control);
  background: linear-gradient(90deg, var(--surface) 0%, var(--surface-2) 50%, var(--surface) 100%);
  background-size: 200% 100%;
  animation: bill-shimmer 1.3s ease-in-out infinite;
}

@keyframes bill-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .billing .bill-skel span {
    animation: none;
  }
}

.billing .alert-act {
  margin-top: var(--space-3);
}

@media (max-width: 1000px) {
  .billing .plans {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 720px) {
  .billing .plans {
    grid-template-columns: 1fr;
  }
}

.billing .tbl {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}

.billing .tr {
  display: grid;
  grid-template-columns: 1.3fr 1.6fr 1fr 0.9fr 0.7fr;
  align-items: center;
  gap: var(--space-4);
  padding: 14px 20px;
  font-size: 13px;
  border-top: 1px solid var(--line);
}

.billing .tr.head {
  border-top: none;
  background: var(--surface-2);
  color: var(--tx-3);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  font-weight: 600;
}

.billing .tr .amt {
  font-variant-numeric: tabular-nums;
  color: var(--tx);
}

/* Fallback/empty row (a single message cell): span the whole table, center the message, and give it
   generous vertical space so it reads as an intentional empty state, not a cramped data-row-height bar. */
.billing .tr:has(> .muted) {
  padding: var(--space-8) var(--space-5);
}
.billing .tr > .muted {
  grid-column: 1 / -1;
  margin: 0;
  text-align: center;
}

/* Status pills - a centered, tinted pill, consistent with the app's status chips. */
.billing .badge-ok,
.billing .badge-neutral {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
}

.billing .badge-ok {
  background: var(--good-tint);
  color: var(--good);
}

.billing .badge-neutral {
  background: var(--surface-2);
  color: var(--tx-2);
}

.billing .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--good);
}

/* The invoice-link cell right-aligns its content (justify-self on the inline <a> was a no-op). */
.billing .tr.inv-row > span:last-child {
  text-align: right;
}

.billing .inv {
  color: var(--tx-3);
  font-size: 12.5px;
  text-decoration: none;
}

.billing .inv:hover {
  color: var(--lime);
}

.billing .hist-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--tx-3);
}

.billing .hist-nav {
  display: flex;
  gap: 8px;
}

.billing .hist-nav button {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  border: 1px solid var(--line-2);
  background: none;
  display: grid;
  place-items: center;
  color: var(--tx-2);
  cursor: pointer;
  transition: 0.12s;
}

.billing .hist-nav button:hover:not(:disabled) {
  color: var(--tx);
  border-color: var(--tx-3);
}

.billing .hist-nav button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.billing .pay-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-5);
  margin-top: var(--space-8);
}

.billing .pay-note .pt {
  font-weight: 500;
  font-size: 13.5px;
}

.billing .pay-note .ps {
  font-size: 12px;
  color: var(--tx-3);
  margin-top: 2px;
}

/* gallery (FRONTEND.md 5.2) */
.gallery {
  display: flex;
  flex-direction: column;
}
.gallery .toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 24px 6px;
  flex: none;
  /* Sticky below the 60px topbar so the search/filters stay visible while cards scroll under. */
  position: sticky;
  top: 60px;
  z-index: var(--z-dropdown);
  background: var(--bg);
}
.gallery .search {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 38px;
  width: 280px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 0 13px;
  color: var(--tx-3);
  transition: border-color 0.15s;
}
.gallery .search:focus-within {
  border-color: var(--line-2);
}
.gallery .search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  color: var(--tx);
  font-size: 13.5px;
  font-family: inherit;
}
.gallery .search input::placeholder {
  color: var(--tx-3);
}
.gallery .filters {
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 3px;
}
.gallery .filters a,
.gallery .filters button {
  padding: 7px 15px;
  border: none;
  background: none;
  border-radius: 8px;
  font-weight: 500;
  font-size: 12.5px;
  font-family: inherit;
  color: var(--tx-3);
  text-decoration: none;
  cursor: pointer;
  transition: 0.12s;
}
.gallery .filters a:hover,
.gallery .filters button:hover {
  color: var(--tx-2);
}
.gallery .filters a.on,
.gallery .filters button.on {
  background: var(--surface-2);
  color: var(--tx);
}
.gallery .scroll {
  padding: 16px 24px 40px;
}
.gal {
  column-count: 5;
  column-gap: 16px;
}
@media (max-width: 1640px) {
  .gal {
    column-count: 4;
  }
}
@media (max-width: 1200px) {
  .gal {
    column-count: 3;
  }
}
@media (max-width: 820px) {
  .gal {
    column-count: 2;
  }
}
.gcard {
  break-inside: avoid;
  margin-bottom: 16px;
  border-radius: 14px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: 0.18s;
  display: block;
  width: 100%;
  background: var(--surface);
  padding: 0;
  text-align: left;
}
.gcard:hover {
  border-color: var(--line-2);
  transform: translateY(-3px);
}
.gcard.story {
  aspect-ratio: 9 / 16;
}
.gcard.feed {
  aspect-ratio: 4 / 5;
}
.gcard.stacked {
  /* Offset "peek" of the second creative behind the card (pure shadow, no second image). */
  box-shadow: 6px -6px 0 -1px var(--surface-2), 6px -6px 0 0 var(--line-2);
  margin-top: 6px;
}
.stack-badge {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 5px;
  background: rgba(0, 0, 0, 0.55);
  padding: 3px 8px;
  border-radius: 7px;
  color: var(--tx-2);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.gcard .art {
  position: absolute;
  inset: 0;
}
.gcard .art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.gcard .fmt-badge {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 3;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  padding: 3px 8px;
  border-radius: 7px;
  color: var(--tx-2);
}
.gcard .quick {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 3;
  display: flex;
  gap: 6px;
  opacity: 0;
  transition: 0.15s;
  transform: translateY(-3px);
}
.gcard:hover .quick {
  opacity: 1;
  transform: none;
}
.qbtn.fav-on {
  color: var(--lime);
  border-color: rgba(212, 248, 75, 0.4);
}
/* Product name as a readable pill at the card's bottom-left (glass chip, matches the format badges),
   so it stays legible over any image instead of low-contrast text on a gradient. */
.gcard .label {
  position: absolute;
  left: 10px;
  bottom: 10px;
  max-width: calc(100% - 20px);
  z-index: 2;
  padding: 6px 12px;
  border-radius: 100px;
  background: rgba(var(--bg-rgb), 0.72);
  backdrop-filter: blur(8px);
  border: 1px solid var(--glass-line);
  color: var(--tx);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.gal-more {
  column-span: all;
  display: flex;
  justify-content: center;
  padding: 20px 0;
}
.empty-msg {
  color: var(--tx-3);
  text-align: center;
  padding: 60px 0;
  font-size: 14px;
}

/* Admin console (F4-A). Reuses the app shell (.app/.side/.nav-item/.main/.top/.brand*). New:
   ADMIN badge, back link, Overview KPI cards, unit economics, generation stats, recent signups.
   Tokens only. Data-table + drawer + status-badge CSS lands with F4-B. */
.admin-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.8px;
  color: var(--lime);
  border: 1px solid var(--lime-dim);
  border-radius: 5px;
  padding: 1px 5px;
  vertical-align: middle;
}

.back {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--tx-2);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: 0.15s;
}

.back:hover {
  background: var(--surface);
  color: var(--tx);
}

.back-ic {
  width: 14px;
  height: 14px;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  margin-left: 3px;
}

.admin-scroll {
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  /* Cap + center on ultrawide so rows never stretch into a void (rubric #7; billing caps too). */
  width: 100%;
  max-width: 1400px;
  margin-inline: auto;
}

.kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}

.kpi {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px;
}

.kpi .kl {
  font-size: 12px;
  color: var(--tx-3);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.kpi .kv {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(30px, 1.56vw, 40px);
  color: var(--tx);
  margin-top: 8px;
}

.kpi .kv .u {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 14px;
  color: var(--tx-3);
  text-decoration: none;
}

.adm-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px 20px;
}

.panel .pt {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--tx);
  margin-bottom: 14px;
}

.econ-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}

.econ-row .el {
  font-size: 13px;
  color: var(--tx-2);
}

.econ-row .ev {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--tx);
}

.econ-row .ev.good {
  color: var(--good);
}

.econ-row .ev.bad {
  color: var(--bad);
}

.margin-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--surface-2);
  margin-top: 14px;
  overflow: hidden;
}

.margin-bar .mfill {
  display: block;
  height: 100%;
  background: var(--lime);
}

.econ-note {
  font-size: 11px;
  color: var(--tx-3);
  line-height: 1.4;
  margin-top: 12px;
}

.genstats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.gstat {
  background: var(--surface-2);
  border-radius: 12px;
  padding: 14px;
}

.gstat .gl {
  font-size: 12px;
  color: var(--tx-3);
}

.gstat .gv {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(22px, 1.15vw, 30px);
  color: var(--tx);
  margin-top: 6px;
}

.gstat .gv.good {
  color: var(--good);
}

.gstat .gv.bad {
  color: var(--bad);
}

.su-tbl {
  display: flex;
  flex-direction: column;
}

.su-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}

.su-mail {
  font-size: 13px;
  color: var(--tx);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.plan-pill {
  font-size: 11px;
  font-weight: 500;
  color: var(--tx-2);
  background: var(--surface-2);
  border-radius: 6px;
  padding: 3px 9px;
}

.su-when {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--tx-3);
}

.su-empty {
  color: var(--tx-3);
  font-size: 13px;
  padding: 10px 0;
}

/* Admin console (F4-B): shared stat strip, toolbar, data table, status pills, invite modal.
   Tokens only. Drawer / step-timeline / cost-box CSS lands with F4-B2. Toolbar classes are
   namespaced under .adbar so they never clash with the gallery's .gallery .search/.filters. */
.statstrip {
  display: grid;
  /* auto-fit so both the 4-stat (Users) and 5-stat (Jobs) strips fill one row on desktop and wrap
     gracefully on narrow viewports. */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}

.ministat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 14px 16px;
  /* A short strip (few stats) must not stretch one card across the page. */
  max-width: 340px;
}

.ministat .ml {
  font-size: 11.5px;
  color: var(--tx-3);
}

.ministat .mv {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(22px, 1.15vw, 30px);
  margin-top: 5px;
}

.ministat .mv.good {
  color: var(--good);
}

.ministat .mv.warn {
  color: var(--warn);
}

.ministat .mv.bad {
  color: var(--bad);
}

.adbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 16px;
}

.adbar-l {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* .btn-lime is full-width for form submits; keep it compact as a toolbar action. */
.adbar .btn-lime {
  width: auto;
  flex: none;
  white-space: nowrap;
}

.adbar .search {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 0 13px;
  width: 260px;
  color: var(--tx-3);
}

.adbar .search:focus-within {
  border-color: var(--line-2);
}

.adbar .search input {
  border: none;
  background: none;
  outline: none;
  color: var(--tx);
  font-family: var(--font-ui);
  font-size: 13px;
  width: 100%;
}

.adbar .search input::placeholder {
  color: var(--tx-3);
}

.adbar .chips {
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 3px;
}

.adbar .chips button,
.adbar .chips a {
  padding: 7px 13px;
  border: none;
  background: none;
  border-radius: 8px;
  font-weight: 500;
  font-size: 12.5px;
  color: var(--tx-3);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.adbar .chips button.on,
.adbar .chips a.on {
  background: var(--surface-2);
  color: var(--tx);
}

/* Right-side toolbar group: the primary lime "Invite user" plus the lower-emphasis, deliberately
   separate "Invite admin" action. btn-line alone leaves the button's default pale background; force
   a transparent fill + readable white text so it reads as a dark secondary button, not a white one. */
.adbar-r {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.adbar .btn-op,
.sec-head .btn-op {
  flex: none;
  width: auto;
  white-space: nowrap;
  padding: 11px 16px;
  background: transparent;
  color: var(--tx);
}

.dtbl {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.dhead,
.drow {
  display: grid;
  align-items: center;
  padding: 13px 18px;
  font-size: 13px;
}

.dhead {
  color: var(--tx-3);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  font-weight: 600;
}

.drow {
  border-top: 1px solid var(--line);
}

.dtbl.customers .dhead,
.dtbl.customers .drow {
  grid-template-columns: 2.2fr 0.9fr 1.3fr 0.6fr 1fr 1fr 0.7fr;
  gap: 12px;
}

.dtbl.admins .dhead,
.dtbl.admins .drow {
  grid-template-columns: 2.2fr 1.3fr 1fr;
  gap: 12px;
}

.dtbl.audits .dhead,
.dtbl.audits .drow {
  grid-template-columns: 1.1fr 1.6fr 1fr 1.2fr 2.4fr;
  gap: 12px;
}

.c-name {
  font-size: 13px;
  color: var(--tx);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Pills hug their label inside grid rows; a grid item otherwise stretches to the column. */
.drow > .plan-pill {
  justify-self: start;
}

.au-sum {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--tx-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Demo-requests queue (F1). Reuses .dtbl/.drow/.st; visual refresh will restyle admin tables. */
.dtbl.demo .dhead,
.dtbl.demo .drow {
  grid-template-columns: 2fr 1.4fr 1fr 1fr 1.8fr;
  gap: 12px;
}
.dr-when,
.dr-decided {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--tx-3);
}
.dr-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--warn);
}
.dr-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.dr-grant {
  display: flex;
  align-items: center;
  gap: 6px;
}
.dr-amount {
  width: 62px;
  text-align: center;
}

.u-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* Initials avatar (workspace or account). display:grid also survives the mobile stacked-card
   layout, where an inline span would collapse to nothing. */
.u-ava {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  flex: none;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  color: var(--tx-2);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.u-mail {
  font-size: 12.5px;
  color: var(--tx-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cred-t {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--tx-2);
}

.credbar {
  height: 5px;
  border-radius: 4px;
  background: var(--surface-2);
  margin-top: 5px;
  overflow: hidden;
}

.credbar i {
  display: block;
  height: 100%;
  background: var(--lime);
}

.st {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 7px;
  border: 1px solid;
  justify-self: start;
}

.st .d {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.st.good {
  color: var(--good);
  border-color: var(--good-dim);
  background: var(--good-tint);
}

.st.good .d {
  background: var(--good);
}

.st.warn {
  color: var(--warn);
  border-color: var(--warn-dim);
  background: var(--warn-tint);
}

.st.warn .d {
  background: var(--warn);
}

.st.bad {
  color: var(--bad);
  border-color: var(--bad-dim);
  background: var(--bad-tint);
}

.st.bad .d {
  background: var(--bad);
}

.st.run {
  color: var(--lime);
  border-color: var(--lime-dim);
  background: var(--lime-tint);
}

.st.run .d {
  background: var(--lime);
}

.when {
  color: var(--tx-3);
  font-size: 12.5px;
}

.mrr {
  font-family: var(--font-mono);
  font-weight: 600;
  justify-self: end;
}

.drow-more {
  display: flex;
  justify-content: center;
  padding: 16px 0;
}

/* Admin redesign 2026-07-16: nav icons + badge, topbar range picker, Overview cockpit strip,
   customer drawer, plans info note. Tokens only. */
.nav-item {
  gap: 10px;
}

.nav-item .ni {
  flex: none;
  color: var(--tx-3);
  transition: 0.15s;
}

.nav-item:hover .ni {
  color: var(--tx-2);
}

.nav-item.active .ni {
  color: var(--lime);
}

/* Operator entry pinned at the sidebar bottom, just above the credits box. */
.side-foot .side-admin {
  margin-bottom: 10px;
}

.nav-badge {
  margin-left: auto;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--lime);
  color: var(--on-lime);
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  display: grid;
  place-items: center;
}

.top-r {
  margin-left: auto;
  display: flex;
  align-items: center;
}

.range-chips {
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 3px;
}

.range-chips a {
  padding: 6px 11px;
  border-radius: 8px;
  font-weight: 500;
  font-size: 12.5px;
  color: var(--tx-3);
  text-decoration: none;
  transition: 0.12s;
}

.range-chips a:hover {
  color: var(--tx-2);
}

.range-chips a.on {
  background: var(--surface-2);
  color: var(--tx);
}

.att-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}

.att-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 14px 16px;
  text-decoration: none;
  color: var(--tx-2);
  transition: 0.15s;
}

.att-card:hover {
  border-color: var(--line-2);
  background: var(--surface-2);
  color: var(--tx);
}

.att-n {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 22px;
  color: var(--tx);
}

.att-n.warn {
  color: var(--warn);
}

.att-n.bad {
  color: var(--bad);
}

.att-l {
  font-size: 13px;
}

.att-arrow {
  margin-left: auto;
  flex: none;
  color: var(--tx-3);
}

.att-card:hover .att-arrow {
  color: var(--tx);
}

a.kpi {
  display: block;
  text-decoration: none;
  transition: 0.15s;
}

a.kpi.link:hover {
  border-color: var(--line-2);
  background: var(--surface-2);
}

.sec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
}

.sec-head .sec-lab {
  margin: 0;
}

.info-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 14px 16px;
  font-size: 12.5px;
  color: var(--tx-2);
  line-height: 1.5;
}

.info-note svg {
  flex: none;
  color: var(--tx-3);
  margin-top: 1px;
}

/* Customer drawer */
.dr-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.dr-stat {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px;
  min-width: 0;
}

.ds-l {
  font-size: 11px;
  color: var(--tx-3);
}

.ds-v {
  margin-top: 7px;
  font-size: 13.5px;
  color: var(--tx);
}

.dr-note {
  margin-top: 12px;
  font-size: 12px;
  color: var(--tx-3);
  line-height: 1.5;
}

.dr-member {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.dr-member:last-of-type {
  border-bottom: none;
}

.dr-job {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}

.dr-job:last-of-type {
  border-bottom: none;
}

.dr-job-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--tx-2);
}

.dr-grant-form {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

.dr-grant-form .inv-field {
  flex: 1;
}

.dr-grant-form .btn-lime {
  flex: none;
  width: auto;
  white-space: nowrap;
  height: var(--h-control);
  padding: 0 16px;
}

#grant-result {
  margin-top: 8px;
}

.inv-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.inv-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.inv-field > span {
  font-size: 12px;
  color: var(--tx-3);
}

.inv-field input,
.inv-field select {
  height: var(--h-control);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  padding: 0 12px;
  color: var(--tx);
  font-family: var(--font-ui);
  font-size: 13px;
  outline: none;
}

.inv-field input:focus,
.inv-field select:focus {
  border-color: var(--line-2);
}

.inv-msg {
  font-size: 12.5px;
  padding: 4px 0;
}

.inv-msg.good {
  color: var(--good);
}

.inv-msg.bad {
  color: var(--bad);
}

.inv-link {
  width: 100%;
  height: var(--h-control);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  padding: 0 12px;
  color: var(--tx-2);
  font-family: var(--font-mono);
  font-size: 12px;
  outline: none;
}

/* Acknowledgement checkbox row in the operator-invite modal (must be ticked to submit). */
.inv-ack {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 13px;
  color: var(--tx-2);
  line-height: 1.45;
  cursor: pointer;
}

.inv-ack input {
  margin-top: 2px;
  flex: none;
  accent-color: var(--lime);
}

/* Links inside the consent row (e.g. Terms / Privacy) use the brand accent, not the UA blue. */
.inv-ack a {
  color: var(--lime);
}

/* Admin console (F4-B2b): Jobs table variant + the right-slide job-steps drawer. Own .dr-scrim
   (the base .scrim is the centered modal). Tokens only; reuses the status dim/tint tokens. */
.dtbl.jobs .dhead,
.dtbl.jobs .drow {
  grid-template-columns: 0.8fr 1.7fr 1.4fr 1.3fr 1.1fr 0.8fr 1fr;
  gap: 12px;
}

.drow.click {
  cursor: pointer;
  transition: 0.12s;
}

.drow.click:hover {
  background: var(--bg-2);
}

.mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--tx-2);
}

.mono.dim {
  color: var(--tx-3);
}

.dr-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 40;
  display: none;
}

.dr-scrim.show {
  display: block;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: 440px;
  max-width: 100%;
  background: var(--surface);
  border-left: 1px solid var(--line-2);
  z-index: 41;
  transform: translateX(100%);
  transition: transform 0.22s ease;
  display: flex;
  flex-direction: column;
}

.drawer.show {
  transform: none;
}

.dr-head {
  padding: 20px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.dr-id {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--tx-3);
}

.dr-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  margin-top: 4px;
}

.dr-sub {
  font-size: 12.5px;
  color: var(--tx-3);
  margin-top: 3px;
}

.dr-x {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  color: var(--tx-3);
  border: 1px solid var(--line);
  background: none;
  cursor: pointer;
  flex: none;
}

.dr-x:hover {
  color: var(--tx);
  border-color: var(--line-2);
}

.dr-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

.dr-lab {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--tx-3);
  font-weight: 600;
  margin-bottom: 14px;
}

.step {
  display: flex;
  gap: 13px;
  padding-bottom: 20px;
  position: relative;
}

.step::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 22px;
  bottom: 0;
  width: 1.5px;
  background: var(--line);
}

.step:last-child::before {
  display: none;
}

.step-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex: none;
  display: grid;
  place-items: center;
  z-index: 1;
}

.step-dot.done {
  background: var(--good-tint);
  color: var(--good);
}

.step-dot.bad {
  background: var(--bad-tint);
  color: var(--bad);
}

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

.step-name {
  font-size: 13.5px;
  font-weight: 500;
}

.step-meta {
  font-size: 11.5px;
  color: var(--tx-3);
  margin-top: 2px;
  font-family: var(--font-mono);
}

.cost-box {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  margin-top: 6px;
}

.cost-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12.5px;
  padding: 5px 0;
}

.cost-line .cl {
  color: var(--tx-2);
}

.cost-line .cv {
  font-family: var(--font-mono);
}

.cost-line.tot {
  border-top: 1px solid var(--line);
  margin-top: 5px;
  padding-top: 10px;
  font-weight: 600;
}

.cost-line.tot .cv {
  color: var(--lime);
}

/* F4-C: Revenue (charts / breakdown / KPI deltas) + Plans (config tables / edit drawer) */

.grid2 {
  display: grid;
  grid-template-columns: 1.7fr 1fr;
  gap: 14px;
  margin-top: 14px;
}

.grid2b {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 14px;
  margin-top: 14px;
}

.panel-h {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 14px;
}

.panel-h .pt {
  margin-bottom: 0;
}

.panel-h .ps {
  font-size: 11.5px;
  color: var(--tx-3);
  margin-top: 3px;
}

.kd {
  font-size: 12px;
  margin-top: 7px;
  color: var(--tx-3);
}

.kd b {
  font-weight: 600;
}

.kd.up {
  color: var(--good);
}

.kd.down {
  color: var(--bad);
}

.chart {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  height: 200px;
  padding-top: 10px;
}

.chart .col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  height: 100%;
}

.chart .bars {
  flex: 1;
  width: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.chart .bar {
  width: 26px;
  border-radius: 5px 5px 0 0;
}

.chart .bar.rev {
  background: var(--lime);
}

.chart .col-l {
  font-size: 11px;
  color: var(--tx-3);
  font-family: var(--font-mono);
}

.chart-empty {
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 20px;
  color: var(--tx-3);
  font-size: 13px;
}

.breakdown {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.bd-row .bd-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  margin-bottom: 7px;
}

.bd-row .bd-name {
  color: var(--tx-2);
}

.bd-row .bd-val {
  font-family: var(--font-mono);
  font-weight: 600;
}

.bd-track {
  height: 8px;
  border-radius: 5px;
  background: var(--surface-2);
  overflow: hidden;
}

.bd-track i {
  display: block;
  height: 100%;
  background: var(--lime);
  border-radius: 5px;
}

.gstat .gv .u {
  font-size: 13px;
  color: var(--tx-3);
  font-weight: 400;
}

.sec-lab {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  font-weight: 600;
  margin: 22px 0 12px;
}

.dtbl.plans .dhead,
.dtbl.plans .drow {
  grid-template-columns: 1fr 0.8fr 0.9fr 1fr 1.5fr 0.9fr 0.9fr 0.6fr;
  gap: 12px;
}

.pl-name {
  font-family: var(--font-display);
  font-weight: 600;
}

.pl-hidden {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 10.5px;
  color: var(--tx-3);
  border: 1px solid var(--line-2);
  border-radius: 6px;
  padding: 1px 6px;
  margin-left: 6px;
}

.icon-btn {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: none;
  display: grid;
  place-items: center;
  color: var(--tx-3);
  justify-self: end;
  cursor: pointer;
}

.icon-btn:hover {
  color: var(--tx);
  border-color: var(--line-2);
}

.pe-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pe-ro {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 0 0 10px;
  border-bottom: 1px solid var(--line);
}

.pe-ro-l {
  font-size: 13px;
  color: var(--tx-2);
}

.pe-ro-v {
  font-size: 13px;
  color: var(--tx);
  text-align: right;
}

.pe-note {
  font-size: 11px;
  color: var(--tx-3);
  margin-left: 6px;
}

.pe-check {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--tx-2);
  cursor: pointer;
}

.pe-check input {
  width: 16px;
  height: 16px;
  accent-color: var(--lime);
}

.dr-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 10px;
}

/* F4-D: admin 2FA enrolment (QR + manual key on the auth card) */

.totp-qr {
  /* Literal white (not a theme token) on purpose: a QR needs true black-on-white contrast to scan,
     regardless of the viewer's light/dark theme. */
  background: #fff;
  padding: 12px;
  border-radius: 12px;
  width: max-content;
  margin: 6px auto 16px;
}

.totp-qr img {
  display: block;
  width: 180px;
  height: 180px;
}

.totp-secret {
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 2px;
  color: var(--tx-2);
  word-break: break-all;
  text-align: center;
  margin: 4px 0 18px;
}

/* Account / profile settings (/account). Wrapper-scoped like .billing; responsive from the start:
   fluid width, single-column stacking, own breakpoint (does not depend on the sidebar collapsing).
   Scrolls with the document (the shell uses whole-page scroll); no reserved gutter is needed because
   the document scrollbar is hidden, so the post-save flash can't cause a horizontal reflow. */
.account {
  max-width: 940px;
  margin: 0 auto;
  padding: 28px 24px 48px;
}

/* Identity hero: avatar + name/email + status chips. */
.account .acct-hero {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-6);
  margin-bottom: var(--space-5);
  box-shadow: var(--shadow-1);
}

.account .acct-ava {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  color: var(--lime);
  background: rgba(var(--lime-rgb), 0.12);
  border: 1px solid rgba(var(--lime-rgb), 0.28);
}

.account .acct-ident {
  min-width: 0;
}

.account .acct-name {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  line-height: 1.15;
  color: var(--tx);
  margin: 0;
  word-break: break-word;
}

.account .acct-email {
  color: var(--tx-3);
  font-size: 13.5px;
  margin-top: 3px;
  word-break: break-word;
}

.account .acct-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.account .acct-chip {
  font-size: 12px;
  color: var(--tx-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 10px;
}

.account .acct-chip-op {
  color: var(--lime);
  background: rgba(var(--lime-rgb), 0.1);
  border-color: rgba(var(--lime-rgb), 0.28);
}

/* Card grid: two columns on wide, one column below 860px. */
.account .acct-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
  align-items: stretch;
}

.account .acct-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
}

.account .acct-title {
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  color: var(--tx);
  margin: 0 0 var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
}

.account .muted {
  color: var(--tx-3);
  font-size: 12.5px;
  margin: 0 0 var(--space-4);
}

.account .acct-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  flex: 1;
}

/* Pin each card's trailing action to the bottom so buttons line up across the equal-height grid. */
.account .acct-form > .btn,
.account .acct-card > .btn {
  align-self: flex-start;
  margin-top: auto;
}

/* Profile edit mode: fields read as locked (dimmed, non-editable) until "Edit" is clicked. */
.account .input.is-locked {
  opacity: 0.55;
  cursor: default;
}

.account .acct-edit-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: auto;
}

/* Plan & billing mini definition list. */
.account .acct-mini {
  margin: 0 0 var(--space-4);
}

.account .acct-mini-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
  font-size: 13.5px;
}

.account .acct-mini-row dt {
  color: var(--tx-3);
}

.account .acct-mini-row dd {
  color: var(--tx);
  margin: 0;
}

/* Sessions actions + two-step "sign out everywhere" confirm. */
.account .acct-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: auto;
}

.account .acct-confirm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.account .acct-confirm-t {
  font-size: 13px;
  color: var(--bad);
}

@media (max-width: 860px) {
  .account .acct-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .account .acct-hero {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ===== Responsive pass (F5-#15) ===== */

/* Collapsible sidebar. A hamburger toggles Alpine `nav` -> `.app.nav-open`. Desktop defaults open;
   below 1000px the sidebar becomes an off-canvas drawer over a backdrop (never squeezes content). */
.side {
  transition: transform 0.18s ease;
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-right: 12px;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--tx-2);
  cursor: pointer;
}

.nav-toggle:hover {
  color: var(--tx);
  border-color: var(--line-2);
}

.nav-backdrop {
  display: none;
}

/* Desktop-collapsed: reclaim the sidebar grid column. Scoped to >=1001px so the DEFAULT (no class,
   e.g. before Alpine hydrates or with JS disabled) stays SHOWN on desktop and CLOSED on mobile - the
   collapse/open are opt-in classes, never the fail-safe default. */
@media (min-width: 1001px) {
  .app.nav-collapsed {
    grid-template-columns: 0 1fr;
  }
  .app.nav-collapsed .side {
    transform: translateX(-100%);
    overflow: hidden;
  }
  /* Sidebar collapsed: the docked composer spans the full width. */
  .app.nav-collapsed .gbar-wrap {
    left: 0;
  }
}

@media (max-width: 1000px) {
  /* Sidebar leaves the grid and overlays as a drawer; content is always full-width. Default is
     CLOSED (drawer off-canvas, no backdrop); `.nav-open` is required to open it. */
  .app {
    grid-template-columns: 1fr;
  }
  .side {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(280px, 82vw);
    z-index: 50;
    transform: translateX(-100%);
  }
  .app.nav-open .side {
    transform: none;
  }
  /* Mobile: sidebar is an overlay, so the docked composer spans the full width. */
  .gbar-wrap {
    left: 0;
  }
  .app.nav-open .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(2px);
    z-index: 45;
  }

  /* Content grids collapse. */
  .kpis {
    grid-template-columns: repeat(2, 1fr);
  }
  .att-strip {
    grid-template-columns: 1fr;
  }
  .adm-grid2,
  .genstats,
  .grid2,
  .grid2b,
  .billing .bill-top {
    grid-template-columns: 1fr;
  }
  .saved-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  /* Data tables -> stacked label/value cards (admin users/jobs/plans + billing invoices). */
  .dtbl {
    overflow: visible;
  }
  .dhead,
  .billing .tr.head {
    display: none;
  }
  /* Variant-specific selectors to beat the base .dtbl.X .drow grid (3-class specificity). */
  .dtbl.customers .drow,
  .dtbl.admins .drow,
  .dtbl.audits .drow,
  .dtbl.jobs .drow,
  .dtbl.plans .drow,
  .dtbl.demo .drow,
  .billing .tr {
    grid-template-columns: 1fr;
    gap: 10px;
    padding: 16px;
  }
  /* The stacked card caps its own width otherwise (ministat cap is for strips, not cards). */
  .ministat {
    max-width: none;
  }
  /* Topbar range picker stays usable next to the title on small screens. */
  .range-chips a {
    padding: 5px 8px;
    font-size: 11.5px;
  }
  .au-sum {
    white-space: normal;
  }
  .drow > *,
  .billing .tr > * {
    display: block;
    justify-self: stretch !important;
    text-align: left;
  }
  .drow > *[data-label]::before,
  .billing .tr > *[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    color: var(--tx-3);
    font-size: 11px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
  }
  /* Chips read as plain (still colored) text under their label - no stretched box. */
  .drow > .plan-pill,
  .drow > .st {
    background: none;
    border: none;
    padding: 0;
  }
  .drow > .st .d {
    display: none;
  }
  /* Icon-only actions (plans edit pencil) stay a compact right-aligned button, not a stretched row. */
  .drow > .icon-btn {
    justify-self: end !important;
    width: auto;
  }
  /* Avatar + name stay side by side inside the stacked card (the .drow > * block rule above would
     otherwise collapse the flex row). */
  .drow > .u-cell {
    display: flex;
  }

  /* Toolbars stack; searches go full-width. */
  .adbar,
  .adbar-l,
  .gallery .toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  .adbar .search,
  .gallery .search {
    width: 100%;
  }
  .adbar .chips,
  .adbar-r {
    flex-wrap: wrap;
  }
  .pay-note {
    flex-direction: column;
    align-items: flex-start;
  }

  /* Generate bar wraps; keep the format popover on-screen. */
  .gbar {
    flex-wrap: wrap;
  }
  .gbar-wrap {
    padding: 12px 14px 26px;
  }
  .fmt-pop {
    max-width: calc(100vw - 28px);
  }

  /* Shrink oversized numerics + page padding. */
  .kpi .kv,
  .billing .tu-credits,
  .billing .tu-price {
    font-size: 22px;
  }
  .canvas {
    padding: 16px 16px 164px;
  }
  .empty-state {
    min-height: calc(100vh - 60px - 16px - 164px);
    padding-bottom: 40px;
  }
  /* Upload tools (Ad Reference / Swipe Ad): the upload chip leaves no room for the note input on
     one line, so the note breaks into its own full-width second row; the taller composer needs a
     matching canvas/empty-state offset (base row 44px + 8px gap = +52px over 164px). */
  .tool-upload .gbar > .describe {
    flex: 1 1 100%;
    order: 9;
  }
  .tool-upload .canvas {
    padding-bottom: 216px;
  }
  .tool-upload .empty-state {
    min-height: calc(100vh - 60px - 16px - 216px);
  }
  .admin-scroll {
    padding: 16px;
  }
  .billing {
    padding: 16px;
  }
  .account {
    padding: 16px 16px 32px;
  }
  .gallery .scroll {
    padding: 12px 14px 32px;
  }
  .top {
    padding: 0 14px;
  }
  .scrim {
    padding: 12px;
  }
}

@media (max-width: 640px) {
  .kpis {
    grid-template-columns: 1fr;
  }
  .gal {
    column-count: 1;
  }
  /* Generate bar stacks full-width so the note input keeps a usable width (flex-wrap alone lets
     the flex:1 describe collapse to ~0). Canvas gets extra bottom clearance for the taller bar. */
  .gbar {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .gbar > .prod-chip,
  .gbar > .describe,
  .gbar > .fmt-wrap,
  .gbar > .gen-btn {
    width: 100%;
  }
  /* Stacked column: restore the note input to its natural slot (the 768 two-row order does not
     apply once everything is full-width). */
  .tool-upload .gbar > .describe {
    order: 0;
  }
  .canvas {
    padding-bottom: 286px;
  }
  .empty-state {
    min-height: calc(100vh - 60px - 16px - 286px);
    padding-bottom: 20px;
  }
}

/* ---------- visual refresh: font normalization + global focus ring ---------- */
/* Buttons and numeric data values use the UI sans, never the serif display face. */
.gen-btn,
.btn-lime,
.billing .pn,
.kpi .kv,
.gstat .gv {
  font-family: var(--font-ui);
}

/* Keyboard focus ring on interactive controls (a11y). :focus-visible only, so a mouse click stays
   clean; placed last so it wins over the older `:focus { outline: none }` rules at equal specificity. */
.btn:focus-visible,
a:focus-visible,
button:focus-visible,
.input:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
