/* ═══════════════════════════════════════════════════════════════
   Cadence full-screen conversation shell — Phase 2 of the Cadence
   launch sweep (docs/course-audit/00-cadence-launch-sweep-build-
   contract.md Section 8). One reusable shell, mounted once into
   #cadenceShellRoot on headspa-mastery.html, opened/closed via
   assets/js/cadence-shell.js.

   Uses the page's own design tokens (defined inline in
   headspa-mastery.html's :root and assets/css/aimt-design-system.css)
   rather than introducing new ones — restrained, quiet, institutional,
   matching the existing .checkpoint / #guidePanel surfaces.
   ═══════════════════════════════════════════════════════════════ */

#cadenceShellRoot {
  position: relative;
  z-index: 0;
}

/* Close-time focus return target (cadence-shell.js wireCheckpoint()):
   the checkpoint's own container gets tabIndex=-1 so focus can land
   there safely on close without joining the page's tab order. A
   restrained ring (matching the page's own text color) replaces the
   browser-default outline so this reads as intentional, not an
   accidental blue-ring artifact. */
.checkpoint:focus {
  outline: 2px solid var(--text, #262626);
  outline-offset: 3px;
  border-radius: 18px;
}

.cshell-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 18, 15, 0.42);
  opacity: 0;
  visibility: hidden;
  /* Slowed + eased for a more graceful arrival (Cadence polish pass, item
     3) -- was 0.22s ease, felt like an abrupt swap coming off the
     checkpoint card's own (also-slowed) entering transition. */
  transition: opacity 0.4s ease;
  z-index: 2490;
}
.cshell-overlay.show { opacity: 1; visibility: visible; }

.cshell {
  position: fixed;
  inset: 0;
  /* Above every other fixed/sticky surface in the page (.lesson-nav at
     100, #guidePanel at 300, #guideBtn at 200) but below the global
     #reviewModeBanner (3000), which must stay visible even while the
     shell is open. */
  z-index: 2500;
  background: var(--bg, #faf8f5);
  display: flex;
  flex-direction: column;
  transform: translateY(16px);
  opacity: 0;
  visibility: hidden;
  /* Slowed + eased for a more graceful arrival (Cadence polish pass, item
     3) -- was 0.22s ease/ease for both properties. */
  transition: opacity 0.45s cubic-bezier(0.16, 1, 0.3, 1), transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
  /* Dynamic viewport height keeps the shell correctly sized on mobile
     browsers whose chrome resizes on scroll, and shrinks to make room
     for the review-mode banner (see getPageChromeOffsetTop()) and an
     open on-screen keyboard. JS sets an explicit px height via
     --cshell-vh (updateViewportHeight()) and deliberately never sets it
     to 0 -- an unset value here correctly falls through to 100dvh. Do
     NOT add a `min-height: 100vh` floor here: it was tried and found to
     override the intentionally-smaller chrome-adjusted height,
     overflowing the composer past the bottom of the viewport (confirmed
     via 375x812 mobile QA) -- the JS guard is what actually prevents
     collapse, not a CSS floor.  */
  height: 100dvh;
  height: calc(var(--cshell-vh, 100dvh));
}
.cshell.open { opacity: 1; visibility: visible; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  .cshell-overlay, .cshell { transition: none; }
}

/* ── Tablet/desktop: focused "device" presentation (Cadence Phase 2A) ──
   Below 768px, Cadence stays true edge-to-edge full-screen (Section 4's
   mobile requirement — untouched above). At 768px and up, the goal is
   "entering a focused conversation environment," not a stretched browser
   overlay: the page dims behind a centered, phone-shaped conversation
   surface with an intentional, contained height — not full-bleed, not a
   generic modal. */
@media (min-width: 768px) {
  .cshell-overlay {
    /* Darker than the mobile/base value on purpose — on a full-bleed
       mobile screen there's no page left to dim, but here the dimmed
       page IS the point: it's what makes the centered card read as a
       deliberate "stage," not a floating card with a faint tint. */
    background: rgba(20, 18, 15, 0.6);
  }
  .cshell {
    inset: auto;
    top: 50%;
    left: 50%;
    width: min(440px, 92vw);
    /* Intentionally not full viewport height — a phone-like vertical
       silhouette, capped so it never becomes an oversized column on a
       tall monitor, floored by vh so it still fits a shorter laptop
       window. */
    height: min(860px, 88vh);
    /* var(--cshell-banner-nudge) shifts the centered card down to clear
       the global #reviewModeBanner when Review Mode is active (see
       getPageChromeOffsetTop() in cadence-shell.js) -- 0px the rest of
       the time, so this has no effect in production. */
    transform: translate(-50%, calc(-50% + var(--cshell-banner-nudge, 0px))) scale(0.97);
    border-radius: 32px;
    overflow: hidden;
    box-shadow: 0 30px 90px rgba(0, 0, 0, 0.35), 0 4px 24px rgba(0, 0, 0, 0.18);
    border: 0.5px solid rgba(255, 255, 255, 0.08);
  }
  .cshell.open {
    transform: translate(-50%, calc(-50% + var(--cshell-banner-nudge, 0px))) scale(1);
  }
}

/* ── Header ── */
.cshell-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(0.85rem + env(safe-area-inset-top, 0px)) 1.1rem 0.85rem;
  border-bottom: 0.5px solid var(--border, rgba(0,0,0,0.06));
  background: var(--white, #fff);
}
/* Cadence identity badge. .cshell-id is a plain flex wrapper (no shape,
   no fill) around the unified .cadence-id mark (assets/css/cadence-
   identity.css) -- .cadence-id-chip recolors the mark to a clean black
   line/dot treatment (no backing shape) so it reads on .cshell-head's
   own light background. The old wordmark span (.cshell-id-label) is
   gone too: it never fit inside the header in the first place and the
   approved layout doesn't call for a separate "Cadence" label next to
   the module title/status anyway. Static/resting only -- see cadence-
   shell.js's openCheckpoint()/openAskCadence() for why this header mark
   is never animated (the large Cadence Check card mark owns that). */
.cshell-id {
  display: flex; align-items: center; flex-shrink: 0;
}
.cshell-id .cadence-id { --cadence-id-size: 52px; }
.cshell-titles { min-width: 0; flex: 1; }
.cshell-module {
  font-family: var(--aimt-font-sans); font-size: 0.85rem; font-weight: 500;
  color: var(--text, #262626);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cshell-status {
  font-family: var(--aimt-font-sans); font-size: 0.68rem; color: var(--muted, #a3968d);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cshell-close {
  flex-shrink: 0;
  width: 34px; height: 34px; border-radius: 50%;
  background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted2, #c4bdb5);
  transition: background 0.15s, color 0.15s;
}
.cshell-close:hover { background: var(--surface, #f0ede8); color: var(--text, #262626); }
.cshell-close svg { width: 15px; height: 15px; }

.cshell-review-banner {
  flex-shrink: 0;
  display: none;
  align-items: center;
  gap: 8px;
  padding: 0.45rem 1.1rem;
  background: #fff4e8;
  color: #8b5e00;
  font-family: var(--aimt-font-sans);
  font-size: 0.72rem;
  font-weight: 500;
  border-bottom: 0.5px solid rgba(139,94,0,0.15);
}
.cshell.review-mode .cshell-review-banner { display: flex; }

.cshell-fixtures {
  display: none;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0.55rem 1.1rem;
  border-bottom: 0.5px solid var(--border, rgba(0,0,0,0.06));
  background: var(--surface, #f0ede8);
}
.cshell.review-mode .cshell-fixtures { display: flex; }
.cshell-fixture-btn {
  background: var(--white, #fff) !important;
  border: 0.5px solid var(--border2, rgba(0,0,0,0.09)) !important;
  border-radius: var(--aimt-radius-pill, 980px);
  padding: 0.28rem 0.7rem;
  font-family: var(--aimt-font-sans);
  font-size: 0.66rem;
  color: var(--muted, #a3968d);
  cursor: pointer;
}
.cshell-fixture-btn:hover, .cshell-fixture-btn.active { color: var(--text, #262626); border-color: var(--text, #262626) !important; }

/* ── Transcript ── */
.cshell-transcript {
  /* min-height:0 is load-bearing, not decorative: flex items default to
     min-height:auto (content-based), which for a tall transcript would
     otherwise stretch .cshell taller than the viewport and push the
     composer below the fold instead of letting this pane scroll
     internally. Confirmed via mobile-viewport QA (375x812). */
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 1.25rem 1.1rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.cshell-transcript-inner {
  max-width: 640px;
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.cshell-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0.9rem 0 0.3rem;
  font-family: var(--aimt-font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted2, #c4bdb5);
}
.cshell-divider::before, .cshell-divider::after {
  content: ''; flex: 1; height: 0.5px; background: var(--border2, rgba(0,0,0,0.09));
}

.cshell-msg { display: flex; gap: 9px; max-width: 100%; }
.cshell-msg.assistant { align-self: flex-start; }
.cshell-msg.user { align-self: flex-end; flex-direction: row-reverse; }
.cshell-msg-av {
  width: 34px; height: 34px; flex-shrink: 0; align-self: flex-end;
  display: flex; align-items: center; justify-content: center;
}
/* Same as .cshell-id above: .cadence-id-chip is a shapeless black-line
   mark, so the wrapper stays shapeless for the assistant case too.
   Static, never animated -- the large Cadence Check card mark is the
   one animated surface. User messages keep their own circular "You"
   chip (unrelated to the Cadence identity).
   24px (matching the wrapper's old size) rendered the mark's 3 rings +
   8 orbiting dots as a plain 1-2 concentric-circle blob -- the dots and
   inner rings are sub-pixel at that size and disappear under
   antialiasing, so all that's left to see is an outer ring + center
   dot: a bullseye/target, not "Cadence" (owner QA). Checked at 32px too
   -- still read as borderline/blob-like; 40px is where the ring of 8
   dots reliably reads as distinct from the outer ring rather than
   merging into it (verified against an isolated render, same geometry,
   at 24/32/36/40/52px side by side). A later pass found 40px slightly
   too large relative to the message text beside it (owner QA) -- 34px
   (re-verified against the same isolated render) is the modest
   reduction that still keeps every node legible; this is the floor for
   this context, not a return to the 24-32px range that read as a
   bullseye. #guideBtn's floating-pill mark and .cshell-id's header mark
   are separate contexts/sizes and are intentionally left at their own
   already-verified sizes (40px / 52px). */
.cshell-msg.assistant .cshell-msg-av .cadence-id { --cadence-id-size: 34px; }
.cshell-msg.user .cshell-msg-av { border-radius: 50%; background: var(--surface, #f0ede8); color: var(--muted, #a3968d); font-size: 0.6rem; font-weight: 500; font-family: var(--aimt-font-sans); }
.cshell-bub {
  padding: 0.7rem 0.95rem;
  border-radius: 16px;
  font-family: var(--aimt-font-sans);
  font-size: 0.875rem;
  line-height: 1.65;
  font-weight: 300;
  max-width: 82%;
  word-break: break-word;
  white-space: pre-wrap;
}
.cshell-msg.assistant .cshell-bub { background: var(--white, #fff); border: 0.5px solid var(--border, rgba(0,0,0,0.06)); color: var(--text, #262626); border-bottom-left-radius: 4px; }
.cshell-msg.user .cshell-bub { background: var(--teal2, #4d403a); color: #fff; border-bottom-right-radius: 4px; }
.cshell-bub p { margin: 0; }
.cshell-bub p + p { margin-top: 0.45rem; }

.cshell-kicker {
  font-family: var(--aimt-font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8a8078;
  margin: 0 0 0.35rem 33px;
}

.cshell-typing { display: flex; gap: 4px; align-items: center; padding: 0.1rem 0; }
.cshell-typing span { width: 5px; height: 5px; border-radius: 50%; background: var(--muted2, #c4bdb5); animation: cshellTyping 1.2s infinite; }
.cshell-typing span:nth-child(2) { animation-delay: .18s; }
.cshell-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes cshellTyping { 0%,80%,100% { transform: scale(1); opacity: .4; } 40% { transform: scale(1.4); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cshell-typing span { animation: none; opacity: .7; } }

/* ── Historical / read-only fallback card (Section 7) ── */
.cshell-fallback-card {
  align-self: stretch;
  max-width: 100%;
  border: 0.5px solid var(--border2, rgba(0,0,0,0.09));
  border-radius: var(--aimt-radius-md, 12px);
  background: var(--white, #fff);
  padding: 1rem 1.1rem;
}
.cshell-fallback-title {
  font-family: var(--aimt-font-sans); font-size: 0.78rem; font-weight: 600;
  color: var(--aimt-success, #3a5a3a); margin-bottom: 0.5rem;
  display: flex; align-items: center; gap: 6px;
}
.cshell-fallback-title svg { width: 13px; height: 13px; flex-shrink: 0; }
.cshell-fallback-label { font-family: var(--aimt-font-mono); font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted, #a3968d); margin: 0.6rem 0 0.2rem; }
.cshell-fallback-body { font-family: var(--aimt-font-sans); font-size: 0.85rem; line-height: 1.65; font-weight: 300; color: var(--text, #262626); }

/* ── Pass state banner ── */
.cshell-pass-banner {
  align-self: center;
  display: flex; align-items: center; gap: 7px;
  padding: 0.5rem 1rem;
  border-radius: var(--aimt-radius-pill, 980px);
  background: var(--aimt-success-light, #e8ede8);
  color: var(--aimt-success, #3a5a3a);
  font-family: var(--aimt-font-sans); font-size: 0.76rem; font-weight: 600;
  margin: 0.4rem 0;
}
.cshell-pass-banner svg { width: 13px; height: 13px; }

/* ── Composer ── */
.cshell-composer {
  flex-shrink: 0;
  border-top: 0.5px solid var(--border, rgba(0,0,0,0.06));
  background: var(--white, #fff);
  padding: 0.75rem 1.1rem calc(0.9rem + env(safe-area-inset-bottom, 0px));
}
.cshell-composer-inner {
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  gap: 8px;
  align-items: flex-end;
  background: var(--surface, #f0ede8);
  border-radius: var(--aimt-radius-md, 12px);
  padding: 8px 8px 8px 14px;
  transition: background 0.15s, border-color 0.15s;
  border: 0.5px solid transparent;
}
.cshell-composer-inner:focus-within { background: var(--white, #fff); border-color: rgba(0,0,0,0.15); }
.cshell-input {
  flex: 1;
  min-width: 0;
  background: none; border: none; outline: none; resize: none;
  font-family: var(--aimt-font-sans); font-size: 0.9rem; font-weight: 300;
  line-height: 1.55; color: var(--text, #262626);
  min-height: 24px; max-height: 168px; padding: 3px 0;
}
.cshell-input::placeholder { color: var(--muted2, #c4bdb5); }
.cshell-input[disabled] { opacity: 0.6; }
.cshell-send {
  width: 34px; height: 34px; border-radius: var(--aimt-radius-sm, 10px);
  background: #262626; border: none; color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  transition: background 0.15s, opacity 0.15s;
}
.cshell-send:disabled { background: var(--muted2, #c4bdb5); cursor: not-allowed; opacity: 0.75; }
.cshell-send svg { width: 13px; height: 13px; }

.cshell-hint {
  max-width: 640px;
  margin: 0.4rem auto 0;
  font-family: var(--aimt-font-sans); font-size: 0.68rem; color: var(--muted, #a3968d);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.cshell-retry-btn {
  font-family: var(--aimt-font-sans); font-size: 0.8rem; font-weight: 600;
  padding: 0.55rem 1.15rem; border-radius: var(--aimt-radius-sm, 10px);
  border: none; cursor: pointer; transition: background 0.15s;
  background: #4d403a; color: #fff;
}
.cshell-retry-btn:hover { background: #5d4f48; }

.cshell-continue-row { max-width: 640px; margin: 0 auto; display: flex; justify-content: flex-end; padding-top: 0.15rem; }
/* Compact AIMT primary action, not a repeat of the "Competency
   demonstrated" success badge above it -- Continue is navigation, so it
   carries no checkmark of its own. height (not padding-driven) keeps it
   a precise, on-brand 48-52px regardless of content; width stays auto/
   content-sized so it reads as a normal button, not a filled square --
   the previous version's oversized-square look was actually a bug: its
   icon (ICON_CHECK) had no explicit svg sizing rule anywhere, so it
   rendered at the browser's ~300x150px SVG default and inflated the
   whole button around it. */
.cshell-continue-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 50px;
  width: auto;
  padding: 0 1.4rem;
  border-radius: var(--aimt-radius-sm, 10px);
  border: none;
  cursor: pointer;
  background: var(--aimt-success, #3a5a3a);
  color: #fff;
  font-family: var(--aimt-font-sans);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: background 0.15s;
}
.cshell-continue-btn:hover { background: #335133; }
.cshell-continue-btn svg { width: 11px; height: 11px; flex-shrink: 0; }

.cshell-error-row {
  max-width: 640px; margin: 0 auto 0.5rem;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0.6rem 0.85rem;
  background: var(--aimt-error-light, #f0e8e8);
  border-radius: var(--aimt-radius-md, 12px);
}
.cshell-error-text { font-family: var(--aimt-font-sans); font-size: 0.78rem; color: var(--aimt-error, #7a3030); }

/* ── Focus visibility (Section 23) ── */
.cshell *:focus-visible {
  outline: 2px solid var(--text, #262626);
  outline-offset: 2px;
}

/* ── Mobile: near-native messaging feel ── */
@media (max-width: 480px) {
  .cshell-transcript { padding: 1rem 0.85rem 1.25rem; }
  .cshell-bub { max-width: 88%; font-size: 0.86rem; }
  .cshell-head { padding-left: 0.85rem; padding-right: 0.85rem; }
  .cshell-composer { padding-left: 0.85rem; padding-right: 0.85rem; }
  /* Full-width for easier touch targeting -- height stays the same
     48-52px as desktop/tablet, only width changes. Bottom safe-area is
     already handled by .cshell-composer's own padding, which this row
     lives inside. */
  .cshell-continue-row { justify-content: stretch; }
  .cshell-continue-btn { width: 100%; }
}

/* Activation affordance applied by JS to the (now inert-for-typing)
   inline checkpoint textarea — see wireCheckpoint() in cadence-shell.js.
   Kept intentionally subtle to match the restrained aesthetic. */
.cp-input.cadence-shell-trigger { cursor: pointer; }
.cp-input.cadence-shell-trigger:hover { background: rgba(255,255,255,0.98); }
.cp-status[data-cshell-viewable="1"] { cursor: pointer; }
.cp-res[data-cshell-viewable="1"] { cursor: pointer; }
