/* ============================================================
   ppt-gallery.css — the deck gallery at /presentation ("viewer mode").

   Rides on flows.css for the dashboard shell (sidebar, navbar,
   dashboard-container, panel-card, btn-primary-action) so this page
   looks like /billing, /credits and /flows. It used to ship its own
   sidebar+navbar partials and its own light theme, which is why it
   never matched the rest of the app.

   The EDITOR (/presentation/:id) deliberately does NOT use this — it is a
   full-bleed workspace with its own chrome, like Slides. See ppt-editor.css.
   ============================================================ */

/* flows.css styles .dashboard-title h1 but never colours it, so it falls
   through to material-dashboard's dark navy — invisible on a dark page. */
.dashboard-title h1 { color: var(--text-primary); }

.btn-secondary-action {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; font-size: .82rem; font-weight: 600;
  border-radius: 9px; text-decoration: none; cursor: pointer;
  color: var(--text-secondary);
  background: var(--bg-hover, rgba(255,255,255,.06));
  border: 1px solid var(--border-color);
  font-family: inherit;
}
.btn-secondary-action:hover { color: var(--text-primary); border-color: var(--accent-purple, #8b5cf6); }
.btn-secondary-action .material-symbols-rounded,
.btn-primary-action .material-symbols-rounded { font-size: 18px; }

/* ── Stats strip ─────────────────────────────────────────── */
.ppt-stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 14px; margin-bottom: 20px;
}
@media (max-width: 900px) { .ppt-stats-grid { grid-template-columns: repeat(2, 1fr); } }

.ppt-stat-card {
  padding: 16px 18px; border-radius: 12px;
  background: var(--bg-card, rgba(255,255,255,.03));
  border: 1px solid var(--border-color);
}
.ppt-stat-icon { color: var(--accent-purple, #8b5cf6); margin-bottom: 8px; }
.ppt-stat-icon .material-symbols-rounded { font-size: 22px; }
.ppt-stat-label {
  font-size: .68rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
}
.ppt-stat-value { font-size: 1.6rem; font-weight: 800; color: var(--text-primary); margin-top: 2px; }

/* ── Tabs ────────────────────────────────────────────────── */
.ppt-tabs {
  display: flex; gap: 4px; margin-bottom: 16px;
  border-bottom: 1px solid var(--border-color);
}
.ppt-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 10px 14px; background: none; border: none;
  border-bottom: 2px solid transparent; cursor: pointer;
  color: var(--text-muted); font-size: .84rem; font-weight: 600;
  font-family: inherit;
}
.ppt-tab:hover { color: var(--text-primary); }
.ppt-tab.active { color: var(--accent-purple, #8b5cf6); border-bottom-color: var(--accent-purple, #8b5cf6); }
.ppt-tab .material-symbols-rounded { font-size: 18px; }
.ppt-tab-content { display: none; }
.ppt-tab-content.active { display: block; }

/* ── The deck grid ───────────────────────────────────────── */
.ppt-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: 18px;
}

.ppt-card {
  border-radius: 12px; overflow: hidden;
  background: var(--bg-card, rgba(255,255,255,.03));
  border: 1px solid var(--border-color);
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.ppt-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent-purple, #8b5cf6);
  box-shadow: 0 12px 30px rgba(0,0,0,.35);
}

/* The real first slide, rendered at 320px wide and scaled to fit the card. */
.ppt-card-preview {
  position: relative; display: block; aspect-ratio: 16/9;
  background: #0d0d11; overflow: hidden; text-decoration: none;
  border-bottom: 1px solid var(--border-color);
}
/* Rendered at a fixed 320x180 so renderSlide's font scaling (clientWidth/1280)
   is stable, then scaled to whatever width the card actually is. The card is
   fluid, so the scale factor is set in JS — CSS can't divide by a measured
   width without container queries. */
.ppt-card-canvas {
  position: relative;
  width: 320px; height: 180px;
  transform-origin: top left;
  overflow: hidden;
}
.ppt-card-open {
  position: absolute; inset: 0; z-index: 5;
  display: flex; align-items: center; justify-content: center; gap: 7px;
  background: rgba(10,10,14,.62); color: #fff;
  font-size: .82rem; font-weight: 600;
  opacity: 0; transition: opacity .15s;
}
.ppt-card:hover .ppt-card-open { opacity: 1; }

.ppt-card-body { padding: 12px 14px 14px; }
.ppt-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.ppt-card-title-link { text-decoration: none; min-width: 0; }
.ppt-card-title {
  margin: 0; font-size: .95rem; font-weight: 700; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ppt-card-title-link:hover .ppt-card-title { color: var(--accent-purple, #8b5cf6); }

.ppt-card-tools { display: flex; gap: 2px; flex-shrink: 0; }
.ppt-icon-btn {
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; border-radius: 6px; cursor: pointer;
  color: var(--text-muted); text-decoration: none;
}
.ppt-icon-btn:hover { background: var(--bg-hover, rgba(255,255,255,.08)); color: var(--text-primary); }
.ppt-icon-btn.ppt-danger:hover { color: #f87171; background: rgba(239,68,68,.14); }
.ppt-icon-btn .material-symbols-rounded { font-size: 18px; }

.ppt-card-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 8px; font-size: .72rem; color: var(--text-muted);
}
.ppt-card-meta span { display: inline-flex; align-items: center; gap: 4px; }
.ppt-card-meta .material-symbols-rounded { font-size: 14px; }

.ppt-status-badge {
  margin-left: auto; padding: 2px 8px; border-radius: 999px;
  font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.ppt-status-completed  { background: rgba(16,185,129,.16); color: #34d399; }
.ppt-status-generating { background: rgba(139,92,246,.16); color: #a78bfa; }
.ppt-status-draft      { background: rgba(148,163,184,.16); color: #94a3b8; }
.ppt-status-failed     { background: rgba(239,68,68,.16); color: #f87171; }

/* ── Empty state ─────────────────────────────────────────── */
.ppt-empty-state {
  grid-column: 1 / -1; text-align: center; padding: 56px 20px;
  border: 1px dashed var(--border-color); border-radius: 12px;
}
.ppt-empty-icon .material-symbols-rounded { font-size: 44px; color: var(--text-muted); }
.ppt-empty-title { margin: 10px 0 4px; font-size: 1.05rem; color: var(--text-primary); }
.ppt-empty-text { margin: 0 auto 16px; max-width: 420px; font-size: .84rem; color: var(--text-muted); line-height: 1.6; }

/* ── Modal ───────────────────────────────────────────────────────────────────
   The card OWNS the viewport height and never exceeds it. Header and tabs are
   fixed, the body is the only scroller, the footer is pinned. The old layout
   let the card grow to whatever the brief form needed and scrolled the OVERLAY
   instead, which pushed the Generate button off the bottom of the screen.
   ─────────────────────────────────────────────────────────────────────────── */
.ppt-modal-overlay {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(6,6,10,.72); backdrop-filter: blur(3px);
  display: none; align-items: center; justify-content: center;
  padding: 20px 16px; overflow: hidden;
}
.ppt-modal-overlay.show { display: flex; }
.ppt-modal-card {
  width: 100%; max-width: 1060px;
  max-height: calc(100vh - 40px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg-panel, #16161c);
  border: 1px solid var(--border-color); border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.ppt-modal-header {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 22px 0;
}

/* A pane is one tab's content: itself a column of body + footer. */
.ppt-pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.ppt-pane-form { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* min-height:0 is what lets a flex child actually shrink and scroll — without
   it the body grows to its content and the footer leaves the screen again. */
.ppt-modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 22px 18px; }
.ppt-modal-footer {
  flex: 0 0 auto; padding: 12px 22px 16px;
  border-top: 1px solid var(--border-color);
  background: var(--bg-panel, #16161c);
}
.ppt-footer-row { display: flex; align-items: center; gap: 16px; }
.ppt-footer-hint { flex: 1 1 auto; font-size: .76rem; color: var(--text-muted); line-height: 1.45; }
.ppt-generate-cta { flex: 0 0 auto; min-width: 250px; padding: 12px 20px; font-size: .9rem; }

/* Two columns of brief on a desktop; one on anything narrow. */
.ppt-form-cols {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 22px; align-items: start;
}

/* Desktop: the COLUMNS own the scrolling, not the body. The two catalogue
   grids stretch into whatever height is left and scroll inside themselves, so
   every field of the brief is on screen at once — which is the whole point of
   the two-column layout. */
@media (min-width: 941px) {
  /* The body is itself a flex column and the grid of columns is its growing
     child. `height:100%` looks equivalent and is NOT: a percentage height
     against a flex item whose own height came from flex resolves to auto in
     Chrome, and the columns silently grew to their content instead. */
  .ppt-modal-body { overflow: hidden; display: flex; flex-direction: column; }
  .ppt-generate-sub { flex: 0 0 auto; }
  .ppt-form-cols { flex: 1 1 auto; min-height: 0; align-items: stretch; }
  .ppt-form-col { min-height: 0; display: flex; flex-direction: column; }
  .ppt-form-col-scroll { overflow-y: auto; padding-right: 6px; }
  .ppt-grow { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .ppt-grow .ppt-style-grid,
  .ppt-grow .ppt-structure-grid { flex: 1 1 auto; min-height: 108px; max-height: none; }

  /* The instructions box takes the slack at the bottom of the right column,
     instead of leaving a dead rectangle of panel under it. */
  .ppt-form-col-scroll > .ppt-form-group:last-child {
    flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; margin-bottom: 0;
  }
  .ppt-form-col-scroll > .ppt-form-group:last-child textarea {
    flex: 1 1 auto; min-height: 84px;
  }
}

@media (max-width: 940px) {
  .ppt-form-cols { grid-template-columns: 1fr; gap: 0; }
  .ppt-footer-row { flex-direction: column; align-items: stretch; gap: 10px; }
  .ppt-footer-hint { display: none; }
  .ppt-generate-cta { width: 100%; justify-content: center; }
}
@media (max-width: 620px) {
  .ppt-modal-overlay { padding: 10px; }
  .ppt-modal-card { max-height: calc(100vh - 20px); }
  .ppt-modal-header, .ppt-modal-body, .ppt-modal-footer { padding-left: 14px; padding-right: 14px; }
}

/* Scrollbars inside the modal, so a nested scroll area reads as deliberate
   rather than as content that has been cut off. */
.ppt-modal-body::-webkit-scrollbar,
.ppt-style-grid::-webkit-scrollbar,
.ppt-structure-grid::-webkit-scrollbar { width: 9px; }
.ppt-modal-body::-webkit-scrollbar-thumb,
.ppt-style-grid::-webkit-scrollbar-thumb,
.ppt-structure-grid::-webkit-scrollbar-thumb {
  background: rgba(148,163,184,.28); border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
}
.ppt-modal-body::-webkit-scrollbar-thumb:hover,
.ppt-style-grid::-webkit-scrollbar-thumb:hover,
.ppt-structure-grid::-webkit-scrollbar-thumb:hover { background: rgba(148,163,184,.5); background-clip: content-box; }
.ppt-modal-body::-webkit-scrollbar-track,
.ppt-style-grid::-webkit-scrollbar-track,
.ppt-structure-grid::-webkit-scrollbar-track { background: transparent; }
.ppt-modal-header h2 {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: 1.05rem; font-weight: 700; color: var(--text-primary);
}
.ppt-menu-btn {
  width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; border-radius: 7px; cursor: pointer; color: var(--text-muted);
}
.ppt-menu-btn:hover { background: var(--bg-hover, rgba(255,255,255,.08)); color: var(--text-primary); }

.ppt-source-toggle {
  flex: 0 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  /* Capped: stretched across a 1060px card the two tabs read as a toolbar
     rather than as a choice between two things. */
  width: 100%; max-width: 400px;
  padding: 4px; margin: 12px 22px 0;
  background: var(--bg-hover, rgba(255,255,255,.05));
  border-radius: 10px;
}
@media (max-width: 620px) { .ppt-source-toggle { margin-left: 14px; margin-right: 14px; } }
.ppt-source-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px; border: none; border-radius: 7px; cursor: pointer;
  background: transparent; color: var(--text-muted);
  font-size: .82rem; font-weight: 600; font-family: inherit;
}
.ppt-source-btn.active { background: var(--accent-purple, #8b5cf6); color: #fff; }

.ppt-generate-sub { font-size: .82rem; color: var(--text-muted); margin: 0 0 14px; }

.ppt-form-group { margin-bottom: 14px; }
.ppt-form-group label {
  display: block; margin-bottom: 6px;
  font-size: .74rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-muted);
}
.ppt-form-group input[type="text"],
.ppt-form-group textarea {
  width: 100%; padding: 10px 12px;
  background: var(--bg-hover, rgba(255,255,255,.05));
  border: 1px solid var(--border-color); border-radius: 9px;
  color: var(--text-primary); font-size: .86rem; font-family: inherit;
}
.ppt-form-group textarea { min-height: 72px; resize: vertical; }
.ppt-form-group input:focus, .ppt-form-group textarea:focus {
  outline: none; border-color: var(--accent-purple, #8b5cf6);
}
/* `.ppt-form-group label` is meant for the FIELD label, but it matches every
   descendant <label> — which put the length options, the brand swatches and
   the "use my colours" toggle in uppercase 11px muted type. Opt those back out
   rather than rewriting the field-label rule every other form depends on. */
.ppt-form-group .ppt-pattern-option,
.ppt-form-group .ppt-brand-swatch,
.ppt-form-group .ppt-brand-toggle {
  margin-bottom: 0; text-transform: none; letter-spacing: 0;
  font-size: .78rem; font-weight: 500; color: var(--text-secondary);
}
.ppt-helper-text { margin-top: 5px; font-size: .72rem; color: var(--text-muted); line-height: 1.5; }

.ppt-pattern-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
@media (max-width: 620px) { .ppt-pattern-grid { grid-template-columns: repeat(2, 1fr); } }
.ppt-pattern-option {
  padding: 10px; border-radius: 9px; cursor: pointer;
  background: var(--bg-hover, rgba(255,255,255,.04));
  border: 1px solid var(--border-color);
}
.ppt-pattern-option input { display: none; }
.ppt-pattern-option:hover { border-color: var(--accent-purple, #8b5cf6); }
.ppt-pattern-option.selected {
  border-color: var(--accent-purple, #8b5cf6);
  background: rgba(139,92,246,.14);
}
.ppt-pattern-name { font-size: .8rem; font-weight: 700; color: var(--text-primary); }
.ppt-pattern-desc { font-size: .68rem; color: var(--text-muted); margin-top: 2px; }

/* ── The brief form ──────────────────────────────────────── */
.ppt-req {
  margin-left: 6px; font-weight: 500; text-transform: none;
  letter-spacing: 0; color: var(--text-muted); opacity: .75;
}
.ppt-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 620px) { .ppt-form-row { grid-template-columns: 1fr; } }

.ppt-select {
  width: 100%; height: 38px; padding: 0 10px;
  background: var(--bg-hover, rgba(255,255,255,.05));
  border: 1px solid var(--border-color); border-radius: 9px;
  color: var(--text-primary); font-size: .84rem; font-family: inherit;
}
.ppt-style-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.ppt-style-toolbar .ppt-select { width: 190px; }

/* Each swatch is a REAL slide drawn by the editor's renderer in that style's
   own palette — so what you pick is honestly what you get. */
/* The catalogues are long (20+ styles), so they scroll inside a framed panel.
   Framing them is the point: an unframed cut-off grid looks like a rendering
   bug, a framed one looks like a list you scroll. */
.ppt-style-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  /* max-content rows + start alignment: once the grid has a definite height
     (it does, it flexes), auto rows get squeezed to fit and the cards render
     as bare swatches with their names clipped off. */
  grid-auto-rows: max-content; align-items: start;
  gap: 8px; max-height: 272px; overflow-y: auto;
  padding: 8px; border-radius: 10px;
  background: rgba(255,255,255,.02); border: 1px solid var(--border-color);
}
.ppt-style-card {
  padding: 0; border-radius: 10px; overflow: hidden; cursor: pointer;
  background: var(--bg-hover, rgba(255,255,255,.04));
  border: 2px solid var(--border-color);
  font-family: inherit; text-align: left;
}
.ppt-style-card:hover { border-color: var(--accent-purple, #8b5cf6); }
.ppt-style-card.selected { border-color: var(--accent-purple, #8b5cf6); box-shadow: 0 0 0 3px rgba(139,92,246,.22); }
.ppt-style-swatch { position: relative; width: 100%; aspect-ratio: 16/9; overflow: hidden; background: #0d0d11; }
.ppt-style-canvas { position: relative; width: 320px; height: 180px; transform-origin: top left; overflow: hidden; }
.ppt-style-name {
  padding: 6px 8px; font-size: .72rem; font-weight: 600; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.ppt-structure-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
  grid-auto-rows: max-content; align-items: start;
  gap: 8px; max-height: 232px; overflow-y: auto;
  padding: 8px; border-radius: 10px;
  background: rgba(255,255,255,.02); border: 1px solid var(--border-color);
}
.ppt-structure-card {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px; border-radius: 9px; cursor: pointer; text-align: left;
  background: var(--bg-hover, rgba(255,255,255,.04));
  border: 1px solid var(--border-color); font-family: inherit;
}
.ppt-structure-card:hover { border-color: var(--accent-purple, #8b5cf6); }
.ppt-structure-card.selected { border-color: var(--accent-purple, #8b5cf6); background: rgba(139,92,246,.14); }
.ppt-structure-card strong { font-size: .78rem; color: var(--text-primary); }
.ppt-structure-card small { font-size: .68rem; color: var(--text-muted); line-height: 1.35; }
.ppt-structure-card em { font-size: .64rem; color: var(--accent-purple, #8b5cf6); font-style: normal; font-weight: 700; }

.ppt-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ppt-chip {
  padding: 5px 11px; border-radius: 999px; cursor: pointer;
  background: var(--bg-hover, rgba(255,255,255,.05));
  border: 1px solid var(--border-color);
  color: var(--text-muted); font-size: .74rem; font-family: inherit;
}
.ppt-chip:hover { color: var(--text-primary); }
.ppt-chip.on {
  background: rgba(139,92,246,.2); border-color: var(--accent-purple, #8b5cf6);
  color: var(--text-primary); font-weight: 600;
}

.ppt-brand-row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.ppt-brand-swatch, .ppt-brand-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .76rem; color: var(--text-muted); cursor: pointer;
}
.ppt-brand-swatch input[type="color"] {
  width: 34px; height: 30px; padding: 2px; cursor: pointer;
  background: var(--bg-hover, rgba(255,255,255,.05));
  border: 1px solid var(--border-color); border-radius: 7px;
}

.ppt-advanced {
  margin-bottom: 14px; padding: 10px 12px; border-radius: 9px;
  background: var(--bg-hover, rgba(255,255,255,.03));
  border: 1px solid var(--border-color);
}
.ppt-advanced summary {
  cursor: pointer; font-size: .78rem; font-weight: 600; color: var(--text-secondary);
}
.ppt-advanced summary:hover { color: var(--text-primary); }
.ppt-advanced textarea { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: .74rem; }

/* ── Generation status ───────────────────────────────────── */
.ppt-status-box {
  /* Lives in the pinned footer, directly above the Generate button. */
  display: none; margin: 0 0 12px; padding: 14px;
  background: var(--bg-hover, rgba(255,255,255,.04));
  border: 1px solid var(--border-color); border-radius: 10px;
}
.ppt-status-box.show { display: block; }
.ppt-status-title {
  display: flex; align-items: center; gap: 9px;
  font-size: .88rem; font-weight: 600; color: var(--text-primary);
}
.ppt-status-message { margin-top: 5px; font-size: .78rem; color: var(--text-muted); }
.ppt-spinner {
  width: 15px; height: 15px; flex-shrink: 0;
  border: 2px solid rgba(139,92,246,.3);
  border-top-color: var(--accent-purple, #8b5cf6);
  border-radius: 50%; animation: pptSpin .8s linear infinite;
}
@keyframes pptSpin { to { transform: rotate(360deg); } }
.ppt-progress-bar {
  height: 5px; margin-top: 11px; border-radius: 999px; overflow: hidden;
  background: var(--bg-hover, rgba(255,255,255,.08));
}
.ppt-progress-fill {
  height: 100%; width: 0;
  background: linear-gradient(90deg, #6366f1, #8b5cf6);
  transition: width .4s ease;
}
.ppt-success-actions { display: none; gap: 8px; margin-top: 12px; }
.ppt-success-actions.show { display: flex; }
.glass-btn-ppt-success { background: #10b981 !important; color: #fff !important; }

/* ── Templates ───────────────────────────────────────────── */
.ppt-template-section-label {
  margin: 14px 0 8px; font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted);
}
.ppt-template-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 10px;
}
.ppt-template-loading { grid-column: 1 / -1; padding: 12px; font-size: .78rem; color: var(--text-muted); }
.ppt-template-grid .ppt-empty-state { padding: 32px 20px; }

/* A template card is a CARD: pattern chip, name, description, then the action.
   It used to be `flex; align-items:center; justify-content:space-between`,
   which laid those four out in a row and squeezed each into a column of
   wrapped words — and .ppt-template-pattern/.ppt-template-desc, which the JS
   has always emitted, had no rules at all. */
.ppt-template-card {
  position: relative;
  display: flex; flex-direction: column; align-items: stretch; gap: 4px;
  padding: 13px; border-radius: 12px;
  background: var(--bg-hover, rgba(255,255,255,.04));
  border: 1px solid var(--border-color);
  transition: border-color .15s, transform .15s;
}
.ppt-template-card:hover { border-color: var(--accent-purple, #8b5cf6); transform: translateY(-1px); }
.ppt-template-pattern {
  align-self: flex-start; margin-bottom: 2px;
  padding: 3px 8px; border-radius: 999px;
  background: rgba(139,92,246,.16); color: #a78bfa;
  font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
}
.ppt-template-name { font-size: .88rem; font-weight: 700; color: var(--text-primary); line-height: 1.3; }
.ppt-template-desc {
  flex: 1 1 auto; font-size: .74rem; color: var(--text-muted); line-height: 1.5;
}
.ppt-template-meta { font-size: .68rem; color: var(--text-muted); margin-top: 2px; }
.ppt-template-card .glass-btn-ppt { padding: 8px 12px; font-size: .78rem; }
/* Delete sits over the card's top-right corner; it had no rules, so it was
   rendering inline as the first thing in the card. */
.ppt-template-delete {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 7px; cursor: pointer;
  background: rgba(0,0,0,.35); color: var(--text-muted);
  opacity: 0; transition: opacity .15s;
}
.ppt-template-card:hover .ppt-template-delete { opacity: 1; }
.ppt-template-delete:hover { background: rgba(239,68,68,.9); color: #fff; }
.ppt-template-delete .material-symbols-rounded { font-size: 16px; }

/* Buttons the old markup still uses inside the modal. */
.glass-btn-ppt {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px; border: 1px solid var(--border-color); border-radius: 9px;
  background: var(--bg-hover, rgba(255,255,255,.06));
  color: var(--text-primary); font-size: .84rem; font-weight: 600;
  cursor: pointer; text-decoration: none; font-family: inherit;
}
.glass-btn-ppt:hover { border-color: var(--accent-purple, #8b5cf6); }
.glass-btn-ppt-primary {
  background: var(--accent-purple, #8b5cf6); border-color: transparent; color: #fff;
}
.glass-btn-ppt-primary:hover { background: #7c3aed; }
