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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.billing .plan form {
  display: flex;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* gallery (FRONTEND.md 5.2) */
.gallery {
  display: flex;
  flex-direction: column;
}
.gallery .toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 24px 6px;
  flex: none;
  /* Sticky below the 60px topbar so the search/filters stay visible while cards scroll under. */
  position: sticky;
  top: 60px;
  z-index: var(--z-dropdown);
  background: var(--bg);
}
.gallery .search {
  display: flex;
  align-items: center;
  gap: 9px;
  height: var(--h-control);
  width: 280px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-control);
  padding: 0 13px;
  color: var(--tx-3);
  transition: border-color 0.15s;
}
.gallery .search:focus-within {
  border-color: var(--lime);
}
.gallery .search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  color: var(--tx);
  font-size: 13.5px;
  font-family: inherit;
}
.gallery .search input::placeholder {
  color: var(--tx-3);
}
.gallery .filters {
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 3px;
}
.gallery .filters a,
.gallery .filters button {
  padding: 7px 15px;
  border: none;
  background: none;
  border-radius: 8px;
  font-weight: 500;
  font-size: 12.5px;
  font-family: inherit;
  color: var(--tx-3);
  text-decoration: none;
  cursor: pointer;
  transition: 0.12s;
}
.gallery .filters a:hover,
.gallery .filters button:hover {
  color: var(--tx-2);
}
.gallery .filters a.on,
.gallery .filters button.on {
  background: var(--surface-2);
  color: var(--tx);
}
.gallery .scroll {
  padding: 16px 24px 40px;
}
.gal {
  /* Responsive grid: as many >=280px columns as fit, each growing (1fr) to fill the row exactly, so
     there is never an empty right gutter at any width or card count. auto-fit collapses unused tracks
     so a few cards on a wide screen stretch to fill rather than leaving a gap. Cards keep their own
     aspect ratio (align-items: start), so rows are ragged at the bottom by design. Replaces CSS
     multicol, which balanced content into fewer/taller columns and flowed column-major. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  align-items: start;
}
.gcard {
  border-radius: 14px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: 0.18s;
  display: block;
  width: 100%;
  background: var(--surface);
  padding: 0;
  text-align: left;
}
.gcard:hover {
  border-color: var(--line-2);
  transform: translateY(-3px);
}
.gcard.story {
  aspect-ratio: 9 / 16;
}
.gcard.feed {
  aspect-ratio: 4 / 5;
}
.gcard.stacked {
  /* Offset "peek" of the second creative behind the card (pure shadow, no second image). */
  box-shadow: 6px -6px 0 -1px var(--surface-2), 6px -6px 0 0 var(--line-2);
  margin-top: 6px;
}
.stack-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 5px;
  background: rgba(0, 0, 0, 0.55);
  padding: 5px 11px;
  border-radius: 9px;
  color: var(--tx-2);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.gcard .art {
  position: absolute;
  inset: 0;
}
.gcard .art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.gcard .fmt-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 3;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  padding: 5px 11px;
  border-radius: 9px;
  color: var(--tx-2);
}
.gcard .quick {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 3;
  display: flex;
  gap: 6px;
  opacity: 0;
  transition: 0.15s;
  transform: translateY(-3px);
}
.gcard:hover .quick {
  opacity: 1;
  transform: none;
}
.qbtn.fav-on {
  color: var(--lime);
  border-color: rgba(212, 248, 75, 0.4);
}
/* Product name as a readable pill at the card's bottom-left (glass chip, matches the format badges),
   so it stays legible over any image instead of low-contrast text on a gradient. */
.gcard .label {
  position: absolute;
  left: 10px;
  bottom: 10px;
  max-width: calc(100% - 20px);
  z-index: 2;
  padding: 8px 14px;
  border-radius: 100px;
  background: rgba(var(--bg-rgb), 0.72);
  backdrop-filter: blur(8px);
  border: 1px solid var(--glass-line);
  color: var(--tx);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.gal-more {
  grid-column: 1 / -1;
  display: flex;
  justify-content: center;
  padding: 20px 0;
}
.empty-msg {
  color: var(--tx-3);
  text-align: center;
  padding: 60px 0;
  font-size: 14px;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Toolbar actions stay compact (form submits elsewhere use .btn-block). */
.adbar .btn {
  flex: none;
  white-space: nowrap;
}

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

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

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

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

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

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

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

/* Right-side toolbar group: the primary lime "Invite user" plus the lower-emphasis, deliberately
   separate "Invite admin" action (.btn-ghost base + the compact .btn-op modifier). */
.adbar-r {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

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

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

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

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

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

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

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

/* The kebab dropdown is absolutely positioned and must escape the table's clip. Admin rows have no
   hover fill, so dropping the clip has no visual cost on the rounded corners. */
.dtbl.admins {
  overflow: visible;
}

.dtbl.invites .dhead,
.dtbl.invites .drow {
  grid-template-columns: 2.2fr 1fr 1.2fr 1fr 1.4fr;
  gap: 12px;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.st.super {
  color: var(--focus);
  border-color: rgba(169, 155, 255, 0.3);
  background: rgba(169, 155, 255, 0.08);
}

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

/* Compact management-action buttons (admin console: admins / invites / drawer members). */
.admin-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  justify-self: end;
}

.btn.btn-xs {
  height: 30px;
  padding: 0 11px;
  font-size: 12.5px;
  border-radius: 8px;
}

.btn-xs.danger {
  color: var(--bad);
  border-color: var(--bad-dim);
}

.btn-xs.danger:hover {
  background: var(--bad-tint);
}

/* Armed (second click confirms) - filled red so "Confirm" reads as the point of no return. Dark
   text (--on-lime) on the --bad fill for AA contrast, matching the .sv-del.arm precedent. */
.btn-xs.danger.arm {
  color: var(--on-lime);
  background: var(--bad);
  border-color: var(--bad);
}

/* Non-destructive btn-xs arms lime (go/positive), mirroring .kebab-item.arm; destructive arms red
   above. Keeps a reversible action (e.g. Deactivate) visually distinct from an irreversible one
   (Delete) sitting beside it, and gives the neutral armed state a fill (else it would be invisible). */
.btn-xs.arm:not(.danger) {
  color: var(--on-lime);
  background: var(--lime);
  border-color: var(--lime);
}

/* Kebab overflow menu - per-admin management actions (Platform admins table). Keeps rows uniform
   no matter how many actions a row has. */
.kebab {
  position: relative;
}

.kebab-btn {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--tx-2);
  cursor: pointer;
}

.kebab-btn:hover {
  background: var(--surface-2);
  color: var(--tx);
}

.kebab-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: var(--z-dropdown);
  min-width: 176px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-2);
}

.kebab-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 32px;
  padding: 0 10px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--tx);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

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

.kebab-item.danger {
  color: var(--bad);
}

.kebab-item.danger:hover {
  background: var(--bad-tint);
}

/* Armed confirm state (second click fires). Non-destructive actions arm lime (go/positive);
   destructive ones arm red (point of no return). Dark text on both fills for AA contrast. */
.kebab-item.arm {
  color: var(--on-lime);
  background: var(--lime);
}

.kebab-item.danger.arm {
  color: var(--on-lime);
  background: var(--bad);
}

/* Thin divider that fences the irreversible "Delete permanently" item off from the softer actions
   above it, so a permanent delete reads as its own zone rather than one more red row in the list. */
.kebab-sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--line);
}

/* Explains why a last-active-super row's menu is intentionally sparse (only Reset 2FA). */
.kebab-note {
  padding: 6px 10px 2px;
  color: var(--tx-3);
  font-size: 11.5px;
}

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

.dr-member-r {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  flex-shrink: 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.dr-member {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  /* Wrap so the action group drops onto its own line in the narrow (~318px) mobile drawer instead of
     forcing horizontal overflow; on the wide drawer it stays one line. */
  flex-wrap: wrap;
}

/* The email is a direct flex child, so it needs min-width:0 for its ellipsis to engage (default
   min-width:auto is content-sized and would never truncate); flex-grow lets it eat the free space. */
.dr-member > .u-mail {
  flex: 1 1 auto;
  min-width: 0;
}

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

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

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

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

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

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

.dr-grant-form .btn {
  flex: none;
  white-space: nowrap;
  padding: 0 16px;
}

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

.inv-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* The submit uses .btn-block, whose `flex: 1` is meant for horizontal button rows; in this COLUMN
   it stretches the button vertically and breaks its fixed 40px height (misaligned vs the inputs
   above). Pin it back so it matches the inputs. */
.inv-form .btn-block {
  flex: 0 0 auto;
}

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

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

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

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

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

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

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

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

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

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

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

.drawer.show {
  transform: none;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.kd b {
  font-weight: 600;
}

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

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

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

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

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

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

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

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

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

/* Second (cost) series for the grouped Overview trend chart. Violet reads clearly against the
   panel (surface-2 was ~1.08:1 and effectively invisible). No border, so a 0-height bar paints
   nothing (a bordered zero-height box would leave a misleading baseline tick). */
.chart .bar.cost {
  background: var(--violet);
}
/* A real but sub-proportional cost day gets a fixed 3px marker so "no cost" and "tiny cost" are
   visually distinct; the honest magnitude lives in the caption under the chart, not the height. */
.chart .bar.cost.tick {
  height: 3px !important;
}

/* Daily variant: slim two-bar columns instead of a handful of wide monthly bars. The column count
   follows the 7/30/90 picker, so at 90 days the min-width bars exceed the panel - scroll instead of
   spilling out of bounds. */
.chart.daily {
  gap: 4px;
  overflow-x: auto;
}
.chart.daily .bars {
  gap: 2px;
}
.chart.daily .bar {
  width: 100%;
  min-width: 3px;
  max-width: 9px;
  border-radius: 3px 3px 0 0;
}
@media (max-width: 640px) {
  .chart.daily {
    gap: 2px;
  }
  .chart.daily .bars {
    gap: 1px;
  }
  /* Keep daily bars readable on a phone rather than 3px slivers; the strip scrolls past ~30 days. */
  .chart.daily .bar {
    min-width: 4px;
  }
}

/* Panel legend (chart series key). */
.legend {
  display: flex;
  gap: 16px;
  font-size: 11.5px;
  color: var(--tx-2);
}
.legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lg-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}
.lg-dot.lg-cost {
  background: var(--violet);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Plan-edit drawer footer. Deliberately NOT .dr-actions - demo_requests.html uses that name
   for its row action cell, and the equal-specificity collision leaked flex-end + margin there. */
.pe-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 10px;
}

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

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

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

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

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

/* ---------- guide page ---------- */
.guide {
  max-width: 940px;
  margin: 0 auto;
  padding: 28px 24px 48px;
}

.guide .g-sec {
  margin-bottom: 34px;
}

.guide .g-h {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  margin: 0 0 14px;
}

.guide .g-card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--space-5);
  color: inherit;
  text-decoration: none;
}

.guide a.g-card {
  transition: border-color 0.15s ease;
}

.guide a.g-card:hover {
  border-color: var(--lime-dim);
}

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

.guide .g-grid2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}

.guide .g-ic {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--lime);
  margin-bottom: 12px;
}

.guide .g-card h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16.5px;
  margin: 0 0 10px;
}

.guide .g-steps {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  color: var(--tx-2);
  font-size: 13.5px;
  line-height: 1.5;
}

.guide .g-steps li::marker {
  color: var(--lime);
  font-weight: 600;
}

.guide .g-list {
  margin: 0;
  padding-left: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--tx-2);
  font-size: 13.5px;
  line-height: 1.5;
}

.guide .g-list li::marker {
  color: var(--tx-3);
}

.guide .g-link {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--lime);
  text-decoration: none;
}

.guide .g-link:hover {
  text-decoration: underline;
}

@media (max-width: 900px) {
  .guide .g-tools,
  .guide .g-grid2 {
    grid-template-columns: 1fr;
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.nav-backdrop {
  display: none;
}

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

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

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

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

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

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

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

@media (max-width: 640px) {
  .kpis {
    grid-template-columns: 1fr;
  }
  /* Charts: shorter on a phone, and never let a chart shove the page sideways. The monthly-growth
     chart (plain .chart, fixed-width bars, no scroll of its own) gets slimmer bars + a scroll
     fallback; the daily chart already scrolls. */
  .chart,
  .chart-empty {
    height: 150px;
  }
  .chart {
    gap: 8px;
    overflow-x: auto;
  }
  .chart .bar {
    width: 18px;
  }
  /* Recent-signups row: email on its own line (was ellipsized in a cramped 3-col), plan + date
     below. */
  .su-row {
    grid-template-columns: 1fr auto;
    gap: 4px 10px;
  }
  .su-mail {
    grid-column: 1 / -1;
    white-space: normal;
  }
  .gal {
    grid-template-columns: 1fr;
  }
  /* Saved product/service cards in the add-entity modal: one per row on a phone (were cramped 2-up
     in a ~360px modal). */
  .saved-grid {
    grid-template-columns: 1fr;
  }
  /* Generate bar stacks full-width so the note input keeps a usable width (flex-wrap alone lets
     the flex:1 describe collapse to ~0). Canvas gets extra bottom clearance for the taller bar. */
  .gbar {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .gbar > .pc-wrap,
  .gbar > .describe,
  .gbar > .fmt-wrap,
  .gbar > .gen-btn {
    width: 100%;
  }
  .pc-wrap .prod-chip {
    width: 100%;
  }
  /* Stacked column: restore the note input to its natural slot (the 768 two-row order does not
     apply once everything is full-width). */
  .tool-upload .gbar > .describe {
    order: 0;
  }
  .canvas {
    padding-bottom: 286px;
  }
  .empty-state {
    min-height: calc(100vh - 60px - 16px - 286px);
    padding-bottom: 20px;
  }
}

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

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

/* The block above only ties (and beats by order) the outline:none rules at EQUAL specificity.
   These selectors outrank the element-level ring, so they need explicit counterparts or their
   keyboard focus is invisible. */
.copy-edit textarea:focus-visible,
.cta-select:focus-visible,
.billing .tu-slider:focus-visible,
.gallery .search input:focus-visible,
.adbar .search input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Screen-reader-only text (the visible skeletons are aria-hidden decoration). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Manual busy state for fetch-based forms (htmx-request never fires there - login). The dim
   comes from the disabled attribute set alongside it - one opacity for every unavailable button. */
.btn.busy {
  pointer-events: none;
}
.btn.busy .spinner-sm {
  display: inline-block;
}

/* Custom chevron so selects match the hand-drawn icon language instead of the OS arrow.
   The data URI cannot read CSS variables - the stroke is --tx-3's literal value (#7c7365). */
select.input,
.cta-select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%237c7365' stroke-width='2.5'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
}

/* Minimal app footer under the content column (legal lives on the landing page too). */
.app-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 18px 28px;
  border-top: 1px solid var(--line);
  color: var(--tx-3);
  font-size: 12px;
}
.app-foot-links {
  display: flex;
  gap: 18px;
}
.app-foot-links a {
  color: var(--tx-3);
  text-decoration: none;
  transition: color var(--dur-base) var(--ease);
}
.app-foot-links a:hover {
  color: var(--tx-2);
}
