/*
 * Custom styles that extend or patch layout.css.
 * Tailwind is pre-compiled — add missing utilities and component overrides here.
 */

/* ── Course-creator utilities (values not in the precompiled bundle) ──── */

.text-\[\#ff492c\]   { color: #ff492c; }
.text-\[\#0f766e\]   { color: #0f766e; }
.text-\[\#9ca3af\]   { color: #9ca3af; }
.text-\[\#cbd5e1\]   { color: #cbd5e1; }
.bg-\[\#f7faff\]     { background-color: #f7faff; }
.border-\[\#dbeafe\] { border-color: #dbeafe; }
.max-w-\[460px\]     { max-width: 460px; }
.pr-16               { padding-right: 4rem; }
.stroke-\[3\]        { stroke-width: 3; }
.leading-normal      { line-height: 1.5; }
.m-0                 { margin: 0; }
.text-ellipsis       { text-overflow: ellipsis; }
.no-underline        { text-decoration: none; }

/* ── Marketplace utilities (not present in precompiled layout.css) ─────── */

/* Course info strip: flex-wrap so a hidden cell (e.g. non-mobile-friendly
   course) never leaves an empty grid track. Internal dividers drawn via
   borders + negative margins clipped by the container's overflow-hidden,
   so they stay correct for any cell count. */
.info-strip { display: flex; flex-wrap: wrap; }
.info-strip > * {
  flex: 1 1 50%;                 /* mobile: 2 per row, lone last cell grows to fill */
  border-left: 1px solid hsl(var(--border));
  border-top: 1px solid hsl(var(--border));
  margin-left: -1px;
  margin-top: -1px;
}
@media (min-width: 1024px) { .info-strip > * { flex: 1 1 0; } }  /* lg: single row, equal width */

/* size-N (alias of w-N + h-N) */
.size-3 { width: 0.75rem; height: 0.75rem; }
.size-3\.5 { width: 0.875rem; height: 0.875rem; }
.size-6 { width: 1.5rem; height: 1.5rem; }
.size-7 { width: 1.75rem; height: 1.75rem; }
.size-8 { width: 2rem; height: 2rem; }
.size-9 { width: 2.25rem; height: 2.25rem; }
.size-10 { width: 2.5rem; height: 2.5rem; }
.size-12 { width: 3rem; height: 3rem; }
.size-14 { width: 3.5rem; height: 3.5rem; }
.size-16 { width: 4rem; height: 4rem; }

/* sm: variants missing from layout.css */
@media (min-width: 640px) {
  .sm\:block        { display: block; }
  .sm\:inline-flex  { display: inline-flex; }
  .sm\:grid-cols-2  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* letter-spacing step missing from layout.css (uppercase micro-labels) */
.tracking-wide { letter-spacing: 0.025em; }

/* hover variants missing from layout.css (Prime awareness banner) */
.hover\:bg-white\/90:hover { background-color: rgb(255 255 255 / 0.9); }
.hover\:bg-primary-foreground\/10:hover { background-color: hsl(var(--primary-foreground) / 0.1); }

/* Print: when .printing-receipt is on <body>, hide every direct child of body
   (including <main> and the open <dialog>'s top-layer paint) and show only
   the cloned receipt container the Stimulus controller injected. Without the
   clone, the dialog's top-layer would print a second copy of the receipt
   on top of any in-page copy. */
@media print {
  body.printing-receipt > *                        { display: none !important; }
  body.printing-receipt > #receipt-print-container { display: block !important; padding: 32px 40px; }
}

/* Marketplace-checkout cart row layout — flexbox-based so column widths are
   predictable. On mobile each cell stacks. On sm+ they line up horizontally
   with fixed widths for thumb / price / qty / total / trash and a flexible
   course column that consumes whatever's left. */
.mp-checkout-row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: stretch;
}
@media (min-width: 640px) {
  .mp-checkout-row {
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
  }
  .mp-cell-thumb  { width: 40px;  flex-shrink: 0; }
  .mp-cell-course { flex: 1 1 0;  min-width: 0; }
  .mp-cell-price  { width: 72px;  flex-shrink: 0; text-align: right; }
  .mp-cell-qty    { width: 110px; flex-shrink: 0; display: flex; justify-content: center; }
  .mp-cell-total  { width: 80px;  flex-shrink: 0; text-align: right; }
  .mp-cell-trash  { width: 32px;  flex-shrink: 0; text-align: right; }
}

/* Two-col checkout page: main column (1fr) + sticky summary (360px) on lg+ */
.mp-checkout-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
@media (min-width: 1024px) {
  .mp-checkout-grid { grid-template-columns: minmax(0, 1fr) 360px; }
}

/* Cart-page row: 4-column grid (info / seats / price / remove) on sm+,
   stacked on mobile. The same grid is used by the column header so cells
   line up. */
.mp-cart-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
}
@media (min-width: 640px) {
  .mp-cart-grid {
    grid-template-columns: minmax(0, 1fr) 130px 130px 40px;
    gap: 1rem;
    align-items: center;
  }
}

/* Billing + Payment side-by-side inside the left column on md+ */
.mp-checkout-billing-payment {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}
@media (min-width: 768px) {
  .mp-checkout-billing-payment { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Saved-card row: highlights when its inner radio is :checked. */
.mp-saved-card { transition: border-color 120ms, background-color 120ms; }
.mp-saved-card:has(input[type="radio"]:checked) {
  border-color: hsl(var(--primary));
  background-color: hsl(var(--primary) / 0.05);
}

.bg-muted\/40 { background-color: hsl(var(--muted) / 0.4); }
.text-\[10px\] { font-size: 10px; }
.text-\[11px\] { font-size: 11px; }
.text-\[34px\] { font-size: 34px; }
.min-h-\[88px\] { min-height: 88px; }
.min-h-\[260px\] { min-height: 260px; }
.w-\[150px\] { width: 150px; }
.w-\[170px\] { width: 170px; }
.w-\[180px\] { width: 180px; }
.max-w-\[120px\] { max-width: 120px; }
@media (max-width: 1279px) { .max-xl\:hidden { display: none; } }
@media (max-width: 1299px) { .max-\[1299px\]\:hidden { display: none; } }
@media (min-width: 1024px) { .lg\:hidden { display: none; } }
@media (min-width: 1024px) { .lg\:table-cell, .hidden.lg\:table-cell { display: table-cell; } }
@media (min-width: 1280px) { .xl\:hidden { display: none; } .xl\:min-w-\[900px\] { min-width: 900px; } }
.border-t-2 { border-top-width: 2px; }
.sm\:min-w-\[200px\] { }
.sm\:max-w-\[300px\] { }
.sm\:min-w-\[600px\] { }
.sm\:max-w-\[720px\] { }
.sm\:min-w-\[800px\] { }
.sm\:max-w-\[960px\] { }
@media (min-width: 640px) {
  .sm\:min-w-\[200px\] { min-width: 200px; }
  .sm\:max-w-\[300px\] { max-width: 300px; }
  .sm\:min-w-\[600px\] { min-width: 600px; }
  .sm\:max-w-\[720px\] { max-width: 720px; }
  .sm\:min-w-\[800px\] { min-width: 800px; }
  .sm\:max-w-\[960px\] { max-width: 960px; }
}

/* Marketplace-checkout extras (not in precompiled bundle) */
.ring-primary\/15        { --tw-ring-color: hsl(var(--primary) / 0.15); }
.border-primary\/15      { border-color: hsl(var(--primary) / 0.15); }
.bg-primary-foreground\/15 { background-color: hsl(var(--primary-foreground) / 0.15); }
.border-x {
  border-left-width: 1px;
  border-left-style: solid;
  border-right-width: 1px;
  border-right-style: solid;
}

/* sided padding */
.pr-10 { padding-right: 2.5rem; }

/* select chrome reset */

/* centred-icon helpers */
.top-1\/2 { top: 50%; }
.-translate-y-1\/2 {
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x, 0), -50%);
}

/* One keyboard focus ring everywhere: the 2px --ring with a 2px gap that
   ui_button already draws. Elements that set their own focus style keep it.
   Firefox shows its native ring instead: Tailwind's :-moz-focusring rule in
   layout.css has the same specificity and loads later. */
:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
}
/* --ring is 1.8:1 on the navy sidebar; white is 11:1. */
[data-sidebar="sidebar"] :focus-visible {
  outline-color: hsl(var(--sidebar-ring));
}

/* focus styling */
.focus\:outline-none:focus { outline: 2px solid transparent; outline-offset: 2px; }
.focus\:ring-2:focus {
  --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width, 0px) var(--tw-ring-offset-color, #fff);
  --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width, 0px)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), 0 0 #0000;
}
.focus\:ring-primary\/30:focus { --tw-ring-color: hsl(var(--primary) / 0.30); }
.focus\:ring-primary\/50:focus { --tw-ring-color: hsl(var(--primary) / 0.50); }

/* color tokens with opacity (variations of layout.css's solid bg-primary, bg-success, etc.) */
.bg-primary\/5  { background-color: hsl(var(--primary) / 0.05); }
.bg-primary\/10 { background-color: hsl(var(--primary) / 0.10); }
.bg-primary\/15 { background-color: hsl(var(--primary) / 0.15); }
.bg-primary\/20 { background-color: hsl(var(--primary) / 0.20); }
.bg-primary\/40 { background-color: hsl(var(--primary) / 0.40); }
.bg-success\/10 { background-color: hsl(var(--success) / 0.10); }
.border-primary\/20 { border-color: hsl(var(--primary) / 0.20); }
.border-primary\/40 { border-color: hsl(var(--primary) / 0.40); }
.text-success { color: hsl(var(--success)); }
.text-destructive { color: hsl(var(--destructive)); }

/* hover states */
.hover\:bg-muted:hover { background-color: hsl(var(--muted)); }
.hover\:bg-primary\/5:hover  { background-color: hsl(var(--primary) / 0.05); }
.hover\:bg-primary\/15:hover { background-color: hsl(var(--primary) / 0.15); }
.hover\:bg-primary\/90:hover { background-color: hsl(var(--primary) / 0.90); }
.hover\:border-primary\/40:hover { border-color: hsl(var(--primary) / 0.40); }
.hover\:text-destructive:hover { color: hsl(var(--destructive)); }
.hover\:underline:hover { text-decoration-line: underline; }

/* line-clamp */
.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* responsive grid spans + widths used by marketplace pages */
@media (min-width: 1024px) {
  .lg\:hidden { display: none !important; }
  .lg\:col-span-1 { grid-column: span 1 / span 1; }
  .lg\:col-span-2 { grid-column: span 2 / span 2; }
  .lg\:col-span-3 { grid-column: span 3 / span 3; }
  .lg\:w-48 { width: 12rem; }
  .lg\:w-60 { width: 15rem; }
  .lg\:w-80 { width: 20rem; }
  .lg\:flex-shrink-0 { flex-shrink: 0; }
  .lg\:flex-row { flex-direction: row; }
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lg\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
@media (min-width: 1280px) {
  .xl\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .xl\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1536px) {
  .\32xl\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* arbitrary-value max-widths and aspect ratios used in marketplace pages */
.max-w-\[1600px\] { max-width: 1600px; }
.max-w-\[1400px\] { max-width: 1400px; }
.max-w-\[1200px\] { max-width: 1200px; }
.max-w-\[1100px\] { max-width: 1100px; }
.max-w-\[900px\]  { max-width: 900px; }
.max-w-\[720px\]  { max-width: 720px; }
.max-w-\[520px\]  { max-width: 520px; }
.max-w-\[380px\]  { max-width: 380px; }  /* cart drawer panel */
.aspect-\[16\/10\] { aspect-ratio: 16 / 10; }
.aspect-\[16\/8\]  { aspect-ratio: 16 / 8; }
.aspect-\[4\/3\]   { aspect-ratio: 4 / 3; }
.text-\[34px\]    { font-size: 34px; line-height: 2.5rem; }
/* Marketplace results busy state during a filter/search Turbo navigation. */
.mp-loading { opacity: 0.55; pointer-events: none; transition: opacity 0.15s ease; }
/* Course-detail enroll card (cover + price + buy). It's the 2nd column of
   .mp-hero-grid, so on a stacked mobile/tablet layout it would otherwise fall
   below the entire description/curriculum/FAQ column. Lift it above that
   content so the price and Add to Cart are reachable without a long scroll;
   restore source order (right column) on lg+. */
.mp-enroll-aside { order: -1; }
@media (min-width: 1024px) { .mp-enroll-aside { order: 0; } }
@media (min-width: 1024px) { .lg\:border-r { border-right-width: 1px; } }
@media (min-width: 1024px) { .lg\:border-b-0 { border-bottom-width: 0; } }
.min-h-\[280px\]   { min-height: 280px; }
.min-w-\[1\.25rem\] { min-width: 1.25rem; }
.max-h-56 { max-height: 14rem; }
.max-h-72 { max-height: 18rem; }

.m-auto {
  margin: auto;
}
.inline-block {
  display: inline-block;
}
.ul-padding {
  padding-inline-start: 20px;
}
.min-w-\[9rem\] {
  min-width: 9rem;
}

.bg-black\/10 {
  background-color: rgb(0 0 0 / 0.1);
}
.group:hover .group-hover\:bg-black\/0 {
  background-color: rgb(0 0 0 / 0);
}

.bg-green {
  background-color: rgb(16 185 129);
}
.bg-amber {
  background-color: rgb(245 158 11);
}
.bg-red {
  background-color: rgb(239 68 68);
}
.bg-blue {
  background-color: rgb(59 130 246);
}
.border-green {
  border-color: rgb(16 185 129);
}
.border-amber {
  border-color: rgb(245 158 11);
}
.border-red {
  border-color: rgb(239 68 68);
}
.border-blue {
  border-color: rgb(59 130 246);
}

.bg-primary\/90 {
  background-color: hsl(var(--primary) / 0.9);
}
.bg-destructive\/90 {
  background-color: hsl(var(--destructive) / 0.9);
}
.bg-success\/90 {
  background-color: hsl(var(--success) / 0.9);
}
.bg-warning\/90 {
  background-color: hsl(var(--warning) / 0.9);
}
.bg-info\/90 {
  background-color: hsl(var(--info) / 0.9);
}
.bg-foreground\/70 {
  background-color: hsl(var(--foreground) / 0.7);
}
.hover\:bg-foreground-hover:hover {
  background-color: hsl(var(--foreground) / 0.9);
}

/* White text on --destructive is 3.8:1, so solid red fills under white text
   (delete buttons, unread counts) use a darker red: 5.3:1, hover 6.5:1.
   Tints, badge dots and red text keep --destructive. */
:root {
  --destructive-solid: 0 40% 49%;
  --destructive-solid-hover: 0 40% 43%;
}
.bg-destructive.text-destructive-foreground,
.bg-destructive.text-white {
  background-color: hsl(var(--destructive-solid));
}
.text-destructive-foreground.hover\:bg-destructive\/90:hover,
.text-white.hover\:bg-destructive\/90:hover {
  background-color: hsl(var(--destructive-solid-hover));
}
.hover\:bg-success-hover:hover {
  background-color: #348f46;
}

/* Missing half-unit Tailwind utilities */
.bottom-2 { bottom: 0.5rem; }

.pb-10 { padding-bottom: 2.5rem; }

.bg-black { background-color: #000; }

/* Named-group hover (page wrapper uses bare `group`, so scope to the element) */
.group\/cover:hover .group-hover\/cover\:opacity-100 { opacity: 1; }
.gap-2\.5 { gap: 0.625rem; }
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) {
  margin-top: 0.625rem;
}
.py-3\.5 {
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}
.mb-1\.5 { margin-bottom: 0.375rem; }
.tracking-wider { letter-spacing: 0.05em; }

.p-1\.5 {
  padding: 0.375rem;
}
.p-3\.5 {
  padding: 0.875rem;
}
.px-3\.5 {
  padding-left: 0.875rem;
  padding-right: 0.875rem;
}
.pb-3\.5 {
  padding-bottom: 0.875rem;
}
.px-2\.5 {
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}
.py-0\.5 {
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
}
.pl-11 {
  padding-left: 2.75rem;
}
.h-1\.5 {
  height: 0.375rem;
}
.gap-1\.5 {
  gap: 0.375rem;
}
.mb-5 {
  margin-bottom: 1.25rem;
}
.mt-5 {
  margin-top: 1.25rem;
}
.rounded-xl {
  border-radius: 0.75rem;
}

.flash-enter {
  opacity: 0;
  transform: translateY(-12px);
  animation: flash-in 160ms ease-out forwards;
}
@keyframes flash-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.flash-out {
  opacity: 0;
  transform: translateY(-12px);
  transition:
    opacity 140ms ease,
    transform 140ms ease;
}

a[data-state='active'] .tab-badge,
button[data-active='true'] .tab-badge {
  background-color: hsl(var(--notification));
  color: hsl(var(--notification-foreground));
}
a[data-active='inactive'] .tab-badge,
button[data-active='false'] .tab-badge {
  background-color: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
}

details[open] > summary .details-chevron {
  transform: rotate(180deg);
}
.filter-summary::-webkit-details-marker { display: none; }
.filter-summary { list-style: none; }

input[type='submit']:not(:disabled),
input[type='button']:not(:disabled),
input[type='reset']:not(:disabled) {
  cursor: pointer;
}

/* ── Marketplace course-show page layout ────────────────────────────── */
/* Hero: left content + 400px enroll card on lg */
.mp-hero-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 1024px) {
  .mp-hero-grid { grid-template-columns: minmax(0, 1fr) 400px; }
}

/* Curriculum module row: number / title / play icon */
.mp-module-row {
  display: grid;
  gap: 1rem;
  align-items: center;
  grid-template-columns: 56px minmax(0, 1fr);
}
@media (min-width: 640px) {
  .mp-module-row { grid-template-columns: 56px minmax(0, 1fr) auto; }
}

/* Sticky offsets for elements that need to sit below the 57px admin header
   (desktop only — on mobile the columns stack and sticky is not desirable) */
@media (min-width: 1024px) {
  .mp-stick-below-header {
    position: sticky;
    top: 73px;
    /* When the enroll card is taller than the viewport (short laptop screens,
       courses with a cover image + bulk-pricing note + license counter), bound
       its height to the visible area and let it scroll internally. Without this
       the Add to Cart / Buy Now buttons sit below the fold and the user has to
       scroll the whole page to the very end before they appear. */
    max-height: calc(100vh - 73px - 1.5rem);
    overflow-y: auto;
  }
}
.mp-subnav-sticky {
  position: sticky;
  top: 57px;
  z-index: 30;
  background: hsl(var(--background) / 0.95);
  backdrop-filter: blur(8px);
}
.mp-subnav-link {
  position: relative;
  height: 100%;
  display: inline-flex;
  align-items: center;
  border-bottom: 2px solid transparent;
  transition: color 120ms ease, border-color 120ms ease;
}
.mp-subnav-link.subnav-link-active {
  color: hsl(var(--foreground));
  border-bottom-color: hsl(var(--primary));
}

/* Scroll-margin so anchored sections clear the sticky sub-nav (~57+48=105px) */
.scroll-mt-20 { scroll-margin-top: 7rem; }

/* Solid warning/info fills (only -/15 etc. are precompiled) */
.bg-warning { background-color: hsl(var(--warning)); }
.bg-info { background-color: hsl(var(--info)); }

/* Tiny gap utility used by inline star rows */
.gap-0\.5 { gap: 0.125rem; }

/* FAQ accordion (native <details>): rotate chevron when open */
.mp-faq-item summary { list-style: none; }
.mp-faq-item summary::-webkit-details-marker { display: none; }
.mp-faq-item .mp-faq-chevron { transition: transform 200ms ease; }
.mp-faq-item[open] .mp-faq-chevron { transform: rotate(180deg); }

.sidebar-panel {
  width: 70vw;
  transform: translateX(-100%);
  transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.sidebar-panel.is-open {
  transform: translateX(0);
}

@media (min-width: 768px) {
  .sidebar-panel {
    width: var(--sidebar-width);
    max-width: none;
    transform: translateX(0);
  }
  .md\:grid-cols-courses {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(48px, auto);
  }
}
@media (min-width: 1280px) {
  .md\:grid-cols-courses {
    grid-template-columns: minmax(200px, 2fr) 120px 120px 120px 120px 60px;
  }
}

@media (min-width: 640px) {
  .sm\:flex-row {
    flex-direction: row;
  }
  .sm\:items-center {
    align-items: center;
  }
}

@media (max-width: 639px) {
  .progress-stats-grid {
    grid-template-columns: 1fr !important;
  }
  .page-title {
    font-size: 1.5rem !important;
  }
  .notification-panel {
    position: fixed !important;
    top: 57px !important;
    left: 0.5rem !important;
    right: 0.5rem !important;
    width: auto !important;
    max-width: none !important;
    margin-top: 0 !important;
  }
  body:has(.admin-viewing-bar) .notification-panel {
    top: 114px !important;
  }
}

.scrollable-content {
  border: none;
  overflow-y: auto;
  max-height: calc(100vh - 500px);
  min-height: 240px;
}

dialog {
  color: hsl(var(--foreground));
}
dialog:-internal-dialog-in-top-layer::backdrop {
  background-color: rgb(0 0 0 / 0.6);
}

.modal-title {
  padding-inline: 2.5rem;
}
@media (min-width: 640px) {
  .modal-title {
    padding-left: 0;
  }
}

.text-neutral-tertiary {
  color: hsl(var(--secondary));
}
.fill-brand {
  fill: hsl(var(--primary));
}

.settings-tab-wrapper {
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
}
/* Tab bars (ui_tabs_list). overflow-x:auto (for horizontal tab scroll) forces
   overflow-y to auto, which shows a phantom vertical scrollbar for the 1px the
   active-tab underline sits below the row — so pin overflow-y and hide the bar.
   No compiled Tailwind utility exists for scrollbar-width/overflow-y-hidden. */
.ui-tabs-list {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.ui-tabs-list::-webkit-scrollbar {
  display: none;
}
.ui-tabs-list > a {
  flex-shrink: 0;
}
/* A tab bar clips anything painted outside it (see above), so a tab's focus
   ring is drawn inside the bar: flush top and bottom, 4px out into the gap at
   the sides, with 4px kept free at both ends of the bar. */
.ui-tab:first-child {
  margin-left: 4px;
}
.ui-tab:last-child {
  margin-right: 4px;
}
.ui-tab:focus-visible {
  outline: none;
}
.ui-tab:focus-visible::before {
  content: "";
  position: absolute;
  inset: 0 -4px;
  border: 2px solid hsl(var(--ring));
  border-radius: 4px;
  pointer-events: none;
}

/* ── Setup wizard ────────────────────────────────────────────────────── */

.setup-wizard-card-bg {
  background-image: linear-gradient(
    to bottom right,
    hsl(var(--primary) / 0.03),
    hsl(var(--background)),
    hsl(var(--accent) / 0.03)
  );
}

.setup-wizard-step[data-active='true'] {
  border-color: hsl(var(--primary) / 0.2);
  box-shadow: var(--shadow-sm);
}
.setup-wizard-step:not([data-active='true']):hover {
  border-color: hsl(var(--primary) / 0.1);
  box-shadow: var(--shadow-sm);
}

.setup-wizard-step-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 220ms cubic-bezier(0.4, 0, 0.2, 1);
}
.setup-wizard-step-body[data-expanded='true'] {
  grid-template-rows: 1fr;
}
.setup-wizard-step-body > div {
  overflow: hidden;
}

.setup-wizard-step-enter {
  animation: wizard-step-enter 0.3s ease-out both;
}
.setup-wizard-progress-bar {
  animation: wizard-progress-fill 0.7s cubic-bezier(0.4, 0, 0.2, 1) both;
}
.setup-wizard-step-check {
  animation: wizard-check-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.setup-wizard-trophy {
  animation: wizard-trophy-in 0.65s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.setup-wizard-leaving {
  animation: wizard-leave 0.25s ease-in forwards;
  pointer-events: none;
}

.setup-wizard-step-title {
  position: relative;
  display: inline-block;
}
.setup-wizard-step-title::after {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  height: 1px;
  width: 0;
  background: currentColor;
  opacity: 0.7;
  animation: wizard-strike 0.4s ease-out forwards;
  animation-delay: 0.2s;
}

@keyframes wizard-step-enter {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes wizard-progress-fill {
  from {
    width: 0%;
  }
  to {
    width: var(--wizard-progress, 0%);
  }
}
@keyframes wizard-check-pop {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
@keyframes wizard-strike {
  to {
    width: 100%;
  }
}
@keyframes wizard-leave {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(-6px) scale(0.98);
  }
}
@keyframes wizard-trophy-in {
  0% {
    transform: scale(0) rotate(-20deg);
    opacity: 0;
  }
  60% {
    transform: scale(1.2) rotate(6deg);
    opacity: 1;
  }
  80% {
    transform: scale(0.92) rotate(-2deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
    opacity: 1;
  }
}

/* Marketplace course-card meta chips (parity with coggno-app .middle_area_item) */
.mp-meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--card));
  border-radius: 6px;
  font-size: 12px;
  line-height: 1;
  color: hsl(var(--foreground));
  white-space: nowrap;
}
.mp-meta-chip-top-author {
  background-color: #fff3d6;
  border-color: #ffd97a;
  color: #8a5a00;
  font-weight: 600;
}
.mp-meta-chip-bestseller {
  background-color: #fdecd1;
  border-color: #f6c878;
  color: #8a5a00;
  font-weight: 600;
}

/* Coggno Prime toggle switch (parity with coggno-app .toggle-switch) */
.mp-toggle-switch {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
  flex-shrink: 0;
}
.mp-toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.mp-toggle-switch .mp-toggle-slider {
  position: absolute;
  inset: 0;
  background-color: hsl(var(--muted-foreground) / 0.4);
  border-radius: 999px;
  transition: background-color 0.2s ease;
  cursor: pointer;
}
.mp-toggle-switch .mp-toggle-slider::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background-color: #fff;
  border-radius: 50%;
  transition: transform 0.2s ease;
}
.mp-toggle-switch input:checked + .mp-toggle-slider {
  background-color: hsl(var(--primary));
}
.mp-toggle-switch input:checked + .mp-toggle-slider::before {
  transform: translateX(16px);
}

/* ── Certificate template upload card ─────────────────────────────────── */

.cert-grid {
  margin-top: 14px;
  padding: 14px;
  background: #f7faff;
  border: 1px solid #dbeafe;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cert-file {
  display: flex;
  align-items: center;
  gap: 12px;
}

.cert-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: #edf2fe;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.cert-dropzone {
  border: 1.5px dashed #cbd5e1;
  background: #fff;
  border-radius: 8px;
  padding: 18px 16px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.cert-help {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

@media (max-width: 640px) {
  .cert-file,
  .cert-dropzone {
    flex-wrap: wrap;
  }
  .cert-file > .flex-1,
  .cert-dropzone > .flex-1 {
    flex-basis: calc(100% - 52px);
  }
}

/* needs-license label: word shows only on cards wide enough for it; count always shows */
.needs-license-label { display: none; }
@media (min-width: 640px)  { .needs-license-label { display: inline; } }
@media (min-width: 1024px) { .needs-license-label { display: none; } }
@media (min-width: 1280px) { .needs-license-label { display: inline; } }

/* needs-license pill: solid amber, desktop only (mobile uses the line under the cards) */
.needs-license-pill {
  display: none;
  align-items: center;
  gap: 0.25rem;
  background-color: hsl(var(--warning));
  color: hsl(var(--warning-foreground));
  transition:
    transform 200ms cubic-bezier(0.25, 0.1, 0.25, 1),
    box-shadow 200ms cubic-bezier(0.25, 0.1, 0.25, 1),
    filter 200ms ease;
}
@media (min-width: 768px) { .needs-license-pill { display: inline-flex; } }
.needs-license-pill:hover {
  transform: scale(1.03);
  box-shadow: 0 3px 10px -3px hsl(var(--warning) / 0.5);
  filter: brightness(0.96);
}
.needs-license-pill:active {
  transform: scale(0.97);
  filter: brightness(0.9);
  transition-duration: 90ms;
}
@media (prefers-reduced-motion: reduce) {
  .needs-license-pill { transition: none; }
  .needs-license-pill:hover,
  .needs-license-pill:active { transform: none; }
}
/* ==========================================================================
   Phase 1 learner/admin UI — custom rules (relocated from layout.css, which is
   the precompiled Tailwind bundle and must stay read-only per CLAUDE.md).
   Body-class scoped, so specificity keeps them winning over Tailwind utilities
   regardless of stylesheet order.
   ========================================================================== */

/* Whole-app text colour palette (Figma Web-Redesign, per Natalia): body/labels
   #555770, titles #1a1a2e. Captions keep layout.css's --muted-foreground
   (#6a7181, 4.9:1 on white); the Figma #9599ad is 2.8:1. Applied via `html body`
   (no wrapper class) so it wins over layout.css's own `body { color }` — which
   loads after application.css. The base FONT (Inter, 14px, weight 400) and
   heading font already come from layout.css `body` / `h1-h6`, so they are not
   repeated. */
html body {
  color: #555770;
  --foreground: 240 28% 14%;       /* #1a1a2e */
}
html body h1,
html body h2,
html body h3,
html body h4,
html body h5,
html body h6 {
  color: #1a1a2e;
}
.text-label {
  color: #555770;
}

/* iOS Safari auto-zooms when a focused input's font is < 16px. The UI runs a
   sub-16px scale, so bump form controls to 16px on phones only — no effect on
   the desktop design. */
@media (max-width: 640px) {
  body input,
  body select,
  body textarea {
    font-size: 16px;
  }
}

/* Topbar client logo (was inline style) and narrow-screen adjustments so the
   bell/avatar/logo group and course-row thumbnails fit at 320-479px. */
body header .topbar-logo {
  max-height: 28px;
  max-width: 130px;
  width: auto;
  display: block;
}
@media (max-width: 639px) {
  body header .topbar-actions {
    gap: 0.5rem;
  }
  body.learner-app header .topbar-logo {
    max-width: 90px;
  }
  /* Admin hides the client logo + divider on phones so the actions row fits.
     (Handled here, not with sm: utilities — sm:block isn't in the precompiled
     Tailwind bundle.) */
  body.admin-app header .topbar-logo,
  body.admin-app header .topbar-divider {
    display: none;
  }
}
@media (max-width: 479px) {
  body.learner-app .course-row-thumb {
    width: 5rem;
  }
}

/* Any user-provided text (course titles, names, group names) may contain words
   wider than a phone screen. overflow-wrap is inherited, so this one rule lets
   text break anywhere instead of widening the page; white-space: nowrap
   elements (buttons, badges, tabs) are unaffected. */
body main {
  overflow-wrap: anywhere;
}

/* white-space: nowrap elements can't render squeezed text — keep them at
   natural width so the flexible sibling (wrapping text) shrinks instead. */
body main .whitespace-nowrap {
  flex-shrink: 0;
}

/* Tables opt out of overflow-wrap: anywhere — with it, auto table layout
   compresses columns into letter-stacks instead of engaging the horizontal
   scroll wrapper. break-word still guards width-capped cells. */
body main table {
  overflow-wrap: break-word;
}
body main .wrap-anywhere {
  overflow-wrap: anywhere;
}

/* Admin course/license hero media: fixed 280px column beside the info column
   on desktop; stacks above it at full width on phones. */
body.admin-app .course-hero-media {
  width: 280px;
  min-width: 280px;
  min-height: 210px;
}
@media (max-width: 767px) {
  body.admin-app .course-hero {
    flex-direction: column;
  }
  body.admin-app .course-hero-media {
    width: 100%;
    min-width: 0;
    min-height: 0;
    height: 180px;
  }
}

/* missing from the precompiled Tailwind bundle */
.cursor-help {
  cursor: help;
}

/* Instant CSS tooltip (native title tooltips have an unfixable browser delay).
   Usage: <span data-tooltip="text" tabindex="0"> — shows on hover and keyboard focus. */
[data-tooltip] {
  position: relative;
}
[data-tooltip]:hover::after,
[data-tooltip]:focus::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translate(-50%, -6px);
  background: hsl(var(--foreground));
  color: hsl(var(--background));
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  width: max-content;
  max-width: min(300px, 80vw);
  white-space: normal;
  z-index: 50;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* info tips sit in a z-10 layer under the fixed sidebar: open rightwards, away from it */
.info-tip[data-tooltip]:hover::after,
.info-tip[data-tooltip]:focus::after {
  left: 0;
  transform: translate(-1rem, -6px);
}
/* small screens: anchor to the icon's left edge so the bubble can't clip off-screen */
@media (max-width: 640px) {
  [data-tooltip]:hover::after,
  [data-tooltip]:focus::after {
    left: 0;
    transform: translate(-2rem, -6px);
  }
}

/* Course progress (ui_course_progress) */
.progress-steps { display: flex; gap: 3px; width: 100%; }
.progress-step { flex: 1; position: relative; overflow: hidden; border-radius: 9999px; background: hsl(var(--secondary)); }
.progress-step > i { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 9999px; background: hsl(var(--chart)); }
.progress-step-open { background: hsl(var(--chart) / 0.5); }
.progress-steps.is-complete .progress-step { background: hsl(var(--success)); }
.progress-steps.is-failed .progress-step { background: hsl(var(--destructive)); }
.progress-slot { width: 100%; }
@media (min-width: 640px) {
  .progress-slot { width: 10rem; flex-shrink: 0; }
  .progress-slot-wide { width: 15rem; }
}

/* Grid gaps and top margin missing from the compiled bundle (certificate verification page). */
.gap-x-4 { column-gap: 1rem; }
.gap-y-3 { row-gap: 0.75rem; }
.mt-10 { margin-top: 2.5rem; }
.col-span-2 { grid-column: span 2 / span 2; }
