/* Dashboard styles — Day 2 (top bar + folder picker).
 *
 * Visual language matches website/studio-7k9zXnQ.html and website/app/sign-in.html:
 * studio glass cards, gradient backdrop (var(--abni-gradient-soft)), General Sans
 * display typography, 24px radius outer panel + 18px inner cards.
 *
 * Tokens come from website/assets/abni.css. Only dashboard-specific layout +
 * components live here so we don't drift from the shared design system.
 */

@import url("https://fonts.googleapis.com/css2?family=Noto+Emoji:wght@300..700&display=swap");

/* ── Noto Emoji button icons ──────────────────────────
 * Render emoji as a single monochrome glyph across platforms (Mac Apple
 * Color Emoji, Windows Segoe UI Emoji, Linux fonts all draw different
 * things). Noto Emoji is monochrome + consistent, matches our studio
 * aesthetic, and lets `color: currentColor` pull the surrounding text
 * colour. Used on every button label in the dashboard.
 */
.btn-emoji {
  font-family: "Noto Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
  font-weight: 400;
  font-size: 1.05em;
  line-height: 1;
  margin-right: 6px;
  vertical-align: -1px;
  color: currentColor;
  user-select: none;
}

/* Larger icon variant for the process-card row — block-stacked above
 * the label, no right margin. The existing .process-icon container
 * styles below take care of the chip background. */
.process-card .btn-emoji {
  font-size: 1.6em;
  margin-right: 0;
  margin-bottom: 8px;
  display: block;
}

/* Library tile hover-action buttons are 30x30 round chips — the emoji
 * is the only content, so no right margin. */
.lib-tile-action .btn-emoji {
  margin-right: 0;
  vertical-align: 0;
  font-size: 1em;
}

:root {
  --app-card-radius: 24px;
  --app-card-border: rgba(25, 64, 86, 0.10);
  --app-studio-card-radius: 18px;
  --app-success: #2f8a55;
  --app-warning: #c98a2b;
  --app-error: #b03030;
}

body {
  background: var(--abni-gradient-soft);
  min-height: 100dvh;
}

/* ── App shell ────────────────────────────────────── */

.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* ── Top bar ──────────────────────────────────────── */

.app-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 24px;
  background: rgba(255, 255, 255, 0.75);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--app-card-border);
}

.app-topbar .brand-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: 8px;
}
.app-topbar .brand-mark img {
  height: 22px;
  width: auto;
  filter: brightness(0) saturate(1) invert(56%) sepia(38%) saturate(425%) hue-rotate(167deg) brightness(0.94) contrast(0.88);
}

.topbar-spacer { flex: 1; }

.topbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--abni-mute);
}

/* Generic top-bar chips — same shape across switcher / settings / credits / email. */
/* Force [hidden] to win over our author-set `display`. Without this rule,
   `display: inline-flex` below trumps the user-agent `[hidden]{display:none}`
   and a JS `.hidden = true` has no visible effect — bug seen on the
   #superadmin-chip after dropping a user from the SA allowlist. */
[hidden] {
  display: none !important;
}

.topbar-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-ink);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s, box-shadow 0.15s;
  text-decoration: none;
  white-space: nowrap;
}
.topbar-chip:hover {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
  background: rgba(255, 255, 255, 0.85);
}
.topbar-chip.static { cursor: default; color: var(--abni-mute); }
.topbar-chip.static:hover { border-color: var(--app-card-border); color: var(--abni-mute); }

/* ──────────────────────────────────────────────────────────────
   Mobile hamburger + side drawer
   ────────────────────────────────────────────────────────────── */

.topbar-hamburger {
  display: none; /* visible only at mobile breakpoint */
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  color: var(--abni-blue-deep);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.topbar-hamburger:hover {
  border-color: var(--abni-blue-deep);
  background: rgba(255, 255, 255, 0.9);
}
.topbar-hamburger .ui-icon { margin: 0; }

.topbar-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(31, 50, 60, 0.35);
  z-index: 90;
  opacity: 0;
  transition: opacity 180ms ease;
}
.topbar-drawer-backdrop.is-open {
  opacity: 1;
}

.topbar-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(86vw, 320px);
  background: rgba(255, 255, 255, 0.96);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border-left: 1px solid var(--app-card-border);
  box-shadow: -16px 0 40px rgba(31, 50, 60, 0.12);
  z-index: 100;
  transform: translateX(100%);
  transition: transform 200ms ease;
  display: flex;
  flex-direction: column;
}
.topbar-drawer.is-open {
  transform: translateX(0);
}
.topbar-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--app-card-border);
}
.topbar-drawer-email {
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
.topbar-drawer-close {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  color: var(--abni-mute);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.topbar-drawer-close:hover { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); }
.topbar-drawer-items {
  display: flex;
  flex-direction: column;
  padding: 12px 10px;
  gap: 4px;
}
.topbar-drawer-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 12px;
  background: none;
  border: 0;
  border-radius: 10px;
  font-family: var(--abni-font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--abni-ink);
  text-align: left;
  cursor: pointer;
  transition: background 0.15s;
}
.topbar-drawer-item:hover { background: rgba(106, 176, 212, 0.12); }
.topbar-drawer-item .ui-icon { color: var(--abni-blue-deep); flex: 0 0 auto; }
.topbar-drawer-item--danger { color: #b15a18; }
.topbar-drawer-item--danger .ui-icon { color: #b15a18; }

/* Tablet+ breakpoint — collapse topbar chips into the hamburger drawer.
   Triggers earlier (1024px) than the rest of the mobile rules (768px)
   because the topbar fills up faster than the body — by the time the
   chips get cramped (around 1000px) the body is still comfortable. The
   switcher + credits chip + brand mark stay visible at every width;
   identity and balance are load-bearing context. */
@media (max-width: 1024px) {
  .app-topbar {
    gap: 8px;
    padding: 10px 14px;
  }
  .app-topbar .brand-mark { margin-right: 0; }
  .topbar-right { gap: 6px; }
  .topbar-right #settings-btn,
  .topbar-right #users-chip,
  .topbar-right #superadmin-chip,
  .topbar-right #topbar-email,
  .topbar-right #sign-out-btn {
    display: none;
  }
  .topbar-hamburger { display: inline-flex; }
  /* Folder breadcrumb in the topbar is redundant once we're squeezed —
     the in-section breadcrumbs sit right below. Drop it to free width. */
  .app-topbar > .folder-breadcrumb--topbar { display: none; }
  /* Trim the switcher chip — long client names eat the row. */
  #switcher-btn { max-width: 150px; }
  #switcher-btn #switcher-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
/* Phone — further shrink the brand mark + tighten the switcher. */
@media (max-width: 768px) {
  .app-topbar .brand-mark img { height: 18px; }
  #switcher-btn { max-width: 130px; }
  /* Compact topbar (Oliver 2026-06-03): "Ask Abni" already lives in the bottom
     nav, so drop the redundant topbar chip; the credits chip shrinks to icon +
     number (the word "credits" is redundant). Frees room for the switcher +
     credits + hamburger to all fit without overflow. */
  .topbar-right #chat-toggle-btn { display: none; }
  #credits-chip .credits-word { display: none; }
}

/* Credit-balance chip states. Solid colour, no flashing — flashing alarms
   get tuned out fast. Tooltip + click-to-open-credits covers the call-to-
   action. */
.topbar-chip#credits-chip.is-low {
  border-color: #d99815;
  color: #8a5e00;
  background: #fff5e0;
}
.topbar-chip#credits-chip.is-low:hover {
  border-color: #b07b00;
  color: #7a4a00;
}
.topbar-chip#credits-chip.is-empty {
  border-color: #c0392b;
  color: #fff;
  background: #c0392b;
}
.topbar-chip#credits-chip.is-empty:hover {
  border-color: #a13225;
  background: #a13225;
  color: #fff;
}
.topbar-chip .chevron {
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  opacity: 0.7;
}
.topbar-chip .credits-num {
  font-variant-numeric: tabular-nums;
  color: var(--abni-blue-deep);
}
.topbar-chip.email {
  background: transparent;
  border: none;
  padding-left: 4px;
  padding-right: 4px;
  color: var(--abni-mute);
}
.topbar-chip.email:hover { border-color: transparent; background: transparent; color: var(--abni-mute); cursor: default; }

/* Switcher dropdown */
.switcher-wrap { position: relative; }
.switcher-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 280px;
  max-width: 360px;
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: 14px;
  padding: 6px;
  box-shadow: 0 18px 40px rgba(31, 50, 60, 0.14);
  display: none;
}
.switcher-menu.open { display: block; }

.switcher-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  background: transparent;
  border: 0;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--abni-ink);
  cursor: pointer;
  text-align: left;
  transition: background 0.12s;
}
.switcher-item:hover { background: rgba(106, 176, 212, 0.10); }
.switcher-item.is-current { background: rgba(72, 141, 176, 0.10); }
.switcher-item .name { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.switcher-item .role {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--abni-blue-deep);
  background: rgba(72, 141, 176, 0.10);
  padding: 3px 8px;
  border-radius: 999px;
  flex-shrink: 0;
}
.switcher-divider {
  height: 1px;
  background: var(--app-card-border);
  margin: 6px 4px;
}
.switcher-item.new-client {
  color: var(--abni-blue-deep);
  font-weight: 600;
  font-size: 13.5px;
}
.switcher-item.new-client::before {
  content: "+";
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(72, 141, 176, 0.12);
  color: var(--abni-blue-deep);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
}

/* ── Main column ──────────────────────────────────── */

.app-main {
  flex: 1;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 40px 24px 96px;
  /* Flex column so we can reorder sections visually without restructuring
     the HTML — Library renders ABOVE Processes via `order: -1` below,
     even though it lives further down in the document. */
  display: flex;
  flex-direction: column;
  /* 4px between adjacent panels — subtle divider so users see clearly where
     Workspace / Extract / Library / Processes start and end. */
  gap: 4px;
}

/* F6: Visual order: Brands → Brand Style → Library → Processes.
   HTML: folder, empty, processes, library, brand-style.
   CSS order overrides reflow them into the correct visual sequence. */
.app-main #folder-section  { order: 0; }
.app-main #empty-state     { order: 0; }
.app-main #brand-style-section { order: 1; }
.app-main #library-section { order: 2; }
.app-main #processes-section { order: 3; }

.app-hero {
  margin-bottom: 36px;
}
.app-hero h1 {
  font-family: var(--abni-font-display);
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.06;
  color: var(--abni-blue-deep);
  margin: 0 0 10px;
}
.app-hero p {
  font-size: 16px;
  line-height: 1.55;
  color: var(--abni-mute);
  margin: 0;
  max-width: 600px;
}

/* ── Studio panel (matches studio-7k9zXnQ.html .studio-panel) ──
   The three workspace panels (folder / processes / library) stack flush
   as one continuous surface. Default panels are square; the first visible
   panel gets top-rounded corners, the last gets bottom-rounded, and the
   keyline between visible panels is a single 1px top border. */
/* T7: Panels form one continuous surface separated by a single 1px keyline.
   No per-panel vertical gap or separate card shadow between panels.
   The shadow belongs to the group, applied only on the outermost corners. */
.studio-panel {
  background: rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: 0;
  padding: 32px;
  /* No per-panel shadow — the group shadow comes from the first visible panel only. */
  box-shadow: none;
}
/* Single group shadow on the topmost visible panel. */
#folder-section:not([hidden]),
#empty-state:not([hidden]) {
  box-shadow: 0 12px 40px rgba(31, 50, 60, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
/* Stacked-surface keyline — adjacent visible panels share a single border.
   Remove the top border of the lower panel so only one 1px line shows. */
.studio-panel:not([hidden]) + .studio-panel:not([hidden]) {
  border-top: 0;
}
/* Top-rounded corners: whichever of folder/empty-state leads the stack. */
#folder-section,
#empty-state {
  border-top-left-radius: var(--app-card-radius);
  border-top-right-radius: var(--app-card-radius);
}
/* Bottom-rounded corners: the *last* visible panel in the visual stack gets
   them. Processes is at order: 3 — bottom of the visual stack. The global
   `:has(+ ...)` rule below works on DOM order so doesn't account for flex
   `order` reordering; anchor the rounded bottom explicitly to Processes. */
#processes-section {
  border-bottom-left-radius: var(--app-card-radius);
  border-bottom-right-radius: var(--app-card-radius);
}
/* Strip bottom-radius from any panel that has a visible sibling below it. */
.studio-panel:not([hidden]):has(+ .studio-panel:not([hidden])) {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.studio-section-head {
  display: flex;
  /* T1: wrap so the title sits on its own row above the breadcrumb/toggles row */
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  margin-bottom: 20px;
}
.studio-section-head h2 {
  font-family: var(--abni-font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  margin: 0;
}
.studio-section-head .hint { font-size: 13px; color: var(--abni-mute); }
.lib-total-count { margin-right: 8px; }

/* T1/F2: Section title — label that spans the full width, above the
   breadcrumb/toggles row. width:100% forces a wrap in the flex container. */
.section-title {
  font-family: var(--abni-font-display);
  font-size: 21px;
  font-weight: 900;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  white-space: nowrap;
  flex-shrink: 0;
  /* T1: own row */
  width: 100%;
  margin-bottom: 6px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
/* Section-title icon — bigger than the inline .ui-icon so it reads as a
   section glyph at first glance. Inherits the title colour. */
.section-title-icon {
  width: 26px;
  height: 26px;
  stroke: currentColor;
  fill: none;
  flex-shrink: 0;
}

/* Library header — top row holds title + count inline; toggles stack
   in a right-aligned column. Title row keeps title visible alongside
   the item count instead of forcing the count below. */
.studio-section-head.library-head {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "title toggles"
    "crumbs toggles";
  gap: 6px 16px;
  align-items: start;
}
.library-head > .section-title {
  grid-area: title;
  width: auto;
  margin-bottom: 0;
  align-self: baseline;
}
.library-head .folder-breadcrumb {
  grid-area: crumbs;
  margin: 0;
}
.library-head-toggles {
  grid-area: toggles;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  justify-self: end;
}
.library-head-toggles .lib-total-count {
  margin: 0;
  align-self: flex-end;
}

/* Slot below the filters panel that receives the Details toggle when
   filters are expanded. Right-aligns the toggle, sits between filters
   panel and the multi-select bar. */
.lib-details-after-filters {
  display: flex;
  justify-content: flex-end;
  margin: 10px 0;
}
.lib-details-after-filters:empty {
  display: none;
}

/* F2/F3: Right side of the section head — breadcrumb + toggles + hint in one row. */
.section-head-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  flex: 1;
  justify-content: flex-end;
  min-width: 0;
}

/* ── Folder breadcrumb (shared across folder / processes / library heads)
   Three instances, kept in sync by renderBreadcrumb() in dashboard.js.
   "📁 / All brands / Brand / Sub-brand / Campaign" — each segment is a
   button that jumps the cascade to that level. */
.folder-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  font-family: var(--abni-font-display);
}
.folder-breadcrumb .fb-icon-btn,
.folder-breadcrumb .fb-home-btn {
  background: none;
  border: none;
  padding: 4px 4px;
  margin: 0;
  cursor: pointer;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  transition: background-color 120ms ease;
}
.folder-breadcrumb .fb-icon-btn:hover,
.folder-breadcrumb .fb-icon-btn:focus-visible,
.folder-breadcrumb .fb-home-btn:hover,
.folder-breadcrumb .fb-home-btn:focus-visible {
  background: rgba(36, 96, 142, 0.08);
  outline: none;
}
.folder-breadcrumb .fb-icon {
  font-size: 16px;
  line-height: 1;
}
.folder-breadcrumb .fb-segment {
  background: none;
  border: none;
  padding: 4px 6px;
  margin: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  /* Preserve the user's casing for brand / sub-brand / campaign names —
     count labels and suffix tail (`15 BRANDS`, `> 0 SUB-BRANDS, 9 ITEMS`)
     still inherit uppercase from the container. */
  text-transform: none;
  cursor: pointer;
  border-radius: 6px;
  transition: background-color 120ms ease, color 120ms ease;
}
.folder-breadcrumb .fb-segment:hover,
.folder-breadcrumb .fb-segment:focus-visible {
  background: rgba(36, 96, 142, 0.08);
  outline: none;
}
.folder-breadcrumb .fb-segment.is-current {
  color: var(--abni-ink);
  cursor: default;
}
.folder-breadcrumb .fb-segment.is-current:hover {
  background: transparent;
}
.folder-breadcrumb .fb-sep {
  color: var(--abni-mute);
  font-weight: 400;
  font-size: 12px;
  user-select: none;
  padding: 0 2px;
}
/* F3: Count suffix appended after the deepest breadcrumb segment. */
.folder-breadcrumb .fb-suffix {
  color: var(--abni-mute);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.02em;
  user-select: none;
  white-space: nowrap;
}

/* ── Grid + studio-card (matches studio reference) ── */
/* T5: brand tile grid — 3 per row, equal-height rows via align-items:stretch
   (default, so tiles in a row expand to the tallest sibling). */
.studio-grid {
  display: grid;
  /* Auto-fill so the grid reflows by its ACTUAL width — drops columns
     gracefully when the chat side-panel narrows the content area, instead of
     cramming a fixed 3-up into a thin column. ~3-up at the full 1080 width. */
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  grid-auto-rows: auto;
  align-items: stretch;
  gap: 16px;
}
@media (max-width: 860px) { .studio-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .studio-grid { grid-template-columns: 1fr; } }
@media (max-width: 560px) {
  .studio-grid { grid-template-columns: 1fr; }
  .app-main { padding: 24px 16px 64px; }
  /* Panels keep square corners on mobile too — the first/last visible
     panel in the stack picks up rounded corners via the rules above. */
  .studio-panel { padding: 24px; }
}

.studio-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 8px;
  border-radius: var(--app-studio-card-radius);
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  cursor: pointer;
  transition: transform 0.18s var(--abni-ease), box-shadow 0.18s, border-color 0.18s, opacity 0.18s;
  text-align: left;
  font-family: inherit;
  color: inherit;
  -webkit-appearance: none;
  appearance: none;
}
.studio-card:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(31, 50, 60, 0.10); }
.studio-card.is-selected {
  border-color: var(--abni-blue-deep);
  box-shadow: 0 0 0 2px var(--abni-blue-deep), 0 12px 32px rgba(72, 141, 176, 0.18);
}
.studio-card.is-creating { opacity: 0.65; cursor: progress; }
.studio-card.is-creating:hover { transform: none; box-shadow: none; }

.studio-card-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  overflow: hidden;
  background: var(--abni-blue-soft);
}
.studio-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.studio-card-thumb.no-image {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--abni-blue-deep);
  background: linear-gradient(135deg, var(--abni-blue-soft) 0%, var(--abni-paper) 100%);
}
.studio-card-thumb .initials {
  font-family: var(--abni-font-display);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--abni-blue-deep);
  text-transform: uppercase;
}

.studio-card-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--abni-ink);
  padding: 0 6px 6px;
  letter-spacing: -0.005em;
}
.studio-card-meta {
  font-size: 11px;
  color: var(--abni-mute);
  padding: 0 6px;
  letter-spacing: 0.04em;
  font-weight: 600;
  margin-top: -4px;
}

.studio-card.compact .studio-card-thumb { aspect-ratio: 16 / 10; border-radius: 10px; }
.studio-card.compact .studio-card-name { font-size: 13.5px; padding: 0 4px 4px; }

/* Brand-extracted indicator chip — small, subtle, top-right corner of the thumb. */
.brand-status-chip {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px 4px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border: 1px solid var(--app-card-border);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--abni-mute);
  box-shadow: 0 2px 6px rgba(31, 50, 60, 0.06);
}
.brand-status-chip .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.brand-status-chip.ok { color: var(--app-success); }
.brand-status-chip.ok .dot { background: var(--app-success); }
.brand-status-chip.needs { color: var(--app-warning); }
.brand-status-chip.needs .dot { background: var(--app-warning); }
.brand-status-chip.loading { opacity: 0.6; }
.brand-status-chip.loading .dot { background: var(--abni-mute); }

/* ── F5/T4/T5: Brand tile — two-column layout, fills grid cell height ─── */
.brand-tile {
  position: relative;
  display: flex;
  flex-direction: row;
  gap: 14px;
  padding: 14px;
  border-radius: var(--app-studio-card-radius);
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  cursor: pointer;
  transition: transform 0.18s var(--abni-ease), box-shadow 0.18s, border-color 0.18s, opacity 0.18s;
  text-align: left;
  font-family: inherit;
  color: inherit;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  /* T5: equal-height rows — let the grid row establish the height (grid-auto-rows:
     minmax(min-content,auto)) and align-self:stretch fills it. Removing height:100%
     avoids the circular-reference problem with auto-sized tracks in CSS Grid. */
  align-self: stretch;
  box-sizing: border-box;
  /* No min-height floor on populated tiles — they size to their natural
     content (thumb 128px + padding ≈ 156px). The Add tile's min-height
     below matches this so alone-in-row Add tiles don't shrink. */
}
.brand-tile:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(31, 50, 60, 0.10); }
.brand-tile.is-selected {
  border-color: var(--abni-blue-deep);
  box-shadow: 0 0 0 2px var(--abni-blue-deep), 0 12px 32px rgba(72, 141, 176, 0.18);
}
.brand-tile.is-creating { opacity: 0.65; cursor: progress; }
.brand-tile.is-creating:hover { transform: none; box-shadow: none; }

/* Left column */
.brand-tile-left {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
  align-items: flex-start;
}
.brand-tile-level {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--abni-mute);
  white-space: nowrap;
}
/* T4: doubled thumb size — 128×128 square */
.brand-tile-thumb {
  width: 128px;
  height: 128px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--abni-blue-soft);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.brand-tile-thumb img {
  width: 100%;
  height: 100%;
  /* F5: contain so the full brand hero is always visible */
  object-fit: contain;
  display: block;
}
.brand-tile-thumb.no-image {
  background: linear-gradient(135deg, var(--abni-blue-soft) 0%, var(--abni-paper) 100%);
}
.brand-tile-thumb.no-image .initials {
  font-family: var(--abni-font-display);
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--abni-blue-deep);
  text-transform: uppercase;
}

/* Right column */
.brand-tile-right {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
}
.brand-tile-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--abni-ink);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.brand-tile-stats {
  font-size: 12px;
  color: var(--abni-mute);
}
.brand-tile-activity {
  font-size: 11.5px;
  color: var(--abni-mute);
  opacity: 0.75;
}

/* F5/F6: Unified status pill — same chip used in brand tile and Brand Style header.
   Source of truth for Needs setup / Ready wording + colour. */
.brand-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  white-space: nowrap;
}
.brand-status-pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}
.brand-status-pill.loading {
  color: var(--abni-mute);
  border-color: var(--app-card-border);
  background: rgba(255, 255, 255, 0.8);
  opacity: 0.7;
}
.brand-status-pill.ok {
  color: var(--app-success);
  border-color: rgba(47, 138, 85, 0.25);
  background: rgba(47, 138, 85, 0.07);
}
.brand-status-pill.needs {
  color: var(--app-warning);
  border-color: rgba(201, 138, 43, 0.25);
  background: rgba(201, 138, 43, 0.07);
}
/* ──────────────────────────────────────────────────────────────
   Extraction status dots — per-category indicator next to tile actions.
   V1 ships ONE dot (Image style); Text + Design follow once their
   extraction backends land.

   Grey  — nothing set locally + no parent has values
   Blue  — inherited from parent (nothing local)
   Orange — has local content but not locked
   Green — locked (level explicitly marked Ready)
   ────────────────────────────────────────────────────────────── */

.ext-dots {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-end;
  margin-top: auto;
}
.ext-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, transform 140ms ease;
}
.ext-dot:hover {
  transform: translateY(-1px);
  border-color: var(--abni-blue-deep);
}
.ext-dot:focus-visible {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}
.ext-dot-bullet {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--abni-mute);
  display: inline-block;
}
.ext-dot--grey  .ext-dot-bullet { background: #c5ccd5; }
.ext-dot--blue  .ext-dot-bullet { background: #6ab0d4; }
.ext-dot--orange .ext-dot-bullet { background: #d99815; }
.ext-dot--green .ext-dot-bullet { background: #2ea920; }

.ext-lock-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  color: var(--abni-mute);
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.ext-lock-btn:hover {
  color: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
}
.ext-lock-btn:focus-visible {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}
.ext-lock-btn.is-locked {
  color: #2f8a55;
  border-color: rgba(47, 138, 85, 0.35);
  background: rgba(47, 138, 85, 0.08);
}
.ext-lock-btn svg {
  width: 12px;
  height: 12px;
}

.brand-tile-pill {
  align-self: flex-end;
  margin-top: auto;
}

/* Add-new tile — dashed border, plus icon.
   Two key shifts from the previous build:
   1. The .add-thumb was `width: 100%; aspect-ratio: 16/9` which in a 3-col
      grid sized the thumb to ~220px tall (column-width × 9/16) and made
      the whole tile balloon to ~270px while populated brand-tiles sat
      around 156px. Replaced with a fixed 56×56 icon footprint that lets
      the tile size to its content + the min-height floor.
   2. Dashed border style mirrors `.bs-ref-add` (the Upload / Pick-from-
      library tiles in the Brand Style panel) so every "add something
      here" affordance reads consistently across the app. */
.studio-card.add-new {
  border: 2px dashed rgba(106, 176, 212, 0.55);
  background: rgba(255, 255, 255, 0.55);
  align-items: center;
  justify-content: center;
  text-align: center;
  align-self: stretch;
  min-height: 156px;
  gap: 8px;
}
.studio-card.add-new:hover {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.10);
}
.studio-card.add-new .add-thumb {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--abni-blue-deep);
  flex: 0 0 auto;
}
.studio-card.add-new .add-thumb .plus {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(72, 141, 176, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  font-family: var(--abni-font-display);
}
.studio-card.add-new .add-label {
  padding: 6px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--abni-blue-deep);
}
.studio-card.add-new.compact { min-height: 140px; }
.studio-card.add-new.compact .add-thumb { width: 48px; height: 48px; }
.studio-card.add-new.compact .add-label { font-size: 12.5px; }

/* Cascading sub-rows (sub-brands beneath selected brand, campaigns beneath selected sub-brand). */
.studio-cascade {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px dashed var(--app-card-border);
}
/* T3: Cascade level headers inherit .section-title styles; only spacing override here. */
.studio-cascade-label {
  margin-bottom: 12px;
  /* width:100% already set on .section-title; don't need it again here */
}
/* T6: Sub-brand and campaign rows match the brand grid — 3 per row, brand-tile layout. */
.studio-cascade-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  gap: 16px;
}
.studio-cascade-row.subbrands {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 860px) {
  .studio-cascade-row,
  .studio-cascade-row.subbrands { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .studio-cascade-row,
  .studio-cascade-row.subbrands { grid-template-columns: 1fr; }
}

/* Skeleton (studio reference uses the same shimmer animation) */
.studio-skeleton {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 880px) { .studio-skeleton { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .studio-skeleton { grid-template-columns: 1fr; } }
.studio-skeleton .sk {
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  background: linear-gradient(90deg, var(--abni-blue-soft) 0%, var(--abni-paper) 50%, var(--abni-blue-soft) 100%);
  background-size: 200% 100%;
  animation: app-shimmer 1.4s linear infinite;
}
.skeleton-line {
  height: 14px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--abni-blue-soft) 0%, var(--abni-paper) 50%, var(--abni-blue-soft) 100%);
  background-size: 200% 100%;
  animation: app-shimmer 1.4s linear infinite;
  margin-top: 8px;
}
@keyframes app-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Tiny spinner used inside creating-state cards. */
.spinner-sm {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--abni-blue-soft);
  border-top-color: var(--abni-blue-deep);
  animation: app-spin 0.9s linear infinite;
}
@keyframes app-spin { to { transform: rotate(360deg); } }

/* ── Empty state (zero clients) ───────────────────── */
.empty-state {
  text-align: center;
  padding: 24px 0 8px;
}
.empty-state h2 {
  font-family: var(--abni-font-display);
  font-size: 24px;
  font-weight: 700;
  color: var(--abni-blue-deep);
  letter-spacing: -0.01em;
  margin: 0 0 10px;
}
.empty-state p {
  color: var(--abni-mute);
  font-size: 15px;
  line-height: 1.5;
  margin: 0 auto 24px;
  max-width: 440px;
}

/* ──────────────────────────────────────────────────────────
   Processes section (Day 3) — Create / Brandify / Improve / Resize
   launchpads. Create is functional; others render with "Thursday".
   ────────────────────────────────────────────────────────── */

.processes-panel { /* same chrome as .studio-panel */ }

/* Category tabs above the process-card row. Two pills:
   "Create" (default) and "Style and amend". Hide all process cards whose
   data-category doesn't match state.processCategory; on first paint the
   "Create" tab is active so only the Create card renders. */
.process-tabs {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  margin: 0 0 16px;
  background: rgba(72, 141, 176, 0.07);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
}
.process-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 0;
  background: transparent;
  border-radius: 999px;
  font-family: var(--abni-font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--abni-mute);
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
.process-tab:hover { color: var(--abni-blue-deep); }
.process-tab.is-active {
  background: var(--abni-white);
  color: var(--abni-ink);
  box-shadow: 0 1px 3px rgba(31, 50, 60, 0.10);
}
/* Cards filtered out by the active tab are hidden, not removed —
   keeps focus / state intact when toggling tabs. */
.process-card[hidden] { display: none !important; }

.processes-row {
  display: grid;
  /* Auto-fill: ~6-up at full width, reflows down as the chat panel narrows the
     content area (was a fixed 6-up that crammed when the panel opened). */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
@media (max-width: 1200px) { .processes-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 880px) { .processes-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Phone: 2-up process cards (was a single full-width stack) — compact picker,
   far less vertical scroll before the form. */
@media (max-width: 480px) { .processes-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } }

.process-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 16px 18px;
  border-radius: 14px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: inherit;
  transition: transform 0.18s var(--abni-ease), box-shadow 0.18s, border-color 0.18s, background 0.18s;
  -webkit-appearance: none;
  appearance: none;
}
.process-card:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(31, 50, 60, 0.10);
  border-color: var(--abni-blue-deep);
}
.process-card.is-active {
  border-color: var(--abni-blue-deep);
  box-shadow: 0 0 0 2px var(--abni-blue-deep), 0 12px 32px rgba(72, 141, 176, 0.16);
  background: rgba(106, 176, 212, 0.06);
}
.process-card:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.process-card .process-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: rgba(72, 141, 176, 0.12);
  color: var(--abni-blue-deep);
  font-family: var(--abni-font-display);
  font-weight: 700;
  font-size: 16px;
}
.process-card .process-name {
  font-family: var(--abni-font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--abni-ink);
  letter-spacing: -0.005em;
}
.process-card .process-sub {
  font-size: 12px;
  color: var(--abni-mute);
  letter-spacing: 0.02em;
}
.process-card .process-sub.coming {
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 10.5px;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
}

/* Inline process panels — only the one matching the active launchpad shows. */
.process-panel[hidden] { display: none; }

/* Create panel — expanded inline below the launchpad row. */
.create-panel {
  margin-top: 20px;
  padding: 24px;
  border-radius: 18px;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.6);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.create-context {
  font-size: 12.5px;
  color: var(--abni-mute);
  letter-spacing: 0.02em;
}
.create-context strong {
  font-weight: 600;
  color: var(--abni-ink);
  margin-left: 4px;
}

.create-mode {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--app-card-border);
  align-self: flex-start;
}
.create-mode-btn {
  padding: 7px 16px;
  font-family: var(--abni-font-body);
  font-size: 13.5px;
  font-weight: 600;
  border-radius: 999px;
  border: 0;
  background: transparent;
  color: var(--abni-mute);
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
.create-mode-btn[aria-pressed="true"] {
  background: var(--abni-blue-deep);
  color: #fff;
}
.create-mode-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.studio-field-label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  margin: 0;
}

.create-prompt {
  width: 100%;
  min-height: 96px;
  max-height: 280px;
  resize: vertical;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--abni-ink);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.create-prompt:focus {
  outline: none;
  border-color: var(--abni-blue-bright);
  box-shadow: 0 0 0 4px rgba(106, 176, 212, 0.18);
}
.create-prompt::placeholder { color: var(--abni-mute); opacity: 0.7; }

.create-options {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}
.create-option-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.create-option-label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--abni-mute);
}
.chip-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}
.chip {
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-ink);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s, box-shadow 0.15s;
}
.chip:hover { border-color: var(--abni-blue-deep); color: var(--abni-blue-deep); }
.chip.is-selected {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
  box-shadow: 0 4px 14px rgba(72, 141, 176, 0.25);
}
.chip-group.is-disabled .chip,
.chip:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Credit-gate modal: shows when a batch submit would exceed the workspace
   credit balance. Two rows summarise the math (need vs have), then a
   role-aware action row. */
.credit-gate-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 14px 0 4px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--abni-paper);
}
.credit-gate-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 13px;
  color: var(--abni-mute);
}
.credit-gate-row strong {
  color: var(--abni-ink);
  font-family: var(--abni-font-body);
  font-weight: 700;
}
.credit-gate-row.is-deficit strong {
  color: #c0392b;
}

/* Brandify multi-select preview strip: a horizontal row of up to 5
   thumbnails inside the dropzone area when N library tiles are picked.
   Selectors are scoped tightly to win over `.dz-preview img` (which sets
   border-radius / max-height / contain object-fit) and
   `.dz-preview.is-library-source img` (which paints a 2px blue ring). */
.dz-preview.is-multi .dz-preview-strip {
  display: grid;
  /* Always 5 equal columns so a single picked tile sizes the same as five.
     Gives the user a visual cue for how many more they can add. */
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  width: 100%;
  margin-bottom: 8px;
}
.dz-preview.is-multi .dz-preview-strip-cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--abni-paper);
}
.dz-preview.is-multi .dz-preview-strip-cell img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  display: block;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
.dz-preview-strip-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.dz-preview-strip-remove:hover { background: rgba(0, 0, 0, 0.75); }
.dz-preview-strip-remove svg { width: 12px; height: 12px; }

.create-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  border-top: 1px dashed var(--app-card-border);
  padding-top: 18px;
}
.create-hint {
  font-size: 13px;
  color: var(--abni-mute);
  margin: 0;
  flex: 1;
  min-width: 220px;
}
.create-submit {
  padding: 12px 24px;
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--abni-blue-deep);
  color: #fff;
  font-family: var(--abni-font-body);
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s, box-shadow 0.15s;
}
.create-submit:hover:not(:disabled) {
  background: var(--abni-blue-deeper);
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(72, 141, 176, 0.25);
}
.create-submit:disabled {
  background: var(--abni-blue-soft);
  color: var(--abni-mute);
  cursor: not-allowed;
}

/* Day 5 — submit-side cost chip + insufficient-balance Top-up link.
 *
 * Layout: small subtle pill sits beside the submit. Order in DOM is
 * chip → topup → submit, wrapped in `.submit-wrap` (an inline-flex row).
 * The chip is information-only; the topup link only shows when the user's
 * balance < estimated cost, alongside the submit being force-disabled. */
.submit-wrap {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cost-chip {
  /* Read-only cost preview — looks like text, not a button. The previous
     pill-with-border styling was being mistaken for an interactive chip. */
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  background: transparent;
  border: none;
  padding: 5px 4px;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: color 0.15s;
}
.cost-chip.is-insufficient {
  color: var(--app-error);
  border-color: rgba(176, 48, 48, 0.40);
  background: rgba(176, 48, 48, 0.06);
}
.cost-topup {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cost-topup:hover { color: var(--abni-blue-deeper); }

/* ──────────────────────────────────────────────────────────
   Library section + tile state machine (Day 3 centrepiece)
   ────────────────────────────────────────────────────────── */

.library-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
/* Pagination bar — full-width inside the grid (spans every column), sits
   above and below the tile rows. The grid pushes 14px gaps either side. */
.lib-page-bar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 6px 0;
}
.lib-page-bar--top { margin-bottom: 2px; }
.lib-page-bar--bottom { margin-top: 6px; }
.lib-page-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  background: rgba(72, 141, 176, 0.08);
  border: 1px solid var(--app-card-border);
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.lib-page-btn:hover:not(:disabled) { background: rgba(72, 141, 176, 0.16); }
.lib-page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.lib-page-label {
  font-size: 13px;
  color: var(--abni-mute);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.library-empty {
  padding: 32px 16px;
  text-align: center;
  color: var(--abni-mute);
  font-size: 14px;
  border: 1px dashed var(--app-card-border);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.45);
}
.library-empty p { margin: 0; }

/* Tile — base, plus per-state modifiers. */
.lib-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 6px;
  border-radius: 16px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  cursor: pointer;
  overflow: hidden;
  transition: transform 0.18s var(--abni-ease), box-shadow 0.18s, border-color 0.18s;
}
.lib-tile:hover:not(.lib-tile--processing):not(.lib-tile--failed) {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(31, 50, 60, 0.10);
}
.lib-tile-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  overflow: hidden;
  /* Neutral letterbox background for contain-scaled images */
  background: #f0f2f5;
}
.lib-tile-thumb img {
  width: 100%;
  height: 100%;
  /* F1: show the full image, no cropping — letterbox to fit the square */
  object-fit: contain;
  display: block;
  transition: filter 0.25s, opacity 0.25s;
}
.lib-tile-thumb.no-image {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--abni-blue-soft) 0%, var(--abni-paper) 100%);
  color: var(--abni-blue-deep);
  font-family: var(--abni-font-display);
  font-weight: 700;
  font-size: 22px;
}

.lib-tile-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-ink);
  padding: 0 6px 4px;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Tile detail strip — matches the old web library: metadata line +
   truncated description + tag pills. Tightened vertical rhythm so the
   text block reads as one unit rather than three separate paragraphs.
   Hidden when the user toggles off "Details" at the top-right. */
.lib-tile-name {
  /* Override the default padding so the gap to the metadata strip is
     just enough to read as a continuation. */
  padding-bottom: 2px;
}
.lib-tile-meta {
  font-size: 11px;
  color: var(--abni-mute);
  padding: 0 6px 2px;
  letter-spacing: 0.01em;
  line-height: 1.35;
}
.lib-tile-description {
  font-size: 12px;
  color: var(--abni-ink-soft, #4f5a66);
  font-style: italic;
  line-height: 1.35;
  padding: 2px 6px 4px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Match the line-clamp visually — the box always reserves exactly
     two lines of height so descriptions never overflow into a peeking
     third line when fonts render slightly tall. */
  max-height: calc(12px * 1.35 * 2);
}
.lib-tile-tags {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 6px 8px;
}
.lib-tile-tag-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  color: var(--abni-mute, #6b7681);
  line-height: 1.4;
}
/* Icon + label pair — used inside a row. Standalone groups fill the row;
   on the status row two groups sit side-by-side (golden left, hero right). */
.lib-tile-tag-group {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  flex: 1;
}
.lib-tile-tag-group.is-right {
  flex: 0 0 auto;
  margin-left: auto;
  justify-content: flex-end;
}
.lib-tile-tag-icon {
  font-size: 11px;
  line-height: 1;
  flex-shrink: 0;
  /* The emoji needs a small nudge to align visually with the text
     baseline — emoji glyphs sit a bit low in most system fonts. */
  transform: translateY(1px);
}
.lib-tile-tag-list {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Standalone (non-status) rows let the labels stretch to fill the line. */
.lib-tile-tag-row:not(.lib-tile-tag-row--status) .lib-tile-tag-list {
  flex: 1;
}
/* #10 — removable assetUsed chips in the lightbox View tab. The library tile
   passes no remove callback, so it keeps the plain comma list; only the View
   tab renders these chips, so let that group wrap. */
.lib-tile-tag-group--assetUsed { flex-wrap: wrap; }
.im-assetused-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 3px 1px 8px;
  margin: 0 4px 4px 0;
  border-radius: 11px;
  background: var(--abni-surface-2, rgba(0, 0, 0, 0.06));
  font-size: 11px;
  line-height: 1.5;
  max-width: 100%;
}
.im-assetused-chip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.im-assetused-chip-x {
  border: 0;
  background: transparent;
  color: var(--abni-text-muted, #8a8a8a);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 3px;
  border-radius: 8px;
}
.im-assetused-chip-x:hover { color: var(--abni-danger, #d33b30); background: rgba(0, 0, 0, 0.08); }
.im-assetused-chip-x:disabled { opacity: 0.4; cursor: default; }
/* The status row sits a touch tighter against the description above. */
.lib-tile-tag-row--status {
  width: 100%;
}
/* (user-tags row now uses 🏷️ icon prefix like the other rows — no
   extra indent needed) */

/* T3: .lib-tile-golden corner pin removed — golden ⭐ now lives in the
   chip-row .lib-tile-icon-cluster below the image. */

/* Show/hide details toggle in the section head — iOS-style switch. */
.studio-section-head .head-right {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.lib-details-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}
.lib-details-switch-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  letter-spacing: 0.04em;
}
.lib-details-switch input {
  /* Visually hidden but keeps the checkbox accessible for keyboard +
     assistive tech. The track + thumb below render the switch chrome. */
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}
.lib-details-switch-track {
  position: relative;
  display: inline-block;
  width: 34px;
  height: 20px;
  background: #cdd5dd;
  border-radius: 999px;
  transition: background-color 160ms ease;
  flex-shrink: 0;
}
.lib-details-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.25);
  transition: transform 160ms ease;
}
.lib-details-switch input:checked ~ .lib-details-switch-track {
  background: var(--abni-blue-deep, #24608e);
}
.lib-details-switch input:checked ~ .lib-details-switch-track .lib-details-switch-thumb {
  transform: translateX(14px);
}
.lib-details-switch input:focus-visible ~ .lib-details-switch-track {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}

/* Hide the meta / description / tags blocks when details are off. */
.library-panel.no-details .lib-tile-meta,
.library-panel.no-details .lib-tile-description,
.library-panel.no-details .lib-tile-tags {
  display: none;
}

/* ── F7: Library Filters panel ─────────────────────────────── */
.lib-filters-panel {
  background: rgba(248, 250, 252, 0.85);
  border: 1px solid var(--app-card-border);
  border-radius: 14px;
  padding: 16px 20px;
  margin-bottom: 20px;
}
.lib-filters-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 24px;
  margin-bottom: 14px;
}
.lib-filters-row:last-of-type { margin-bottom: 0; }
.lib-filter-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 140px;
}
.lib-filter-group--tags { width: 100%; }
.lib-filter-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--abni-mute);
}
.lib-search-input {
  padding: 7px 12px;
  border: 1px solid var(--app-card-border);
  border-radius: 8px;
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 13px;
  color: var(--abni-ink);
  outline: none;
  transition: border-color 0.15s;
  min-width: 180px;
}
.lib-search-input:focus { border-color: var(--abni-blue-deep); }
.lib-format-chips,
.lib-sort-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.lib-format-chip,
.lib-sort-chip {
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.lib-format-chip:hover,
.lib-sort-chip:hover { border-color: var(--abni-blue-deep); color: var(--abni-blue-deep); }
.lib-format-chip.is-selected,
.lib-sort-chip.is-selected {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.lib-filter-tag-categories {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
}
.lib-filter-tag-cat {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 80px;
}
.lib-filter-tag-cat-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--abni-mute);
}
.lib-filter-tag-cat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.lib-filter-tag-empty {
  font-size: 11px;
  color: var(--abni-mute);
  opacity: 0.5;
}
.lib-filters-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px dashed var(--app-card-border);
  padding-top: 12px;
  margin-top: 12px;
}
.lib-filters-actions {
  /* border/padding now on the parent .lib-filters-footer */
}
.lib-filters-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--abni-mute);
  letter-spacing: 0.03em;
}
.lib-filter-clear-btn {
  padding: 5px 12px;
  border-radius: 8px;
  border: 1px solid var(--app-card-border);
  background: transparent;
  font-family: var(--abni-font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.lib-filter-clear-btn:hover { border-color: var(--app-error); color: var(--app-error); }
/* Filled state — applied when any filter / search is active so the
   button reads as the clear affordance and not as panel chrome. */
.lib-filter-clear-btn.is-active {
  background: var(--app-error);
  border-color: var(--app-error);
  color: #fff;
}
.lib-filter-clear-btn.is-active:hover {
  background: #8c2828;
  border-color: #8c2828;
  color: #fff;
}

/* Section-head breadcrumbs duplicate the always-on top-bar breadcrumb —
   hide them everywhere by default. Brand Style keeps its own, visible only
   when the panel is expanded. */
.studio-section-head .folder-breadcrumb { display: none; }
.brand-style-panel:not(.is-collapsed) .studio-section-head .folder-breadcrumb { display: flex; }

/* Brand Style collapsed header: status dot + title + Show toggle. Hint hides
   because it's prose; the dot stays so users always see the level's
   extraction / lock state at a glance even when the panel is hidden. */
.brand-style-panel.is-collapsed #brand-style-hint { display: none; }

/* Workspace / Processes / Library collapsed headers: title + Show toggle
   only. When collapsed, hide breadcrumb, hint, count, and sibling switches
   (Filters / Details for library) so the head reads as just "Workspace / Show".
   This is the same shape as Brand Style for consistency. */
#folder-section.is-collapsed .section-head-right > .folder-breadcrumb,
#folder-section.is-collapsed #brand-hint,
#folder-section.is-collapsed #folder-view-toggle,
#processes-section.is-collapsed .section-head-right > .folder-breadcrumb,
#processes-section.is-collapsed #processes-hint,
#library-section.is-collapsed .library-head > .folder-breadcrumb,
#library-section.is-collapsed #library-hint,
#library-section.is-collapsed #lib-filters-toggle-label,
#library-section.is-collapsed #lib-details-switch-wrap {
  display: none;
}

/* ──────────────────────────────────────────────────────────────
   Section heads — grid layout for the top dashboard panels so the
   Show toggle sits on the title row and every other right-aligned
   element (view-toggle, hint, filters/details, breadcrumb) lines up
   to the same clean right edge.

   Scoped to the dashboard sections + brand-style; other studio-panel
   instances (settings/credits/users modal sections) keep the global
   flex-wrap layout.
   ────────────────────────────────────────────────────────────── */

#folder-section > .studio-section-head,
#processes-section > .studio-section-head {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "title showtoggle"
    "rest  rest";
  align-items: center;
  column-gap: 12px;
  row-gap: 8px;
  margin-bottom: 16px;
  padding-right: 0;
}
#folder-section > .studio-section-head > .section-title,
#processes-section > .studio-section-head > .section-title {
  grid-area: title;
  width: auto;
  margin-bottom: 0;
  white-space: normal;
  min-width: 0;
}
#folder-section > .studio-section-head > .section-show-toggle,
#processes-section > .studio-section-head > .section-show-toggle {
  grid-area: showtoggle;
  justify-self: end;
  margin: 0;
}
#folder-section > .studio-section-head > .section-head-right,
#processes-section > .studio-section-head > .section-head-right {
  grid-area: rest;
  justify-content: flex-end;
}

/* Library head — same shape but the second row hosts breadcrumb +
   library-head-toggles instead of a generic section-head-right. */
#library-section > .library-head {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "title showtoggle"
    "crumbs toggles";
  align-items: center;
  column-gap: 12px;
  row-gap: 8px;
  margin-bottom: 16px;
  padding-right: 0;
}
#library-section > .library-head > .section-title {
  grid-area: title;
  width: auto;
  margin-bottom: 0;
}
#library-section > .library-head > .section-show-toggle {
  grid-area: showtoggle;
  justify-self: end;
  margin: 0;
}
#library-section > .library-head > .folder-breadcrumb { grid-area: crumbs; }
#library-section > .library-head > .library-head-toggles { grid-area: toggles; }

.section-show-toggle {
  /* normalised — placement is via grid-area on the parent rule. */
  margin: 0;
}

/* Collapsed state — title stays in the same y position as when expanded;
   only the body content and the head's bottom margin go away, leaving
   symmetric padding above and below the title row. No forced height /
   flex-centering — those caused the title to "pop up" when toggling
   from expanded → collapsed because the centered position differed from
   the natural one. */
.studio-panel.is-collapsed .studio-section-head {
  margin-bottom: 0;
}
.studio-panel.is-collapsed .section-title {
  width: auto;
  margin-bottom: 0;
}

/* ── F6: Brand Style expand/collapse toggle ─────────────────── */
.brand-style-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: transparent;
  font-family: var(--abni-font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  flex-shrink: 0;
}
.brand-style-toggle-btn:hover {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
  background: rgba(72, 141, 176, 0.06);
}
.brand-style-chevron {
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  opacity: 0.7;
  transition: transform 0.2s;
}
.brand-style-toggle-btn[aria-expanded="true"] .brand-style-chevron {
  transform: rotate(-135deg) translate(-1px, -1px);
}

/* T3: .lib-tile-hero-pin thumb overlays removed — hero cups now live in
   the chip-row .lib-tile-icon-cluster below the image. */

/* T1: .lib-tile-actions and .lib-tile-action removed — those overlay
   buttons are gone. Tile click now opens the lightbox modal instead. */

/* T3: Icon cluster — star (golden) + cup(s) (hero) at the right end of
   the status chip row. No text labels. */
.lib-tile-tag-row--status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 20px;
}
.lib-tile-tag-status-left {
  flex: 1;
}
.lib-tile-icon-cluster {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.lib-tile-icon-cluster-btn {
  font-size: 14px;
  line-height: 1;
  cursor: default;
  user-select: none;
  /* tooltip via title attr */
}
.lib-tile-icon-cluster-btn.is-golden { color: #ffc832; }
.lib-tile-icon-cluster-btn.is-hero { color: var(--app-warning, #c98a2b); }

/* ── State-specific styling ─────────────────────────────── */

/* Anything not in a terminal "ready" state: fade the image, show overlay. */
.lib-tile--processing .lib-tile-thumb img {
  filter: grayscale(0.2) brightness(0.92);
  opacity: 0.55;
}

/* Generic phase overlay — top-center badge over the image. */
.lib-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  pointer-events: none;
  z-index: 2;
}
.lib-tile-overlay .lt-spinner {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, 0.55);
  border-top-color: var(--abni-blue-deep);
  animation: app-spin 0.9s linear infinite;
}
.lib-tile-overlay .lt-label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(25, 64, 86, 0.70);
  padding: 5px 10px;
  border-radius: 999px;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  white-space: nowrap;
}
.lib-tile-overlay .lt-pct {
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  font-variant-numeric: tabular-nums;
  background: rgba(25, 64, 86, 0.70);
  padding: 3px 9px;
  border-radius: 999px;
}

/* Auditing / fixing — image is fully visible, badge sits under the image. */
.lib-tile--auditing .lib-tile-thumb img,
.lib-tile--fixing .lib-tile-thumb img {
  filter: none;
  opacity: 1;
}
.lib-tile--auditing .lib-tile-overlay,
.lib-tile--fixing .lib-tile-overlay {
  align-items: flex-end;
  justify-content: flex-end;
  padding: 10px;
}
.lib-tile--auditing .lib-tile-overlay .lt-label,
.lib-tile--fixing .lib-tile-overlay .lt-label {
  background: rgba(255, 255, 255, 0.92);
  color: var(--abni-blue-deep);
  font-size: 10.5px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lib-tile--auditing .lib-tile-overlay .lt-label::before,
.lib-tile--fixing .lib-tile-overlay .lt-label::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--abni-blue-deep);
  animation: app-pulse 1.4s ease-in-out infinite;
}
@keyframes app-pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}

/* Failed state — red pill centred over the image, matching the
   processing-overlay placement so the eye lands on the same spot for
   in-flight + failed states. */
.lib-tile--failed {
  border-color: rgba(176, 48, 48, 0.40);
}
.lib-tile--failed .lib-tile-thumb img {
  filter: grayscale(0.6) brightness(0.85);
  opacity: 0.55;
}
.lib-tile-fail-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(176, 48, 48, 0.92);
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  box-shadow: 0 4px 12px rgba(176, 48, 48, 0.30);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  cursor: help;
  white-space: nowrap;
}
.lib-tile-fail-badge .retry {
  margin-left: 4px;
  background: rgba(255, 255, 255, 0.18);
  border: 0;
  color: #fff;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-weight: 700;
  font-size: 11px;
  padding: 0;
  line-height: 1;
}
.lib-tile-fail-badge .retry:hover { background: rgba(255, 255, 255, 0.35); }

/* Selected (Day 5 — slot reserved). */
.lib-tile--selected {
  border-color: var(--abni-blue-deep);
  box-shadow: 0 0 0 2px var(--abni-blue-deep);
}
.lib-tile--selected .lib-tile-thumb img { filter: brightness(0.9); }
.lib-tile-select-check {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 3;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--abni-blue-deep);
  color: #fff;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
}
.lib-tile--selected .lib-tile-select-check { display: inline-flex; }

/* T4: .lib-tile-score removed — score pill deleted per locked decision.
   Data model untouched; item.score still present if server returns it. */

/* ──────────────────────────────────────────────────────────
   Image-detail modal (Day 4) — replaces the Day 3 fullscreen viewer.
   Glass-card launchpad for everything you can do to an image:
     View / Versions / Amend / Brandify / Resize / Improve / Audit /
     Edit Details.
   Layout: 60% image + version chip on the left, 40% tabs + active
   panel on the right. Full-screen on mobile.
   ────────────────────────────────────────────────────────── */
.image-modal {
  position: fixed;
  inset: 0;
  z-index: 160;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.image-modal[hidden] { display: none; }
.im-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(25, 64, 86, 0.62);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  animation: modal-fade 0.18s ease-out;
}
.im-shell {
  position: relative;
  width: min(96vw, 1320px);
  height: min(88vh, 900px);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.96);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: var(--app-card-radius);
  box-shadow: 0 28px 70px rgba(31, 50, 60, 0.30);
  overflow: hidden;
  animation: modal-slide 0.22s var(--abni-ease);
}

/* ── Library prev/next — floating tray below the modal shell ── */
.im-lib-nav-tray {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  padding: 6px 14px;
  box-shadow: 0 4px 18px rgba(31, 50, 60, 0.18);
  position: relative;
  z-index: 10;
  flex-shrink: 0;
}

/* Top bar */
.im-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.6);
}
.im-title-wrap { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
/* Set letter (A/B/C…) — mirrors the on-tile chat letter so the user can note
   "I want B improved". Shown only when the modal opened from a lettered grid. */
.im-set-letter {
  flex-shrink: 0;
  min-width: 24px; height: 24px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--abni-blue-deep, #1f3a4d); color: #fff;
  font-family: var(--abni-font-display);
  font-size: 13px; font-weight: 800; line-height: 1; border-radius: 999px;
}
.im-set-letter[hidden] { display: none; }
.im-title {
  font-family: var(--abni-font-display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--abni-blue-deep);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.im-close {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.7);
  color: var(--abni-blue-deep);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, transform 0.15s, color 0.15s;
}
.im-close:hover {
  background: var(--abni-blue-deep);
  color: #fff;
  transform: scale(1.05);
}

/* Body — 60/40 split */
.im-body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 4fr);
  min-height: 0;
}

/* Stage (left) */
.im-stage {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 18px 16px;
  background: linear-gradient(180deg, rgba(106, 176, 212, 0.05) 0%, rgba(255, 255, 255, 0) 60%);
  border-right: 1px solid var(--app-card-border);
  min-height: 0;
}
.im-stage-canvas {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Card chrome removed 2026-05-16 — image sits flush on the stage column
     background, no rounded corners, no inner paper card. */
  overflow: hidden;
  position: relative;
}
.im-stage-canvas img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
.im-stage-empty {
  color: var(--abni-mute);
  font-size: 13px;
  font-weight: 600;
}

/* Version chip + arrows */
.im-version-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.im-version-arrow {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.8);
  color: var(--abni-blue-deep);
  font-size: 18px;
  line-height: 1;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.im-version-arrow:hover:not(:disabled) {
  background: var(--abni-blue-deep);
  color: #fff;
  transform: translateY(-1px);
}
.im-version-arrow:disabled { opacity: 0.35; cursor: not-allowed; }
.im-version-chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid var(--app-card-border);
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  letter-spacing: 0.04em;
  min-width: 96px;
  justify-content: center;
  cursor: help;
}
.im-version-bar[hidden] { display: none; }

/* Side (tabs + panels) */
.im-side {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}
.im-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 14px 18px 0;
  border-bottom: 1px solid var(--app-card-border);
}
.im-tab {
  padding: 8px 12px 10px;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  margin-bottom: -1px;
  border-radius: 6px 6px 0 0;
}
.im-tab:hover { color: var(--abni-blue-deep); }
.im-tab.is-active {
  color: var(--abni-blue-deep);
  border-bottom-color: var(--abni-blue-deep);
}
.im-tab.is-dirty::after {
  content: "•";
  margin-left: 4px;
  color: var(--app-warning);
}

.im-panels {
  flex: 1;
  overflow-y: auto;
  padding: 20px 22px 24px;
}
.im-panel { display: none; }
.im-panel.is-active { display: flex; flex-direction: column; gap: 12px; }

.im-panel-hint {
  font-size: 13px;
  color: var(--abni-mute);
  line-height: 1.5;
  margin: 0 0 4px;
}
.im-panel-tip {
  font-size: 11.5px;
  color: var(--abni-mute);
  margin: 4px 0 0;
}

.im-field { display: flex; flex-direction: column; gap: 8px; }
.im-field-label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--abni-mute);
}
.im-readout {
  font-size: 14px;
  line-height: 1.5;
  color: var(--abni-ink);
  white-space: pre-wrap;
  word-wrap: break-word;
}
.im-tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.im-tag-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
  white-space: nowrap;
}

/* Modal titles with a leading icon (set-asset, batch-tag, …). */
.modal-title-with-icon {
  display: flex;
  align-items: center;
  gap: 8px;
}
.set-asset-title-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--abni-blue-deep);
}
.set-asset-current {
  margin-top: 14px;
}
.set-asset-current-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--abni-mute);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.set-asset-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.set-asset-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 4px 4px 4px 10px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
  white-space: nowrap;
}
.set-asset-chip--asset {
  background: rgba(72, 141, 176, 0.18);
}
.set-asset-chip-icon {
  width: 12px;
  height: 12px;
  margin-right: 2px;
  flex-shrink: 0;
}
.set-asset-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
  padding: 0;
}
.set-asset-chip-x:hover:not(:disabled) {
  background: rgba(72, 141, 176, 0.25);
  opacity: 1;
}
.set-asset-chip-x:disabled {
  opacity: 0.3;
  cursor: default;
}
.set-asset-chip-x svg {
  width: 12px;
  height: 12px;
}
/* Rename pencil on an asset pill (#11) — sits before the ×, same affordance. */
.set-asset-chip-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
  padding: 0;
  margin-right: 1px;
}
.set-asset-chip-edit:hover {
  background: rgba(72, 141, 176, 0.25);
  opacity: 1;
}
.set-asset-chip-edit svg {
  width: 12px;
  height: 12px;
}
/* Staged for removal (the × fail-safe) — struck through until Save commits. */
.set-asset-chip.is-pending-removal {
  opacity: 0.6;
  text-decoration: line-through;
  background: rgba(211, 59, 48, 0.12);
}
.set-asset-chip.is-pending-removal .set-asset-chip-x { color: #d33b30; opacity: 1; }

/* Read-only asset thumbnail tiles in the lightbox View tab (#10 replacement). */
.im-asset-tiles { margin-top: 10px; }
.im-asset-tiles-label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--abni-text-muted, #6b7785);
  margin-bottom: 6px;
}
.im-asset-tiles-label svg { width: 13px; height: 13px; }
.im-asset-tiles-row { display: flex; flex-wrap: wrap; gap: 8px; }
.im-asset-tile { width: 64px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.im-asset-tile-thumb {
  width: 64px;
  height: 64px;
  object-fit: contain;
  border-radius: 8px;
  background: var(--abni-surface-2, rgba(0, 0, 0, 0.04));
  border: 1px solid rgba(0, 0, 0, 0.07);
}
.im-asset-tile-thumb--missing {
  display: flex;
  align-items: center;
  justify-content: center;
  border-style: dashed;
  border-color: rgba(0, 0, 0, 0.18);
  color: var(--abni-text-muted, #9aa6b2);
}
.im-asset-tile-thumb--missing svg { width: 20px; height: 20px; }
.im-asset-tile-name {
  font-size: 11px;
  text-align: center;
  color: var(--abni-text-muted, #6b7785);
  max-width: 64px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.im-tag-row:empty::before {
  content: "No tags";
  font-size: 12.5px;
  color: var(--abni-mute);
}
.im-meta-row {
  flex-direction: row;
  align-items: center;
  gap: 10px;
}
.im-meta {
  font-size: 12px;
  color: var(--abni-mute);
}
.im-score-chip {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(47, 138, 85, 0.10);
  color: var(--app-success);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.im-score-chip.warn {
  background: rgba(201, 138, 43, 0.12);
  color: var(--app-warning);
}
.im-score-chip.bad {
  background: rgba(176, 48, 48, 0.10);
  color: var(--app-error);
}
/* Score-pill row wrapper — keeps the pill content-width and flush-right
   inside the otherwise stretch-aligned .im-field column. 2026-05-16. */
.im-score-row {
  display: flex;
  justify-content: flex-end;
}

/* Versions list */
.im-versions-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.im-version-row {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 6px;
  border-radius: 12px;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
  text-align: left;
  font-family: inherit;
}
.im-version-row:hover {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
}
.im-version-row.is-active {
  /* Single visual indicator — soft outer halo only. Avoids the previous
     double-ring (inner border + outer focus) that confused which row was
     selected. The row's own border stays unchanged. */
  box-shadow: 0 0 0 3px rgba(72, 141, 176, 0.28);
}
/* Suppress the browser's default focus outline on the version-row buttons —
   `.is-active` (above) is the canonical selected-state indicator. The
   `:focus-visible` style still applies for keyboard navigation. */
.im-version-row:focus { outline: none; }
.im-version-row:focus-visible {
  outline: 2px solid rgba(72, 141, 176, 0.45);
  outline-offset: 2px;
}
.im-version-row .vt-thumb {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--abni-blue-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}
.im-version-row .vt-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.im-version-row .vt-meta {
  min-width: 0;
}
.im-version-row .vt-label {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--abni-ink);
}
.im-version-row .vt-date {
  font-size: 11.5px;
  color: var(--abni-mute);
  margin-top: 2px;
}
.im-version-row .vt-props {
  font-size: 12px;
  color: var(--abni-mute);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Versions that never completed (stuck pending → swept to failed, or genuinely
   failed mid-pipeline) — set-current-version rejects them, so render them as
   visually disabled with a status badge so users know why they can't click. */
.im-version-row.is-incomplete {
  opacity: 0.55;
  cursor: not-allowed;
}
.im-version-row.is-incomplete:hover {
  background: inherit;
  border-color: inherit;
}
.im-version-row .vt-status-badge {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 4px;
  background: #f4d5d5;
  color: #9b3535;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
}
.im-version-row .vt-score {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--abni-blue-deep);
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  letter-spacing: 0.04em;
}
/* Form controls inside panels */
.im-input,
.im-textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--abni-ink);
  transition: border-color 0.2s, box-shadow 0.2s;
  -webkit-appearance: none;
  appearance: none;
}
.im-textarea { resize: vertical; min-height: 80px; }
.im-input:focus,
.im-textarea:focus {
  outline: none;
  border-color: var(--abni-blue-bright);
  box-shadow: 0 0 0 4px rgba(106, 176, 212, 0.18);
}
.im-input::placeholder,
.im-textarea::placeholder { color: var(--abni-mute); opacity: 0.7; }

.im-chip-group { margin-top: 4px; }

.im-panel-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px dashed var(--app-card-border);
}
/* Inline variant — used directly under a single input so the Save button
   sits compactly against its field rather than at the bottom of the panel.
   Strips the dividing border and tight padding the default variant uses. */
.im-panel-actions.im-panel-actions-inline {
  padding-top: 8px;
  margin-top: 0;
  border-top: 0;
}
.im-btn {
  padding: 10px 20px;
  border-radius: 10px;
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.im-btn.primary {
  background: var(--abni-blue-deep);
  color: #fff;
}
.im-btn.primary:hover:not(:disabled) {
  background: var(--abni-blue-deeper);
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(72, 141, 176, 0.25);
}
.im-btn.primary:disabled {
  background: var(--abni-blue-soft);
  color: var(--abni-mute);
  cursor: not-allowed;
}
.im-btn.ghost {
  background: transparent;
  color: var(--abni-mute);
  border-color: var(--app-card-border);
}
.im-btn.ghost:hover { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); }
.im-btn.danger {
  background: transparent;
  color: var(--app-error, #c0392b);
  border-color: var(--app-error, #c0392b);
}
.im-btn.danger:hover:not(:disabled) {
  background: var(--app-error, #c0392b);
  color: #fff;
}

/* T5: View panel quick actions — hero level toggles, golden toggle, download/delete. */
.im-view-actions {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--app-card-border);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.im-hero-level-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
/* Level toggle button — used for hero-per-level and golden */
.im-level-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  border-radius: 8px;
  border: 1.5px solid var(--app-card-border);
  background: transparent;
  color: var(--abni-mute);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.im-level-toggle:hover:not(:disabled) {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
}
.im-level-toggle.is-active,
.im-level-toggle[aria-pressed="true"] {
  background: var(--abni-blue-deep);
  color: #fff;
  border-color: var(--abni-blue-deep);
}
.im-level-toggle:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* "Download + Delete" row in view panel */
.im-view-btns {
  justify-content: flex-start;
  border-top: none;
  padding-top: 0;
  margin-top: 0;
}

/* Audit */
.im-audit-summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--app-card-border);
}
.im-audit-empty {
  font-size: 13px;
  color: var(--abni-mute);
}
.im-audit-criteria {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.im-audit-criterion {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--app-card-border);
  font-size: 13px;
}
.im-audit-criterion .ac-name { color: var(--abni-ink); font-weight: 500; }
.im-audit-criterion .ac-score { font-weight: 700; color: var(--abni-blue-deep); font-variant-numeric: tabular-nums; }

/* ── Lightbox fade-out transition (T2 — process bar) ── */
.image-modal.is-fading {
  transition: opacity 200ms ease-out;
  opacity: 0;
  pointer-events: none;
}

/* ── Library prev/next nav buttons (inside the floating tray) ── */
.im-lib-nav {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--abni-blue-deep);
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, transform 0.15s;
  flex-shrink: 0;
}
.im-lib-nav:hover:not(:disabled) {
  background: var(--abni-blue-deep);
  color: #fff;
  border-radius: 50%;
  transform: scale(1.05);
}
.im-lib-nav:disabled { opacity: 0.32; cursor: not-allowed; }
.im-lib-pos {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-ink);
  letter-spacing: 0.02em;
  min-width: 48px;
  text-align: center;
  flex-shrink: 0;
}

/* ── Overview: identity repeat (title + crumb inside tab, T3) ── */
.im-overview-identity {
  padding-bottom: 8px;
  border-bottom: 1px solid var(--app-card-border);
  margin-bottom: 2px;
}
.im-overview-title {
  font-family: var(--abni-font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--abni-blue-deep);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ── Overview: inline tag pill row (T3) ── */
.im-tag-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.im-tag-pill-row:empty::before {
  content: "No tags";
  font-size: 12.5px;
  color: var(--abni-mute);
}

/* ── Overview: toggle section description (T3) ── */
.im-toggle-desc {
  font-size: 12px;
  color: var(--abni-mute);
  margin: 0;
  line-height: 1.4;
}

/* ── Overview: single-line metadata under the title ── */
.im-overview-props {
  font-size: 14px;
  line-height: 1.5;
  color: var(--abni-mute);
  margin-top: 4px;
}
.im-overview-props:empty { display: none; }

/* ── Overview: tag categories ── */
.im-tag-categories {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.im-tag-category {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.im-tag-cat-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--abni-mute);
  white-space: nowrap;
  flex-shrink: 0;
}
.im-tag-cat-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.im-tag-categories:empty::before {
  content: "No tags";
  font-size: 12.5px;
  color: var(--abni-mute);
}

/* ── Overview: provenance ── */
.im-provenance { margin-top: 4px; }
.im-provenance-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.im-prov-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.im-prov-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--abni-mute);
  min-width: 90px;
  padding-top: 2px;
  flex-shrink: 0;
}
.im-prov-value {
  font-size: 13px;
  color: var(--abni-ink);
  line-height: 1.45;
  flex: 1;
  min-width: 0;
  word-break: break-word;
}
.im-prov-thumb {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--abni-blue-soft);
  cursor: pointer;
  border: 1.5px solid var(--app-card-border);
  flex-shrink: 0;
  transition: border-color 0.15s;
}
.im-prov-thumb:hover { border-color: var(--abni-blue-deep); }
.im-prov-thumb img { width: 100%; height: 100%; object-fit: cover; }
.im-prov-thumbs { display: flex; gap: 6px; flex-wrap: wrap; }
.im-prov-chips { display: flex; gap: 5px; flex-wrap: wrap; }
.im-prov-chip {
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
}
.im-prov-prompt {
  font-size: 12.5px;
  color: var(--abni-ink);
  font-style: italic;
  opacity: 0.8;
}
.im-prov-details { width: 100%; }
.im-prov-details summary {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  cursor: pointer;
  margin-bottom: 4px;
}
.im-prov-details pre {
  font-size: 11px;
  color: var(--abni-mute);
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--abni-paper);
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--app-card-border);
  margin: 0;
}

/* ── Versions list: duplicate button ── */
.vt-dup-btn {
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 8px;
  border: 1.5px solid var(--app-card-border);
  background: transparent;
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  font-family: inherit;
}
.vt-dup-btn:hover:not(:disabled) {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
}
.vt-dup-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── Used-in grid (T3) ── */
.im-used-in-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
}
.im-used-in-thumb {
  border-radius: 10px;
  overflow: hidden;
  border: 1.5px solid var(--app-card-border);
  background: var(--abni-blue-soft);
  cursor: pointer;
  transition: border-color 0.15s, transform 0.15s;
  display: flex;
  flex-direction: column;
}
.im-used-in-thumb:hover {
  border-color: var(--abni-blue-deep);
  transform: translateY(-2px);
}
.im-used-in-thumb img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
}
.im-used-in-as {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--abni-mute);
  padding: 4px 6px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.im-used-in-empty {
  font-size: 13px;
  color: var(--abni-mute);
  grid-column: 1 / -1;
}

/* ── Edit Details: current description + tags block (T4) ── */
.im-current-desc-wrap {
  background: rgba(72, 141, 176, 0.06);
  border: 1px solid var(--app-card-border);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.im-current-desc {
  font-size: 13px;
  color: var(--abni-ink);
  line-height: 1.45;
  margin: 0;
}
.im-current-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* ── Edit Details: agent-mediated input ── */
.im-agent-edit-status {
  font-size: 12.5px;
  color: var(--abni-mute);
  margin: 8px 0 0;
  font-style: italic;
  display: flex;
  align-items: center;
  gap: 6px;
}
.im-agent-edit-status.is-working {
  color: var(--abni-blue-deep);
  font-style: normal;
}
.im-agent-edit-status.is-working::before {
  content: "";
  width: 12px;
  height: 12px;
  border: 2px solid var(--abni-blue-deep);
  border-top-color: transparent;
  border-radius: 50%;
  animation: im-agent-edit-spin 0.7s linear infinite;
  flex-shrink: 0;
}
.im-agent-edit-status.is-success {
  color: var(--abni-blue-deep);
  font-style: normal;
}
.im-agent-edit-status.is-success::before {
  content: "✓";
  font-weight: 700;
}
.im-agent-edit-status.is-error {
  color: var(--app-error);
  font-style: normal;
}
.im-agent-edit-status.is-error::before {
  content: "⚠";
}
@keyframes im-agent-edit-spin {
  to { transform: rotate(360deg); }
}
.im-manual-edit-details {
  margin-top: 16px;
  border-top: 1px dashed var(--app-card-border);
  padding-top: 12px;
}
.im-manual-edit-toggle {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
.im-manual-edit-toggle::-webkit-details-marker { display: none; }
.im-manual-edit-toggle::before { content: "+ "; }
details[open] .im-manual-edit-toggle::before { content: "- "; }
.im-manual-edit-body { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }

/* ── Sticky process bar (T2) ── */
.im-side {
  position: relative; /* anchor for the sticky bar */
}
.im-process-bar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 18px;
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--app-card-border);
}
.im-process-bar-row {
  display: flex;
  gap: 4px;
  flex-wrap: nowrap;
}
.im-process-bar-procs {
  /* Function buttons cluster to the right of the top row */
  justify-content: flex-end;
}
.im-process-bar-utility {
  /* Download + Delete cluster on the right of the bottom row too — keeps
     visual rhythm with the top row */
  justify-content: flex-end;
}
.im-proc-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 7px 8px;
  border-radius: 9px;
  border: 1.5px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.7);
  color: var(--abni-blue-deep);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.im-proc-btn:hover {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(72, 141, 176, 0.22);
}

/* Mobile — full screen, stage on top, panels below */
@media (max-width: 880px) {
  .im-shell {
    width: 100vw;
    height: 100dvh;
    border-radius: 0;
    border: 0;
    margin: 0;
  }
  .im-body { grid-template-columns: 1fr; grid-template-rows: 50vh 1fr; }
  .im-stage { border-right: 0; border-bottom: 1px solid var(--app-card-border); padding: 12px; }
  .im-tabs {
    overflow-x: auto;
    flex-wrap: nowrap;
    padding: 10px 14px 0;
    scrollbar-width: none;
  }
  .im-tabs::-webkit-scrollbar { display: none; }
  .im-tab { white-space: nowrap; }
  .im-panels { padding: 16px; }
  .im-process-bar { flex-wrap: wrap; gap: 6px; padding: 8px 12px; }
  .im-process-bar-right { justify-content: flex-start; }
}

/* ── Modal (used for + New client / brand / sub-brand / campaign) ── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(25, 64, 86, 0.40);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 100;
  animation: modal-fade 0.15s ease-out;
}
.modal-backdrop.open { display: flex; }

.modal {
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: var(--app-card-radius);
  padding: 28px;
  width: 100%;
  max-width: 440px;
  box-shadow: 0 24px 60px rgba(31, 50, 60, 0.20);
  animation: modal-slide 0.22s var(--abni-ease);
}
.modal h2 {
  font-family: var(--abni-font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--abni-blue-deep);
  margin: 0 0 8px;
}
.modal .modal-sub {
  font-size: 14px;
  color: var(--abni-mute);
  line-height: 1.5;
  margin: 0 0 20px;
}
.modal label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  margin: 0 0 10px;
}
.modal input[type="text"] {
  width: 100%;
  padding: 13px 16px;
  border-radius: 12px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 15px;
  color: var(--abni-ink);
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
  -webkit-appearance: none;
  appearance: none;
}
.modal input[type="text"]:focus {
  border-color: var(--abni-blue-bright);
  box-shadow: 0 0 0 4px rgba(106, 176, 212, 0.18);
}
.modal .modal-error {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--app-error);
  background: rgba(176, 48, 48, 0.07);
  border: 1px solid rgba(176, 48, 48, 0.18);
  display: none;
}
.modal .modal-error.visible { display: block; }
.modal-actions {
  margin-top: 22px;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: flex-end;
}
/* ── SA modal: Agent workflows tab — per-pipeline tune-editor launcher ── */
.sa-workflows-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
  padding: 4px 0 8px;
}
.sa-workflow-btn { width: 100%; }
.sa-workflows-status {
  font-size: 12.5px;
  color: var(--abni-mute);
  margin: 8px 0 0;
}
.sa-workflows-status.is-error { color: var(--app-error); }

.modal-btn {
  padding: 11px 22px;
  font-family: var(--abni-font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
}
.modal-btn.primary {
  background: var(--abni-blue-deep);
  color: #fff;
}
.modal-btn.primary:hover:not(:disabled) { background: var(--abni-blue-deeper); transform: translateY(-1px); }
.modal-btn.primary:disabled { opacity: 0.55; cursor: not-allowed; }
.modal-btn.ghost {
  background: transparent;
  color: var(--abni-mute);
  border-color: var(--app-card-border);
}
.modal-btn.ghost:hover { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); }

@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-slide { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ── Toast (top-right, fades) ─────────────────────── */
.toast-stack {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  max-width: calc(100vw - 32px);
}
.toast {
  pointer-events: auto;
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: 12px;
  padding: 12px 16px 12px 14px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 240px;
  max-width: 360px;
  box-shadow: 0 12px 28px rgba(31, 50, 60, 0.16);
  animation: toast-in 0.22s var(--abni-ease);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--abni-ink);
}
.toast.removing { animation: toast-out 0.18s var(--abni-ease) forwards; }
.toast .toast-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 6px;
  flex-shrink: 0;
}
.toast.error .toast-dot { background: var(--app-error); }
.toast.error { color: var(--app-error); }
.toast.info .toast-dot { background: var(--abni-blue-deep); }
.toast.success .toast-dot { background: var(--app-success); }
.toast-close {
  background: transparent;
  border: 0;
  color: inherit;
  opacity: 0.5;
  cursor: pointer;
  padding: 0 2px;
  margin-left: auto;
  font-size: 18px;
  line-height: 1;
}
.toast-close:hover { opacity: 1; }

@keyframes toast-in { from { opacity: 0; transform: translateX(8px); } to { opacity: 1; transform: translateX(0); } }
@keyframes toast-out { to { opacity: 0; transform: translateX(8px); } }

/* ──────────────────────────────────────────────────────────
   Day 4 — Brandify / Improve / Resize launchpad components
   (dropzone, picked-image, library picker modal)
   ────────────────────────────────────────────────────────── */

/* Dropzone — mirror of .studio-dropzone from studio-7k9zXnQ.html. */
.dropzone {
  position: relative;
  width: 100%;
  min-height: 180px;
  border-radius: 14px;
  border: 2px dashed rgba(106, 176, 212, 0.55);
  background: rgba(255, 255, 255, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  cursor: pointer;
  transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
.dropzone:hover,
.dropzone.is-hover {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
}
.dropzone.is-hover {
  box-shadow: 0 0 0 4px rgba(106, 176, 212, 0.18);
}
.dropzone .dz-prompt {
  color: var(--abni-blue-deep);
  font-size: 15px;
  font-weight: 500;
  max-width: 340px;
  line-height: 1.5;
}
.dropzone .dz-prompt small {
  display: block;
  margin-top: 6px;
  color: var(--abni-mute);
  font-size: 12px;
  font-weight: 400;
}
.dropzone input[type="file"] { display: none; }
.dropzone.has-file {
  cursor: default;
  padding: 16px;
}
.dz-preview {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.dz-preview img {
  max-width: 100%;
  max-height: 280px;
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(31, 50, 60, 0.10);
  object-fit: contain;
  background: var(--abni-paper);
}
.dz-preview .dz-meta {
  font-size: 12px;
  color: var(--abni-mute);
}
.dz-preview-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}
.dz-preview-row button {
  padding: 7px 14px;
  font-size: 13px;
  font-family: var(--abni-font-body);
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.dz-preview-row button:hover {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
}
/* Library-sourced brandify preview — same shape as a freshly-uploaded
   dz-preview but the source is an existing library tile. The meta line
   already calls this out ("· From library"); the subtle accent below makes
   it visually obvious at a glance which source the panel is using. */
.dz-preview.is-library-source img {
  box-shadow: 0 6px 18px rgba(31, 50, 60, 0.10), 0 0 0 2px var(--abni-blue-deep, #2a5a8a);
}

/* Picked-image surface (Improve + Resize panels). */
.picked-image {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px;
  border-radius: 14px;
  border: 1px dashed var(--app-card-border);
  background: rgba(255, 255, 255, 0.55);
  min-height: 96px;
}
.picked-image.has-image {
  border-style: solid;
}
.pick-image-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 12px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.pick-image-btn:hover {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
  transform: translateY(-1px);
}
.pick-image-icon {
  font-family: var(--abni-font-display);
  font-weight: 700;
  font-size: 16px;
}
.picked-thumb {
  width: 72px;
  height: 72px;
  border-radius: 10px;
  object-fit: cover;
  background: var(--abni-blue-soft);
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(31, 50, 60, 0.10);
}
/* Amend shows a LARGE preview of the image being edited (not a thumbnail) so
   it's clear what you're amending — stacked, full-width, whole image visible. */
#amend-picked.has-image { flex-direction: column; align-items: stretch; gap: 12px; }
#amend-picked.has-image .picked-thumb {
  width: 100%;
  height: auto;
  max-height: 340px;
  object-fit: contain;
  border-radius: 12px;
  background: rgba(25, 64, 86, 0.04);
}
#amend-picked.has-image .picked-meta { width: 100%; }
#amend-picked.has-image .picked-change { align-self: flex-end; }
.picked-meta {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.picked-meta .picked-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--abni-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.picked-meta .picked-sub {
  font-size: 12px;
  color: var(--abni-mute);
}
.picked-change {
  padding: 7px 14px;
  font-size: 13px;
  font-family: var(--abni-font-body);
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  color: var(--abni-mute);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.picked-change:hover {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
}

/* Multi-select hint — shown inside .picked-image when the user has more
   than one library tile selected but the active panel only takes one.
   Replaces the default "Pick an image" button with a guidance message
   plus a "Deselect all" button so the user can recover quickly. */
.picked-multi-hint {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 16px;
  width: 100%;
}
.picked-multi-msg {
  font-size: 13.5px;
  color: #5a7287;
  line-height: 1.4;
}
.picked-multi-clear {
  align-self: flex-start;
  padding: 8px 14px;
  border: 1px solid #cbd6e2;
  border-radius: 8px;
  background: #fff;
  color: var(--abni-ink);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.picked-multi-clear:hover {
  border-color: var(--abni-blue);
  color: var(--abni-blue-deep);
}

/* Library picker modal — reused by Improve + Resize. */
.library-picker-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(25, 64, 86, 0.40);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 120;
  animation: modal-fade 0.15s ease-out;
}
.library-picker-backdrop.open { display: flex; }

.library-picker {
  background: rgba(255, 255, 255, 0.96);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: var(--app-card-radius);
  padding: 24px;
  width: 100%;
  max-width: 640px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: 0 24px 60px rgba(31, 50, 60, 0.20);
  animation: modal-slide 0.22s var(--abni-ease);
}
.library-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.library-picker-head h2 {
  font-family: var(--abni-font-display);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--abni-blue-deep);
  margin: 0;
}
.library-picker-close {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid var(--app-card-border);
  color: var(--abni-mute);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.library-picker-close:hover {
  border-color: var(--abni-blue-deep);
  color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
}
.library-picker-sub {
  margin: 0;
  font-size: 13px;
  color: var(--abni-mute);
}
.library-picker-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  overflow-y: auto;
  padding: 2px 4px 2px 0;
  flex: 1;
  min-height: 0;
}
@media (max-width: 560px) { .library-picker-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.library-picker-tile {
  position: relative;
  border-radius: 10px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  cursor: pointer;
  overflow: hidden;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.library-picker-tile:not(.is-disabled):hover {
  border-color: var(--abni-blue-deep);
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(31, 50, 60, 0.10);
}
.library-picker-tile .lpt-thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 7px;
  overflow: hidden;
  background: var(--abni-blue-soft);
}
.library-picker-tile .lpt-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.library-picker-tile .lpt-name {
  font-size: 11px;
  color: var(--abni-ink);
  padding: 0 2px 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.library-picker-tile.is-disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.library-picker-tile.is-disabled .lpt-thumb img {
  filter: grayscale(0.35) brightness(0.9);
}
.library-picker-tile .lpt-badge {
  position: absolute;
  inset: auto 4px 4px 4px;
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(25, 64, 86, 0.75);
  padding: 3px 6px;
  border-radius: 6px;
}
.library-picker-empty {
  padding: 32px 16px;
  text-align: center;
  color: var(--abni-mute);
  font-size: 14px;
  border: 1px dashed var(--app-card-border);
  border-radius: 14px;
}
.library-picker-empty p { margin: 0; }
.library-picker-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 4px;
}

/* ──────────────────────────────────────────────────────────
   Day 5 — Library toolbar (sort/filter chips + multi-select bar)
   Plus the dropzone tile, move picker, and batch dialogs.
   ────────────────────────────────────────────────────────── */

.library-toolbar {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}

.lib-chips {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.lib-chip-menu-wrap { position: relative; }
.lib-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.7);
  font-family: var(--abni-font-body);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--abni-ink);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.lib-chip:hover { border-color: var(--abni-blue-deep); background: rgba(106, 176, 212, 0.10); }
.lib-chip strong { font-weight: 600; color: var(--abni-blue-deep); }
.lib-chip-caret { font-size: 10px; color: var(--abni-mute); }
.lib-chip[aria-expanded="true"] {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.10);
}

.lib-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 30;
  min-width: 180px;
  padding: 6px;
  background: rgba(255, 255, 255, 0.98);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--app-card-border);
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(31, 50, 60, 0.16);
  display: none;
}
.lib-menu.open { display: block; }
.lib-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border-radius: 8px;
  border: 0;
  background: transparent;
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--abni-ink);
  cursor: pointer;
}
.lib-menu-item:hover { background: rgba(106, 176, 212, 0.10); }
.lib-menu-item.is-selected { background: rgba(72, 141, 176, 0.12); color: var(--abni-blue-deep); font-weight: 600; }

.lib-filter-panel {
  min-width: 320px;
  padding: 14px;
  display: none;
  flex-direction: column;
  gap: 14px;
}
.lib-filter-panel.open { display: flex; }
.lib-filter-section { display: flex; flex-direction: column; gap: 6px; }
.lib-filter-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--abni-mute);
}
.lib-filter-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  max-height: 96px;
  overflow-y: auto;
}
.lib-filter-tag {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--abni-ink);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.lib-filter-tag:hover { border-color: var(--abni-blue-deep); }
.lib-filter-tag.is-selected {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.lib-filter-tags-empty {
  font-size: 12px;
  color: var(--abni-mute);
}
.lib-filter-score { display: flex; flex-direction: column; gap: 4px; }
.lib-filter-score input[type="range"] { width: 100%; }
.lib-filter-score-readout {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  font-variant-numeric: tabular-nums;
}
.lib-filter-types { display: flex; gap: 6px; flex-wrap: wrap; }
.lib-type-chip {
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-size: 12px;
  font-weight: 500;
  color: var(--abni-ink);
  cursor: pointer;
}
.lib-type-chip.is-selected {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.lib-filter-actions {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding-top: 4px;
  border-top: 1px solid var(--app-card-border);
}
.lib-filter-clear,
.lib-filter-close {
  font-family: var(--abni-font-body);
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
}
.lib-filter-clear { background: transparent; border: 1px solid var(--app-card-border); color: var(--abni-mute); }
.lib-filter-clear:hover { color: var(--app-error); border-color: rgba(176, 48, 48, 0.40); }
.lib-filter-close {
  background: var(--abni-blue-deep);
  border: 1px solid var(--abni-blue-deep);
  color: #fff;
}

.lib-active-filters { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.lib-active-filter {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.12);
  border: 1px solid rgba(72, 141, 176, 0.25);
  color: var(--abni-blue-deep);
  font-size: 11.5px;
  font-weight: 600;
}
.lib-active-filter button {
  background: transparent;
  border: 0;
  color: var(--abni-blue-deep);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 0 0 4px;
}
.lib-active-filter button .btn-emoji {
  margin-right: 0;
  font-size: 0.9em;
}
.lib-active-filter button:hover { color: var(--app-error); }

/* Multi-select floating action bar. Same CSS-specificity trap as the picker
   and brand-style-body — `display: flex` would beat the UA stylesheet's
   `[hidden] { display: none }` and the bar would always be visible. Force
   hidden to win so the bar appears only when at least one tile is checked
   (handler toggles bar.hidden on selection-set length). */
.lib-batch-bar[hidden] { display: none !important; }
.lib-batch-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--app-card-border);
  box-shadow: 0 8px 20px rgba(31, 50, 60, 0.08);
  animation: lib-batch-in 0.18s var(--abni-ease);
}
@keyframes lib-batch-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.lib-batch-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
}
.lib-batch-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.lib-batch-btn {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--abni-ink);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.lib-batch-btn:hover { border-color: var(--abni-blue-deep); color: var(--abni-blue-deep); }
.lib-batch-btn.danger { color: var(--app-error); border-color: rgba(176, 48, 48, 0.30); }
.lib-batch-btn.danger:hover { background: rgba(176, 48, 48, 0.08); color: var(--app-error); }
.lib-batch-btn.ghost { color: var(--abni-mute); }
.lib-batch-btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: auto; }
.lib-batch-btn:disabled:hover { border-color: var(--app-card-border); color: var(--abni-ink); background: var(--abni-white); }

/* T2: Level-actions bars — one per cascade row (brand / sub-brand / campaign).
   Each row injects its own bar when the relevant level is selected.
   Uses .lib-batch-bar for overall chrome; .level-actions-bar adds spacing below. */
.level-actions-bar {
  margin-bottom: 12px;
}
.level-actions-path {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}
.level-actions-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--abni-mute);
  white-space: nowrap;
  flex-shrink: 0;
}
.level-actions-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.level-actions-rename-input {
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--abni-blue-deep);
  border-radius: 6px;
  padding: 2px 8px;
  outline: none;
  min-width: 180px;
  color: var(--abni-ink);
  background: var(--abni-white);
}

/* Multi-select hover affordance — checkbox on each tile. */
.lib-tile-select-toggle {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 4;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: 2px solid rgba(255, 255, 255, 0.9);
  background: rgba(25, 64, 86, 0.35);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  padding: 0;
}
.lib-tile.lib-tile--ready:hover .lib-tile-select-toggle { display: inline-flex; }
.lib-tile.lib-tile--selected .lib-tile-select-toggle {
  display: inline-flex;
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
}
/* While any tile is selected, expose the checkbox on all tiles so the user
   doesn't have to hover to find them. */
.library-grid.has-selection .lib-tile.lib-tile--ready .lib-tile-select-toggle {
  display: inline-flex;
}

/* ── Dropzone tile (always position 0 in the Library grid) ── */
.lib-tile--upload {
  cursor: pointer;
  background: transparent;
  border: 2px dashed rgba(106, 176, 212, 0.55);
  transition: border-color 0.18s, background 0.18s, box-shadow 0.18s, transform 0.18s;
}
.lib-tile--upload:hover {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
  transform: translateY(-2px);
}
.lib-tile--upload.is-hover {
  border-style: solid;
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.12);
  box-shadow: 0 0 0 4px rgba(106, 176, 212, 0.18);
}
.lib-tile--upload .lib-tile-thumb {
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 8px;
}
.lt-upload-plus {
  font-family: var(--abni-font-display);
  font-weight: 600;
  font-size: 40px;
  color: var(--abni-blue-deep);
  line-height: 1;
}
.lt-upload-prompt {
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  text-align: center;
}
.lt-upload-sub {
  font-size: 11px;
  color: var(--abni-mute);
  text-align: center;
}

/* Expanded upload card (after a file is chosen). */
.lib-tile--upload.lib-tile--upload-loaded {
  border-style: solid;
  background: var(--abni-white);
  padding: 8px;
  cursor: default;
}
.lt-upload-preview {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--abni-blue-soft);
}
.lt-upload-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.lt-upload-card-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 6px;
}
.lt-upload-intent {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.lt-upload-intent button {
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--abni-ink);
  cursor: pointer;
}
.lt-upload-intent button.is-selected {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.lt-upload-intent button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.lt-upload-actions {
  display: flex;
  gap: 6px;
}
.lt-upload-actions button {
  flex: 1;
  padding: 6px 8px;
  border-radius: 8px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  font-family: var(--abni-font-body);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--abni-ink);
  cursor: pointer;
}
.lt-upload-actions .lt-upload-submit {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.lt-upload-actions .lt-upload-submit:disabled {
  background: var(--abni-blue-soft);
  border-color: var(--app-card-border);
  color: var(--abni-mute);
  cursor: not-allowed;
}

/* ── Move-target picker tree ── */
.move-picker .move-picker-body {
  max-height: 56vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* .move-row is now a flex container (div) housing .move-row-pick + optional .move-row-drill. */
.move-row {
  display: flex;
  align-items: stretch;
  border-radius: 10px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.6);
  overflow: hidden;
  width: 100%;
}
.move-row:has(.move-row-pick.is-selected) {
  border-color: var(--abni-blue-deep);
  background: rgba(72, 141, 176, 0.12);
}
.move-row-pick {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  padding: 8px 12px;
  text-align: left;
  font-family: var(--abni-font-body);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--abni-ink);
  background: none;
  border: none;
  cursor: pointer;
}
.move-row-pick:hover { background: rgba(106, 176, 212, 0.08); }
.move-row-pick.is-selected {
  font-weight: 600;
  color: var(--abni-blue-deep);
}
.move-row-drill {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 0 10px;
  background: none;
  border: none;
  border-left: 1px solid rgba(0,0,0,0.07);
  cursor: pointer;
  color: var(--abni-mute);
}
.move-row-drill:hover { background: rgba(106, 176, 212, 0.12); color: var(--abni-blue-deep); }
.move-row.is-brand { }
.move-row.is-sub-brand .move-row-pick { padding-left: 30px; font-size: 13px; }
.move-row.is-campaign .move-row-pick { padding-left: 12px; font-size: 12.5px; color: var(--abni-mute); }
.move-row.is-campaign .move-row-pick.is-selected { color: var(--abni-blue-deep); }
.move-row .move-meta {
  margin-left: auto;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--abni-mute);
}
/* Breadcrumb back button in drill levels. */
.move-picker-back {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 4px;
  margin-bottom: 4px;
  font-family: var(--abni-font-body);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--abni-mute);
  background: none;
  border: none;
  cursor: pointer;
  border-radius: 6px;
}
.move-picker-back:hover { color: var(--abni-blue-deep); background: rgba(106, 176, 212, 0.08); }

/* danger primary modal button (delete confirm). */
.modal-btn.primary.danger {
  background: var(--app-error);
  border-color: var(--app-error);
}
.modal-btn.primary.danger:hover {
  background: #8a2424;
  border-color: #8a2424;
}

/* ────────── Asset picker (per-process panel) ──────────
 *
 * Collapsible <details> block that sits below each process panel's prompt
 * input. Rows are grouped by hierarchy level (Brand / Sub-brand / Campaign);
 * each row renders a horizontal scroll of asset thumbnails. Click toggles
 * selection. "Refresh prompt" rebuilds the prompt textarea via
 * POST /v1/images/prepare-prompt. */
.asset-picker {
  border: 1px solid var(--app-card-border);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.5);
  padding: 0;
  overflow: hidden;
}
.asset-picker[open] { background: rgba(255, 255, 255, 0.75); }
.asset-picker-summary {
  list-style: none;
  cursor: pointer;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  user-select: none;
}
.asset-picker-summary::-webkit-details-marker { display: none; }
/* Dropdown caret removed — asset-picker is always-open in the new layout,
   so the chevron implied an interaction it didn't have. The icon + title
   alone read more cleanly. */
.asset-picker-summary::before {
  content: "";
  display: none;
  transition: transform 0.18s;
  color: var(--abni-mute);
  font-size: 11px;
  width: 12px;
}
.asset-picker[open] .asset-picker-summary::before { transform: rotate(90deg); }
.asset-picker-title { letter-spacing: 0.02em; }
.asset-picker-count {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--abni-mute);
  letter-spacing: 0.03em;
}
.asset-picker-count.has-selection { color: var(--abni-blue-deep); }

.asset-picker-body {
  padding: 4px 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.asset-picker-empty {
  padding: 8px 0 12px;
  color: var(--abni-mute);
  font-size: 12.5px;
}
.asset-picker-loading,
.asset-picker-error {
  padding: 8px 0 12px;
  color: var(--abni-mute);
  font-size: 12.5px;
  font-style: italic;
}
.asset-picker-error { color: var(--app-error); font-style: normal; }

.asset-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.asset-row-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--abni-mute);
}
/* T5: brand/sub-brand user name keeps original casing */
.asset-row-label .ap-level-name {
  text-transform: none;
  letter-spacing: 0.02em;
}
.asset-row-thumbs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.asset-thumb {
  appearance: none;
  border: 2px solid var(--app-card-border);
  background: var(--abni-white);
  border-radius: 10px;
  padding: 4px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 88px;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.asset-thumb:hover { border-color: var(--abni-blue-deep); transform: translateY(-1px); }
.asset-thumb img {
  width: 76px;
  height: 76px;
  object-fit: cover;
  border-radius: 6px;
  background: var(--abni-blue-soft);
}
.asset-thumb-name {
  font-size: 11px;
  font-weight: 600;
  color: var(--abni-ink);
  text-align: center;
  line-height: 1.2;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.asset-thumb.is-selected {
  border-color: var(--abni-blue-deep);
  box-shadow: 0 4px 14px rgba(72, 141, 176, 0.22);
}
.asset-thumb.is-selected::after {
  content: "✓";
  position: absolute;
  margin-top: -4px;
  margin-left: 60px;
  background: var(--abni-blue-deep);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.asset-thumb { position: relative; }

.asset-picker-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px 14px;
  border-top: 1px dashed var(--app-card-border);
}
.asset-refresh-btn {
  appearance: none;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  border-radius: 10px;
  padding: 8px 14px;
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: border-color 0.15s, background 0.15s;
}
.asset-refresh-btn:hover:not(:disabled) {
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.08);
}
.asset-refresh-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.asset-refresh-status {
  font-size: 12px;
  color: var(--abni-mute);
}
.asset-refresh-status.is-success { color: var(--abni-blue-deep); }
.asset-refresh-status.is-error { color: var(--app-error); }

/* ── Refresh preview — non-editable summary box above the Refresh button ── */
.refresh-preview {
  margin: 8px 0 4px;
  padding: 10px 14px;
  border: 1px solid rgba(106, 176, 212, 0.35);
  background: rgba(106, 176, 212, 0.05);
  border-radius: 10px;
  font-family: var(--abni-font-body);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--abni-ink, #1d2330);
  white-space: pre-wrap;
}
.refresh-preview[hidden] { display: none !important; }
.refresh-preview-row { display: flex; align-items: baseline; gap: 6px; }
.refresh-preview-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--abni-mute);
  min-width: 84px;
}
.refresh-preview-value { color: var(--abni-ink, #1d2330); }
.refresh-preview-asset { font-weight: 600; }
.refresh-preview-mode { font-style: italic; color: var(--abni-mute); }

/* ── Refresh / check-for-assets gate row — compact button right-aligned
   with the Generate button width. Success messages render to the LEFT. */
.refresh-gate-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin: 12px 0 4px;
  flex-wrap: wrap;
}
/* Secondary "Check for assets" affordance. Asset detection now runs
   automatically (debounced) as the user types, so this is an optional
   manual re-scan — small + quiet, never the primary action. */
.refresh-gate-btn {
  appearance: none;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white, #ffffff);
  border-radius: 999px;
  padding: 5px 12px;
  font-family: var(--abni-font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: color 0.15s, border-color 0.15s, background 0.15s, transform 0.05s;
  order: 2;
}
.refresh-gate-btn .btn-emoji { font-size: 12px; }
.refresh-gate-btn:hover:not(:disabled) {
  color: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
}
.refresh-gate-btn:active:not(:disabled) { transform: translateY(1px); }
.refresh-gate-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* Status message + "Accepted ✓" chip are retired — detection is now silent
   and generation isn't gated, so neither has anything to report. Kept as
   no-ops in case any stray markup references them. */
.refresh-gate-row .asset-refresh-status { display: none; }
.refresh-gate-accepted { display: none !important; }

/* ── Level delete inventory panel ── */
.level-delete-inventory {
  margin: 10px 0 0;
  font-size: 13px;
}
.ldi-skeleton {
  color: var(--abni-mute);
  font-style: italic;
  padding: 6px 0;
}
.ldi-summary {
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--app-fg);
}
.ldi-style-row {
  font-size: 12px;
  color: var(--abni-mute);
  margin-bottom: 6px;
}
.ldi-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 8px;
}
.ldi-chip {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
  background: rgba(106, 176, 212, 0.12);
  color: var(--abni-blue-deep);
  border: 1px solid rgba(106, 176, 212, 0.3);
}
.ldi-images {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-height: 160px;
  overflow-y: auto;
  margin-top: 6px;
}
.ldi-image-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ldi-thumb {
  width: 32px;
  height: 32px;
  border-radius: 4px;
  object-fit: cover;
  background: var(--abni-blue-soft);
  flex-shrink: 0;
}
.ldi-img-title {
  font-size: 12px;
  color: var(--app-fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ldi-more {
  font-size: 12px;
  color: var(--abni-mute);
  padding: 2px 0;
}

/* ──────────────────────────────────────────────────────────
   Manage Brand Style — read/edit brand config for the active brand.
   Sits below the library panel; visible only when state.expandedBrand is
   set. Four blocks in a responsive grid: Summary, Extract, Rules,
   Golden refs.
   ────────────────────────────────────────────────────────── */

/* T1: Brand Style panel — single vertical column layout */
.brand-style-panel { /* bottom radius handled by global rule */ }
/* Two-column section head — left stacks title/breadcrumb/subtitle,
   right is a fixed cluster (pill + toggle) anchored top-right. Position
   doesn't shift when the panel expands and the breadcrumb appears. */
.brand-style-panel .bs-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: 12px;
}
.brand-style-panel .bs-head-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  min-width: 0;
}
.brand-style-panel .bs-head-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
/* Override the global rule that hides section-head breadcrumbs except
   in expanded brand-style — now the breadcrumb sits in the left stack
   inside .bs-head. The original rule looked at .studio-section-head
   descendants; our new structure preserves that, so this override still
   applies via .brand-style-panel:not(.is-collapsed). */
/* Same CSS-specificity trap as the picker — `display: flex` beats
   `[hidden] { display: none }`, so the collapsed body never actually
   disappeared. Force hidden to win. */
.brand-style-body[hidden] { display: none !important; }
.brand-style-body {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* T1: Each logical sub-section */
.bs-section {
  padding: 20px 0 20px;
  border-top: 1px solid var(--app-card-border);
}
.bs-section:first-child { border-top: none; padding-top: 0; }

.bs-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 14px;
}
.bs-section-title {
  font-family: var(--abni-font-display);
  /* Bumped from 11px so Brand Style inner section headings (Golden
     references, Extracted style, Brand image rules, etc.) sit clearly
     above their sub-headings. Top-level panel title is still larger
     (.section-title at 16px). */
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--abni-blue-deep);
  margin: 0;
}
.bs-section-meta {
  font-size: 12px;
  color: var(--abni-mute);
}

/* Legacy .bs-block selectors — kept for any references in generated content */
.bs-block-head { display: flex; flex-direction: column; gap: 4px; }
.bs-block-head h3 {
  font-family: var(--abni-font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  margin: 0;
}
.bs-block-sub {
  font-size: 13px;
  color: var(--abni-mute);
  line-height: 1.5;
}

/* Summary block */
.bs-summary-body { display: flex; flex-direction: column; gap: 14px; font-size: 13px; }
.bs-summary-loading,
.bs-summary-empty {
  color: var(--abni-mute);
  font-style: italic;
}
.bs-summary-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 12px;
  align-items: start;
}
.bs-summary-label {
  font-family: var(--abni-font-display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-mute);
  padding-top: 2px;
}
.bs-summary-value {
  color: var(--abni-ink);
  line-height: 1.5;
}
.bs-summary-value.is-empty { color: var(--abni-mute); font-style: italic; }
.bs-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.bs-swatch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 4px;
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  font-size: 11px;
  color: var(--abni-ink);
}
.bs-swatch-chip {
  width: 18px;
  height: 18px;
  border-radius: 999px;
  border: 1px solid rgba(31, 50, 60, 0.10);
  flex: 0 0 auto;
}
.bs-summary-count {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
  font-weight: 600;
  font-size: 12px;
}

/* Extract block */
.bs-extract-dropzone { min-height: 140px; }
.bs-extract-job {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(72, 141, 176, 0.06);
  border: 1px solid var(--app-card-border);
  font-size: 13px;
}
.bs-extract-job-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
}
.bs-extract-job-status.is-pending { color: var(--abni-blue-deep); }
.bs-extract-job-status.is-error { color: var(--app-error); }
.bs-extract-job-status.is-ready { color: var(--abni-blue-deep); }
.bs-extract-results { display: flex; flex-direction: column; gap: 6px; }
.bs-extract-result-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--abni-white);
  border: 1px solid var(--app-card-border);
  font-size: 12.5px;
}
.bs-extract-result-actions { display: inline-flex; gap: 6px; }
.bs-extract-mini-btn {
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  color: var(--abni-mute);
  cursor: pointer;
  font-weight: 600;
}
.bs-extract-mini-btn:hover { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); }
.bs-extract-mini-btn.is-locked { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); background: rgba(106, 176, 212, 0.10); }

/* Rules block */
.bs-rules-body { display: flex; flex-direction: column; gap: 8px; max-height: 360px; overflow-y: auto; }
.bs-rules-loading,
.bs-rules-empty {
  color: var(--abni-mute);
  font-style: italic;
  font-size: 13px;
  padding: 6px 0;
}
.bs-rule-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: start;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--abni-paper, #f7f8f9);
  border: 1px solid var(--app-card-border);
}
.bs-rule-text { font-size: 13px; color: var(--abni-ink); line-height: 1.4; }
.bs-rule-scope {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.10);
  color: var(--abni-blue-deep);
  white-space: nowrap;
}
.bs-rule-scope.is-create-only {
  background: rgba(31, 50, 60, 0.06);
  color: var(--abni-mute);
}
/* Per-rule on/off switch (replaces the old per-rule lock) */
.bs-rule-toggle {
  gap: 6px;
  margin-right: 4px;
}
.bs-rule-toggle .lib-details-switch-label {
  font-size: 11px;
  min-width: 20px;
  text-align: right;
}
/* Switched-off rules stay visible but read as paused. */
.bs-rule-row.is-off { opacity: 0.55; }
.bs-rule-row.is-off .bs-rule-toggle { opacity: 1; }
.bs-rule-row.is-off .bs-rule-toggle .lib-details-switch-label { color: var(--abni-mute); }

/* Inherited rules — distinct from own rules; read-only here (toggle only). */
.bs-rule-row.is-inherited {
  background: rgba(72, 141, 176, 0.05);
  border-style: dashed;
}
.bs-rule-inherited {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(72, 141, 176, 0.14);
  color: var(--abni-blue-deep);
  white-space: nowrap;
}

/* Assets pinned to a rule — injected whenever the rule applies. */
.bs-rule-pins {
  margin-top: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--abni-blue-deep);
}
.bs-rule-assets { margin: 4px 0 2px; }
.bs-rule-assets-label {
  font-size: 11.5px;
  color: var(--abni-mute);
  margin-bottom: 6px;
}
/* Tile picker in the rule form — reuses the Create-panel .asset-row/.asset-thumb
   look; this just stacks the level rows and caps the height. */
.bs-rule-asset-tiles {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 300px;
  overflow-y: auto;
}
.bs-rule-assets-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.bs-rule-asset-chip {
  font-size: 11.5px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-paper, #f7f8f9);
  color: var(--abni-ink);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.bs-rule-asset-chip.is-on {
  background: var(--abni-blue-deep, #1f3a4d);
  color: #fff;
  border-color: var(--abni-blue-deep, #1f3a4d);
}

/* Per-rule action buttons (edit / delete) */
.bs-rule-actions {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}
.bs-rule-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 4px 9px;
  border: 1px solid var(--app-card-border);
  background: var(--abni-white);
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s, background 0.18s;
}
.bs-rule-btn:hover { color: var(--abni-blue-deep); border-color: var(--abni-blue-deep); }
.bs-rule-btn.danger:hover { color: var(--abni-red, #c0392b); border-color: var(--abni-red, #c0392b); }

/* Add-rule tile */
.bs-rule-add-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1.5px dashed var(--app-card-border);
  background: transparent;
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-mute);
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s, background 0.18s;
  width: 100%;
  text-align: center;
}
.bs-rule-add-tile:hover {
  color: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  background: rgba(106, 176, 212, 0.04);
}

/* Inline rule form (add / edit) */
.bs-rule-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border-radius: 10px;
  background: var(--abni-paper, #f7f8f9);
  border: 1px solid var(--app-card-border);
}
.bs-rule-form textarea {
  width: 100%;
  min-height: 64px;
  resize: vertical;
  padding: 8px 10px;
  border: 1px solid var(--app-card-border);
  border-radius: 8px;
  font-size: 13px;
  font-family: inherit;
  background: var(--abni-white);
  color: var(--abni-ink);
  box-sizing: border-box;
}
.bs-rule-form textarea:focus { outline: none; border-color: var(--abni-blue-deep); }
.bs-rule-form-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.bs-rule-form select {
  flex: 0 0 auto;
  padding: 6px 10px;
  border: 1px solid var(--app-card-border);
  border-radius: 8px;
  font-size: 12.5px;
  font-family: inherit;
  background: var(--abni-white);
  color: var(--abni-ink);
}
.bs-rule-form-btns {
  display: flex;
  gap: 6px;
  margin-left: auto;
}
.bs-rule-form-save {
  padding: 5px 14px;
  background: var(--abni-blue-deep);
  color: #fff;
  border: none;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  transition: opacity 0.18s;
}
.bs-rule-form-save:disabled { opacity: 0.5; cursor: default; }
.bs-rule-form-cancel {
  padding: 5px 14px;
  background: transparent;
  color: var(--abni-mute);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

/* Golden refs block */
.bs-refs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
}
.bs-refs-loading,
.bs-refs-empty {
  grid-column: 1 / -1;
  color: var(--abni-mute);
  font-style: italic;
  font-size: 13px;
  padding: 6px 0;
}
.bs-ref-card {
  position: relative;
  border-radius: 10px;
  border: 1px solid var(--app-card-border);
  overflow: hidden;
  background: var(--abni-paper, #f7f8f9);
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
}
.bs-ref-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bs-ref-card-foot {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 6px 8px;
  font-size: 11px;
  color: #fff;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.72) 100%);
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 4px;
}
.bs-ref-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bs-ref-remove {
  background: rgba(255, 255, 255, 0.18);
  border: 0;
  color: #fff;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bs-ref-remove:hover { background: rgba(255, 255, 255, 0.32); }
.bs-ref-add {
  border: 2px dashed rgba(106, 176, 212, 0.55);
  background: rgba(255, 255, 255, 0.55);
  color: var(--abni-blue-deep);
  border-radius: 10px;
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s;
}
.bs-ref-add:hover { background: rgba(106, 176, 212, 0.10); border-color: var(--abni-blue-deep); }
.bs-ref-add .btn-emoji { font-size: 20px; }
.bs-ref-card.is-uploading { opacity: 0.6; }

/* ── T2: Updated ref card — hover shows ✕ remove button ── */
.bs-ref-remove {
  position: absolute;
  top: 6px;
  right: 6px;
  background: rgba(0, 0, 0, 0.55);
  border: 0;
  color: #fff;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  font-size: 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 2;
}
.bs-ref-card:hover .bs-ref-remove { opacity: 1; }
.bs-ref-remove:hover { background: rgba(0, 0, 0, 0.78); }

/* Two add affordances side-by-side */
.bs-ref-add {
  border: 2px dashed rgba(106, 176, 212, 0.55);
  background: rgba(255, 255, 255, 0.55);
  color: var(--abni-blue-deep);
  border-radius: 10px;
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s;
}
.bs-ref-add:hover { background: rgba(106, 176, 212, 0.10); border-color: var(--abni-blue-deep); }
.bs-ref-add-icon { font-size: 18px; line-height: 1; }

/* ── T3: Extract controls ── */
.bs-extract-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  flex-wrap: wrap;
}
/* Right-align the Extract submit cluster (cost chip + top-up + button)
   to mirror the Create / Brandify panels. The stale-refs chip stays on
   the left so the user notices it first; the submit cluster floats right. */
.bs-extract-submit {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
}
/* The brand-style toggle sits on its own line, right-aligned, just under the
   Extract button — it governs the extracted STYLE (rules are separate). */
.bs-style-toggle-row {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 2px;
}
/* Creation director (Photo + 3 Document variants) — wrapping cards; Temperature on its own row. */
.bs-director-engine { margin-bottom: 18px; }
.bs-director-options {
  display: flex;
  gap: 12px;
  align-items: stretch;
}
/* All options on ONE row (equal, shrinkable columns); stack on mobile. */
.bs-director-options-wrap { flex-wrap: nowrap; gap: 8px; }
.bs-director-options-wrap .bs-director-option { flex: 1 1 0; }
.bs-director-option {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 9px 10px;
  border: 1px solid var(--abni-border, #d9e2ec);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.bs-director-option:has(input:checked) {
  border-color: var(--abni-blue, #2f6fb0);
  background: var(--abni-blue-tint, #eef4fb);
}
.bs-director-option input { margin-top: 2px; accent-color: var(--abni-blue, #2f6fb0); cursor: pointer; }
.bs-director-option-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bs-director-option-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--abni-blue-deep, #1b3a5b);
}
.bs-director-option-desc { font-size: 11px; color: var(--abni-grey, #8a98a8); line-height: 1.3; }
.bs-director-option.is-disabled { opacity: 0.45; cursor: not-allowed; }
.bs-director-option.is-disabled input { cursor: not-allowed; }
@media (max-width: 768px) {
  .bs-director-options { flex-direction: column; }
}
/* LOCKED = read-only: fade + disable every panel section EXCEPT the lock toggle itself (so the
   panel can still be unlocked). Covers versions, golden refs, extract, director, temp, rules. */
#brand-style-body.is-locked .bs-section:not(.bs-lock-section) {
  opacity: 0.5;
  pointer-events: none;
}
/* Director TUNING sliders — Faithfulness + Temperature, side by side (stack on mobile). */
.bs-tuning-grid {
  display: flex;
  gap: 32px;
  align-items: flex-start;
}
.bs-tuning-control { flex: 1 1 0; min-width: 0; }
.bs-tuning-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 7px;
}
.bs-tuning-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--abni-blue-deep, #1b3a5b);
}
.bs-tuning-readout {
  font-size: 14px;
  font-weight: 700;
  color: var(--abni-blue, #2f6fb0);
  font-variant-numeric: tabular-nums;
}
.bs-tuning-range {
  width: 100%;
  height: 4px;
  cursor: pointer;
  accent-color: var(--abni-blue, #2f6fb0);
}
.bs-tuning-range:disabled { opacity: 0.45; cursor: not-allowed; }
.bs-tuning-ends {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  font-size: 11px;
  color: var(--abni-grey, #8a98a8);
}
@media (max-width: 768px) {
  .bs-tuning-grid { flex-direction: column; gap: 16px; }
}
.bs-extract-btn {
  padding: 8px 20px;
  border-radius: 8px;
  border: 1.5px solid var(--abni-blue-deep);
  background: var(--abni-blue-deep);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s, opacity 0.18s;
}
.bs-extract-btn:disabled {
  opacity: 0.45;
  cursor: default;
}
.bs-extract-btn:not(:disabled):hover { background: var(--abni-ink); border-color: var(--abni-ink); }

.bs-stale-chip {
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 180, 0, 0.14);
  color: #9a6800;
  border: 1px solid rgba(255, 180, 0, 0.35);
}

/* T3/T7: Progress bar */
/* Same CSS-specificity trap as the picker modal — `display: flex` beats
   the UA `[hidden] { display: none }`. Force hidden to win so the bar
   actually disappears between jobs. */
.bs-extract-progress[hidden] { display: none !important; }
.bs-extract-progress {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bs-extract-progress-bar-wrap {
  height: 6px;
  border-radius: 999px;
  background: var(--app-card-border);
  overflow: hidden;
}
.bs-extract-progress-bar {
  height: 100%;
  border-radius: 999px;
  background: var(--abni-blue-deep);
  transition: width 0.4s ease;
}
.bs-extract-progress-label {
  font-size: 12px;
  color: var(--abni-mute);
}

/* ── T4: Versions inline picker ── */
.bs-versions-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.bs-version-pill {
  padding: 4px 12px;
  border-radius: 999px;
  border: 1.5px solid var(--app-card-border);
  background: var(--abni-white);
  color: var(--abni-ink);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.18s, background 0.18s;
}
.bs-version-pill:hover { border-color: var(--abni-blue-deep); }
.bs-version-pill.is-current {
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
}
.bs-version-pill.is-previewing {
  border-color: var(--abni-blue-deep);
  background: rgba(72, 141, 176, 0.12);
  color: var(--abni-blue-deep);
}

.bs-version-preview-banner {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(72, 141, 176, 0.08);
  border: 1px solid rgba(72, 141, 176, 0.25);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 13px;
}
.bs-version-preview-label { color: var(--abni-ink); flex: 1 1 auto; }
.bs-version-restore-btn,
.bs-version-back-btn {
  padding: 4px 12px;
  border-radius: 999px;
  border: 1.5px solid var(--abni-blue-deep);
  background: var(--abni-white);
  color: var(--abni-blue-deep);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s;
}
.bs-version-restore-btn:hover,
.bs-version-back-btn:hover { background: rgba(72, 141, 176, 0.10); }

/* ── Lock Brand Style section — Locked/Unlocked iOS-switch (replaced the
   older "Mark as ready" button, 2026-05-26). Meta line and toggle both
   right-aligned so the affordance sits in the panel's bottom-right corner. */
.bs-lock-section { padding-top: 24px; }
.bs-lock-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.bs-lock-meta {
  font-size: 12px;
  color: var(--abni-mute);
  line-height: 1.5;
}
/* Lock-icon glyph next to the toggle label — sits inside the iOS-switch
   <label>. Width matches label-line-height so it aligns optically. */
.bs-lock-toggle .bs-lock-icon {
  display: inline-flex;
  align-items: center;
  width: 14px;
  height: 14px;
  color: var(--abni-mute);
  transition: color 160ms ease;
}
.bs-lock-toggle .bs-lock-icon svg { width: 100%; height: 100%; }
/* When the toggle is on, lift the icon + label colour to match the active
   blue thumb track for a coherent locked-state. */
.bs-lock-toggle.is-locked .bs-lock-icon,
.bs-lock-toggle.is-locked .lib-details-switch-label {
  color: var(--abni-blue-deep);
}
.bs-lock-toggle.is-disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* Extraction On/Off toggle — sits in the same bs-lock-row, before the lock
   toggle. Uses the same iOS-switch chrome (.lib-details-switch); only the
   colour treatment differs so the two toggles aren't confused. */
.bs-extraction-toggle .lib-details-switch-label {
  color: var(--abni-mute);
  transition: color 160ms ease;
}
.bs-extraction-toggle.is-on .lib-details-switch-label {
  color: var(--abni-blue-deep);
}
.bs-extraction-toggle.is-disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* When the active level is inheriting (no own extraction), dim the STYLE
   READOUT so users feel the read-only/borrowed nature of the extracted values.
   Golden refs, the Extract button, and the footer toggles stay fully
   interactive — those are the inputs the user needs to reactivate.
   RULES are NOT dimmed/disabled here: they are independent of extraction and
   must stay fully editable at any level (add/edit/toggle/suppress) regardless
   of whether a style has been extracted. */
.brand-style-panel.is-inherited #bs-summary-body {
  opacity: 0.55;
  filter: saturate(0.8);
  pointer-events: none;
  transition: opacity 160ms ease;
}

/* Status-dot variant inside the Brand Style header — same visual as
   the tile dots but sits inline with the "Show" toggle. We override the
   legacy .brand-style-status-pill CSS (text-pill) since the element is
   now styled as an .ext-dot. */
.brand-style-status-pill.ext-dot {
  /* Inherit ext-dot sizing/border from the tile rules; nothing else needed. */
}

/* ── Segmented control — pill-shaped option group with sliding indicator.
   Used as a 3-way switch where each option is mutually exclusive and the
   chosen option needs to feel like the "active" anchor in a tight set.
   Reach for this when a chip-group feels too loose and tabs feel too heavy.

   Structure:
     <div class="seg-control" role="radiogroup">
       <button class="seg-option is-active" role="radio" aria-checked="true">…</button>
       <button class="seg-option" role="radio" aria-checked="false">…</button>
       <button class="seg-option" role="radio" aria-checked="false">…</button>
       <span class="seg-indicator" aria-hidden="true"></span>
     </div>

   Indicator position is JS-driven — the script measures the active option's
   offsetLeft + width and sets `--seg-pos` + `--seg-w` CSS variables on the
   parent. Without JS the active option still reads correctly via .is-active. */
.seg-control {
  display: inline-flex;
  position: relative;
  background: rgba(72, 141, 176, 0.08);
  border-radius: 999px;
  padding: 4px;
  gap: 0;
  font-family: var(--abni-font-body);
}
.seg-option {
  position: relative;
  z-index: 1;
  border: 0;
  background: transparent;
  padding: 8px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--abni-mute);
  cursor: pointer;
  border-radius: 999px;
  transition: color 160ms ease;
  font-family: inherit;
}
.seg-option:hover { color: var(--abni-blue-deep); }
.seg-option.is-active { color: var(--abni-blue-deep); }
.seg-option:focus-visible {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}
.seg-indicator {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: var(--seg-pos, 4px);
  width: var(--seg-w, 80px);
  background: #fff;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(31, 50, 60, 0.10);
  transition: left 220ms cubic-bezier(0.34, 1.20, 0.64, 1), width 220ms cubic-bezier(0.34, 1.20, 0.64, 1);
  z-index: 0;
}

/* ── T5/T8: Extracted style section — proper hierarchy.
   Headings: EXTRACTED STYLE (.bs-section-title, 14px caps, dark blue)
           >  Photo style / Colours / Visual world (.bs-extracted-subhead,
              13px sentence-case, mid-blue, sits close to its rows)
           >  Style / Mood / Lighting / Composition / Description
              (.bs-summary-label, 11.5px caps, muted).
   Each sub-section wraps in a .bs-extracted-group for visual containment. */
.bs-extracted-group {
  margin-top: 22px;
}
.bs-extracted-group:first-of-type {
  margin-top: 12px;
}
.bs-extracted-subhead {
  font-family: var(--abni-font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--abni-blue-deep);
  /* Tight under-margin so sub-heading reads visually grouped with its rows */
  margin: 0 0 6px;
}
.bs-vw-text {
  font-size: 13px;
  color: var(--abni-ink);
  line-height: 1.6;
}
.bs-vw-text.is-empty { color: var(--abni-mute); font-style: italic; }

/* ── T7: PDF dropzone ── */
.bs-pdf-dropzone {
  min-height: 100px;
}

/* ── T2: Library picker popover ── */
/* `display: flex` here would beat `[hidden] { display: none }` from the
   UA stylesheet so the modal would never actually hide. Force hidden to
   win. */
.bs-lib-picker-backdrop[hidden] { display: none !important; }
.bs-lib-picker-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 20, 36, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 800;
}
.bs-lib-picker-sheet {
  background: var(--abni-white);
  border-radius: 18px;
  width: min(680px, 92vw);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(8, 20, 36, 0.25);
}
.bs-lib-picker-head {
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--app-card-border);
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.bs-lib-picker-title {
  font-family: var(--abni-font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--abni-ink);
  flex: 1 1 auto;
}
.bs-lib-picker-sub {
  font-size: 12px;
  color: var(--abni-mute);
}
/* When the sub-hint appears beneath a studio-field-label (e.g. above the
   Brandify dropzone) it needs to render as its own block with a touch of
   breathing room before the dropzone below. */
#brandify-source-hint {
  display: block;
  margin: -4px 0 8px;
}
.bs-lib-picker-close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--abni-mute);
  cursor: pointer;
  line-height: 1;
  padding: 0 2px;
}
.bs-lib-picker-close:hover { color: var(--abni-ink); }
.bs-lib-picker-grid {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
  align-content: start;
}
.bs-lib-picker-empty {
  grid-column: 1 / -1;
  color: var(--abni-mute);
  font-style: italic;
  font-size: 13px;
  padding: 20px 0;
  text-align: center;
}
.bs-lib-picker-tile {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 1;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color 0.15s;
  background: var(--abni-paper, #f7f8f9);
}
.bs-lib-picker-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bs-lib-picker-tile.is-selected {
  border-color: var(--abni-blue-deep);
}
.bs-lib-picker-check {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--abni-blue-deep);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s;
}
.bs-lib-picker-tile.is-selected .bs-lib-picker-check { opacity: 1; }
.bs-lib-picker-actions {
  padding: 14px 20px;
  border-top: 1px solid var(--app-card-border);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.bs-lib-picker-cancel {
  padding: 8px 18px;
  border-radius: 8px;
  border: 1.5px solid var(--app-card-border);
  background: var(--abni-white);
  color: var(--abni-mute);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.bs-lib-picker-cancel:hover { border-color: var(--abni-ink); color: var(--abni-ink); }
.bs-lib-picker-confirm {
  padding: 8px 18px;
  border-radius: 8px;
  border: 1.5px solid var(--abni-blue-deep);
  background: var(--abni-blue-deep);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s;
}
.bs-lib-picker-confirm:disabled { opacity: 0.45; cursor: default; }
.bs-lib-picker-confirm:not(:disabled):hover { background: var(--abni-ink); border-color: var(--abni-ink); }

/* ── F9-F12: Sheet-style modal overlay ───────────────────────────────────
 * Full-screen backdrop + right-anchored sheet. Used for Settings, Credits,
 * Users, and Super-admin modals. Kept separate from .modal-backdrop (the
 * original dialog variant used for create-folder / move / batch-tag).
 */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 20, 36, 0.48);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s;
  z-index: 900;
}
.sheet-backdrop.open {
  opacity: 1;
  pointer-events: auto;
}
.modal-sheet {
  background: #fff;
  width: min(480px, 100vw);
  height: 100%;
  display: flex;
  flex-direction: column;
  box-shadow: -8px 0 40px rgba(8, 20, 36, 0.18);
  transform: translateX(40px);
  transition: transform 0.22s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  overflow: hidden;
}
.sheet-backdrop.open .modal-sheet {
  transform: translateX(0);
}
.modal-sheet--wide {
  width: min(680px, 100vw);
}
.modal-sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 28px 20px;
  border-bottom: 1px solid #eef0f4;
  flex-shrink: 0;
}
.modal-sheet-head h2 {
  font-size: 18px;
  font-weight: 700;
  color: var(--abni-blue-deep);
  margin: 0 0 4px;
}
.modal-sheet-sub {
  font-size: 13px;
  color: var(--abni-mute, #8090a0);
  margin: 0;
  line-height: 1.5;
}
.modal-sheet-close {
  flex-shrink: 0;
  background: none;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: #aab0bb;
  cursor: pointer;
  padding: 0 4px;
  transition: color 0.15s;
}
.modal-sheet-close:hover { color: var(--abni-blue-deep); }
.modal-sheet-body {
  flex: 1 1 0;
  overflow-y: auto;
  padding: 20px 28px 40px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ── Settings / Users shared panel grid ─────────────────────────────────── */
.settings-panel {
  border: 1px solid #eef0f4;
  border-radius: 14px;
  padding: 20px;
  background: #fff;
}
.settings-grid {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 14px;
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.settings-row.stacked {
  flex-direction: column;
  align-items: flex-start;
}
.settings-row-label {
  font-size: 13px;
  font-weight: 600;
  color: #6b7a8d;
  min-width: 110px;
  flex-shrink: 0;
}
.settings-row-value {
  font-size: 13px;
  color: var(--abni-blue-deep);
}
.settings-row-value.mono {
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  word-break: break-all;
}
.settings-inline {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
}
.settings-input {
  flex: 1;
  min-width: 0;
  border: 1.5px solid #d8dde7;
  border-radius: 8px;
  padding: 7px 11px;
  font-size: 13px;
  color: var(--abni-blue-deep);
  background: #fafbfc;
  transition: border-color 0.15s;
}
.settings-input:focus {
  outline: none;
  border-color: var(--abni-blue, #3b7dc8);
}
.settings-help {
  font-size: 12px;
  color: var(--abni-mute, #8090a0);
  margin: 4px 0 0;
  line-height: 1.5;
}

/* Settings toggle-row (checkbox + label). */
.settings-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  cursor: pointer;
  padding: 4px 0;
}
.settings-toggle-text { flex: 1; }
.settings-toggle-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--abni-blue-deep);
}
.settings-toggle-sub {
  font-size: 12px;
  color: var(--abni-mute, #8090a0);
  margin-top: 2px;
}
/* Simple toggle track. */
.settings-switch { position: relative; flex-shrink: 0; }
.settings-switch input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.settings-switch-track {
  display: block;
  width: 36px;
  height: 20px;
  background: #d0d6df;
  border-radius: 999px;
  transition: background 0.18s;
}
.settings-switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.18s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
}
.settings-switch input:checked + .settings-switch-track {
  background: var(--abni-blue, #3b7dc8);
}
.settings-switch input:checked + .settings-switch-track::after {
  transform: translateX(16px);
}

/* Role pill. */
.role-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #eef0f4;
  color: #6b7a8d;
}
.role-pill--owner, .role-pill--admin { background: #e8f0fe; color: #1a56db; }
.role-pill--creator,
.role-pill--editor { background: #ecfdf5; color: #059669; }
.role-pill--viewer { background: #f5f3ff; color: #7c3aed; }

/* Role-pill rendered as a <select> in the Users list — keeps the pill
   shape but reveals a native dropdown caret for admins. */
select.role-pill {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 22px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  cursor: pointer;
  border: 0;
  font-family: inherit;
}
select.role-pill:disabled { opacity: 0.55; cursor: progress; }
select.role-pill:focus-visible {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}

/* Sheet modal action buttons. */
.modal-btn {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
  white-space: nowrap;
}
.modal-btn.primary {
  background: var(--abni-blue-deep);
  color: #fff;
}
.modal-btn.primary:hover { filter: brightness(1.1); }
.modal-btn.primary:disabled { opacity: 0.5; cursor: not-allowed; }
.modal-btn.primary.danger { background: #e53e3e; }
.modal-btn.ghost {
  background: #f3f4f6;
  color: var(--abni-blue-deep);
  border: 1.5px solid #d8dde7;
}
.modal-btn.ghost:hover { background: #e8eaf0; }
.modal-error {
  font-size: 12px;
  color: #e53e3e;
  min-height: 16px;
  display: none;
}
.modal-error.visible { display: block; }

/* ── F10: Credits modal ──────────────────────────────────────────────────── */
/* Post-checkout success banner — shown after Stripe redirect with the plan
   name + credit count. Auto-dismissed after the user closes the modal or
   clicks the × button. Green-tinted to read as a positive confirmation. */
.credits-success-panel {
  padding: 12px 14px !important;
  background: linear-gradient(180deg, #e8f7ee 0%, #def1e6 100%);
  border: 1px solid #b9e3c8;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.6);
}
.credits-success-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.credits-success-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #2f9a5b;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: 700;
  flex-shrink: 0;
}
.credits-success-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.credits-success-title {
  font-size: 14px;
  font-weight: 700;
  color: #1e5d36;
}
.credits-success-sub {
  font-size: 12.5px;
  color: #34764f;
}
.credits-success-dismiss {
  background: transparent;
  border: 0;
  color: #5a8e6f;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 4px;
}
.credits-success-dismiss:hover { background: rgba(46,125,84,0.10); }

.credits-context-panel { padding: 14px 16px !important; }
.credits-context-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.credits-context-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.credits-context-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #8090a0;
}
.credits-context-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--abni-blue-deep);
}
.credits-context-id {
  font-size: 11px;
  color: #aab0bb;
  font-family: monospace;
}
.credits-context-role { font-size: 12px; color: #6b7a8d; }
.credits-balance-panel { }
.credits-balance-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.credits-balance-readout { display: flex; flex-direction: column; gap: 4px; }
.credits-balance-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #8090a0;
}
.credits-balance-value {
  font-size: 36px;
  font-weight: 800;
  color: var(--abni-blue-deep);
  line-height: 1.1;
}
.credits-balance-plan {
  font-size: 12px;
  color: #aab0bb;
}
.credits-balance-actions { display: flex; flex-direction: column; gap: 8px; padding-top: 8px; }
.credits-topup-btn {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  background: var(--abni-blue, #3b7dc8);
  color: #fff;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: filter 0.15s;
}
.credits-topup-btn:hover { filter: brightness(1.1); }
.credits-topup-hint { font-size: 12px; color: #8090a0; max-width: 240px; line-height: 1.5; margin: 0; }
.credits-activity-panel { }
.credits-activity { display: flex; flex-direction: column; }
.credits-activity:empty { display: none; }
.credits-activity-empty p { font-size: 13px; color: #8090a0; }
.credits-activity-row {
  display: grid;
  grid-template-columns: 36px 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid #e6ebf1;
}
.credits-activity-row:last-child { border-bottom: 0; }
.credits-activity-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: rgba(72, 141, 176, 0.08);
  font-family: "Noto Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
  font-size: 14px;
  line-height: 1;
  color: var(--abni-blue-deep);
  font-variant-emoji: text;
}
.credits-activity-body { display: flex; flex-direction: column; min-width: 0; }
.credits-activity-desc {
  font-size: 14px;
  font-weight: 600;
  color: var(--abni-ink);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.credits-activity-meta {
  font-size: 12px;
  color: var(--abni-mute);
  font-variant-numeric: tabular-nums;
}
.credits-activity-meta .sep { opacity: 0.5; padding: 0 4px; }
.credits-activity-delta {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--abni-ink);
}
.credits-activity-delta.is-positive { color: #2f9a5b; }
.credits-activity-delta.is-negative { color: #b03a3a; }
.credits-activity-balance {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (max-width: 520px) {
  .credits-activity-row {
    grid-template-columns: 36px 1fr auto;
    grid-template-areas:
      "icon body delta"
      "icon body balance";
  }
  .credits-activity-icon { grid-area: icon; align-self: start; }
  .credits-activity-body { grid-area: body; }
  .credits-activity-delta { grid-area: delta; align-self: end; }
  .credits-activity-balance { grid-area: balance; text-align: right; }
}
.credits-rates-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 12px;
}
.credits-rate-card {
  border: 1px solid #eef0f4;
  border-radius: 10px;
  padding: 12px 14px;
  background: #fafbfc;
}
/* Old single-line rate card (deprecated — replaced by the rich card layout
   below). Kept as a no-op for any unmigrated callers. */
.credits-rate-op { font-size: 12px; font-weight: 600; color: #6b7a8d; margin-bottom: 6px; }

/* Rich rate card — mirrors the layout on the standalone /app/credits.html
   page. Title row (emoji + name), large credit total, description, optional
   per-resolution breakdown chips. */
.credits-rates-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
  margin-top: 12px;
}
.credits-rate-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--app-card-border);
  border-radius: 12px;
  background: var(--abni-white);
}
.credits-rate-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.credits-rate-emoji {
  font-family: "Noto Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
  font-size: 16px;
  line-height: 1;
  color: var(--abni-blue-deep);
}
.credits-rate-name {
  font-family: var(--abni-font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--abni-blue-deep);
}
.credits-rate-cost {
  font-family: var(--abni-font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--abni-ink);
  font-variant-numeric: tabular-nums;
}
.credits-rate-cost .unit {
  font-size: 12px;
  font-weight: 600;
  color: var(--abni-mute);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-left: 4px;
}
.credits-rate-cost.is-range { font-size: 22px; }
.credits-rate-sub {
  font-size: 12px;
  line-height: 1.45;
  color: var(--abni-mute);
  margin: 0;
}
.credits-rate-breakdown {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.credits-rate-breakdown span {
  font-size: 11px;
  font-weight: 600;
  color: var(--abni-mute);
  background: rgba(72, 141, 176, 0.06);
  border: 1px solid var(--app-card-border);
  border-radius: 999px;
  padding: 3px 8px;
  font-variant-numeric: tabular-nums;
}

/* Credits — plans panel section heads. Override the shared studio-section-
   head's inline layout so the title sits alone, larger, with the hint
   wrapping to the next line. Matches what Oliver asked for: prominent
   section labels ("Subscriptions" / "Credit packs") with the description
   tucked beneath. */
.credits-plans-panel .studio-section-head {
  display: block;
}
.credits-plans-panel .studio-section-head h2 {
  font-size: 22px;
  font-weight: 800;
  margin: 0 0 6px;
  color: var(--abni-ink);
}
.credits-plans-panel .studio-section-head .hint {
  display: block;
  font-size: 13px;
  color: var(--abni-mute);
}

/* Credits — Subscriptions panel (dropdown + current-plan banner + actions).
   Replaces the multi-card subscriptions grid; one tier at a time is
   simpler for the user since only one subscription is ever active. */
.credits-subs-panel .studio-section-head { display: block; }
.credits-subs-panel .studio-section-head h2 {
  font-size: 22px;
  font-weight: 800;
  margin: 0 0 6px;
  color: var(--abni-ink);
}
.credits-subs-panel .studio-section-head .hint {
  display: block;
  font-size: 13px;
  color: var(--abni-mute);
}
.credits-subs-current {
  margin: 12px 0 14px;
  padding: 10px 12px;
  background: #f0f6fb;
  border: 1px solid #d6e4ee;
  border-radius: 8px;
}
.credits-subs-current-line {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.credits-subs-current-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6b7a8d;
  text-transform: uppercase;
}
.credits-subs-current-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--abni-blue-deep);
}
.credits-subs-current-detail {
  margin-top: 4px;
  font-size: 12.5px;
  color: #5a7287;
}
.credits-subs-current-detail .credits-subs-cancel-notice {
  color: #b95b1a;
  font-weight: 600;
}
.credits-subs-controls {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.credits-subs-pick {
  flex: 1;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.credits-subs-pick-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6b7a8d;
  text-transform: uppercase;
}
.credits-subs-select {
  font-size: 14px;
  padding: 10px 12px;
  border: 1px solid #cbd6e2;
  border-radius: 8px;
  background: #fff;
  color: var(--abni-ink);
  min-height: 40px;
}
.credits-subs-update {
  padding: 10px 16px;
  border-radius: 8px;
  border: 0;
  background: var(--abni-blue);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  min-height: 40px;
}
.credits-subs-update:disabled {
  background: #c8d3df;
  color: #fff;
  cursor: not-allowed;
}
.credits-subs-update:not(:disabled):hover {
  background: var(--abni-blue-deep);
}
.credits-subs-actions {
  display: flex;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}
.credits-subs-manage,
.credits-subs-cancel {
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  background: #fff;
  border: 1px solid #cbd6e2;
  color: var(--abni-ink);
}
.credits-subs-manage:hover {
  border-color: var(--abni-blue);
  color: var(--abni-blue-deep);
}
.credits-subs-cancel {
  color: #b03a3a;
  border-color: #e8c5c5;
}
.credits-subs-cancel:hover {
  background: #fbf0f0;
  border-color: #d18a8a;
}
.credits-subs-cancel:disabled {
  color: #aab0bb;
  border-color: #e6ebf1;
  cursor: not-allowed;
  background: #f4f6f9;
}
.credits-subs-non-admin {
  margin-top: 10px;
  font-size: 12px;
  color: var(--abni-mute);
}

/* Credits — top-up plans grid. Card-per-plan with credits + price headline
   and a primary Buy button (Stripe Checkout). Non-admin sees the cards
   read-only with a disabled Buy + admin-only foot note. */
.credits-plans-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.credits-plan-card {
  border: 1px solid #eef0f4;
  border-radius: 12px;
  padding: 16px;
  background: #fafbfc;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Subscription cards get a subtle accent so the recurring-vs-one-off
   distinction is obvious at a glance even before reading the label. */
.credits-plan-card.is-subscription {
  border-color: var(--abni-blue-deep);
  background: linear-gradient(180deg, rgba(72, 141, 176, 0.06), #fafbfc 60%);
}
.credits-plan-name { font-size: 13px; font-weight: 700; color: var(--abni-ink); }
.credits-plan-credits { font-size: 20px; font-weight: 800; color: var(--abni-blue-deep); }
.credits-plan-price { font-size: 13px; color: var(--abni-mute); }
.credits-plan-buy {
  margin-top: 10px;
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--abni-blue-deep);
  background: var(--abni-blue-deep);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.credits-plan-buy:hover:not(:disabled) { background: #2d6c98; }
.credits-plan-buy:disabled { opacity: 0.45; cursor: not-allowed; }
.credits-plans-foot {
  margin-top: 12px;
  font-size: 12px;
  color: var(--abni-mute);
}

/* ── F11: Users modal ────────────────────────────────────────────────────── */
.users-list { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.users-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: #f7f8fa;
  border-radius: 10px;
}
.users-row-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--abni-blue, #3b7dc8);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.users-row-info { flex: 1; min-width: 0; }
.users-row-name { font-size: 13px; font-weight: 600; color: var(--abni-blue-deep); display: flex; align-items: center; gap: 6px; }
.users-row-email { font-size: 12px; color: #8090a0; }
.users-you-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  background: #eef0f4;
  color: #8090a0;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.users-remove-btn {
  background: none;
  border: 1.5px solid #f4c1c1;
  border-radius: 6px;
  color: #e53e3e;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
  transition: background 0.15s;
  flex-shrink: 0;
}
.users-remove-btn:hover { background: #fff0f0; }
.users-empty p { font-size: 13px; color: #8090a0; padding: 12px 0; }

/* ── F12: Super-admin modal ──────────────────────────────────────────────── */
.sa-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid #eef0f4;
  padding: 0 28px;
  flex-shrink: 0;
}
.sa-tab {
  background: none;
  border: none;
  border-bottom: 2.5px solid transparent;
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 600;
  color: #8090a0;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.sa-tab:hover { color: var(--abni-blue-deep); }
.sa-tab.is-active {
  color: var(--abni-blue, #3b7dc8);
  border-bottom-color: var(--abni-blue, #3b7dc8);
}
.sa-panel { display: flex; flex-direction: column; gap: 16px; }
.sa-panel:not(.is-active) { display: none; }
.sa-pricing-table,
.sa-clients-list,
.sa-flags-list {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sa-pricing-row,
.sa-clients-row,
.sa-flags-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: #f7f8fa;
  border-radius: 10px;
  font-size: 13px;
}
.sa-pricing-row-name,
.sa-clients-row-name,
.sa-flags-row-name { flex: 1; font-weight: 600; color: var(--abni-blue-deep); }
.sa-usage-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
  margin-top: 12px;
}
.sa-metric-card {
  border: 1px solid #eef0f4;
  border-radius: 12px;
  padding: 16px;
  background: #fafbfc;
}
.sa-metric-label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #8090a0; margin-bottom: 6px; }
.sa-metric-value { font-size: 28px; font-weight: 800; color: var(--abni-blue-deep); }

/* SA shared helpers */
.muted-text { color: #8090a0; font-weight: 400; }
.sa-pricing-row-name .muted-text,
.sa-clients-row-name .muted-text,
.sa-flags-row-name .muted-text { font-size: 12px; }

/* SA override input — narrow inline number field */
.sa-override-input { font-size: 13px !important; padding: 5px 8px !important; height: auto !important; }

/* SA Clients tab meta cells */
.sa-clients-meta { font-size: 12px; color: #5a6878; white-space: nowrap; }

/* SA pill badges (plan / status) */
.sa-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  text-transform: lowercase;
}
.sa-plan-pill { background: #eef0f4; color: #5a6878; }
.sa-status-pill.status-active { background: #ecfdf5; color: #059669; }
.sa-status-pill.status-disabled { background: #fef2f2; color: #dc2626; }
.sa-status-pill.status-neutral { background: #f5f3ff; color: #7c3aed; }

/* SA feature-flags chip — on state */
.sa-flag-chip { font-size: 12px; padding: 4px 10px; }
.sa-flag-chip.is-selected { background: var(--abni-blue, #3b7dc8); border-color: var(--abni-blue, #3b7dc8); color: #fff; }
.sa-flags-status { min-width: 50px; text-align: right; }

/* SA row button — compact variant */
.sa-row-btn { font-size: 12px !important; }

/* ── Moderation queue ────────────────────────────────────────────────────── */
.moderation-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: #dc2626;
  color: #fff;
  border-radius: 99px;
  font-size: 11px;
  font-weight: 700;
  margin-left: 6px;
  vertical-align: middle;
  line-height: 1;
}
.mod-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.mod-flag-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 4px;
}
.mod-flag-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: #f7f8fa;
  border-radius: 10px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.12s;
}
.mod-flag-row:hover { background: #eef0f4; }
.mod-flag-thumb {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
  background: #e0e4ea;
}
.mod-flag-thumb-placeholder {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background: #e0e4ea;
  flex-shrink: 0;
}
.mod-flag-body { flex: 1; min-width: 0; }
.mod-flag-client { font-weight: 600; color: var(--abni-blue-deep); font-size: 12px; }
.mod-flag-reason { color: #5a6878; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 320px; }
.mod-flag-cats { font-size: 11px; color: #8090a0; margin-top: 2px; }
.mod-flag-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
.mod-flag-ts { font-size: 11px; color: #8090a0; }
.mod-sev-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
  text-transform: lowercase;
  white-space: nowrap;
}
.mod-sev-pill.sev-critical { background: #fef2f2; color: #dc2626; }
.mod-sev-pill.sev-high     { background: #fff7ed; color: #c2410c; }
.mod-sev-pill.sev-medium   { background: #fefce8; color: #a16207; }
.mod-sev-pill.sev-low      { background: #f0fdf4; color: #16a34a; }
.mod-status-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
  text-transform: lowercase;
  white-space: nowrap;
}
.mod-status-pill.s-open       { background: #eff6ff; color: #2563eb; }
.mod-status-pill.s-reviewed   { background: #ecfdf5; color: #059669; }
.mod-status-pill.s-dismissed  { background: #f9fafb; color: #9ca3af; }
.mod-status-pill.s-escalated  { background: #fdf4ff; color: #9333ea; }
.mod-load-more-wrap { display: flex; justify-content: center; padding-top: 12px; }
/* Moderation detail modal */
.mod-detail-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1100;
}
.mod-detail-backdrop.open { display: flex; }
.mod-detail-sheet {
  background: #fff;
  border-radius: 16px;
  width: min(700px, 96vw);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(15, 23, 42, 0.18);
}
.mod-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 20px 24px 14px;
  border-bottom: 1px solid #eef0f4;
  flex-shrink: 0;
}
.mod-detail-title { font-size: 16px; font-weight: 700; color: var(--abni-blue-deep); }
.mod-detail-close {
  background: none;
  border: none;
  font-size: 22px;
  color: #8090a0;
  cursor: pointer;
  line-height: 1;
  padding: 0;
  margin-left: 12px;
  flex-shrink: 0;
}
.mod-detail-close:hover { color: var(--abni-blue-deep); }
.mod-detail-body {
  overflow-y: auto;
  padding: 20px 24px;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.mod-detail-img {
  width: 100%;
  max-height: 280px;
  object-fit: contain;
  border-radius: 10px;
  background: #f0f2f5;
}
.mod-detail-section-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #8090a0;
  margin-bottom: 4px;
}
.mod-detail-prompt {
  font-size: 13px;
  color: #1e293b;
  background: #f7f8fa;
  border-radius: 8px;
  padding: 10px 12px;
  line-height: 1.5;
  max-height: 120px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
}
.mod-detail-reason { font-size: 13px; color: #5a6878; }
.mod-pause-banner {
  background: #fef2f2;
  border: 1px solid #fca5a5;
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  color: #dc2626;
}
.mod-pause-banner-icon { font-size: 18px; flex-shrink: 0; }
.mod-pause-banner-text { flex: 1; }
.mod-detail-foot {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 14px 24px 18px;
  border-top: 1px solid #eef0f4;
  flex-shrink: 0;
}
.mod-notes-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mod-notes-input {
  width: 100%;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
  resize: vertical;
  min-height: 56px;
  font-family: inherit;
  box-sizing: border-box;
}
.mod-notes-input:focus { outline: none; border-color: var(--abni-blue, #3b7dc8); }

/* ── Outline SVG icon sizing ──────────────────────────────────────────────
 * Applied to every <svg class="ui-icon"> element that replaces the old
 * .btn-emoji colour-emoji spans. Inherits currentColor so the icon matches
 * the surrounding text / button colour automatically.
 */
.ui-icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  vertical-align: -0.15em;
  margin-right: 6px;
}
/* Process cards: icon block-stacked above the label */
.process-card .ui-icon {
  width: 1.6em;
  height: 1.6em;
  display: block;
  margin: 0 auto 8px;
  vertical-align: 0;
}
/* Library tile tag icon — no right margin needed */
.lib-tile-tag-icon .ui-icon {
  margin-right: 2px;
  vertical-align: -0.1em;
}
/* Standalone icon buttons (close chip, active filter clear) */
.lib-active-filter button .ui-icon,
button:not(:has(+ *)) > .ui-icon:only-child {
  margin-right: 0;
}

/* ──────────────────────────────────────────────────────────────
   Folder view toggle (Grid vs Cascade) — chip pair in Workspace head
   ────────────────────────────────────────────────────────────── */

.folder-view-toggle {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--app-card-border);
  padding: 2px;
  gap: 0;
}
.folder-view-chip {
  appearance: none;
  background: none;
  border: 0;
  padding: 4px 12px;
  font-family: var(--abni-font-display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-mute);
  border-radius: 999px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.folder-view-chip:hover { color: var(--abni-blue-deep); }
.folder-view-chip.is-selected {
  background: var(--abni-blue-deep);
  color: #fff;
}
.folder-view-chip:focus-visible {
  outline: 2px solid rgba(36, 96, 142, 0.4);
  outline-offset: 2px;
}

/* ──────────────────────────────────────────────────────────────
   Cascade folder view — drill list rendered inline in #brands-root
   when state.folderView === "cascade". Visually mirrors the Move-
   to-folder modal so users learn one folder-nav pattern.
   ────────────────────────────────────────────────────────────── */

.fcasc-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 4px;
}
.fcasc-row {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--app-card-border);
  background: rgba(255, 255, 255, 0.6);
  text-align: left;
  font-family: var(--abni-font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--abni-ink);
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.fcasc-row:hover {
  background: rgba(106, 176, 212, 0.12);
  border-color: rgba(36, 96, 142, 0.35);
}
.fcasc-row .fcasc-icon {
  flex: 0 0 auto;
  color: var(--abni-blue-deep);
}
.fcasc-row .fcasc-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fcasc-row .fcasc-meta {
  flex: 0 0 auto;
  font-family: var(--abni-font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-mute);
  white-space: nowrap;
}
.fcasc-row .fcasc-chevron {
  flex: 0 0 auto;
  color: var(--abni-mute);
}
.fcasc-row.fcasc-add {
  border-style: dashed;
  background: transparent;
  color: var(--abni-blue-deep);
  font-weight: 600;
}
.fcasc-row.fcasc-add:hover {
  background: rgba(106, 176, 212, 0.08);
  border-color: var(--abni-blue-deep);
}
.fcasc-back {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 0;
  background: none;
  font-family: var(--abni-font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--abni-blue-deep);
  cursor: pointer;
  border-radius: 999px;
  align-self: flex-start;
}
.fcasc-back:hover { background: rgba(106, 176, 212, 0.12); }
.fcasc-loading, .fcasc-error {
  padding: 12px 14px;
  font-size: 13px;
  color: var(--abni-mute);
}
.fcasc-error { color: var(--abni-warn, #b35c0e); }

/* ──────────────────────────────────────────────────────────────
   Mobile modals — full-screen sheets at ≤768px.

   All modal-backdrop / library-picker-backdrop / sheet-backdrop
   modals turn into full-viewport sheets so the action bar lives
   at the bottom of the screen and the content scrolls between the
   title and the actions. The lightbox uses a different container
   class (.image-modal) and gets its own treatment in Phase 5.
   ────────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
  /* ── Centered modals: .modal-backdrop > .modal ── */
  .modal-backdrop {
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
  }
  .modal {
    width: 100vw;
    max-width: none;
    min-height: 100vh;
    max-height: 100vh;
    border-radius: 0;
    border: 0;
    padding: 20px 18px 96px;
    overflow-y: auto;
    box-shadow: none;
    -webkit-overflow-scrolling: touch;
  }
  .modal-actions {
    position: sticky;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 24px -18px -96px;
    padding: 14px 18px calc(14px + env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--app-card-border);
    z-index: 5;
  }
  .modal-actions .modal-btn {
    flex: 1 1 auto;
    justify-content: center;
  }

  /* ── Wide pickers: .library-picker-backdrop > .library-picker
     (Library picker + Move picker share the same container class). */
  .library-picker-backdrop {
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
  }
  .library-picker {
    width: 100vw;
    max-width: none;
    height: 100vh;
    max-height: 100vh;
    min-height: 100vh;
    border-radius: 0;
    border: 0;
    box-shadow: none;
    padding: 16px 14px calc(16px + env(safe-area-inset-bottom));
    gap: 12px;
  }
  /* The picker's footer action row (Cancel + Move/Pick) goes sticky too.
     Move modal uses `.move-picker-actions` and library uses
     `.library-picker-actions` — match both. */
  .move-picker-actions,
  .library-picker-actions {
    position: sticky;
    bottom: 0;
    margin: 8px -14px calc(-16px - env(safe-area-inset-bottom));
    padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--app-card-border);
    z-index: 2;
  }

  /* ── Right-side slide sheets: .sheet-backdrop > .modal-sheet
     Settings / Credits / Users / Superadmin. Already mostly full-width
     on phones thanks to the existing min() rule; flatten chrome so
     it reads as a clean fullscreen view. */
  .modal-sheet,
  .modal-sheet--wide {
    width: 100vw;
    box-shadow: none;
  }

  /* ── Lightbox (.image-modal) — bottom-sheet over image.
     Overrides the existing 880px stacked layout. Image fills the
     viewport; .im-side floats up as a sheet covering ~50vh by default,
     tap-expanded to ~88vh via the .im-sheet-handle button. Process
     bar pins to the bottom of the sheet so it's always reachable.
     The im-topbar (title + close) sits as a floating overlay on the
     image so the image gets the full viewport. */
  /* Pin the sheet shell to fill the modal. Flex-centering a full-height shell
     overflowed the top by ~27px and clipped the title — taking the shell out
     of flex flow (absolute) removes the centering maths so the title always
     clears the top. (Leave .image-modal's flex alone so the floating library
     nav tray keeps its place.) */
  .im-shell {
    position: absolute;
    inset: 0;
    height: auto;
    max-height: none;
    margin: 0;
    border: 0;
    border-radius: 0;
  }
  .im-body {
    display: block;
    position: relative;
    height: 100%;
  }
  .im-stage {
    height: 100%;
    border-bottom: 0;
    padding: 8px;
    /* Reserve space for the (smaller, secondary) sheet so the image's bottom
       clears it. Image is the HERO — it gets ~62vh; the sheet peeks below. */
    padding-bottom: 40vh;
  }
  .im-stage-canvas { height: 100%; }
  .im-stage-canvas img { max-height: 100%; }
  .im-side {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    /* Secondary to the image: a smaller default peek (tabs + a glimpse + the
       sticky actions). Pull the handle up for the full details (92vh). */
    height: 38vh;
    max-height: 92vh;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    backdrop-filter: blur(20px) saturate(140%);
    border-top: 1px solid var(--app-card-border);
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    box-shadow: 0 -12px 40px rgba(31, 50, 60, 0.18);
    transition: height 220ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    z-index: 5;
  }
  .im-side.is-expanded { height: 92vh; }
  .im-side.is-collapsed { height: 56px; }

  /* Drag-handle button — hidden on desktop, shown on mobile. */
  .im-sheet-handle {
    appearance: none;
    background: none;
    border: 0;
    padding: 8px 0 4px;
    display: flex;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
  }
  .im-sheet-handle-grip {
    width: 44px;
    height: 4px;
    background: var(--app-card-border);
    border-radius: 999px;
    transition: background 140ms ease;
  }
  .im-sheet-handle:hover .im-sheet-handle-grip { background: var(--abni-blue-deep); }

  /* Floating prev/next tray — pin it just ABOVE the sheet (not flex-centred in
     the modal, which drifted onto the tabs on taller phones and clipped them). */
  .im-lib-nav-tray {
    position: absolute;
    left: 50%;
    bottom: calc(38vh + 10px);
    transform: translateX(-50%);
    z-index: 6;
  }
  .im-tabs {
    padding: 6px 12px 0;
    /* Let the 4 tabs scroll rather than clip "Used in" on a narrow phone. */
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
    /* Don't let the flex column compress the tab row. overflow-x:auto coerces
       overflow-y to auto, so a shrunk row clips the tab tops (icons + labels
       half-cut). Pin its height so it always shows the full tab. */
    flex-shrink: 0;
  }
  .im-tabs::-webkit-scrollbar { display: none; }
  .im-tab { flex: 0 0 auto; }
  /* Action row wraps so all five processes show — no half-cut "mystery" button. */
  .im-process-bar-procs {
    flex-wrap: wrap;
    justify-content: center;
  }
  .im-panels {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 8px;
  }
  .im-process-bar {
    flex-shrink: 0;
    position: sticky;
    bottom: 0;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--app-card-border);
    z-index: 2;
  }

  /* Topbar overlays the image, with a soft chip backdrop so title +
     close stay legible against any photo. */
  .im-topbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
    /* Clear the status bar / notch so the title pill is never clipped. */
    padding: calc(10px + env(safe-area-inset-top, 0px)) 10px 10px;
    background: linear-gradient(to bottom, rgba(8, 20, 36, 0.32), transparent);
    border-bottom: 0;
  }
  /* Drop the redundant title pill on mobile — the title is already in the
     details sheet below. The topbar keeps just the A/B/C set badge (its own
     standalone pill) + the close button, giving the image more room. */
  .im-topbar .im-title-wrap { background: none; padding: 0; max-width: calc(100% - 56px); gap: 7px; }
  .im-topbar .im-set-letter { min-width: 22px; height: 22px; font-size: 12px; }
  .im-topbar .im-title { display: none; }
  .im-topbar .im-close {
    background: rgba(255, 255, 255, 0.88);
    border: 1px solid var(--app-card-border);
    border-radius: 999px;
    width: 36px;
    height: 36px;
  }
}

/* Desktop — hide the sheet-handle button entirely; it's only meaningful
   when the panel is a bottom-sheet. */
.im-sheet-handle { display: none; }
@media (max-width: 768px) {
  .im-sheet-handle { display: flex; }
}

/* ============================================================
   Mobile bottom-nav + single-section tabs  (≤768px)
   Turns the top-to-bottom cascade into an app-like tab layout so
   each section gets the full screen and Create/Generate is one tap
   away — no endless scroll. Everything here is gated under the
   breakpoint; desktop keeps the full cascade untouched.
   ============================================================ */
.mobile-nav { display: none; }

@media (max-width: 768px) {
  /* Bottom nav bar — fixed, thumb-reachable, frosted. */
  .mobile-nav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    justify-content: space-around;
    align-items: stretch;
    gap: 4px;
    padding: 6px 8px calc(6px + env(safe-area-inset-bottom, 0px));
    background: rgba(255, 255, 255, 0.92);
    -webkit-backdrop-filter: saturate(140%) blur(14px);
    backdrop-filter: saturate(140%) blur(14px);
    border-top: 1px solid var(--app-card-border);
    box-shadow: 0 -4px 20px rgba(31, 50, 60, 0.06);
  }
  .mobile-nav-btn {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 48px;
    padding: 6px 4px;
    border: 0;
    background: none;
    border-radius: 12px;
    cursor: pointer;
    color: var(--abni-mute);
    font-family: var(--abni-font-body);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.01em;
    transition: color 0.15s, background 0.15s;
  }
  .mobile-nav-btn .ui-icon { width: 22px; height: 22px; margin: 0; }
  .mobile-nav-btn.is-active {
    color: var(--abni-blue-deep);
    background: rgba(106, 176, 212, 0.12);
  }
  .mobile-nav-btn:active { transform: translateY(1px); }

  /* Single-section tabs: tighten the column, leave room for the nav bar,
     and show only the active section's group. */
  .app-main {
    /* Full-bleed on mobile: no side padding here — the glass panel runs to the
       screen edge so we don't pay padding twice (was 14px here + 24px on the
       panel = wasted space). The panel's own padding is the only inset. */
    padding: 14px 0 calc(84px + env(safe-area-inset-bottom, 0px));
    gap: 0;
  }
  .app-main > .app-hero,
  .app-main > .studio-panel { display: none; }
  /* One visible panel per tab — fill the width, single modest inner padding. */
  .app-main > .studio-panel { padding: 18px 16px; }

  /* Active-tab visibility. :not([hidden]) so we never force-show a section
     the app has intentionally hidden (e.g. Extract before a brand is opened). */
  .app-main[data-mobile-tab="folder"] > #folder-section:not([hidden]),
  .app-main[data-mobile-tab="folder"] > #empty-state:not([hidden]),
  .app-main[data-mobile-tab="folder"] > #brand-style-section:not([hidden]),
  .app-main[data-mobile-tab="processes"] > #processes-section:not([hidden]),
  .app-main[data-mobile-tab="library"] > #library-section:not([hidden]) {
    display: block;
  }
  /* Chat tab — shown as a full-height flex section (composer pinned bottom). */
  .app-main[data-mobile-tab="chat"] > #chat-section:not([hidden]) {
    display: flex;
  }
  /* Fallback before JS sets the tab — show Workspace, no blank flash. */
  .app-main:not([data-mobile-tab]) > #folder-section:not([hidden]),
  .app-main:not([data-mobile-tab]) > #empty-state:not([hidden]) {
    display: block;
  }
}

/* ── Mobile iteration 2: denser library, sticky Generate, scroll-row assets ── */
@media (max-width: 768px) {
  /* Library: 2-up on phones (was one giant column at minmax(220px)), ~3-4 on tablet. */
  .library-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
  }
  .lib-tile-name { font-size: 13px; }
  .lib-tile-description { font-size: 11.5px; }

  /* Asset thumbs scroll in a single row instead of wrapping into many rows. */
  .asset-row-thumbs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 4px;
  }
  .asset-row-thumbs .asset-thumb { flex: 0 0 auto; scroll-snap-align: start; }

  /* Generate becomes a pinned action bar at the bottom of the Create tab,
     floating just above the nav so it's always reachable without scrolling. */
  .submit-wrap {
    display: flex;
    position: sticky;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    z-index: 30;
    width: 100%;
    gap: 8px;
    margin-top: 12px;
    padding: 8px 10px;
    background: rgba(255, 255, 255, 0.95);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid var(--app-card-border);
    border-radius: 14px;
    box-shadow: 0 6px 22px rgba(31, 50, 60, 0.12);
  }
  .submit-wrap .cost-chip { order: 1; }
  .submit-wrap .cost-topup { order: 2; }
  .submit-wrap .create-submit { order: 3; flex: 1; padding: 12px 16px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Abni Chat (Phase 1, read-only) — a section of .app-main.
   Desktop (>768px): a side panel docked right of the main flow; the cascade
   reflows beside it (not an overlay), toggled by the topbar "Ask Abni" chip.
   Mobile (≤768px): the 4th bottom-nav tab — content swaps to it, nav stays.
   Revealed dev-gated by initChat() (removes [hidden]).
   ═══════════════════════════════════════════════════════════════════════ */

/* Desktop side panel — hidden until .app-shell.chat-open, then fixed to the
   right with .app-main padding reserving its width so nothing sits under it. */
#chat-section {
  display: none;
  flex-direction: column;
  min-height: 0;
  background: var(--abni-paper);
}
/* Panel width scales with the screen: comfortable on laptops, roomier on wide
   monitors (≈28vw), capped so reading lines don't get unwieldy. The main
   column's reserved space is derived from the same var so they stay in sync. */
.app-shell { --chat-w: clamp(384px, 28vw, 620px); }
.app-shell.chat-open #chat-section {
  display: flex;
  position: fixed;
  top: var(--chat-top, 60px);
  right: 0;
  bottom: 0;
  width: var(--chat-w);
  z-index: 45;
  border-left: 1px solid var(--abni-line);
  box-shadow: -10px 0 32px rgba(25, 64, 86, 0.10);
  /* Override .studio-panel's 32px padding so the chat fills the panel — the
     header / log / composer carry their own internal padding. */
  padding: 0;
}
/* When the side panel is open, the main column drops its centred 1080 cap and
   uses the whole region LEFT of the panel (so content fills the space instead
   of floating as a thin centred column), clearing the panel width + a gap. */
@media (min-width: 769px) {
  .app-shell.chat-open .app-main {
    max-width: none;
    margin: 0;
    padding-left: 24px;
    padding-right: calc(var(--chat-w) + 24px);
  }
}
.topbar-chip#chat-toggle-btn[aria-pressed="true"] {
  background: var(--abni-ink);
  color: #fff;
  border-color: var(--abni-ink);
}

.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--abni-line);
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(8px);
}
.chat-head-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.chat-head-name { font-family: var(--abni-font-display); font-weight: 700; font-size: 16px; color: var(--abni-ink); }
.chat-scope-chip {
  display: inline-flex;
  align-items: center;
  max-width: 220px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--abni-blue-soft);
  color: var(--abni-blue-deeper);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-scope-chip:empty { display: none; }
.chat-head-actions { display: flex; gap: 4px; }
.chat-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--abni-mute);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.chat-icon-btn:hover { background: rgba(25, 64, 86, 0.08); color: var(--abni-ink); }
.chat-icon-btn .ui-icon { width: 18px; height: 18px; }

.chat-log {
  flex: 1;
  overflow-y: auto;
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Empty state + starter prompts */
.chat-empty { margin: auto 0; text-align: center; padding: 12px 6px; }
.chat-empty-title { font-family: var(--abni-font-display); font-size: 18px; font-weight: 700; color: var(--abni-ink); margin-bottom: 6px; }
.chat-empty-sub { font-size: 13.5px; color: var(--abni-mute); margin-bottom: 18px; line-height: 1.5; }
.chat-starters { display: flex; flex-direction: column; gap: 8px; }
.chat-starter {
  text-align: left;
  padding: 11px 14px;
  border: 1px solid var(--abni-line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.7);
  color: var(--abni-ink);
  font-family: var(--abni-font-body);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.12s;
}
.chat-starter:hover { border-color: var(--abni-blue-deep); background: #fff; transform: translateX(2px); }
/* First-brand hero — a visually-distinct primary action (not just another pill). */
.chat-starter-hero {
  text-align: center;
  background: var(--abni-blue-deep);
  border-color: var(--abni-blue-deep);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  padding: 13px 14px;
  box-shadow: 0 2px 10px rgba(20, 40, 90, 0.18);
}
.chat-starter-hero:hover { background: var(--abni-ink); border-color: var(--abni-ink); color: #fff; transform: translateY(-1px); }

/* Messages */
.chat-msg { display: flex; flex-direction: column; max-width: 100%; }
.chat-msg.user { align-items: flex-end; }
.chat-msg.assistant { align-items: flex-start; }
.chat-bubble {
  max-width: 92%;
  padding: 10px 14px;
  border-radius: 16px;
  font-size: 14px;
  line-height: 1.55;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.chat-msg.user .chat-bubble {
  background: var(--abni-blue-deep);
  color: #fff;
  border-bottom-right-radius: 5px;
}
.chat-msg.assistant .chat-bubble {
  background: #fff;
  color: var(--abni-ink);
  border: 1px solid var(--abni-line);
  border-bottom-left-radius: 5px;
}
/* Markdown inside assistant bubbles */
.chat-bubble p { margin: 0 0 8px; }
.chat-bubble p:last-child { margin-bottom: 0; }
.chat-bubble ul, .chat-bubble ol { margin: 4px 0 8px; padding-left: 20px; }
.chat-bubble li { margin: 2px 0; }
.chat-bubble code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  background: rgba(25, 64, 86, 0.08);
  padding: 1px 5px;
  border-radius: 5px;
}
.chat-bubble pre {
  background: rgba(25, 64, 86, 0.06);
  border-radius: 10px;
  padding: 10px 12px;
  overflow-x: auto;
  margin: 6px 0;
}
.chat-bubble pre code { background: none; padding: 0; }
.chat-bubble a { color: var(--abni-blue-deep); text-decoration: underline; }
.chat-bubble strong { font-weight: 700; }

/* Progressive-reveal caret ("type-on"). Sits inline at the end of the last
   revealed block while the reply types in. */
.chat-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 1px;
  vertical-align: -0.14em;
  background: var(--abni-blue-deep);
  animation: chatCaret 1s steps(1, end) infinite;
}
@keyframes chatCaret { 50% { opacity: 0; } }
.chat-bubble.is-revealing { cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .chat-caret { display: none; } }

/* Tool-call transparency steps */
.chat-steps { display: flex; flex-direction: column; gap: 3px; margin: 0 0 6px; }
.chat-step {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  font-size: 11.5px;
  color: var(--abni-mute);
  background: rgba(25, 64, 86, 0.05);
  padding: 3px 9px;
  border-radius: 999px;
}
.chat-step::before { content: "✓"; color: var(--app-success); font-weight: 700; }

/* Inline image gallery — reflows with the panel width (2-up on a laptop, 3-up
   on a wide monitor where the panel is roomier). */
.chat-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  margin-top: 8px;
  max-width: 100%;
}
.chat-img {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--abni-line);
  background: var(--abni-blue-soft);
}
.chat-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.chat-img .chat-img-hero {
  position: absolute; top: 5px; left: 5px;
  background: rgba(25, 64, 86, 0.82); color: #fff;
  font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 999px;
}
/* Letter badge (A/B/C) — top-right, doubles as a tappable SELECT toggle so the
   user can pick images and reference them ("the lighting in B") next turn. */
.chat-img .chat-img-letter {
  position: absolute; top: 5px; right: 5px; z-index: 2;
  min-width: 18px; height: 18px; padding: 0 3px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.92); color: var(--abni-blue-deep, #1f3a4d);
  font-size: 11px; font-weight: 800; line-height: 1; border-radius: 999px;
  border: 1px solid rgba(25, 64, 86, 0.25); cursor: pointer;
}
.chat-img .chat-img-letter:hover { background: #fff; }
.chat-img .chat-img-letter.is-on {
  background: var(--abni-blue-deep, #1f3a4d); color: #fff;
  border-color: var(--abni-blue-deep, #1f3a4d);
}
.chat-img.is-selected {
  border-color: var(--abni-blue-deep, #1f3a4d);
  box-shadow: 0 0 0 2px var(--abni-blue-deep, #1f3a4d);
}
/* Name caption — lets the user pick an image/asset by name at a glance. */
.chat-img .chat-img-name {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 12px 8px 5px;
  background: linear-gradient(transparent, rgba(25, 64, 86, 0.86));
  color: #fff;
  font-size: 11px; font-weight: 600; line-height: 1.2;
  text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none;
}

/* Typing indicator */
.chat-typing { display: inline-flex; gap: 4px; padding: 12px 14px; }
.chat-typing span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--abni-blue-mid);
  animation: chatDot 1.2s infinite ease-in-out;
}
.chat-typing span:nth-child(2) { animation-delay: 0.18s; }
.chat-typing span:nth-child(3) { animation-delay: 0.36s; }
@keyframes chatDot { 0%, 60%, 100% { opacity: 0.3; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

/* Composer */
.chat-composer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 14px;
  border-top: 1px solid var(--abni-line);
  background: rgba(255, 255, 255, 0.7);
}
.chat-input {
  flex: 1;
  resize: none;
  max-height: 140px;
  padding: 10px 12px;
  border: 1px solid var(--abni-line);
  border-radius: 12px;
  font-family: var(--abni-font-body);
  font-size: 14px;
  line-height: 1.4;
  color: var(--abni-ink);
  background: #fff;
}
.chat-input:focus { outline: none; border-color: var(--abni-blue-deep); }
.chat-send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  flex: none;
  border: none;
  border-radius: 12px;
  background: var(--abni-blue-deep);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.chat-send:disabled { opacity: 0.4; cursor: not-allowed; }
.chat-send .ui-icon { width: 18px; height: 18px; }

/* Image attach (vision) */
.chat-composer { flex-wrap: wrap; }
.chat-attach-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none; border: none; border-radius: 12px;
  background: transparent; color: var(--abni-mute); cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.chat-attach-btn:hover { background: rgba(25, 64, 86, 0.08); color: var(--abni-blue-deep); }
.chat-attach-btn .ui-icon { width: 18px; height: 18px; }
.chat-attach-chip {
  flex-basis: 100%; order: -1; display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; margin-bottom: 6px; border: 1px solid var(--abni-line);
  border-radius: 10px; background: var(--abni-blue-soft); font-size: 12px; color: var(--abni-ink);
}
.chat-attach-chip img { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; flex: none; }
.chat-attach-chip span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-attach-remove { border: none; background: none; color: var(--abni-mute); cursor: pointer; font-size: 13px; padding: 2px 6px; line-height: 1; }
.chat-attach-remove:hover { color: var(--app-error); }
.chat-user-image { max-width: 60%; align-self: flex-end; margin-top: 6px; border-radius: 12px; border: 1px solid var(--abni-line); cursor: zoom-in; }
.chat-img { cursor: zoom-in; }

/* Lightweight full-screen zoom for chat images without a library entry
   (dropped image / captured site screenshot). Click or Esc to dismiss. */
.chat-zoom-overlay {
  position: fixed; inset: 0; z-index: 4000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 10, 14, 0.86);
  padding: 4vmin; cursor: zoom-out;
  opacity: 0; transition: opacity 0.16s ease;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.chat-zoom-overlay.is-in { opacity: 1; }
.chat-zoom-img {
  max-width: 92vw; max-height: 92vh;
  object-fit: contain; border-radius: 10px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
  transform: scale(0.98); transition: transform 0.16s ease;
}
.chat-zoom-overlay.is-in .chat-zoom-img { transform: scale(1); }

/* #4 — "what Abni remembers" panel (invisible-but-deletable). */
.chat-memory-overlay {
  position: fixed; inset: 0; z-index: 4100;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 10, 14, 0.5); padding: 5vmin;
}
.chat-memory-panel {
  width: 420px; max-width: 92vw; max-height: 80vh;
  display: flex; flex-direction: column;
  background: var(--abni-paper, #fff);
  border: 1px solid var(--abni-line, #e4e7ec);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.28);
}
.chat-memory-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--abni-line, #e4e7ec);
  font-weight: 650; font-size: 14px; color: var(--abni-ink, #16202c);
}
.chat-memory-x { border: none; background: transparent; cursor: pointer; font-size: 15px; color: var(--abni-mute, #6b7785); line-height: 1; padding: 4px; }
.chat-memory-list { overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.chat-memory-empty { padding: 22px 16px; color: var(--abni-mute, #6b7785); font-size: 13px; line-height: 1.5; text-align: center; }
.chat-memory-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 10px; background: rgba(25, 64, 86, 0.04); }
.chat-memory-col { flex: 1; min-width: 0; }
.chat-memory-text { font-size: 13.5px; color: var(--abni-ink, #16202c); line-height: 1.4; }
.chat-memory-meta { margin-top: 3px; font-size: 11px; color: var(--abni-mute, #6b7785); text-transform: capitalize; }
.chat-memory-del { border: none; background: transparent; color: var(--abni-mute, #6b7785); cursor: pointer; font-size: 13px; padding: 2px 4px; border-radius: 6px; flex: 0 0 auto; }
.chat-memory-del:hover:not(:disabled) { background: rgba(220, 38, 38, 0.1); color: #dc2626; }
.chat-memory-del:disabled { opacity: 0.4; cursor: default; }

@media (max-width: 768px) {
  /* Mobile: the chat tab is a static, full-area section (not a fixed panel).
     Fill the viewport between topbar and bottom-nav; composer pins to the
     section's bottom via flex. Override any desktop fixed positioning. */
  #chat-section {
    position: static;
    inset: auto;
    width: auto;
    z-index: auto;
    border-left: none;
    box-shadow: none;
    padding: 0; /* override .studio-panel 24px — fill the tab edge-to-edge */
    height: calc(100dvh - var(--chat-top, 60px) - 84px - env(safe-area-inset-bottom, 0px));
  }
  .app-shell.chat-open .app-main { padding-right: 14px; }
  .chat-gallery { max-width: 100%; }
}

/* ── Full-screen image zoom (picked-image previews) ── */
.img-zoom-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: rgba(15, 30, 38, 0.86);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity 0.2s var(--abni-ease);
}
.img-zoom-overlay.is-open { opacity: 1; }
.img-zoom-img {
  max-width: 96vw;
  max-height: 92vh;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
  cursor: zoom-out;
}
.img-zoom-close {
  position: fixed;
  top: 18px;
  right: 22px;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s;
}
.img-zoom-close:hover { background: rgba(255, 255, 255, 0.3); }

/* Chat send button in Stop mode (while streaming). */
.chat-send.is-stop { background: var(--abni-mute); }
.chat-send.is-stop:hover { background: var(--abni-ink); }

/* ── Chat write-action confirm card (cost-confirm before generate) ── */
.chat-proposal {
  margin-top: 8px;
  align-self: flex-start;
  max-width: 86%;
  border: 1px solid var(--abni-blue-soft);
  border-radius: 14px;
  background: rgba(106, 176, 212, 0.07);
  padding: 12px 14px;
}
.chat-proposal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.chat-proposal-summary { font-size: 13px; font-weight: 600; color: var(--abni-ink); }
.chat-proposal-cost {
  font-size: 12px;
  font-weight: 700;
  color: var(--abni-blue-deep);
  background: #fff;
  border: 1px solid var(--abni-line);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}
.chat-proposal-actions { display: flex; gap: 8px; }
.chat-proposal-btn {
  padding: 8px 14px;
  border-radius: 10px;
  font-family: var(--abni-font-body);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.chat-proposal-btn.primary { background: var(--abni-blue-deep); color: #fff; }
.chat-proposal-btn.primary:hover { background: var(--abni-blue-deeper); }
.chat-proposal-btn.primary.danger { background: var(--app-error); }
.chat-proposal-btn.ghost { background: transparent; border-color: var(--abni-line); color: var(--abni-mute); }
.chat-proposal-btn.ghost:hover { color: var(--abni-ink); border-color: var(--abni-blue-deep); }
.chat-proposal.is-done {
  background: rgba(47, 138, 85, 0.08);
  border-color: rgba(47, 138, 85, 0.3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.chat-proposal-go { font-size: 13px; font-weight: 600; color: var(--app-success); }
.chat-proposal-view { background: none; border: none; color: var(--abni-blue-deep); font-weight: 600; font-size: 12.5px; cursor: pointer; white-space: nowrap; }
.chat-proposal.is-error { background: rgba(176, 48, 48, 0.06); border-color: rgba(176, 48, 48, 0.3); }
.chat-proposal-err { display: block; font-size: 12.5px; color: var(--app-error); margin-bottom: 8px; }

/* Multi-step project plan (§5.6) */
.chat-plan {
  margin-top: 8px;
  align-self: flex-start;
  max-width: 92%;
  border: 1px solid var(--abni-blue-soft);
  border-radius: 14px;
  background: rgba(106, 176, 212, 0.07);
  padding: 12px 14px;
}
.chat-plan-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.chat-plan-goal { font-size: 13px; font-weight: 700; color: var(--abni-ink); }
.chat-plan-steps {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.chat-plan-step {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  color: var(--abni-ink);
  line-height: 1.4;
}
.chat-plan-ico {
  flex: none;
  width: 18px;
  text-align: center;
  font-weight: 700;
  color: var(--abni-mute);
}
.chat-plan-step.is-running .chat-plan-ico { color: var(--abni-blue-deep); animation: chatSpin 1s linear infinite; display: inline-block; }
.chat-plan-step.is-done .chat-plan-ico { color: var(--app-success); }
.chat-plan-step.is-error .chat-plan-ico { color: var(--app-error); }
.chat-plan-step.is-blocked { opacity: 0.5; }
.chat-plan-step.is-done .chat-plan-step-txt { color: var(--abni-mute); }
.chat-plan-step-cost { color: var(--abni-mute); font-size: 11.5px; font-weight: 600; }
.chat-plan-step-err { color: var(--app-error); font-size: 11.5px; }
.chat-plan-note { font-size: 12px; color: var(--abni-mute); margin-bottom: 10px; }
.chat-plan-note.is-error { color: var(--app-error); }
@keyframes chatSpin { to { transform: rotate(360deg); } }
