/* ================================================================
   TARGETED PRACTICE — search + select ARENA exercises to drill

   Mounts under <main id="page-targeted-practice"> in index.html.
   Controller: targeted-practice/targeted-practice.js.

   Two modes:
     - SEARCH (default): search card + selected card with static
       readiness bars per item + Submit button.
     - REVIEW (after Submit): search card hidden, selected card
       renamed "Practice results", each item's bar animates
       before→after, per-item Colab action + Ready badge appear,
       Back-to-search button replaces Submit.

   Bar styling re-uses the .stats-bar / .stats-bar-fill /
   .target-difficulty-delta classes from stats/render.css +
   practice/bars.css so the look matches the rest of the app.
   ================================================================ */

.tp-card {
  background: linear-gradient(180deg, var(--panel), var(--panel-deep));
  border: 1px solid rgb(var(--tint-rgb) / calc(0.12 * var(--tint-k)));
  border-radius: 14px;
  padding: 20px 22px;
  margin-bottom: 18px;
  color: var(--white);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* targeted-practice.css loads after components.css, so its `display: flex`
   on .tp-card / .tp-submit-btn / .tp-back-btn would otherwise win over the
   global `.hidden { display: none }`. Re-assert display:none for our own
   elements so adding the `hidden` class actually hides them. */
.tp-card.hidden,
.tp-submit-btn.hidden,
.tp-back-btn.hidden,
.tp-banner.hidden { display: none; }

/* ---- Guest banner (below topbar, persists across tabs) ----
   Shown to anyone not logged in. Markup in index.html; toggled by
   app.js updateTabVisibility(). Mirrors the .tp-banner layout. */
.guest-banner.hidden { display: none; }

.guest-banner {
  display: block;
  background: linear-gradient(90deg,
    rgb(var(--info-rgb) / calc(0.18 * var(--wash-k))),
    rgb(var(--ok-rgb) / calc(0.14 * var(--wash-k))));
  border-bottom: 1px solid rgb(var(--info-rgb) / calc(0.42 * var(--wash-k)));
  color: var(--white);
}

.guest-banner-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 9px 22px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.guest-banner-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--info);
  box-shadow: 0 0 0 4px rgb(var(--info-rgb) / 0.18);
  flex: 0 0 auto;
}

.guest-banner-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--info);
}

/* Basis, not `auto`: on `auto` the sentence asks for its full content width,
   which alone overflows the row, so the button wrapped onto a line of its own
   under the text. A shrinkable basis keeps both on one line and lets the text
   take whatever the button doesn't. */
.guest-banner-meta {
  font-size: 13px;
  color: var(--color-muted);
  flex: 1 1 320px;
  min-width: 0;
}
.guest-banner-meta strong { color: var(--white); font-weight: 700; }

/* Continue-with-Google button (GIS-rendered) sitting inline in the banner.

   Two different things can land in here and only one of them is ours to
   style. Signed out of Google, GIS renders an HTML button and honours the
   theme/shape we pass in app.js (a blue pill). Signed IN to Google it
   renders the personalised "Continue as <name>" widget inside a
   cross-origin FedCM iframe (accounts.google.com/gsi/button, allow=
   identity-credentials-get) — a white, square-cornered card we cannot
   reach into: no selector, no theme, no border-radius of ours applies to
   its contents. So we shape the box it arrives in: the pill radius rounds
   off the white card's square corners so it stops reading as a stray white
   rectangle dropped on the dark banner, and matches the signed-out pill. */
.guest-banner-google {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  min-height: 40px;
  width: fit-content;
  /* Far right of the banner row — it is the one thing in here to act on. */
  margin-left: auto;
  border-radius: 999px;
  overflow: hidden;
  /* Shadow only, no ring: the white card is already the highest-contrast
     thing in the banner, and a light ring around the signed-out blue pill
     reads as a stray outline. */
  box-shadow: 0 2px 10px rgb(0 0 0 / 0.35);
}
/* GIS nests the button (or the iframe) two divs deep; every wrapper has to
   carry the radius or the white card's corners survive the clip. */
.guest-banner-google > div,
.guest-banner-google > div > div,
.guest-banner-google iframe {
  border-radius: inherit;
  overflow: hidden;
}

.guest-banner-btn {
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 7px;
  border: 1px solid transparent;
  background: var(--info);
  color: var(--on-accent);
  cursor: pointer;
  white-space: nowrap;
}
.guest-banner-btn:hover { filter: brightness(1.12); }
.guest-banner-btn-ghost {
  background: rgb(var(--well-rgb) / calc(0.18 * var(--well-k)));
  border-color: rgb(var(--tint-rgb) / calc(0.28 * var(--tint-k)));
  color: var(--white);
}
.guest-banner-btn-ghost:hover {
  background: rgb(var(--well-rgb) / calc(0.32 * var(--well-k)));
  border-color: rgb(var(--tint-rgb) / calc(0.45 * var(--tint-k)));
}

/* ---- Global Targeted Practice mode banner ----
   Lives below the topbar (outside <main>) so it persists across tab
   switches. Shown by targeted-practice.js whenever the student has an
   active targeted-practice session. Click End → switch back to the
   Targeted Practice tab and enter review mode. */

.tp-banner {
  display: block;
  background: linear-gradient(90deg,
    rgb(var(--ok-rgb) / calc(0.18 * var(--wash-k))),
    rgb(var(--info-rgb) / calc(0.18 * var(--wash-k))));
  border-bottom: 1px solid rgb(var(--ok-rgb) / calc(0.45 * var(--wash-k)));
  color: var(--white);
}

.tp-banner-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 9px 22px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.tp-banner-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 4px rgb(var(--ok-rgb) / 0.18);
  flex: 0 0 auto;
  animation: tp-banner-pulse 2s ease-in-out infinite;
}

@keyframes tp-banner-pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgb(var(--ok-rgb) / 0.18); }
  50%      { box-shadow: 0 0 0 7px rgb(var(--ok-rgb) / 0.08); }
}

.tp-banner-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ok);
}

.tp-banner-meta {
  font-size: 13px;
  color: var(--color-muted);
  flex: 1 1 auto;
  min-width: 0;
}

.tp-banner-end {
  font-family: inherit;
  font-size: 12px;
  padding: 6px 14px;
  border-radius: 7px;
  border: 1px solid rgb(var(--tint-rgb) / calc(0.28 * var(--tint-k)));
  background: rgb(var(--well-rgb) / calc(0.18 * var(--well-k)));
  color: var(--white);
  cursor: pointer;
  white-space: nowrap;
}
.tp-banner-end:hover {
  background: rgb(var(--well-rgb) / calc(0.32 * var(--well-k)));
  border-color: rgb(var(--tint-rgb) / calc(0.45 * var(--tint-k)));
}

.tp-search-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.tp-search-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.tp-search-input {
  flex: 1 1 auto;
  padding: 11px 14px;
  font-size: 14px;
  font-family: inherit;
  border-radius: 9px;
  border: 1px solid rgb(var(--tint-rgb) / calc(0.18 * var(--tint-k)));
  background: rgb(var(--tint-rgb) / calc(0.04 * var(--tint-k)));
  color: var(--white);
  outline: none;
}

.tp-search-input::placeholder {
  color: var(--muted-dim);
}

.tp-search-input:focus {
  border-color: rgb(var(--ok-rgb) / 0.6);
  background: rgb(var(--tint-rgb) / calc(0.07 * var(--tint-k)));
}

.tp-search-clear {
  padding: 0 14px;
  border-radius: 9px;
  border: 1px solid rgb(var(--tint-rgb) / calc(0.18 * var(--tint-k)));
  background: rgb(var(--tint-rgb) / calc(0.04 * var(--tint-k)));
  color: var(--color-muted);
  cursor: pointer;
  font-size: 14px;
  font-family: inherit;
}
.tp-search-clear:hover { background: rgb(var(--tint-rgb) / calc(0.1 * var(--tint-k))); color: var(--white); }

.tp-results-wrap {
  position: relative;
}

.tp-results-hint {
  font-size: 12px;
  color: var(--color-muted);
  padding: 8px 4px;
}

.tp-results-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 380px;
  overflow-y: auto;
  border-radius: 10px;
  border: 1px solid rgb(var(--tint-rgb) / calc(0.1 * var(--tint-k)));
  background: rgb(var(--well-rgb) / calc(0.18 * var(--well-k)));
}

.tp-results-list:empty { display: none; }

.tp-result-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid rgb(var(--tint-rgb) / calc(0.06 * var(--tint-k)));
  cursor: pointer;
  user-select: none;
}

.tp-result-item:last-child { border-bottom: none; }

.tp-result-item:hover {
  background: rgb(var(--tint-rgb) / calc(0.06 * var(--tint-k)));
}

.tp-result-checkbox {
  margin: 0;
  cursor: pointer;
  accent-color: rgb(var(--ok-rgb) / 0.85);
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

.tp-result-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}

.tp-result-title {
  font-size: 13px;
  color: var(--white);
  font-weight: 500;
  line-height: 1.35;
  word-break: break-word;
}

.tp-result-sub {
  font-size: 11px;
  color: var(--color-muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.tp-result-item.tp-result-selected {
  background: rgb(var(--ok-rgb) / 0.10);
}
.tp-result-item.tp-result-selected:hover { background: rgb(var(--ok-rgb) / 0.16); }

/* mark — highlight match substring inside result titles. */
.tp-result-title mark {
  background: rgb(var(--ok-rgb) / 0.22);
  color: inherit;
  padding: 0 1px;
  border-radius: 3px;
}

/* ---- Selected list ---- */

.tp-selected-card {
  gap: 10px;
}

.tp-selected-header {
  display: flex;
  align-items: center;
  gap: 10px;
}

.tp-selected-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.tp-selected-count {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgb(var(--ok-rgb) / 0.12);
  color: var(--ok);
  border: 1px solid rgb(var(--ok-rgb) / 0.45);
}

.tp-selected-empty {
  font-size: 12px;
  color: var(--color-muted);
  padding: 8px 4px;
}
.tp-selected-empty.hidden { display: none; }

.tp-selected-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tp-selected-list:empty { display: none; }

.tp-selected-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 8px;
  background: rgb(var(--tint-rgb) / calc(0.04 * var(--tint-k)));
  border: 1px solid rgb(var(--tint-rgb) / calc(0.1 * var(--tint-k)));
}

.tp-selected-item-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.tp-selected-item-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.tp-selected-item-title {
  font-size: 13px;
  color: var(--white);
  font-weight: 500;
  word-break: break-word;
}

.tp-selected-item-sub {
  font-size: 11px;
  color: var(--color-muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.tp-selected-remove {
  border: 1px solid rgb(var(--danger-rgb) / 0.45);
  background: rgb(var(--danger-rgb) / 0.10);
  color: var(--danger);
  border-radius: 7px;
  padding: 4px 10px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
}
.tp-selected-remove:hover { background: rgb(var(--danger-rgb) / 0.22); }

/* ---- Per-item readiness bar ----
   .tp-bar-row layout mirrors the .stats-bar / .stats-bar-track rows in
   stats/render.css. The bar height + track styling come from the global
   .stats-bar-* rules; we just add layout + width here. */

.tp-bar-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
}

/* Override the global .stats-bar-track defaults (120px width, overflow
   hidden) — we want a full-width track so the marker lines for old/new
   can hang out without being clipped. */
.tp-bar-row .tp-bar-track {
  position: relative;
  width: 100%;
  height: 10px;
  overflow: visible;
}

.tp-bar-value {
  font-size: 12px;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- Review-mode per-item action row ---- */

.tp-selected-item-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 4px;
}

.tp-ready-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgb(var(--ok-rgb) / 0.18);
  color: var(--ok);
  border: 1px solid rgb(var(--ok-rgb) / 0.55);
}

.tp-not-ready-hint {
  font-size: 11px;
  color: var(--color-muted);
  flex: 1 1 auto;
  min-width: 0;
}

.tp-action-practice {
  font-size: 12px;
  font-family: inherit;
  padding: 7px 14px;
  border-radius: 8px;
  text-decoration: none;
  border: 1px solid rgb(var(--tint-rgb) / calc(0.18 * var(--tint-k)));
  background: rgb(var(--tint-rgb) / calc(0.05 * var(--tint-k)));
  color: var(--white);
  cursor: pointer;
  white-space: nowrap;
  margin-left: auto;
}
.tp-action-practice:hover {
  background: rgb(var(--tint-rgb) / calc(0.1 * var(--tint-k)));
  border-color: rgb(var(--tint-rgb) / calc(0.28 * var(--tint-k)));
}

/* Ready exercises get a stronger Colab CTA + left accent on the row. */
.tp-selected-item.tp-selected-ready {
  border-left: 3px solid rgb(var(--ok-rgb) / 0.7);
}
.tp-selected-ready .tp-action-practice {
  background: rgb(var(--ok-rgb) / 0.18);
  border-color: rgb(var(--ok-rgb) / 0.55);
  color: var(--white);
}
.tp-selected-ready .tp-action-practice:hover {
  background: rgb(var(--ok-rgb) / 0.32);
}

/* ---- Submit / Back footer ---- */

.tp-submit-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
  gap: 8px;
}

.tp-submit-btn,
.tp-back-btn {
  padding: 11px 22px;
  font-size: 14px;
  border-radius: 10px;
}

.tp-submit-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* In review mode, the submit row aligns the back button left so it
   reads as a "leave" affordance rather than a primary CTA. */
.tp-review-mode .tp-submit-row {
  justify-content: flex-start;
}

@media (max-width: 600px) {
  /* Too narrow to hold the sentence and the button on one row, so the button
     wraps under it — flush left with the text, not stranded on the right. */
  .guest-banner-google { margin-left: 0; }
  .tp-card { padding: 16px 14px; }
  .tp-submit-row { justify-content: stretch; flex-direction: column; }
  .tp-submit-btn, .tp-back-btn { width: 100%; }
  .tp-action-practice { margin-left: 0; width: 100%; text-align: center; }
}
