/* ==========================================================================
   Library Reader - Courses
   --------------------------------------------------------------------------
   Additive and namespaced. Every selector is scoped under .crs so nothing here
   can leak into the existing (S) reader.

   THEMING: this file never hardcodes a palette. It reads the host app's CSS
   custom properties and falls back to sane values only if they are absent, so
   light/dark comes free from whatever the app already does. If your token names
   differ from the guesses below, override the eight --crs-* values in ONE place
   (see "Host token bridge") and the whole thing re-themes.
   ========================================================================== */

/* --- Host token bridge -----------------------------------------------------
   Maps the app's tokens onto ours. var() chains try several common names, then
   fall back to a literal. Edit ONLY this block if your app uses other names. */
.crs {
  --crs-bg:        var(--bg, var(--background, var(--color-bg, #fbfbfd)));
  --crs-surface:   var(--bg-card, #ffffff);            /* app token: glass card */
  --crs-text:      var(--text, var(--fg, var(--color-text, #16161a)));
  --crs-muted:     var(--text-secondary, #6b6b76);     /* app token is --text-secondary */
  --crs-border:    var(--border, var(--rule, var(--color-border, rgba(0,0,0,.10))));
  --crs-accent:    var(--accent, var(--primary, var(--color-accent, #3d5afe)));
  --crs-accent-fg: var(--accent-contrast, #fff);       /* app has no such token; #fff is right on --accent */
  --crs-shadow:    var(--shadow-md, 0 1px 2px rgba(0,0,0,.04), 0 8px 24px -12px rgba(0,0,0,.18));
  --crs-shadow-lg: var(--shadow-lg, 0 2px 4px rgba(0,0,0,.05), 0 24px 48px -20px rgba(0,0,0,.28));

  --crs-radius: 16px;
  --crs-radius-sm: 10px;
  --crs-gap: clamp(12px, 2.4vw, 20px);
  --crs-pad: clamp(16px, 4vw, 32px);
  --crs-maxw: 780px;

  --crs-ease: cubic-bezier(.22,.61,.36,1);
  --crs-ease-spring: cubic-bezier(.34,1.42,.44,1);
  --crs-dur: 380ms;

  color: var(--crs-text);
}

/* Dark-mode fallback ONLY for apps that have no tokens of their own. If the
   host defines --bg/--text, the chain above already returned the right values
   and these never apply, because we only touch the fallback literals. */
@media (prefers-color-scheme: dark) {
  .crs {
    --crs-bg:      var(--bg, var(--background, var(--color-bg, #0e0e11)));
    --crs-surface: var(--bg-card, #17171c);        /* app token */
    --crs-text:    var(--text, var(--fg, var(--color-text, #ecedf1)));
    --crs-muted:   var(--text-secondary, #9a9aa6); /* app token */
    --crs-border:  var(--border, var(--rule, var(--color-border, rgba(255,255,255,.12))));
    --crs-shadow:    var(--shadow-md, 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7));
    --crs-shadow-lg: var(--shadow-lg, 0 2px 4px rgba(0,0,0,.45), 0 24px 48px -20px rgba(0,0,0,.8));
  }
}
/* Explicit theme hooks, whichever convention the app uses. */
[data-theme="dark"] .crs, .theme-dark .crs, .dark .crs, html.dark .crs {
  --crs-bg:      var(--bg, #0e0e11);
  --crs-surface: var(--bg-card, #17171c);        /* app token */
  --crs-text:    var(--text, #ecedf1);
  --crs-muted:   var(--text-secondary, #9a9aa6); /* app token */
  --crs-border:  var(--border, rgba(255,255,255,.12));
  --crs-shadow:    var(--shadow-md, 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7));
  --crs-shadow-lg: var(--shadow-lg, 0 2px 4px rgba(0,0,0,.45), 0 24px 48px -20px rgba(0,0,0,.8));
}

.crs *, .crs *::before, .crs *::after { box-sizing: border-box; }
.crs img { max-width: 100%; height: auto; }

/* ==========================================================================
   1. Shelf
   ========================================================================== */

.crs-shelf { padding: var(--crs-pad); max-width: 1180px; margin-inline: auto; }

.crs-shelf-head { margin: 0 0 clamp(16px, 3vw, 28px); }
.crs-shelf-head h1 {
  margin: 0 0 6px; font-size: clamp(1.5rem, 4.5vw, 2rem);
  letter-spacing: -.02em; font-weight: 700;
}
.crs-shelf-head p { margin: 0; color: var(--crs-muted); font-size: .95rem; }

/* Search */
.crs-search { position: relative; margin: 18px 0 4px; }
.crs-search input {
  width: 100%; padding: 12px 14px 12px 40px;
  font: inherit; font-size: .95rem; color: var(--crs-text);
  background: var(--crs-surface);
  border: 1px solid var(--crs-border); border-radius: 999px;
  transition: border-color 160ms var(--crs-ease), box-shadow 160ms var(--crs-ease);
}
.crs-search input:focus {
  outline: none; border-color: var(--crs-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--crs-accent) 22%, transparent);
}
.crs-search svg {
  position: absolute; left: 14px; top: 50%; translate: 0 -50%;
  width: 16px; height: 16px; opacity: .5; pointer-events: none;
}

.crs-grid {
  display: grid; gap: var(--crs-gap); margin-top: 22px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));
}

/* --- Course card --- */
.crs-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--crs-surface);
  border: 1px solid var(--crs-border);
  border-radius: var(--crs-radius);
  overflow: hidden; cursor: pointer;
  text-align: left; font: inherit; color: inherit; padding: 0;
  box-shadow: var(--crs-shadow);
  transition: transform var(--crs-dur) var(--crs-ease-spring),
              box-shadow var(--crs-dur) var(--crs-ease),
              border-color 200ms var(--crs-ease);
  /* Staggered entrance, index set inline by JS as --i */
  animation: crs-rise 520ms var(--crs-ease) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}
.crs-card:hover, .crs-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--crs-shadow-lg);
  border-color: color-mix(in srgb, var(--crs-accent) 35%, var(--crs-border));
  outline: none;
}
.crs-card:active { transform: translateY(-1px) scale(.995); }

/* Generated cover. Hues come from the index (deterministic per course), so a
   course always looks like itself without shipping any image assets. */
.crs-cover {
  position: relative; aspect-ratio: 16 / 9; display: grid; place-items: center;
  background:
    radial-gradient(120% 130% at 12% 8%,  hsl(var(--h1) 78% 62%) 0%, transparent 58%),
    radial-gradient(120% 120% at 92% 92%, hsl(var(--h2) 76% 52%) 0%, transparent 60%),
    linear-gradient(135deg, hsl(var(--h1) 62% 44%), hsl(var(--h2) 66% 34%));
  isolation: isolate;
}
/* Fine grain so the gradient reads as a surface, not a CSS default. */
.crs-cover::after {
  content: ""; position: absolute; inset: 0; z-index: 1; opacity: .16;
  background-image: radial-gradient(rgba(255,255,255,.9) .5px, transparent .5px);
  background-size: 4px 4px; mix-blend-mode: overlay;
}
.crs-cover-glyph {
  position: relative; z-index: 2;
  font-size: clamp(2.1rem, 7vw, 2.9rem); font-weight: 800; letter-spacing: -.04em;
  color: rgba(255,255,255,.94);
  text-shadow: 0 2px 18px rgba(0,0,0,.3);
  transition: transform var(--crs-dur) var(--crs-ease-spring);
}
.crs-card:hover .crs-cover-glyph { transform: scale(1.07) rotate(-2deg); }

.crs-cover-badge {
  position: absolute; z-index: 2; top: 10px; right: 10px;
  padding: 4px 9px; border-radius: 999px;
  font-size: .68rem; font-weight: 600; letter-spacing: .02em;
  color: rgba(255,255,255,.95);
  background: rgba(0,0,0,.28);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

.crs-card-body { padding: 14px 15px 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.crs-card-provider {
  font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--crs-muted);
}
.crs-card-title {
  margin: 0; font-size: 1.02rem; font-weight: 650; line-height: 1.3; letter-spacing: -.01em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.crs-card-meta {
  margin-top: auto; padding-top: 10px;
  display: flex; align-items: center; gap: 10px;
  font-size: .78rem; color: var(--crs-muted);
}

/* --- Progress ring --- */
.crs-ring { width: 30px; height: 30px; flex: none; transform: rotate(-90deg); }
.crs-ring circle { fill: none; stroke-width: 3.5; }
.crs-ring .crs-ring-track { stroke: var(--crs-border); }
.crs-ring .crs-ring-fill {
  stroke: var(--crs-accent); stroke-linecap: round;
  stroke-dasharray: var(--circ); stroke-dashoffset: var(--circ);
  animation: crs-ring-fill 900ms var(--crs-ease) 220ms forwards;
}
.crs-ring-label {
  font-variant-numeric: tabular-nums; font-weight: 600; color: var(--crs-text);
}

/* --- Progress bar --- */
.crs-bar { height: 4px; border-radius: 999px; background: var(--crs-border); overflow: hidden; }
.crs-bar > i {
  display: block; height: 100%; border-radius: inherit;
  background: linear-gradient(90deg, hsl(var(--h1) 70% 55%), hsl(var(--h2) 70% 50%));
  width: 0; animation: crs-bar-grow 900ms var(--crs-ease) 200ms forwards;
}

/* ==========================================================================
   2. Course view
   ========================================================================== */

.crs-course { padding-bottom: 64px; }

.crs-hero {
  position: relative; padding: clamp(22px, 5vw, 40px) var(--crs-pad) clamp(20px, 4vw, 30px);
  color: #fff; overflow: hidden;
  background:
    radial-gradient(120% 150% at 10% 0%,  hsl(var(--h1) 78% 58%) 0%, transparent 60%),
    radial-gradient(110% 130% at 95% 100%, hsl(var(--h2) 74% 46%) 0%, transparent 62%),
    linear-gradient(140deg, hsl(var(--h1) 60% 38%), hsl(var(--h2) 64% 28%));
  animation: crs-hero-in 620ms var(--crs-ease) both;
}
.crs-hero::after {
  content: ""; position: absolute; inset: 0; opacity: .14;
  background-image: radial-gradient(rgba(255,255,255,.9) .5px, transparent .5px);
  background-size: 4px 4px; pointer-events: none;
}
.crs-hero-inner { position: relative; z-index: 1; max-width: var(--crs-maxw); margin-inline: auto; }
.crs-hero .crs-card-provider { color: rgba(255,255,255,.78); }
.crs-hero h1 {
  margin: 4px 0 10px; font-size: clamp(1.5rem, 5.4vw, 2.25rem);
  letter-spacing: -.025em; line-height: 1.15; font-weight: 720;
}
.crs-hero-desc {
  margin: 0 0 16px; max-width: 62ch; font-size: .95rem; line-height: 1.6;
  color: rgba(255,255,255,.88);
}
.crs-hero-stats { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; font-size: .82rem; color: rgba(255,255,255,.9); }
.crs-hero .crs-bar { background: rgba(255,255,255,.22); margin-top: 14px; }
.crs-hero .crs-bar > i { background: rgba(255,255,255,.95); }

.crs-back {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,.16); color: #fff;
  border: 1px solid rgba(255,255,255,.22); border-radius: 999px;
  padding: 6px 13px 6px 10px; font: inherit; font-size: .82rem; font-weight: 550;
  cursor: pointer; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  transition: background 180ms var(--crs-ease), transform 180ms var(--crs-ease);
}
.crs-back:hover { background: rgba(255,255,255,.26); transform: translateX(-2px); }
.crs-back svg { width: 14px; height: 14px; }

/* --- Sections accordion --- */
.crs-sections { max-width: var(--crs-maxw); margin: clamp(18px, 4vw, 28px) auto 0; padding-inline: var(--crs-pad); }

.crs-section {
  border: 1px solid var(--crs-border); border-radius: var(--crs-radius);
  background: var(--crs-surface); margin-bottom: 12px; overflow: hidden;
  animation: crs-rise 460ms var(--crs-ease) both;
  animation-delay: calc(var(--i, 0) * 55ms);
}

.crs-section-head {
  width: 100%; display: flex; align-items: center; gap: 12px;
  min-height: 48px; padding: 15px 16px; background: none; border: 0; cursor: pointer;
  font: inherit; color: inherit; text-align: left;
  transition: background 160ms var(--crs-ease);
}
.crs-section-head:hover { background: color-mix(in srgb, var(--crs-text) 4%, transparent); }
.crs-section-head:focus-visible { outline: 2px solid var(--crs-accent); outline-offset: -2px; }
.crs-section-title { flex: 1; font-weight: 620; font-size: .98rem; letter-spacing: -.01em; }
.crs-section-count { font-size: .78rem; color: var(--crs-muted); font-variant-numeric: tabular-nums; }
.crs-chevron {
  width: 18px; height: 18px; flex: none; color: var(--crs-muted);
  transition: transform var(--crs-dur) var(--crs-ease-spring);
}
.crs-section[open] .crs-chevron, .crs-section.is-open .crs-chevron { transform: rotate(90deg); }

/* 0fr -> 1fr animates to auto height without measuring. */
.crs-section-panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--crs-dur) var(--crs-ease-spring);
}
.crs-section.is-open .crs-section-panel { grid-template-rows: 1fr; }
.crs-section-panel > div { overflow: hidden; }

.crs-group-title {
  padding: 12px 16px 6px; font-size: .74rem; font-weight: 650;
  letter-spacing: .07em; text-transform: uppercase; color: var(--crs-muted);
}

/* --- Module row --- */
.crs-mod {
  width: 100%; display: flex; align-items: center; gap: 12px;
  min-height: 44px; padding: 11px 16px; background: none; border: 0; border-top: 1px solid var(--crs-border);
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  transition: background 150ms var(--crs-ease), padding-left 200ms var(--crs-ease);
}
.crs-mod:hover { background: color-mix(in srgb, var(--crs-accent) 7%, transparent); padding-left: 20px; }
.crs-mod:focus-visible { outline: 2px solid var(--crs-accent); outline-offset: -2px; }
.crs-mod-title { flex: 1; font-size: .92rem; line-height: 1.4; }
.crs-mod.is-done .crs-mod-title { color: var(--crs-muted); text-decoration: line-through; text-decoration-thickness: 1px; }
.crs-mod.is-missing { opacity: .5; cursor: not-allowed; }
.crs-mod.is-missing:hover { background: none; padding-left: 16px; }

/* Checkbox. The visual box is 22px so the row stays compact, but the HIT area
   is expanded to 44px via a transparent ::before, meeting the WCAG 2.5.8 /
   Apple HIG minimum without making the list look chunky. */
.crs-check {
  position: relative;
  width: 22px; height: 22px; flex: none; border-radius: 7px;
  border: 1.5px solid var(--crs-border); background: transparent;
  display: grid; place-items: center; cursor: pointer; padding: 0;
  transition: background 200ms var(--crs-ease), border-color 200ms var(--crs-ease),
              transform 240ms var(--crs-ease-spring);
}
.crs-check::before {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; translate: -50% -50%;
  /* No background: invisible, but it is what the finger actually hits. */
}
.crs-check:hover { border-color: var(--crs-accent); transform: scale(1.12); }
.crs-check svg { width: 13px; height: 13px; color: var(--crs-accent-fg); stroke-dasharray: 20; stroke-dashoffset: 20; }
.crs-mod.is-done .crs-check { background: var(--crs-accent); border-color: var(--crs-accent); }
.crs-mod.is-done .crs-check svg { animation: crs-check-draw 340ms var(--crs-ease) forwards; }

/* ==========================================================================
   3. Module reader
   ========================================================================== */

.crs-reader { max-width: var(--crs-maxw); margin-inline: auto; padding: 0 var(--crs-pad) 96px; }

.crs-reader-head {
  padding: clamp(18px, 4vw, 28px) 0 16px;
  border-bottom: 1px solid var(--crs-border); margin-bottom: clamp(18px, 3vw, 26px);
  animation: crs-rise 420ms var(--crs-ease) both;
}
.crs-crumb {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: .78rem; color: var(--crs-muted); margin-bottom: 10px;
}
.crs-crumb button {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.crs-crumb button:hover { color: var(--crs-accent); }
.crs-reader-head h1 {
  margin: 0 0 12px; font-size: clamp(1.35rem, 4.6vw, 1.85rem);
  line-height: 1.25; letter-spacing: -.022em; font-weight: 700;
}
.crs-reader-actions { display: flex; flex-wrap: wrap; gap: 8px; }

.crs-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 999px; font: inherit; font-size: .85rem; font-weight: 550;
  border: 1px solid var(--crs-border); background: var(--crs-surface); color: var(--crs-text);
  cursor: pointer; text-decoration: none;
  transition: transform 180ms var(--crs-ease-spring), border-color 180ms var(--crs-ease), background 180ms var(--crs-ease);
}
.crs-btn:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--crs-accent) 45%, var(--crs-border)); }
.crs-btn svg { width: 15px; height: 15px; }
.crs-btn-primary { background: var(--crs-accent); border-color: var(--crs-accent); color: var(--crs-accent-fg); }
.crs-btn-primary:hover { filter: brightness(1.06); }

/* The prose surface. Deliberately close to the (S) reader so highlighting,
   dictionary and selection all behave identically. */
.crs-prose { font-size: 1.02rem; line-height: 1.72; animation: crs-fade 420ms var(--crs-ease) both; }
.crs-prose > *:first-child { margin-top: 0; }
.crs-prose h1, .crs-prose h2, .crs-prose h3, .crs-prose h4 {
  line-height: 1.3; letter-spacing: -.015em; margin: 1.9em 0 .55em; font-weight: 680;
}
.crs-prose h1 { font-size: 1.5rem; }
.crs-prose h2 { font-size: 1.26rem; }
.crs-prose h3 { font-size: 1.08rem; }
.crs-prose p { margin: 0 0 1.05em; }
.crs-prose ul, .crs-prose ol { margin: 0 0 1.05em; padding-left: 1.35em; }
.crs-prose li { margin: .35em 0; }
.crs-prose a { color: var(--crs-accent); text-underline-offset: 2px; }
.crs-prose strong { font-weight: 660; }
.crs-prose blockquote {
  margin: 1.3em 0; padding: .2em 0 .2em 1.1em;
  border-left: 3px solid color-mix(in srgb, var(--crs-accent) 55%, transparent);
  color: var(--crs-muted); font-style: italic;
}
.crs-prose code {
  font-size: .88em; padding: .16em .42em; border-radius: 5px;
  background: color-mix(in srgb, var(--crs-text) 8%, transparent);
}
.crs-prose pre {
  margin: 1.3em 0; padding: 14px 16px; overflow-x: auto; border-radius: var(--crs-radius-sm);
  background: color-mix(in srgb, var(--crs-text) 7%, transparent);
  border: 1px solid var(--crs-border);
}
.crs-prose pre code { background: none; padding: 0; }
.crs-prose hr { border: 0; border-top: 1px solid var(--crs-border); margin: 2em 0; }
.crs-prose img { border-radius: var(--crs-radius-sm); }
.crs-prose table { width: 100%; border-collapse: collapse; margin: 1.3em 0; font-size: .93rem; }
.crs-prose th, .crs-prose td { padding: 8px 10px; border: 1px solid var(--crs-border); text-align: left; }

/* Prev / next */
.crs-pager { display: flex; gap: 10px; margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--crs-border); }
.crs-pager .crs-btn { flex: 1; justify-content: center; }
.crs-pager .crs-btn[disabled] { opacity: .4; pointer-events: none; }

/* Sticky bottom bar: the one-tap "done and next" that makes this usable on a
   phone without scrolling back up. */
.crs-dockbar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; gap: 10px; align-items: center;
  margin: 26px calc(var(--crs-pad) * -1) 0; padding: 12px var(--crs-pad);
  background: color-mix(in srgb, var(--crs-bg) 88%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--crs-border);
  padding-bottom: max(12px, env(safe-area-inset-bottom));
}
.crs-dockbar .crs-btn { flex: 1; justify-content: center; }

/* --- States --- */
.crs-empty, .crs-loading { padding: 56px var(--crs-pad); text-align: center; color: var(--crs-muted); }
.crs-empty h2 { margin: 0 0 8px; color: var(--crs-text); font-size: 1.1rem; }
.crs-skel {
  border-radius: var(--crs-radius); background: var(--crs-border);
  animation: crs-pulse 1.5s ease-in-out infinite;
}
.crs-skel-card { aspect-ratio: 16/9; margin-bottom: 10px; }

/* ==========================================================================
   4. Keyframes
   ========================================================================== */

@keyframes crs-rise    { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes crs-fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes crs-hero-in { from { opacity: 0; transform: scale(1.03); } to { opacity: 1; transform: none; } }
@keyframes crs-pulse   { 0%,100% { opacity: .5; } 50% { opacity: .85; } }
@keyframes crs-ring-fill  { to { stroke-dashoffset: var(--offset); } }
@keyframes crs-bar-grow   { to { width: var(--pct, 0%); } }
@keyframes crs-check-draw { to { stroke-dashoffset: 0; } }

/* ==========================================================================
   5. Accessibility + responsive
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .crs *, .crs *::before, .crs *::after {
    animation-duration: 1ms !important; animation-delay: 0ms !important;
    transition-duration: 1ms !important;
  }
  /* Animated-to values must still be reached, not just skipped. */
  .crs-ring .crs-ring-fill { stroke-dashoffset: var(--offset); }
  .crs-bar > i { width: var(--pct, 0%); }
  .crs-mod.is-done .crs-check svg { stroke-dashoffset: 0; }
  .crs-card:hover { transform: none; }
}

.crs :where(button, a, input):focus-visible {
  outline: 2px solid var(--crs-accent); outline-offset: 2px; border-radius: 6px;
}
.crs-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 560px) {
  .crs-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 155px), 1fr)); gap: 12px; }
  .crs-card-title { font-size: .92rem; }
  .crs-cover-glyph { font-size: 1.9rem; }
}

/* Touch devices get no hover lift (it sticks after tap on iOS). */
@media (hover: none) {
  .crs-card:hover { transform: none; box-shadow: var(--crs-shadow); }
  .crs-mod:hover { padding-left: 16px; }
}
