/* ==========================================================================
   IMMERSION — enrolled course page
   Ref: handoff § Phase 2.
   ========================================================================== */

.imm-course {
  max-width: var(--imm-content-max);
  margin-inline: auto;
  padding: var(--imm-s-11) var(--imm-s-12) var(--imm-s-13);
}

/* --- Breadcrumb and title ------------------------------------------------- */

.imm-breadcrumb {
  display: flex;
  gap: var(--imm-s-2);
  margin-bottom: var(--imm-s-3);
  font-size: 12.5px;
  color: var(--imm-faint);
}

.imm-breadcrumb a { color: var(--imm-faint); text-decoration: none; }
.imm-breadcrumb a:hover { color: var(--imm-link); }

.imm-course__title {
  margin-bottom: var(--imm-s-7);
  font-size: 31px;
}

/* --- Progress strip ------------------------------------------------------- */

.imm-course__progress { margin-bottom: var(--imm-s-8); }

.imm-course__progress-label {
  margin-bottom: var(--imm-s-2);
  font-size: 14px;
  color: var(--imm-muted);
}

.imm-course__progress-label strong { color: var(--imm-text); font-weight: 700; }

/* --- Day tracker ---------------------------------------------------------- */

.imm-tracker {
  display: flex;
  gap: var(--imm-s-1);
  margin: 0 0 var(--imm-s-9);
  padding: 0;
  list-style: none;
}

.imm-tracker__cell { flex: 1 1 0; min-width: 0; }

/* Weeks. The strip is one run of 28 cells; a wider gap after every seventh
   groups it into four without touching the markup. Same reading Karel asked
   for on the progress page, at strip scale. Not on the last cell, which would
   just hang a gap off the end. */
.imm-tracker__cell:nth-child(7n):not(:last-child) {
  margin-right: var(--imm-s-4);
}

.imm-tracker__cell a {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  border-radius: var(--imm-r-day);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: none;
  transition: background-color var(--imm-t-btn), color var(--imm-t-btn);
}

.imm-tracker__cell.is-done a {
  background: var(--imm-teal);
  color: #fff;
}

.imm-tracker__cell.is-today a {
  background: var(--imm-paper);
  border: 2px solid var(--imm-red);
  color: var(--imm-red);
}

.imm-tracker__cell.is-future a {
  background: var(--imm-line-4);
  color: var(--imm-faint);
}

.imm-tracker__cell.is-checkpoint a {
  background: var(--imm-magenta-wash);
  color: var(--imm-magenta);
}

/* --- Layout --------------------------------------------------------------- */

.imm-course__body {
  display: grid;
  grid-template-columns: 1fr var(--imm-rail);
  gap: var(--imm-s-8);
  align-items: start;
}

.imm-course__main { min-width: 0; }

/* --- Today's card --------------------------------------------------------- */

.imm-today {
  position: relative;
  margin-bottom: var(--imm-s-9);
  padding: var(--imm-s-9) var(--imm-s-10);
  border-radius: var(--imm-r-feature);
  color: var(--imm-on-dark);
  overflow: hidden;
  /*
   * A cinematic still behind the daily resume card. The scrim is layered IN the
   * background shorthand, above the photo, and anchored hard on the left where
   * all the text sits: measured against the actual image, .94 -> .84 -> .5
   * keeps the eyebrow (4.9:1), title (12:1) and meta (5.1:1) over AA while the
   * figure still reads on the right. Fixed rgba, not a token — this is a
   * photograph in both themes, so it must not follow the theme, exactly like
   * the sales hero. --imm-ink is the fallback if the image 404s.
   *
   * The image is a CSS custom property so each course can set its own from the
   * course edit screen (Dashboard background image). The template writes
   * `--imm-today-bg: url(...)` inline when a course has one; unset, it falls
   * back to the default below.
   *
   * The default is served from the Media Library (attachment 249488) rather
   * than the theme's assets/img, because SFTP was unavailable at build time; the
   * source file is kept in assets/img/today-desk.jpg for provenance.
   * Root-relative so it does not hardcode the domain.
   */
  --imm-today-bg: url("/wp-content/uploads/2026/08/today-desk.jpg");
  background:
    linear-gradient(90deg,
      rgba(15, 23, 32, .94) 0%,
      rgba(15, 23, 32, .84) 50%,
      rgba(15, 23, 32, .50) 100%),
    var(--imm-today-bg) center 60% / cover no-repeat;
  background-color: var(--imm-ink);
}

.imm-today__title {
  margin: var(--imm-s-3) 0 var(--imm-s-2);
  max-width: 34rem;
  color: #fff;
  font-size: 24px;
}

.imm-today__meta {
  margin-bottom: var(--imm-s-6);
  max-width: 34rem;
  color: var(--imm-faint-dark-2);
  font-size: 14.5px;
}

/* --- Step list ------------------------------------------------------------ */

.imm-steps { display: grid; gap: var(--imm-s-3); }

.imm-day {
  padding: var(--imm-s-7);
  background: var(--imm-paper);
  border: 1px solid var(--imm-line);
  border-radius: var(--imm-r-panel);
}

/* --- State, at a glance -----------------------------------------------------
   Karel: "Colour-code the collapsed modules subtly to differentiate which ones
   are complete and which aren't."

   A left edge rather than a fill. With most of 28 days collapsed, tinting every
   finished one would read as a wall of colour; an edge scans down the column and
   leaves the card itself alone.

   Order is precedence, not taste: a day can be several of these at once, and the
   later rule wins at equal specificity. Today beats checkpoint beats complete
   beats locked — you always want to know where you are first.

   The 2px taken off the left padding keeps the text aligned with the rows that
   still carry a 1px border.
   -------------------------------------------------------------------------- */

.imm-day {
  border-left-width: 3px;
  padding-left: calc(var(--imm-s-7) - 2px);
}

.imm-day.is-locked {
  background: var(--imm-canvas);
  border-left-color: var(--imm-line-dashed);
}

/* --imm-link, not --imm-teal: the fill weight measures 3.2:1 on a dark card —
   technically passing but close enough to invisible to defeat the point of
   marking it. --imm-link is 5.2 in light and 8.3 in dark. */
.imm-day.is-complete { border-left-color: var(--imm-link); }

.imm-day.is-checkpoint {
  border-color: var(--imm-magenta-line);
  border-left-color: var(--imm-magenta);
}

.imm-day.is-today {
  border-color: var(--imm-red-wash-line);
  border-left-color: var(--imm-red);
}

/* An unstarted, unlocked day keeps the plain edge — that IS its state, and it
   needs to stay distinct from a finished one. */

.imm-day__header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--imm-s-3);
  margin-bottom: var(--imm-s-3);
}

.imm-day__number {
  margin: 0;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: var(--imm-track-eyebrow);
  text-transform: uppercase;
  color: var(--imm-faint);
}

.imm-day__title { margin: 0; font-size: 17.5px; }
.imm-day__title a { color: var(--imm-text); text-decoration: none; }
.imm-day__title a:hover { color: var(--imm-link); }
.imm-day.is-locked .imm-day__title { color: var(--imm-faint); }

.imm-chip--checkpoint {
  background: var(--imm-magenta-wash);
  border: 1px solid var(--imm-magenta-line);
  color: var(--imm-magenta);
}

/* --- Steps ---------------------------------------------------------------- */

.imm-day__steps {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--imm-line-3);
}

.imm-step {
  display: flex;
  align-items: center;
  gap: var(--imm-s-3);
  padding: var(--imm-s-3) 0;
  border-bottom: 1px solid var(--imm-line-3);
}

.imm-step:last-child { border-bottom: 0; }

.imm-step__mark {
  flex: none;
  width: 18px;
  height: 18px;
  border: 2px solid var(--imm-line-dashed);
  border-radius: var(--imm-r-pill);
}

.imm-step__mark { position: relative; }

.imm-step.is-complete .imm-step__mark {
  background: var(--imm-teal);
  border-color: var(--imm-link);
  color: #fff;
}

.imm-step.is-complete .imm-step__mark::after {
  content: "";
  position: absolute;
  top: 46%;
  left: 50%;
  width: 4px;
  height: 8px;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -50%) rotate(45deg);
}

.imm-step.is-current .imm-step__mark { border-color: var(--imm-red); }

.imm-step__title { flex: 1; min-width: 0; font-size: 15px; }
.imm-step__title a { color: var(--imm-body); text-decoration: none; }
.imm-step__title a:hover { color: var(--imm-link); }

.imm-step.is-locked .imm-step__title { color: var(--imm-faint); }

.imm-step__lock { font-size: 13px; color: var(--imm-faint); }

.imm-pill {
  flex: none;
  padding: 6px 12px;
  border-radius: var(--imm-r-pill);
  background: var(--imm-red-wash);
  border: 1px solid var(--imm-red-wash-line);
  color: var(--imm-red);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.imm-pill:hover { background: var(--imm-red); border-color: var(--imm-red); color: #fff; }

/* --- Right rail ----------------------------------------------------------- */

.imm-rail { display: grid; gap: var(--imm-s-4); }

.imm-rail__card {
  padding: var(--imm-s-7);
  background: var(--imm-paper);
  border: 1px solid var(--imm-line);
  border-radius: var(--imm-r-panel);
}

.imm-rail__card--checkpoint {
  background: var(--imm-magenta-wash-2);
  border-color: var(--imm-magenta-line);
}

.imm-rail__stat {
  margin: var(--imm-s-2) 0 var(--imm-s-1);
  font-size: 32px;
  font-weight: 800;
  letter-spacing: var(--imm-track-h1);
  color: var(--imm-text);
}

.imm-rail__stat span {
  font-size: 17px;
  font-weight: 600;
  color: var(--imm-faint);
}

.imm-rail__note { margin: 0; font-size: 13.5px; color: var(--imm-faint); }

.imm-rail__checkpoint { margin: var(--imm-s-2) 0 var(--imm-s-1); font-size: 15px; font-weight: 700; }
.imm-rail__checkpoint a { color: var(--imm-magenta); text-decoration: none; }

.imm-rail__materials { font-size: 14px; }
.imm-rail__materials ul { margin: 0; padding-left: 1.1em; }

/* --- Mobile ---------------------------------------------------------------
   Handoff § Phase 12: the day strip scrolls horizontally with today in view.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .imm-course { padding: var(--imm-s-7) var(--imm-s-5) var(--imm-s-11); }

  .imm-course__body { grid-template-columns: 1fr; }

  .imm-tracker {
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
  }

  .imm-tracker__cell {
    flex: 0 0 44px;
    scroll-snap-align: center;
  }

  /* 44px minimum hit target on touch. */
  .imm-tracker__cell a { height: 44px; }

  /* Handoff § Phase 12: Resume becomes full-width. The row wraps so the pill
     can take the line rather than squeezing the step title. */
  .imm-step { flex-wrap: wrap; }

  .imm-step__title { flex: 1 1 100%; }

  .imm-pill {
    width: 100%;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* Time invested reads as a phrase ("3h 12m"), not a bare numeral, so it wants
   a smaller size than the numeric stats above it. */
.imm-rail__stat--time strong { font-size: 24px; }

/* --- Dashboard (front page) ------------------------------------------------
   Reuses the course page's today card, rail and card grid.
   -------------------------------------------------------------------------- */

.imm-dashboard {
  max-width: var(--imm-content-max);
  margin-inline: auto;
  padding: var(--imm-s-11) var(--imm-s-12) var(--imm-s-13);
}

.imm-dashboard .imm-page-title { margin-bottom: var(--imm-s-8); }

.imm-dashboard__body {
  display: grid;
  grid-template-columns: 1fr var(--imm-rail);
  gap: var(--imm-s-8);
  align-items: start;
}

.imm-dashboard__main { min-width: 0; }

.imm-dashboard__h2 { margin: 0 0 var(--imm-s-5); font-size: 19px; }

.imm-dashboard__courses { margin-top: var(--imm-s-9); }

.imm-dashboard__links {
  margin: var(--imm-s-3) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--imm-s-3);
  font-size: 14px;
}

.imm-dashboard__links a { text-decoration: none; }

.imm-dashboard .imm-course-card__body .imm-progress { margin-top: var(--imm-s-4); }

@media (max-width: 900px) {
  .imm-dashboard { padding: var(--imm-s-7) var(--imm-s-5) var(--imm-s-11); }
  .imm-dashboard__body { grid-template-columns: 1fr; }
}

/* --- Collapsible days -------------------------------------------------------
   Karel: "Collapse the steps except for active modules. So both completed and
   unstarted modules are collapsed."

   Native <details>. The day title stays a link inside the <summary>: clicking
   the link navigates, clicking anywhere else on the row toggles — which is the
   browser's own behaviour, not something scripted.
   -------------------------------------------------------------------------- */

/* Closing a <details> is normally enough — the UA stylesheet hides its
   non-summary children. Here it was not: every day rendered with its steps
   showing even though only one carried `open`, so the markup said collapsed and
   the page did not. I did not pin down why the UA rule failed (it is not a
   competing `display` on .imm-day__steps — that rule sets none), so this states
   it outright rather than relying on inherited behaviour. Verified by toggling
   in a browser: closed 0px, open 245px. */
.imm-day__disclosure { display: block; }

.imm-day__disclosure:not([open]) .imm-day__steps { display: none; }

.imm-day__disclosure > .imm-day__header {
  display: flex;
  align-items: baseline;
  gap: var(--imm-s-4);
  cursor: pointer;
  list-style: none;
}

/* Safari draws its own triangle unless this is here. */
.imm-day__disclosure > .imm-day__header::-webkit-details-marker { display: none; }

/* The chevron. Rotates when the day is open. */
.imm-day__disclosure > .imm-day__header::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-left: auto;
  border-right: 2px solid var(--imm-faint);
  border-bottom: 2px solid var(--imm-faint);
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform var(--imm-t-btn);
}

.imm-day__disclosure[open] > .imm-day__header::after { transform: rotate(-135deg); }

.imm-day__count {
  flex: none;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: var(--imm-track-label);
  color: var(--imm-faint);
  font-variant-numeric: tabular-nums;
}

/* --imm-teal is the FILL weight: on a dark card it measures 3.2:1. The count
   is text, so it takes --imm-link. Caught by the contrast audit on the run
   after this feature landed. */
.imm-day.is-complete .imm-day__count { color: var(--imm-link); }

.imm-day__disclosure > .imm-day__header:focus-visible {
  outline: 2px solid var(--imm-teal);
  outline-offset: 2px;
}
