/* today: ordered source sections, combined by the asset build. */
/* Learn shares the app's light surfaces and navy text. Topic banners keep
   their distinct colours and white labels; lesson buttons retain their depth. */
:root {
  --sheet-action: #d52b3a;
  --sheet-action-lip: #ad1e2e;
}
body.today-view {
  background: var(--paper);
}
#today {
  background: var(--paper);
  border-top-color: var(--paper);
  color: var(--ink);
  padding: 0 18px calc(108px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
  color-scheme: light dark;
  scroll-padding-top: 220px;
  --today-status-height: 70px;
}
#today .today-inner {
  max-width: 540px;
}
#today .sub {
  color: var(--ink-2);
}
/* Row one's shape is declared once for all four tabs, in progress.css beside
   the controls it lays out. Sticking to the top is the only thing Learn does
   differently, and the only thing left here. */
.today-top {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--paper);
}
.today-heading {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
/* The page title is hidden — the banner below is the visible header — so it
   takes no size from the type scale. */
.today-heading h1 {
  margin: 0;
  color: var(--ink);
  font-weight: 900;
  line-height: 1.2;
}
.today-heading p {
  margin: 3px 0 0;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
}
.today-course-topic {
  position: relative;
  margin-bottom: 22px;
  padding-bottom: 8px;
}
.today-chapter-wrap {
  position: sticky;
  top: var(--today-status-height);
  z-index: 3;
  background: var(--paper);
  padding-bottom: 14px;
}
.today-chapter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 72px;
  padding: 12px 16px;
  border-radius: 16px;
  background: var(--topic-banner);
  box-shadow: none;
  color: #fff;
}
.today-chapter > div {
  min-width: 0;
}
.chapter-guidebook {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  min-height: 40px;
  padding: 0 12px;
  border: 2px solid rgb(255 255 255 / 45%);
  border-radius: 12px;
  background: rgb(255 255 255 / 15%);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 0.16s var(--ease),
    transform 0.16s var(--ease);
}
.chapter-guidebook svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
}
.chapter-guidebook:hover {
  background: rgb(255 255 255 / 26%);
}
.chapter-guidebook:active {
  transform: translateY(1px);
  transition-duration: 0.08s;
}
.chapter-guidebook:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .chapter-guidebook {
    transition: none;
  }
}
/* Under 400px the word would push the section title onto two lines, so the
   chip keeps its icon and hands the word to the accessible name. */
@media (max-width: 399px) {
  .chapter-guidebook b {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .chapter-guidebook {
    padding: 0 10px;
  }
}
/* The label is white on the banner, like the reference: 12px bold, which is
   3:1 rather than the 4.5:1 small text wants. The banner colours are already
   as deep as this palette goes (tests/frontend/contrast.test.mjs), so the label is the
   one place the look costs a level; the title beside it clears 3:1 as large
   text, and every other small label in the app sits on paper. */
.today-unit {
  margin: 0 0 3px;
  color: #fff;
  font-size: 12px;
  line-height: 1.1;
  font-weight: 900;
  letter-spacing: 0.65px;
}
/* The banner title tier, shared with Mock Tests' banner so the two cannot
   drift apart; Mock Tests only recolours it for the full-course banner. */
/* The floor is 19px, not 18px: below 18.66px bold, WCAG stops counting this
   as large text and the white-on-colour bar rises from 3:1 to 4.5:1, which no
   version of these hues can meet. */
#today .today-chapter-title,
.mock-banner-title {
  color: #fff;
  margin: 0;
  font-size: clamp(19px, 5vw, 22px);
  font-weight: 900;
  line-height: 1.2;
  letter-spacing: -0.35px;
}
/* The path is drawn about a fifth smaller than it started, so a phone shows
   more of the course at once: coins, their lips, the ring and the zigzag all
   scale together. */
.today-path {
  list-style: none;
  margin: 0;
  padding: 16px 0 0;
}
.today-step {
  display: flex;
  justify-content: center;
  min-height: 98px;
}
.today-lesson {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 140px;
  min-height: 88px;
  padding: 0 0 14px;
  border: 0;
  border-radius: 16px;
  background: none;
  color: var(--ink);
  transform: translateX(calc(var(--path-shift) * 0.8));
}
/* The path winds: learn-path.js numbers the steps 0–6 in turn, and each number
   is an offset from the centre line. */
.today-step[data-shift="0"] {
  --path-shift: 0px;
}
.today-step[data-shift="1"] {
  --path-shift: 48px;
}
.today-step[data-shift="2"] {
  --path-shift: 64px;
}
.today-step[data-shift="3"] {
  --path-shift: 26px;
}
.today-step[data-shift="4"] {
  --path-shift: -32px;
}
.today-step[data-shift="5"] {
  --path-shift: -64px;
}
.today-step[data-shift="6"] {
  --path-shift: -48px;
}
.today-lesson,
.today-lesson * {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
/* The progress ring stays on the stationary wrapper; only the inner face
   compresses and springs back during a lesson press. */
/* The path's steps are rounded squares, the same shape as the mock test tiles,
   rather than the circular coins this started as. One radius drives the face,
   its inner gloss and the ring around the current step, so they cannot part
   company the way five separate 50%s could. */
.today-node-wrap {
  --node-radius: clamp(10px, 1.7vw, 14px);
  position: relative;
  display: block;
  flex: 0 0 52px;
  width: 60px;
  height: 52px;
}
.today-node {
  --node-lip: var(--topic-rest-lip);
  --node-face: var(--topic-rest);
  position: relative;
  display: grid;
  place-items: center;
  width: 60px;
  height: 52px;
  border-radius: var(--node-radius);
  background: var(--topic-rest);
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff05;
  color: var(--topic-icon);
  transform-origin: center bottom;
  transition:
    transform 0.1s var(--ease),
    box-shadow 0.1s var(--ease);
}
/* Every coin icon -- star, play, book, review, medal -- at one size. */
.today-node svg {
  width: 31px;
  height: 31px;
  fill: currentColor;
}
.today-lesson-title {
  color: var(--ink);
  font-size: 12px;
  line-height: 1.25;
  font-weight: 750;
  max-width: 140px;
  text-wrap: balance;
}
.is-current .today-node {
  --node-lip: var(--topic-lip);
  --node-face: var(--topic-node);
  background: var(--topic-node);
  color: #fff;
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff35;
}
/* The active coin sits inside a thick light-grey ring, like the reference. */
.is-current .today-node-wrap::after {
  content: "";
  position: absolute;
  inset: -12px -11px -17px;
  border: 6px solid var(--line-2);
  border-radius: calc(var(--node-radius) + 12px);
  pointer-events: none;
}
.is-current .today-lesson {
  gap: 22px;
  margin-bottom: 8px;
}
.today-start {
  position: absolute;
  bottom: calc(100% + 19px);
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 12px;
  border: 2px solid var(--topic-rest-lip);
  border-radius: 10px;
  background: var(--paper);
  color: var(--topic-icon);
  white-space: nowrap;
  font-size: 12px;
  font-weight: 950;
  letter-spacing: 0.75px;
  text-transform: uppercase;
}
/* The callout breathes, so the eye finds where to start without anything
   having to shout. Uses translate rather than transform, because the bubble is
   centred with transform: translateX(-50%) and would jump sideways otherwise. */
.today-start {
  animation: start-bob 1.9s ease-in-out infinite;
}
@keyframes start-bob {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -4px;
  }
}
.today-start::after {
  content: "";
  position: absolute;
  left: calc(50% - 5px);
  bottom: -6px;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--topic-rest-lip);
  border-bottom: 2px solid var(--topic-rest-lip);
  background: var(--paper);
  transform: rotate(45deg);
}
/* The START callout stands about 55px above its coin and breathes another 4px
   on top of that, so the step has to reserve the room. With less, the callout
   overflows its own row and the sticky chapter header paints over it. */
.today-step.is-current {
  padding-top: 60px;
}
/* Completed lessons become glossy star coins. The inset face and diagonal
   highlights travel with the pressed button; the current-step ring stays put. */
/* Completed coins keep the solid section colour and gain one soft gloss across the face; the icon is a white tick. */
.is-complete .today-node {
  --node-lip: var(--topic-lip);
  --node-face: var(--topic-node);
  isolation: isolate;
  color: #fff;
  background: var(--topic-node);
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff40;
}
/* Game-app finish: a lighter inner face sits on the solid rim, and one wide
   diagonal light band crosses it from top-left to bottom-right. */
.is-complete .today-node::before {
  content: "";
  position: absolute;
  inset: 4px 4px 6px;
  border-radius: calc(var(--node-radius) - 4px);
  background: color-mix(in srgb, var(--topic-node) 88%, #fff);
  pointer-events: none;
}
.is-complete .today-node::after {
  content: "";
  position: absolute;
  inset: 4px 4px 6px;
  border-radius: calc(var(--node-radius) - 4px);
  background: linear-gradient(115deg, transparent 0 40%, #ffffff40 40% 52%, transparent 52%);
  background-size: 250% 100%;
  background-position: 50% 0;
  pointer-events: none;
  transition: background-position 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.is-complete .today-node svg {
  position: relative;
  z-index: 1;
  width: 28px;
  height: 28px;
}
/* The permanent gloss stays in place. A separate light reflection crosses it
   during completion and disappears before the coin settles. */
.today-node-shine {
  position: absolute;
  z-index: 2;
  inset: 4px 4px 6px;
  border-radius: calc(var(--node-radius) - 4px);
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(120deg, transparent 36%, #ffffff30 43%, #ffffffbd 49%, #ffffff75 53%, transparent 62%)
    100% 50% / 250% 100% no-repeat;
}
.is-celebrating .today-lesson:not(.is-pressed) .today-node {
  animation: lesson-finish 0.9s ease-in-out both;
}
.is-celebrating .today-node-shine {
  animation: lesson-shine 0.9s ease-in-out both;
}
.is-awaiting-reveal .today-start,
.is-awaiting-reveal .today-node-wrap::after {
  visibility: hidden;
}
.is-awaiting-reveal .today-node {
  background: var(--topic-rest);
  color: var(--topic-icon);
  --node-lip: var(--topic-rest-lip);
  --node-face: var(--topic-rest);
}
.is-next-cue .today-start {
  animation: next-lesson-label 0.25s ease-out;
}
.is-next-cue .today-lesson:not(.is-pressed) .today-node {
  animation: next-lesson-nudge 1.4s ease-in-out 3;
}
/* The classic route reveals the next lesson's name with the coin. */
html:not([data-design]) #today .is-next-cue .today-lesson-title > * {
  animation: next-lesson-copy 0.3s cubic-bezier(0.2, 0.7, 0.2, 1) 0.12s both;
}
@keyframes lesson-finish {
  0%,
  78%,
  100% {
    transform: none;
  }
  18% {
    transform: translateY(2px) scale(0.97);
  }
  42% {
    transform: translateY(-3px) scale(1.045);
  }
}
@keyframes lesson-shine {
  0%,
  12% {
    background-position: 100% 50%;
    opacity: 0;
  }
  28% {
    opacity: 1;
  }
  68% {
    background-position: 0% 50%;
    opacity: 0.85;
  }
  82%,
  100% {
    background-position: 0% 50%;
    opacity: 0;
  }
}
@keyframes next-lesson-label {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes next-lesson-nudge {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -5px;
  }
}
@keyframes next-lesson-copy {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  html:not([data-design]) #today .is-next-cue .today-lesson-title > * {
    animation: none;
  }
}
@media (hover: hover) and (pointer: fine) {
  /* Hover reads as a light press: the coin sinks a little into its lip. No colour change. */
  .today-lesson:hover .today-node {
    transform: translateY(2px);
    box-shadow:
      0 4px 0 var(--node-lip),
      inset 0 2px 0 #ffffff05;
  }
  .is-current .today-lesson:hover .today-node,
  .is-complete .today-lesson:hover .today-node,
  .is-upcoming .today-lesson:hover .today-node {
    box-shadow:
      0 4px 0 var(--node-lip),
      inset 0 2px 0 #ffffff35;
  }
  /* The reflection reacts to the mouse: the band glides across the face and settles back on leave. */
  .is-complete .today-lesson:hover .today-node::after {
    background-position: 12% 0;
  }
}
/* A press, not a squash. The face sinks the full depth of its lip and the
   lip closes to match, so the bottom edge never moves. */
.today-step .today-lesson.is-pressed .today-node {
  transform: translateY(5px);
  box-shadow:
    0 1px 0 var(--node-lip),
    inset 0 2px 0 #ffffff20;
}
.today-lesson:focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 5px;
}
.today-lesson-title b {
  display: block;
  color: var(--ink);
  font-size: 13px;
  font-weight: 900;
}
/* Every lesson coin is a solid block of its section colour; the current one adds the ring and label. */
/* Everything still ahead of you sits grey, so the colour is an invitation
   rather than wallpaper: where you are now, and the first step of each group —
   somewhere to start if you would rather not pick up where you left off. */
.is-upcoming .today-node {
  --node-lip: var(--disabled);
  --node-face: var(--panel-2);
  background: var(--panel-2);
  color: var(--ink-3);
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff55;
}
.is-upcoming.is-entry .today-node {
  --node-lip: var(--topic-lip);
  --node-face: var(--topic-node);
  background: var(--topic-node);
  color: #fff;
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff35;
}
.is-upcoming:not(.is-entry) .today-guided-kind {
  color: var(--ink-3);
}
.today-load-notice {
  padding: 16px;
  margin-bottom: 20px;
  border: 1px solid var(--brand-line);
  border-radius: 16px;
}
.today-load-notice p {
  color: var(--ink-2);
}
.today-load-notice button {
  color: var(--brand-ink);
}
#today .big {
  color: #fff;
  background: #d52b3a;
}
@media (max-width: 359px) {
  #today {
    padding-left: 14px;
    padding-right: 14px;
  }
  .today-chapter {
    gap: 8px;
    padding-left: 14px;
    padding-right: 14px;
  }
  .today-unit {
    font-size: 11px;
  }
  .today-lesson {
    transform: translateX(calc(var(--path-shift) * 0.65));
  }
}
@media (min-width: 960px) {
  .today-chapter {
    min-height: 76px;
    padding: 14px 22px;
  }
  #today .today-chapter-title,
  .mock-banner-title {
    font-size: 23px;
  }
  .today-step {
    min-height: 112px;
  }
  .today-node-wrap {
    flex-basis: 60px;
    width: 68px;
    height: 60px;
  }
  .today-node {
    width: 68px;
    height: 60px;
  }
  .today-node svg {
    width: 35px;
    height: 35px;
  }
  .is-complete .today-node svg {
    width: 31px;
    height: 31px;
  }
  .today-lesson-title b {
    font-size: 14px;
  }
  /* Specificity beats the base rules declared after this block. */
  #today .today-group-notes {
    display: inline-flex;
    align-items: center;
    width: auto;
    height: 40px;
    gap: 6px;
    padding: 0 14px 0 10px;
    font-size: 13px;
    font-weight: 800;
  }
  #today .today-group-notes .today-notes-label {
    display: inline;
  }
}
/* The path eases into place on first load and after completing a lesson.
   Backwards, not both: a fill holding the end transform keeps the path a
   containing block, and Chrome then pinned the "fixed" Current lesson button
   to the bottom of the whole path, off the screen. */
.today-inner.today-enter {
  animation: today-enter 0.36s cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
}
@keyframes today-enter {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .today-inner.today-enter {
    animation: none;
  }
  .is-complete .today-node::after {
    transition: none;
  }
  .today-node {
    transition: none;
  }
  .is-celebrating .today-lesson:not(.is-pressed) .today-node,
  .is-celebrating .today-node-shine,
  .today-start,
  .is-next-cue .today-start,
  .is-next-cue .today-lesson:not(.is-pressed) .today-node {
    animation: none;
  }
  .today-step .today-lesson.is-pressed .today-node {
    transform: none;
    filter: brightness(0.92);
  }
}
/* Saved lessons sits above the path, and only once something is saved.
   Theme tokens throughout, so the card keeps its contrast in dark mode. */
.today-saved {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin: 0 0 24px;
  padding: 14px 16px;
  border: 2px solid var(--brand-soft-2);
  border-radius: 18px;
  background: var(--brand-soft);
  color: var(--ink);
  text-align: left;
  box-shadow: 0 3px 0 var(--brand-soft-2);
}
.today-saved:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--brand-soft-2);
}
/* Explore topics and Put it into practice: banner cards in the path's own
   colours, like the section banners, with Crumpet on the right (asleep on the
   handbook; holding the trophy) and the app's lip and press. The small line
   reads above the title, but comes after it for screen readers. */
.today-extras {
  display: grid;
  gap: 14px;
  /* Room below, so the last card scrolls clear of the Current lesson button. */
  margin: 8px auto 84px;
  max-width: 380px;
}
.today-extra {
  --extra: #d52b3a;
  --extra-lip: #ad1e2e;
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 96px;
  margin: 0;
  padding: 14px 116px 14px 18px;
  border: none;
  border-radius: 16px;
  background: var(--extra);
  color: #fff;
  text-align: left;
  box-shadow: 0 4px 0 var(--extra-lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}
.today-extra.is-practice {
  --extra: #ff8900;
  --extra-lip: #cc6e00;
}
.today-extra:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--extra-lip);
}
.today-extra:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
.today-extra-text {
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
  min-width: 0;
  /* White on the bright fills keeps a drop in the card's own lip colour. */
  text-shadow: 0 1.5px 0 var(--extra-lip);
}
.today-extra-text b {
  font-size: 20px;
  font-weight: 900;
  line-height: 1.2;
}
.today-extra-text small {
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.today-extra-art {
  position: absolute;
  right: 6px;
  bottom: 0;
  width: 104px;
  height: 104px;
  object-fit: contain;
  pointer-events: none;
}
@media (max-width: 359px) {
  .today-extra {
    padding-right: 96px;
  }
  .today-extra-text b {
    font-size: 18px;
  }
  .today-extra-art {
    width: 88px;
    height: 88px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .today-extra {
    transition: none;
  }
}

/* The floating way back to the current lesson (learn-path-position.js): the
   app's own button, brand blue with a white label and the lip, pressed like
   .big; its arrow points up or down to where the lesson is. It pops in, and
   its arrow nudges towards the lesson the way the START bubble bobs. */
.today-jump {
  --nudge: -3px;
  position: fixed;
  z-index: 6;
  right: 16px;
  /* The phone tab bar is 89px over the inset; at 92px the lip touched it. */
  bottom: calc(104px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 20px 0 16px;
  border: none;
  border-radius: 999px;
  background: var(--brand);
  color: var(--on-brand);
  box-shadow:
    var(--drop) var(--brand-lip),
    0 10px 22px rgb(157 22 39 / 22%);
  font-size: 15px;
  font-weight: 900;
  animation: today-jump-in 0.42s cubic-bezier(0.34, 1.56, 0.64, 1);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}
.today-jump:active {
  transform: translateY(3px);
  box-shadow:
    0 1px 0 var(--brand-lip),
    0 6px 14px rgb(157 22 39 / 18%);
}
.today-jump:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
.today-jump svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: today-jump-nudge 1.9s ease-in-out 0.5s infinite;
  transition: transform 0.15s var(--ease);
}
.today-jump[data-direction="down"] {
  --nudge: 3px;
}
.today-jump[data-direction="down"] svg {
  transform: rotate(180deg);
}
/* Individual properties, so they never fight the press's transform or the
   arrow's turn. */
@keyframes today-jump-in {
  from {
    opacity: 0;
    translate: 0 18px;
    scale: 0.85;
  }
}
@keyframes today-jump-nudge {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 var(--nudge);
  }
}
@media (min-width: 960px) {
  .today-jump {
    bottom: 24px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .today-jump,
  .today-jump svg {
    animation: none;
    transition: none;
  }
}
.today-saved-icon {
  display: grid;
  place-items: center;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: #d52b3a;
  color: #fff;
}
.today-saved-icon svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}
.today-saved-copy {
  flex: 1;
  min-width: 0;
}
.today-saved-copy b {
  display: block;
  font-size: 16px;
  font-weight: 900;
}
.today-saved-copy small {
  display: block;
  margin-top: 2px;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
}
.today-saved-go {
  color: var(--ink-2);
  font-size: 24px;
}
/* The ribbon hangs off a bookmarked coin's top corner, above its shine. */
.today-bookmark {
  position: absolute;
  top: -6px;
  right: -3px;
  z-index: 2;
  width: 18px;
  height: 23px;
  pointer-events: none;
  filter: drop-shadow(0 2px 0 #c73636);
}
.today-bookmark svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: #ff5c5c;
}
/* The list behind the card: a row per lesson, its ribbon at the right to unsave it. */
.saved-lessons-panel h2 {
  margin: 0 0 12px;
}
.saved-lessons {
  display: grid;
  gap: 8px;
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
  max-height: min(60vh, 460px);
  overflow-y: auto;
}
.saved-lesson {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.saved-lesson-open {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  min-height: 58px;
  margin: 0;
  padding: 10px 16px;
  border: 1.5px solid var(--line-2);
  border-radius: 14px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  text-align: left;
}
.saved-lesson-open:hover {
  border-color: var(--brand-line);
}
.saved-lesson-open b {
  font-size: 16px;
  font-weight: 900;
  overflow-wrap: anywhere;
}
.saved-lesson-kind {
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.saved-lesson-remove {
  display: grid;
  place-items: center;
  flex: 0 0 52px;
  min-height: 58px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: #d52b3a;
}
.saved-lesson-remove:hover {
  background: var(--panel);
}
.saved-lesson-remove svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
}
#savedLessonsModal .panel > .big {
  display: block;
  width: 100%;
  margin: 0;
  min-height: 52px;
  border-radius: 14px;
  background: var(--sheet-action);
  color: #fff;
  box-shadow: 0 4px 0 var(--sheet-action-lip);
  font-weight: 800;
}
/* The five syllabus sections keep their colour through every group and coin. */
/* Section palette: five saturated hues with strongly darker lips, so coins and
   banners read as bright, pressable game pieces. They are Learn Canada's own
   (1 Oct 2026): blue, green and purple were each turned a few degrees from the
   values they had shared with Duolingo's palette at the same brightness, and
   orange 3 degrees at full strength, so every contrast below still holds. */
/* Two of the five tokens carry text, so they are set by contrast rather than
   by eye. --topic-banner is behind the white banner title (18px+ bold, so
   3:1), and every hue was under it: blue 2.44, green 2.09, orange 2.18, pink
   2.80. Each is the same hue taken down until it reaches 3:1; purple already
   passed at 3.24 and is untouched. --topic-icon is the small text that sits on
   paper or on a pale --topic-rest face — the START callout, the section pill,
   a paper's number — so it has to reach 4.5:1 on white, which the old lip
   colours did not (blue was 3.20). Both are checked by tests/frontend/contrast.test.mjs. */
[data-section="citizenship"] {
  --topic-banner: #c52b3b;
  --topic-lip: #ad1e2e;
  --topic-node: #d52b3a;
  --topic-ring: #f3a2ab;
  --topic-rest: #fff0f1;
  --topic-rest-lip: #ffd3d8;
  --topic-icon: #9d1627;
}
[data-section="people"] {
  --topic-banner: #36aa0d;
  --topic-lip: #33a50d;
  --topic-node: #40cd0f;
  --topic-ring: #b6ea99;
  --topic-rest: #e6f8df;
  --topic-rest-lip: #c0eaaf;
  --topic-icon: #2b880a;
}
[data-section="history"] {
  --topic-banner: #d67300;
  --topic-lip: #cc6e00;
  --topic-node: #ff8900;
  --topic-ring: #ffca8a;
  --topic-rest: #ffefdc;
  --topic-rest-lip: #ffd5a6;
  --topic-icon: #ab5c00;
}
[data-section="geography"] {
  --topic-banner: #f55ba7;
  --topic-lip: #d94590;
  --topic-node: #ff5fae;
  --topic-ring: #ffb3d9;
  --topic-rest: #ffe6f2;
  --topic-rest-lip: #ffc4e0;
  --topic-icon: #c44986;
}
/* Gold: a lesson done again from memory (gold-offer.js). The coin takes the
   gold Practice tests gives a passed paper, its white tick keeps the gold's own
   drop, and a light crosses it every few seconds. */
.is-gold .today-node {
  --node-face: #e9ac23;
  --node-lip: #cb8e13;
  background: #e9ac23;
  color: #fff;
  box-shadow:
    0 6px 0 var(--node-lip),
    inset 0 2px 0 #ffffff55;
}
.is-gold .today-node::before {
  background: linear-gradient(160deg, #ffd84d, #f5b81c 60%, #eaa716);
}
.is-gold .today-node svg {
  filter: drop-shadow(0 1.5px 0 #b8790a);
}
.is-gold:not(.is-celebrating) .today-node-shine {
  animation: gold-shimmer 3.4s ease-in-out 0.8s infinite;
}
@keyframes gold-shimmer {
  0%,
  58% {
    background-position: 100% 50%;
    opacity: 0;
  }
  66% {
    opacity: 1;
  }
  86% {
    background-position: 0% 50%;
    opacity: 0.85;
  }
  94%,
  100% {
    background-position: 0% 50%;
    opacity: 0;
  }
}

/* The card a finished coin opens: it hangs under the coin's row, over the
   steps below (under the sticky headers), with its caret on the coin. */
.today-step.is-offering {
  position: relative;
  z-index: 2;
}
.gold-offer {
  position: absolute;
  top: calc(100% - 6px);
  left: 50%;
  width: min(320px, calc(100% - 8px));
  padding: 18px 16px 16px;
  border: 2px solid var(--line-2);
  border-radius: 18px;
  background: var(--paper);
  box-shadow:
    0 4px 0 var(--line-2),
    0 14px 30px rgb(15 35 60 / 14%);
  text-align: center;
  translate: -50% 0;
  animation: gold-offer-in 0.24s cubic-bezier(0.34, 1.56, 0.64, 1);
  /* Scrolled into view clear of the tab bar and the Current lesson button. */
  scroll-margin-bottom: calc(150px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
}
.gold-offer::before {
  content: "";
  position: absolute;
  top: -9px;
  left: calc(50% + var(--path-shift, 0px) * 0.8 - 8px);
  width: 14px;
  height: 14px;
  border-top: 2px solid var(--line-2);
  border-left: 2px solid var(--line-2);
  border-top-left-radius: 3px;
  background: var(--paper);
  rotate: 45deg;
}
.gold-offer-title {
  margin: 0 0 6px;
  color: var(--ink);
  font-size: 18px;
  font-weight: 900;
  line-height: 1.25;
}
.gold-offer-text {
  margin: 0 0 16px;
  color: var(--ink-2);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.45;
}
.gold-offer .big {
  font-size: 15px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
/* Go for gold: the app's big button in gold, its white label on the gold drop.
   #today paints every big button blue (today-today-load-notice-button.css). */
#today .gold-offer .gold-offer-go {
  background: linear-gradient(160deg, #ffd23f, #f5b81c 55%, #e9a514);
  color: #fff;
  text-shadow: 0 1.5px 0 #b8790a;
  box-shadow: var(--drop) #cb8e13;
}
#today .gold-offer .gold-offer-go:active,
#today .gold-offer .gold-offer-go.is-pressed {
  box-shadow: 0 0 0 #cb8e13;
}
.gold-offer .ghost {
  margin-top: 12px;
}
@keyframes gold-offer-in {
  from {
    opacity: 0;
    translate: -50% -8px;
    scale: 0.96;
  }
}
@media (prefers-reduced-motion: reduce) {
  .is-gold:not(.is-celebrating) .today-node-shine,
  .gold-offer {
    animation: none;
  }
}
[data-section="government"] {
  --topic-banner: #bd6aed;
  --topic-lip: #9a4fcd;
  --topic-node: #d87ef8;
  --topic-ring: #e8bffc;
  --topic-rest: #f5e7fe;
  --topic-rest-lip: #e5c7fc;
  --topic-icon: #9c59c3;
}
/* The section hues stay saturated in dark — banners, coins and rings read on
   either ground. What cannot survive is --topic-rest and --topic-rest-lip: they
   are the pale resting surface of every not-yet-started coin and its 8px lip,
   so left alone they would be five bright pastel blobs on a dark path. Each
   becomes a deep tint of its own hue, keeping the section colour-coding. */
[data-theme="dark"] [data-section="citizenship"] {
  --topic-rest: #311a22;
  --topic-rest-lip: #201016;
  --topic-icon: #f5a0aa;
}
[data-theme="dark"] [data-section="people"] {
  --topic-rest: #132a0d;
  --topic-rest-lip: #0e1e09;
  --topic-icon: #9ce07f;
}
[data-theme="dark"] [data-section="history"] {
  --topic-rest: #2e1d08;
  --topic-rest-lip: #221505;
  --topic-icon: #ffb96a;
}
[data-theme="dark"] [data-section="geography"] {
  --topic-rest: #2e1122;
  --topic-rest-lip: #220c19;
  --topic-icon: #ffb3d9;
}
[data-theme="dark"] [data-section="government"] {
  --topic-rest: #261a30;
  --topic-rest-lip: #1b1223;
  --topic-icon: #e0b1fb;
}
.today-path-group + .today-path-group {
  margin-top: 16px;
}
.today-group-heading {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 10px;
}
.today-group-heading::after {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--topic-rest);
}
#today .today-group-heading h3 {
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.35;
  font-weight: 750;
  margin: 0;
}
.today-group-notes {
  display: grid;
  place-items: center;
  order: 1;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  padding: 10px;
  border: 0;
  border-radius: 12px;
  color: var(--topic-icon);
  background: var(--topic-rest);
}
.today-group-notes svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
}
.today-notes-label {
  display: none;
}
.today-section-empty {
  margin: 12px 16px 32px;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.5;
}
/* Steps behind the paywall: a plain light-grey coin with a mid-grey icon and a
   slightly darker grey edge, quieter than every coloured step around it. */
.is-locked .today-node {
  --node-lip: #cad2da;
  --node-face: #e2e7ec;
  background: #e2e7ec;
  color: #a3aebb;
  box-shadow: 0 6px 0 var(--node-lip);
}
[data-theme="dark"] .is-locked .today-node {
  --node-lip: #262e37;
  --node-face: #36404b;
  background: #36404b;
  color: #6b7785;
}
.is-locked .today-lesson-title b {
  color: var(--ink-2);
}
/* The line-map look (data-design="v2", app/design.js) colours each section in
   the deep, flat colours of a British route map — red, blue, brown, green and
   purple — in place of the classic bright game pieces. The course map (v3)
   keeps the classic colours. These are the same tokens as the classic palette
   (today-today-saved-icon.css), so every screen that reads them, Topics
   included, follows the switch. Each hue clears 4.5:1 under white on its own,
   so --topic-icon can be the hue itself. */
[data-design="v2"] [data-section="citizenship"] {
  --topic-banner: #c8102e;
  --topic-lip: #9e0c24;
  --topic-node: #c8102e;
  --topic-ring: #efa3ae;
  --topic-rest: #fbe8eb;
  --topic-rest-lip: #f3c4cb;
  --topic-icon: #c8102e;
}
[data-design="v2"] [data-section="people"] {
  --topic-banner: #1447a6;
  --topic-lip: #0f357d;
  --topic-node: #1447a6;
  --topic-ring: #a3b9e8;
  --topic-rest: #e7eefa;
  --topic-rest-lip: #c4d3f2;
  --topic-icon: #1447a6;
}
[data-design="v2"] [data-section="history"] {
  --topic-banner: #a35a1c;
  --topic-lip: #7d4415;
  --topic-node: #a35a1c;
  --topic-ring: #e3bb92;
  --topic-rest: #f8ede3;
  --topic-rest-lip: #ecd3bc;
  --topic-icon: #a35a1c;
}
[data-design="v2"] [data-section="geography"] {
  --topic-banner: #0f7a3a;
  --topic-lip: #0a5a2a;
  --topic-node: #0f7a3a;
  --topic-ring: #9fd4b3;
  --topic-rest: #e5f3ea;
  --topic-rest-lip: #c0e3cd;
  --topic-icon: #0f7a3a;
}
[data-design="v2"] [data-section="government"] {
  --topic-banner: #6c3fa0;
  --topic-lip: #50307a;
  --topic-node: #6c3fa0;
  --topic-ring: #c9b4e4;
  --topic-rest: #f0e9f8;
  --topic-rest-lip: #d9cbee;
  --topic-icon: #6c3fa0;
}
/* Night keeps the banners deep, since they carry white titles, but lifts each
   line (--topic-node) so it still reads on the dark page, and turns the pale
   resting face into a deep tint of its own hue with a light ink on it. */
[data-design="v2"][data-theme="dark"] [data-section="citizenship"] {
  --topic-node: #e5485d;
  --topic-rest: #2b0d13;
  --topic-rest-lip: #1f090e;
  --topic-icon: #ff9eab;
}
[data-design="v2"][data-theme="dark"] [data-section="people"] {
  --topic-node: #5a86e6;
  --topic-rest: #0e1b36;
  --topic-rest-lip: #0a1428;
  --topic-icon: #a3bdf5;
}
[data-design="v2"][data-theme="dark"] [data-section="history"] {
  --topic-node: #c07a35;
  --topic-rest: #2c1b0b;
  --topic-rest-lip: #201407;
  --topic-icon: #f0b47e;
}
[data-design="v2"][data-theme="dark"] [data-section="geography"] {
  --topic-node: #2f9b5a;
  --topic-rest: #0b2717;
  --topic-rest-lip: #081d11;
  --topic-icon: #8adbaa;
}
[data-design="v2"][data-theme="dark"] [data-section="government"] {
  --topic-node: #9a6fd0;
  --topic-rest: #241a33;
  --topic-rest-lip: #1a1226;
  --topic-icon: #cfb0f2;
}
/* The line-map look (data-design="v2", app/design.js): the path as a line
   diagram, the kind on a station wall or above a train door. Each section is a
   line in its own colour under a flat nameplate, each unit an interchange (a
   white circle ringed in ink) and each lesson a stop on it
   (today-route-stations.css). The line runs 10px wide down the left, and the
   names read to its right. Every rule here is scoped to the look, so the
   classic path is untouched. */
[data-design="v2"] #today .today-course-topic {
  --route-x: 22px;
  --route-w: 10px;
  --route-mid: calc(var(--route-x) + var(--route-w) / 2);
  --route-text: 58px;
  --route-done: var(--topic-node);
  --route-ahead: color-mix(in srgb, var(--topic-node) 40%, var(--paper));
  --route-closed: color-mix(in srgb, var(--topic-node) 55%, var(--paper));
}
/* ---------- the nameplate: a flat bar in the line's colour ---------- */
[data-design="v2"] #today .today-chapter {
  min-height: 64px;
  padding: 10px 12px 10px 16px;
  border-radius: 6px;
}
[data-design="v2"] #today .chapter-guidebook {
  border-radius: 6px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
}
/* ---------- the line ---------- */
[data-design="v2"] #today .today-path-group + .today-path-group {
  margin-top: 0;
}
[data-design="v2"] #today .today-path {
  padding: 0;
}
/* Each row paints its own stretch of line as a background, so the line can
   show where you have been (full colour) and where it goes next (paler). */
[data-design="v2"] #today .today-group-heading,
[data-design="v2"] #today .today-step {
  background-image: linear-gradient(var(--route, var(--route-ahead)), var(--route, var(--route-ahead)));
  background-repeat: no-repeat;
  background-size: var(--route-w) 100%;
  background-position: var(--route-x) 0;
}
[data-design="v2"] #today .today-step.is-complete,
[data-design="v2"]
  #today
  .today-group-heading:has(+ .today-path .today-step:first-child:is(.is-complete, .is-current)) {
  --route: var(--route-done);
}
/* The current station: travelled above it, still to come below. */
[data-design="v2"] #today .today-step.is-current {
  background-image:
    linear-gradient(var(--route-done), var(--route-done)), linear-gradient(var(--route-ahead), var(--route-ahead));
  background-size:
    var(--route-w) 50%,
    var(--route-w) 50%;
  background-position:
    var(--route-x) 0,
    var(--route-x) 100%;
}
/* The part the full course opens is drawn hollow, the way a map draws a line
   that is closed or not open yet. */
[data-design="v2"] #today .today-step.is-locked,
[data-design="v2"] #today .today-group-heading:has(+ .today-path .today-step:first-child.is-locked) {
  background-image: linear-gradient(
    90deg,
    var(--route-closed) 0 3px,
    transparent 3px calc(var(--route-w) - 3px),
    var(--route-closed) calc(var(--route-w) - 3px)
  );
}
/* Every section's line starts at its first interchange and ends at its last
   stop. */
[data-design="v2"] #today .today-chapter-wrap + .today-path-group > .today-group-heading {
  background-size: var(--route-w) 50%;
  background-position: var(--route-x) 100%;
}
[data-design="v2"] #today .today-course-topic > .today-path-group:last-of-type .today-step:last-child {
  background-size:
    var(--route-w) 50%,
    0 0;
  background-position: var(--route-x) 0;
}
/* ---------- interchanges: the units ---------- */
[data-design="v2"] #today .today-group-heading {
  position: relative;
  gap: 10px;
  min-height: 60px;
  padding: 8px 0 8px var(--route-text);
}
[data-design="v2"] #today .today-group-heading::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(var(--route-mid) - 14px);
  width: 28px;
  height: 28px;
  border: 5px solid var(--ink);
  border-radius: 50%;
  background: var(--paper);
  transform: translateY(-50%);
}
[data-design="v2"] #today .today-group-heading::after {
  display: none;
}
[data-design="v2"] #today .today-group-heading h3 {
  color: var(--ink);
  font-size: 17px;
  font-weight: 900;
  line-height: 1.25;
}
[data-design="v2"] #today .today-group-notes {
  margin-left: auto;
  border-radius: 8px;
}
/* A finished unit is stamped, as a passport is at a border: it sits with the
   notes at the end of the row and overhangs it rather than making it taller. */
[data-design="v2"] .today-stamp {
  flex: none;
  width: 56px;
  height: 56px;
  margin: -12px 0 -12px auto;
  color: var(--topic-banner);
  opacity: 0.9;
  transform: rotate(-10deg);
  pointer-events: none;
}
[data-design="v2"] #today .today-stamp + .today-group-notes {
  margin-left: 8px;
}
[data-design="v2"] .today-stamp svg {
  width: 100%;
  height: 100%;
}
@media (min-width: 960px) {
  [data-design="v2"] #today .today-path-group {
    max-width: 600px;
    margin-inline: auto;
  }
}
/* Stations on the line-map look (data-design="v2"; today-route-map.css draws
   the line). A lesson is a stop on the line: a ring while it is ahead, a
   filled disc with a tick once done, a lit circle where you are, and a paler
   ring on a closed stretch. The rows read as a list you can tap: a hairline
   between stops and, at the end of every row that opens, a chevron; the
   current row ends in Start and a locked one in a padlock.
   today-route-motion.css moves all of it. */
[data-design="v2"] #today .today-step {
  display: block;
  min-height: 0;
  padding: 0;
}
[data-design="v2"] #today .today-lesson {
  flex-direction: row;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 58px;
  margin: 0;
  padding: 8px 4px 8px var(--route-text);
  border-radius: 0;
  text-align: left;
  transform: none;
}
[data-design="v2"] #today .today-lesson:focus-visible {
  border-radius: 10px;
  outline-offset: -3px;
}
/* A hairline between stops, from the name to the row's end, so the rows read
   as a list to tap; the line itself stays unbroken. */
[data-design="v2"] #today .today-step + .today-step .today-lesson::before {
  content: "";
  position: absolute;
  top: 0;
  right: 4px;
  left: var(--route-text);
  height: 1px;
  background: var(--line-1);
}
[data-design="v2"] #today .today-node-wrap {
  position: absolute;
  top: 50%;
  left: calc(var(--route-mid) - 9px);
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
}
[data-design="v2"] #today .today-node,
[data-design="v2"] #today .is-current .today-node,
[data-design="v2"] #today .is-complete .today-node,
[data-design="v2"] #today .is-upcoming .today-node,
[data-design="v2"] #today .is-locked .today-node {
  width: 100%;
  height: 100%;
  border: 4px solid var(--route-done);
  border-radius: 50%;
  background: var(--paper);
  color: #fff;
  box-shadow: none;
  transform-origin: center;
}
[data-design="v2"] #today .is-complete .today-node {
  background: var(--route-done);
}
[data-design="v2"] #today .is-locked .today-node {
  border-color: var(--route-closed);
}
[data-design="v2"] #today .today-node svg,
[data-design="v2"] #today .today-node::before,
[data-design="v2"] #today .today-node::after,
[data-design="v2"] #today .today-node-shine {
  display: none;
}
[data-design="v2"] #today .is-complete .today-node svg {
  display: block;
  width: 10px;
  height: 10px;
}
/* You are here: a bigger station, lit, with a halo and the lesson's own icon. */
[data-design="v2"] #today .is-current .today-node-wrap {
  left: calc(var(--route-mid) - 16px);
  width: 32px;
  height: 32px;
}
[data-design="v2"] #today .is-current .today-node {
  border: 4px solid var(--paper);
  border-radius: 50%;
  background: var(--topic-node);
  color: #fff;
  box-shadow:
    0 0 0 4px var(--topic-node),
    0 0 0 8px color-mix(in srgb, var(--topic-node) 22%, transparent);
  transform-origin: center;
}
[data-design="v2"] #today .is-current .today-node svg {
  display: block;
  width: 16px;
  height: 16px;
}
[data-design="v2"] #today .is-current .today-node-wrap::after {
  display: none;
}
/* ---------- names ---------- */
[data-design="v2"] #today .today-lesson-title {
  display: flex;
  flex-direction: column-reverse;
  flex: 1;
  min-width: 0;
  max-width: none;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.3;
  text-wrap: pretty;
}
[data-design="v2"] #today .today-lesson-title b {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}
[data-design="v2"] #today .today-guided-kind {
  margin: 1px 0 0;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
}
[data-design="v2"] #today .is-locked .today-lesson-title b {
  color: var(--ink-3);
}
/* ---------- the status column ---------- */
[data-design="v2"] #today .today-open,
[data-design="v2"] #today .today-lock {
  flex: none;
  color: var(--ink-3);
}
[data-design="v2"] #today .today-open {
  width: 22px;
  font-size: 26px;
  text-align: center;
}
[data-design="v2"] #today .today-lock {
  width: 16px;
  height: 16px;
}
[data-design="v2"] #today .today-lock svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: currentColor;
}
[data-design="v2"] #today .today-bookmark {
  position: static;
  flex: none;
  width: 14px;
  height: 18px;
  filter: none;
}
/* Start is a plain sign in the line's colour at the end of the current row. */
[data-design="v2"] #today .today-start {
  position: static;
  order: 2;
  flex: none;
  padding: 8px 16px;
  border: 0;
  border-radius: 6px;
  background: var(--topic-banner);
  color: #fff;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
  transform: none;
  animation: none;
}
[data-design="v2"] #today .today-start::after {
  display: none;
}
/* Pointing at a stop, as on a map: it swells a little and its name is
   underlined in the line's colour. Nothing is drawn behind the row, so the
   line never breaks. */
@media (hover: hover) and (pointer: fine) {
  [data-design="v2"] #today .today-lesson:hover .today-node {
    transform: scale(1.25);
  }
  [data-design="v2"] #today .is-current .today-lesson:hover .today-node {
    transform: scale(1.08);
  }
  [data-design="v2"] #today .today-lesson:hover .today-lesson-title b {
    text-decoration-line: underline;
    text-decoration-thickness: 2px;
    text-decoration-color: var(--route-done);
    text-underline-offset: 4px;
  }
}
[data-design="v2"] #today .today-step .today-lesson.is-pressed .today-node {
  transform: scale(0.85);
}
/* Folding on the line-map look (data-design="v2"): every section but the one
   you are in folds to its nameplate, with a line of summary, and opens on a
   tap (learn-path-controls.js keeps the choice for the visit; the view sets
   is-folded). The row you are on also sits on a soft plate in the line's
   colour, so a new learner's eye lands on "start here" before anything else. */
[data-design="v2"] #today .today-chapter {
  position: relative;
}
/* The toggle covers the whole nameplate, with its chevron at the right; the
   notes button sits above it, and only shows on an open section. */
[data-design="v2"] #today .chapter-toggle {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 12px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: #fff;
  cursor: pointer;
}
[data-design="v2"] #today .chapter-toggle svg {
  width: 26px;
  height: 26px;
  fill: none;
  transition: transform 0.2s var(--ease);
}
[data-design="v2"] #today .is-folded .chapter-toggle svg {
  transform: rotate(-90deg);
}
[data-design="v2"] #today .chapter-toggle:focus-visible {
  outline: 3px solid #fff;
  outline-offset: -4px;
}
[data-design="v2"] #today .chapter-guidebook {
  position: relative;
  z-index: 1;
  margin-right: 38px;
}
[data-design="v2"] #today .is-folded .chapter-guidebook,
[data-design="v2"] #today .is-folded .today-path-group,
[data-design="v2"] #today .is-folded .today-section-empty,
[data-design="v2"] #today .chapter-summary {
  display: none;
}
[data-design="v2"] #today .is-folded .chapter-summary {
  display: block;
  margin: 3px 0 0;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}
[data-design="v2"] #today .is-folded .today-chapter-wrap {
  padding-bottom: 0;
}
[data-design="v2"] #today .today-course-topic.is-folded {
  margin-bottom: 10px;
  padding-bottom: 0;
}
/* Where you are: a soft plate from the name to the row's end, clear of the
   line beside it. */
[data-design="v2"] #today .is-current .today-lesson {
  isolation: isolate;
}
[data-design="v2"] #today .is-current .today-lesson::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 3px 0 3px calc(var(--route-text) - 10px);
  border-radius: 10px;
  background: var(--topic-rest);
}
@media (prefers-reduced-motion: reduce) {
  [data-design="v2"] #today .chapter-toggle svg {
    transition: none;
  }
}
/* How the line map moves (data-design="v2"). Where you are breathes like a live
   position on a map. Finishing a lesson (learn-path-position.js marks the step
   is-just-done, then path-completion.js runs its cue classes) fills the stop
   with its tick, draws the line on to the next stop, and pops that stop into
   place with a ring; the last lesson of a unit
   (is-stamping) slams its passport stamp down. Everything here is off under
   prefers-reduced-motion, as path-completion.js is. */
[data-design="v2"] #today .today-stamp {
  transform-origin: center;
}
/* You are here: the halo breathes. */
[data-design="v2"] #today .is-current .today-node {
  animation: v2-here 2.6s ease-in-out infinite;
}
@keyframes v2-here {
  0%,
  100% {
    box-shadow:
      0 0 0 4px var(--topic-node),
      0 0 0 8px color-mix(in srgb, var(--topic-node) 22%, transparent);
  }
  50% {
    box-shadow:
      0 0 0 4px var(--topic-node),
      0 0 0 12px color-mix(in srgb, var(--topic-node) 10%, transparent);
  }
}
/* Just finished: the stop fills with its tick, and the line draws on past it.
   At the last stop of a line there is no line to draw on. */
[data-design="v2"] #today .is-just-done .today-node {
  animation: v2-disc 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.3s both;
}
[data-design="v2"] #today .today-step.is-just-done {
  animation: v2-line-on 0.55s ease-in-out 0.7s both;
}
[data-design="v2"] #today .today-course-topic > .today-path-group:last-of-type .today-step:last-child.is-just-done {
  animation: none;
}
@keyframes v2-disc {
  from {
    opacity: 0;
    transform: scale(0) rotate(-40deg);
  }
  60% {
    opacity: 1;
    transform: scale(1.25) rotate(4deg);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes v2-line-on {
  from {
    background-size: var(--route-w) 50%;
  }
  to {
    background-size: var(--route-w) 100%;
  }
}
/* The next station, while the finished one celebrates (is-awaiting-reveal): no
   circle yet, and the line arrives from above. Then it is your station
   (is-next-cue): the circle pops into place, its halo rings out, and the sign
   slides in. */
[data-design="v2"] #today .is-awaiting-reveal .today-node {
  transform: scale(0);
  animation: none;
}
[data-design="v2"] #today .today-step.is-awaiting-reveal {
  animation: v2-line-in 0.5s ease-in-out 1.2s both;
}
@keyframes v2-line-in {
  from {
    background-size:
      var(--route-w) 0%,
      var(--route-w) 50%;
  }
  to {
    background-size:
      var(--route-w) 50%,
      var(--route-w) 50%;
  }
}
[data-design="v2"] #today .is-next-cue .today-node {
  animation:
    v2-arrive 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) 0.35s both,
    v2-here 2.6s ease-in-out 0.9s infinite;
}
[data-design="v2"] #today .is-next-cue .today-node-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  display: block;
  border: 3px solid var(--topic-node);
  border-radius: 50%;
  pointer-events: none;
  animation: v2-ring 0.9s ease-out 0.55s both;
}
[data-design="v2"] #today .is-next-cue .today-start {
  animation: v2-sign 0.4s ease-out 0.7s both;
}
@keyframes v2-arrive {
  from {
    transform: scale(0);
  }
  60% {
    transform: scale(1.15);
  }
  to {
    transform: none;
  }
}
@keyframes v2-ring {
  from {
    opacity: 0.9;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(2.4);
  }
}
@keyframes v2-sign {
  from {
    opacity: 0;
    transform: translateX(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* The unit's last lesson done: the passport stamp comes down. */
[data-design="v2"] #today .is-stamping .today-stamp {
  animation: v2-stamp 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.25) 0.9s both;
}
@keyframes v2-stamp {
  from {
    opacity: 0;
    transform: scale(2.2) rotate(-24deg);
  }
  70% {
    opacity: 0.95;
    transform: scale(0.94) rotate(-9deg);
  }
  to {
    opacity: 0.9;
    transform: scale(1) rotate(-10deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  [data-design="v2"] #today .today-step:is(.is-just-done, .is-awaiting-reveal),
  [data-design="v2"]
    #today
    :is(.is-current, .is-just-done, .is-next-cue, .is-stamping)
    :is(.today-node, .today-start, .today-stamp),
  [data-design="v2"] #today .is-next-cue .today-node-wrap::after {
    animation: none;
  }
  [data-design="v2"] #today .is-next-cue .today-node-wrap::after {
    display: none;
  }
  [data-design="v2"] #today .is-awaiting-reveal .today-node {
    transform: none;
  }
}
/* The course map look (data-design="v3", app/design.js): the path as a winding
   course, the way a syllabus app draws it. Every lesson is a big ring with the
   topic's illustration inside, its number and title beside it; the first node
   sits in the middle and the rest alternate left and right, joined by the
   S-shaped links today-v3-links.css draws. Every rule is scoped to the look. */
[data-design="v3"] #today {
  --course-node: 76px;
  --course-ring: 10px;
  --course-gap: 94px;
  --course-caption: 48px;
  --course-line: 12px;
  --course-x-l: 20%;
  --course-x-r: 80%;
  --course-x-c: 50%;
}
[data-design="v3"] #today .today-course-topic {
  --course-done: var(--topic-node);
  --course-ahead: color-mix(in srgb, var(--topic-node) 32%, var(--paper));
  --course-closed: var(--line-2);
  /* Text takes the palette's own ink, which clears 4.5:1 on paper; the bright
     classic hues do not. */
  --course-ink: var(--topic-icon);
  margin-bottom: 0;
  padding-bottom: 0;
}
[data-design="v3"] #today .today-course {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* A row is the link down from the last node, then the node. */
[data-design="v3"] #today .today-step {
  position: relative;
  display: block;
  min-height: 0;
  padding: var(--course-gap) 0 0;
}
[data-design="v3"] #today .today-step[data-link=""] {
  padding-top: 12px;
}
[data-design="v3"] #today .today-step.is-section-start {
  padding-top: calc(var(--course-gap) + var(--course-caption));
}
[data-design="v3"] #today .today-step.is-section-start[data-link=""] {
  padding-top: var(--course-caption);
}
[data-design="v3"] #today [data-side="l"] {
  --course-x: var(--course-x-l);
}
[data-design="v3"] #today [data-side="r"] {
  --course-x: var(--course-x-r);
}
[data-design="v3"] #today [data-side="c"] {
  --course-x: var(--course-x-c);
}
/* A section's name sits on the line above its first node. */
[data-design="v3"] #today .course-caption {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--course-caption);
  margin: 0;
  pointer-events: none;
}
[data-design="v3"] #today .course-caption span {
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--paper);
  color: var(--course-ink);
  font-size: 13px;
  font-weight: 800;
}
/* ---------- the node ---------- */
[data-design="v3"] #today .today-lesson {
  position: relative;
  display: block;
  width: 100%;
  height: var(--course-node);
  min-height: 0;
  margin: 0;
  padding: 0;
  border-radius: 0;
  text-align: left;
  transform: none;
}
[data-design="v3"] #today .course-ring {
  position: absolute;
  top: 0;
  left: calc(var(--course-x) - var(--course-node) / 2);
  display: grid;
  place-items: center;
  width: var(--course-node);
  height: var(--course-node);
  border: var(--course-ring) solid var(--course-ahead);
  border-radius: 50%;
  background: var(--paper);
  transition: transform 0.15s var(--ease);
}
[data-design="v3"] #today .course-face {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--course-done);
}
[data-design="v3"] #today .course-face .book-art {
  width: 44px;
  height: 44px;
  object-fit: contain;
}
[data-design="v3"] #today .course-face svg {
  width: 26px;
  height: 26px;
  fill: currentColor;
}
[data-design="v3"] #today .is-complete .course-ring,
[data-design="v3"] #today .is-current .course-ring {
  border-color: var(--course-done);
}
[data-design="v3"] #today .is-upcoming .course-face {
  filter: grayscale(1) opacity(0.55);
}
[data-design="v3"] #today .is-locked .course-ring {
  border-color: var(--course-closed);
}
[data-design="v3"] #today .is-locked .course-face {
  filter: grayscale(1) opacity(0.45);
}
/* A badge on the ring: a tick once done, a padlock on the closed part. */
[data-design="v3"] #today .course-tick,
[data-design="v3"] #today .course-lock {
  position: absolute;
  right: -6px;
  bottom: -6px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 3px solid var(--paper);
  border-radius: 50%;
  background: var(--course-done);
  color: #fff;
}
[data-design="v3"] #today .course-lock {
  background: var(--ink-3);
}
[data-design="v3"] #today .course-tick svg,
[data-design="v3"] #today .course-lock svg {
  width: 13px;
  height: 13px;
  fill: currentColor;
}
/* The labels of the course map (data-design="v3", today-v3-course.css draws
   the nodes): a lesson's number and title beside its ring, on the side away
   from the line's next bend, with Start under the one you are on. */
[data-design="v3"] #today .course-label {
  position: absolute;
  top: 50%;
  left: calc(var(--course-x) + var(--course-node) / 2 + 16px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: calc(100% - var(--course-x) - var(--course-node) / 2 - 16px);
  color: var(--ink);
  transform: translateY(-50%);
}
[data-design="v3"] #today [data-side="r"] .course-label {
  left: 0;
  align-items: flex-end;
  width: calc(var(--course-x) - var(--course-node) / 2 - 16px);
  text-align: right;
}
[data-design="v3"] #today .course-number {
  color: var(--course-ink);
  font-size: 22px;
  font-weight: 900;
  line-height: 1.1;
}
[data-design="v3"] #today .course-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  text-wrap: balance;
}
[data-design="v3"] #today .is-upcoming .course-number,
[data-design="v3"] #today .is-locked .course-number,
[data-design="v3"] #today .is-locked .course-title {
  color: var(--ink-3);
}
[data-design="v3"] #today .is-upcoming .course-title {
  color: var(--ink-2);
  font-weight: 600;
}
/* Start hangs under the ring you are on, over the line's first stretch. */
[data-design="v3"] #today .today-start {
  position: absolute;
  bottom: -18px;
  left: 50%;
  z-index: 1;
  padding: 7px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--course-ink);
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  transform: translateX(-50%);
  animation: none;
}
[data-design="v3"] #today .today-start::after {
  display: none;
}
/* At night the palette's ink is light, so the sign takes a deep tint of it. */
[data-design="v3"][data-theme="dark"] #today .today-start {
  background: color-mix(in srgb, var(--topic-icon) 40%, var(--paper));
}
[data-design="v3"] #today .today-bookmark {
  position: static;
  width: 14px;
  height: 18px;
  filter: none;
}
@media (min-width: 960px) {
  [data-design="v3"] #today .today-course {
    max-width: 560px;
    margin-inline: auto;
  }
}
/* The links of the course map (data-design="v3"): from the last node's foot to
   this node's head, an S drawn with two rounded bends — each row's ::before
   takes the first bend and ::after the second — in the colour of the node it
   leads to: the section's colour where you have been and where you are, a
   pale tint ahead, grey on the closed part. data-link names the sides it
   joins: lr, rl, or cl for the first bend down from the middle. A section's
   first row also carries a straight stretch behind its caption. */
[data-design="v3"] #today .today-step {
  --course-link: var(--course-ahead);
  --course-top: 0px;
  --course-bend: 33px;
}
[data-design="v3"] #today .today-step:is(.is-complete, .is-current) {
  --course-link: var(--course-done);
}
[data-design="v3"] #today .today-step.is-locked {
  --course-link: var(--course-closed);
}
[data-design="v3"] #today .today-step.is-section-start {
  --course-top: var(--course-caption);
}
[data-design="v3"] #today .today-step::before,
[data-design="v3"] #today .today-step::after {
  content: "";
  position: absolute;
  top: var(--course-top);
  height: 53px;
  border: 0 solid var(--course-link);
  pointer-events: none;
}
[data-design="v3"] #today .today-step::after {
  top: calc(var(--course-top) + 41px);
}
[data-design="v3"] #today .today-step[data-link=""]::before,
[data-design="v3"] #today .today-step[data-link=""]::after,
[data-design="v3"] #today .today-step[data-link=""] .course-caption::before {
  display: none;
}
/* left to right */
[data-design="v3"] #today [data-link="lr"]::before {
  left: calc(var(--course-x-l) - 6px);
  width: calc(30% + 6px);
  border-bottom-width: var(--course-line);
  border-left-width: var(--course-line);
  border-bottom-left-radius: var(--course-bend);
}
[data-design="v3"] #today [data-link="lr"]::after {
  left: 50%;
  width: calc(30% + 6px);
  border-top-width: var(--course-line);
  border-right-width: var(--course-line);
  border-top-right-radius: var(--course-bend);
}
/* right to left */
[data-design="v3"] #today [data-link="rl"]::before {
  left: 50%;
  width: calc(30% + 6px);
  border-right-width: var(--course-line);
  border-bottom-width: var(--course-line);
  border-bottom-right-radius: var(--course-bend);
}
[data-design="v3"] #today [data-link="rl"]::after {
  left: calc(var(--course-x-l) - 6px);
  width: calc(30% + 6px);
  border-top-width: var(--course-line);
  border-left-width: var(--course-line);
  border-top-left-radius: var(--course-bend);
}
/* the middle to the left: the first bend of the course */
[data-design="v3"] #today [data-link="cl"]::before {
  left: 35%;
  width: calc(15% + 6px);
  border-right-width: var(--course-line);
  border-bottom-width: var(--course-line);
  border-bottom-right-radius: 30px;
}
[data-design="v3"] #today [data-link="cl"]::after {
  left: calc(var(--course-x-l) - 6px);
  width: calc(15% + 6px);
  border-top-width: var(--course-line);
  border-left-width: var(--course-line);
  border-top-left-radius: 30px;
}
/* The straight stretch behind a section's caption, down from the last node. */
[data-design="v3"] #today .course-caption::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: -1;
  width: var(--course-line);
  background: var(--course-link);
}
[data-design="v3"] #today [data-link^="l"] .course-caption::before {
  left: calc(var(--course-x-l) - 6px);
}
[data-design="v3"] #today [data-link^="r"] .course-caption::before {
  left: calc(var(--course-x-r) - 6px);
}
/* ---------- motion: where you are breathes; finishing pops the ring ---------- */
[data-design="v3"] #today .is-current .course-ring {
  animation: v3-here 2.6s ease-in-out infinite;
}
@keyframes v3-here {
  0%,
  100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--topic-node) 30%, transparent);
  }
  50% {
    box-shadow: 0 0 0 12px color-mix(in srgb, var(--topic-node) 0%, transparent);
  }
}
[data-design="v3"] #today .is-just-done .course-ring {
  animation: v3-pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.25s both;
}
[data-design="v3"] #today .is-just-done .course-tick {
  animation: v2-disc 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.45s both;
}
@keyframes v3-pop {
  50% {
    transform: scale(1.15);
  }
  to {
    transform: none;
  }
}
[data-design="v3"] #today .is-awaiting-reveal .course-ring {
  animation: none;
}
[data-design="v3"] #today .is-next-cue .course-ring {
  animation:
    v3-pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s both,
    v3-here 2.6s ease-in-out 0.8s infinite;
}
[data-design="v3"] #today .is-next-cue .today-start {
  animation: v2-sign 0.4s ease-out 0.6s both;
}
@media (hover: hover) and (pointer: fine) {
  [data-design="v3"] #today .today-lesson:hover .course-ring {
    transform: scale(1.06);
  }
}
[data-design="v3"] #today .today-lesson.is-pressed .course-ring {
  transform: scale(0.94);
}
@media (prefers-reduced-motion: reduce) {
  [data-design="v3"]
    #today
    :is(.is-current, .is-just-done, .is-next-cue)
    :is(.course-ring, .course-tick, .today-start) {
    animation: none;
  }
}
/* The classic route (the owner's pick, 2 Oct 2026): a section's lessons in one
   line under its banner, stepping left, centre, right and back to the left,
   each coin named beside it with where it stands. routePlacer
   (learn-course-view.js) gives each row data-side (l, c or r) and data-link,
   the sides it joins; today-classic-line.css draws the line. Classic look only. */
html:not([data-design]) #today {
  --route-l: 27%;
  --route-c: 50%;
  --route-r: 73%;
}
html:not([data-design]) #today .today-chapter-wrap {
  padding-bottom: 0;
}
html:not([data-design]) #today .today-route {
  padding: 0 0 8px;
}
/* A row is the gap the line crosses from the last coin, then the coin. */
html:not([data-design]) #today .today-route .today-step {
  --route-gap: 80px;
  position: relative;
  display: block;
  min-height: 0;
  padding: var(--route-gap) 0 0;
}
/* START needs room above the lesson you are on, below the line's bend. */
html:not([data-design]) #today .today-route .today-step.is-current {
  --route-gap: 108px;
}
html:not([data-design]) #today .today-route .today-step:first-child {
  --route-gap: 30px;
}
html:not([data-design]) #today .today-route .today-step.is-current:first-child {
  --route-gap: 64px;
}
html:not([data-design]) #today .today-route [data-side="l"] {
  --route-x: var(--route-l);
}
html:not([data-design]) #today .today-route [data-side="c"] {
  --route-x: var(--route-c);
}
html:not([data-design]) #today .today-route [data-side="r"] {
  --route-x: var(--route-r);
}
/* The button spans the row: its coin on its column, the name beside the coin. */
html:not([data-design]) #today .today-route .today-lesson {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 70px;
  min-height: 0;
  margin: 0;
  padding: 0;
  text-align: left;
  transform: none;
}
html:not([data-design]) #today .today-route .is-current .today-lesson {
  height: 84px;
}
html:not([data-design]) #today .today-route .today-node-wrap {
  position: absolute;
  top: 0;
  left: calc(var(--route-x) - 36px);
}
html:not([data-design]) #today .today-route .is-current .today-node-wrap {
  left: calc(var(--route-x) - 44px);
}
html:not([data-design]) #today .today-route .today-start {
  bottom: calc(100% + 16px);
  left: var(--route-x);
}
/* Names sit to the right of a coin, or to its left on the right-hand column. */
html:not([data-design]) #today .today-route .today-lesson-title {
  --route-label: 52px;
  position: absolute;
  top: 32px;
  right: 0;
  left: calc(var(--route-x) + var(--route-label));
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  max-width: none;
  text-align: left;
  overflow-wrap: break-word;
  translate: 0 -50%;
}
html:not([data-design]) #today .today-route .is-current .today-lesson-title {
  --route-label: 60px;
  top: 39px;
}
html:not([data-design]) #today .today-route [data-side="r"] .today-lesson-title {
  right: calc(100% - var(--route-x) + var(--route-label));
  left: 0;
  align-items: flex-end;
  text-align: right;
}
html:not([data-design]) #today .today-route .today-lesson-title b {
  max-width: 100%;
  color: var(--ink);
  font-size: 16px;
  font-weight: 900;
  line-height: 1.2;
}
html:not([data-design]) #today .today-route .is-locked .today-lesson-title b {
  color: var(--ink-2);
}
html:not([data-design]) #today .today-route .today-guided-kind {
  display: none;
}
html:not([data-design]) #today .today-lesson-status {
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 800;
}
html:not([data-design]) #today .is-complete .today-lesson-status {
  color: var(--correct-ink);
}
html:not([data-design]) #today .is-complete .today-lesson-status::before {
  content: "✓ ";
}
html:not([data-design]) #today .is-current .today-lesson-status {
  color: var(--topic-icon);
}
/* The gold card hangs under its coin, over the coin's lip as it always has
   (the buttons above sit a layer up). On the side columns it keeps to the
   page, its caret still on the coin. */
html:not([data-design]) #today .today-route .gold-offer {
  z-index: 2;
}
html:not([data-design]) #today .today-route [data-side="l"] .gold-offer {
  left: calc(var(--route-x) - 56px);
  width: min(320px, calc(100% - var(--route-x) + 52px));
  translate: none;
}
html:not([data-design]) #today .today-route [data-side="l"] .gold-offer::before {
  left: 48px;
}
html:not([data-design]) #today .today-route [data-side="r"] .gold-offer {
  right: calc(100% - var(--route-x) - 56px);
  left: auto;
  width: min(320px, calc(var(--route-x) + 52px));
  translate: none;
}
html:not([data-design]) #today .today-route [data-side="r"] .gold-offer::before {
  right: 48px;
  left: auto;
}
/* The classic route's line (the owner's pick, 2 Oct 2026): from each coin to
   the next in two rounded bends, in the section colour only when both lessons
   are complete and grey otherwise. A row's ::before takes the first bend, down from the
   last coin and across to halfway; ::after the second, across and down into
   the coin. data-link names the columns a row's line joins, from and to
   (today-classic-route.css); a section's first lesson stands under the last
   one before its banner, and the line runs on beneath the banner. The sticky
   banners (z-index 3) and top row (4) cover the line as it scrolls. Classic
   look only.
   Each bend is a box with the same border and radius all round, reaching
   --route-hide past its two hidden sides and clipped back to its one corner:
   WebKit seams a corner where two different border sides meet. The halves
   overlap by 2px, clipped back by 1px, so they meet without a seam at any
   pixel ratio. */
html:not([data-design]) #today {
  --route-line: 12px;
  --route-bend: 40px;
  --route-hide: 30px;
}
html:not([data-design]) #today .today-route .today-step {
  --route-link: var(--line-2);
}
html:not([data-design]) #today .today-route .today-step.is-link-complete {
  --route-link: var(--topic-node);
}
html:not([data-design]) #today .today-route [data-link^="l"] {
  --route-from: var(--route-l);
}
html:not([data-design]) #today .today-route [data-link^="c"] {
  --route-from: var(--route-c);
}
html:not([data-design]) #today .today-route [data-link^="r"] {
  --route-from: var(--route-r);
}
html:not([data-design]) #today .today-route :is([data-link="lc"], [data-link="lr"], [data-link="cr"]) {
  --route-span: calc((var(--route-x) - var(--route-from)) / 2 + var(--route-line) / 2);
}
html:not([data-design]) #today .today-route :is([data-link="cl"], [data-link="rl"], [data-link="rc"]) {
  --route-span: calc((var(--route-from) - var(--route-x)) / 2 + var(--route-line) / 2);
}
html:not([data-design]) #today .today-route .today-step::before,
html:not([data-design]) #today .today-route .today-step::after {
  content: "";
  position: absolute;
  z-index: 0;
  border: var(--route-line) solid var(--route-link);
  border-radius: 26px;
  pointer-events: none;
}
html:not([data-design]) #today .today-route .today-step::before {
  top: calc(-1 * var(--route-hide));
  width: calc(var(--route-span) + var(--route-hide));
  height: calc(var(--route-bend) + var(--route-line) / 2 + var(--route-hide));
}
html:not([data-design]) #today .today-route .today-step::after {
  top: calc(var(--route-bend) - var(--route-line) / 2);
  width: calc(var(--route-span) + 2px + var(--route-hide));
  height: calc(var(--route-gap) - var(--route-bend) + var(--route-line) / 2 + 4px + var(--route-hide));
}
html:not([data-design]) #today .today-route .today-step[data-link=""]::before,
html:not([data-design]) #today .today-route .today-step[data-link=""]::after,
html:not([data-design]) #today .today-route :is([data-link="ll"], [data-link="cc"], [data-link="rr"])::after {
  display: none;
}
/* Towards the right. */
html:not([data-design]) #today .today-route :is([data-link="lc"], [data-link="lr"], [data-link="cr"])::before {
  left: calc(var(--route-from) - var(--route-line) / 2);
  clip-path: inset(var(--route-hide) var(--route-hide) 0 0);
}
html:not([data-design]) #today .today-route :is([data-link="lc"], [data-link="lr"], [data-link="cr"])::after {
  left: calc((var(--route-from) + var(--route-x)) / 2 - 2px - var(--route-hide));
  clip-path: inset(0 0 var(--route-hide) calc(var(--route-hide) + 1px));
}
/* Towards the left. */
html:not([data-design]) #today .today-route :is([data-link="cl"], [data-link="rl"], [data-link="rc"])::before {
  left: calc((var(--route-from) + var(--route-x)) / 2 - var(--route-hide));
  clip-path: inset(var(--route-hide) 0 0 var(--route-hide));
}
html:not([data-design]) #today .today-route :is([data-link="cl"], [data-link="rl"], [data-link="rc"])::after {
  left: calc(var(--route-x) - var(--route-line) / 2);
  clip-path: inset(0 calc(var(--route-hide) + 1px) var(--route-hide) 0);
}
/* Straight on, from under the banner into a section's first coin. */
html:not([data-design]) #today .today-route :is([data-link="ll"], [data-link="cc"], [data-link="rr"])::before {
  top: 0;
  left: calc(var(--route-x) - var(--route-line) / 2);
  width: var(--route-line);
  height: calc(var(--route-gap) + 4px);
  border: 0;
  border-radius: 0;
  background: var(--route-link);
}
/* And on from a section's last coin to the next banner. */
html:not([data-design]) #today .today-course-topic:not(:last-of-type) .today-step:last-child .today-lesson::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: 100%;
  left: calc(var(--route-x) - var(--route-line) / 2);
  width: var(--route-line);
  height: 44px;
  background: var(--line-2);
  pointer-events: none;
}
html:not([data-design]) #today .today-course-topic.is-bridge-complete .today-step:last-child .today-lesson::after {
  background: var(--topic-node);
}
/* The classic Learn path's coins (the owner's picks, 2 Oct 2026): rounded
   squares in solid colours with the app's white symbols. Finished lessons and
   the one you are on wear the section colour; lessons not reached yet are solid
   grey. Gold lessons (today-gold.css) keep their gold and shine. The lesson you
   are on is a size up, with a gold START. Where the coins sit
   and their names are today-classic-route.css. Classic look only. */
html:not([data-design]) #today .today-node-wrap {
  --node-radius: 22px;
  width: 72px;
  height: 64px;
}
html:not([data-design]) #today .today-node {
  width: 72px;
  height: 64px;
  border-radius: 22px;
  box-shadow:
    0 6px 0 var(--node-lip),
    0 12px 18px rgb(157 22 39 / 0.12);
}
html:not([data-design]) #today .today-node svg {
  width: 30px;
  height: 30px;
}
html:not([data-design]) #today .is-complete:not(.is-gold) .today-node {
  --node-lip: var(--topic-lip);
  background: var(--topic-node);
  color: #fff;
}
html:not([data-design]) #today .is-complete:not(.is-gold) .today-node::before,
html:not([data-design]) #today .is-complete:not(.is-gold) .today-node::after,
html:not([data-design]) #today .is-complete:not(.is-gold) .today-node-shine {
  display: none;
}
html:not([data-design]) #today .is-upcoming .today-node,
html:not([data-design]) #today .is-locked .today-node {
  --node-lip: #afbbca;
  --node-face: #cdd6e1;
  background: var(--node-face);
  color: #fff;
  box-shadow: 0 6px 0 var(--node-lip);
}
html:not([data-design]) #today .is-current .today-node-wrap {
  width: 88px;
  height: 78px;
}
html:not([data-design]) #today .is-current .today-node {
  --node-soft-shadow: 0 14px 22px rgb(157 22 39 / 0.16);
  width: 88px;
  height: 78px;
  border-radius: 24px;
  box-shadow:
    0 6px 0 var(--node-lip),
    var(--node-soft-shadow);
}
html:not([data-design]) #today .is-current .today-node svg {
  width: 36px;
  height: 36px;
}
html:not([data-design]) #today .is-current .today-node-wrap::after {
  display: none;
}
html:not([data-design]) #today .today-start {
  padding: 7px 14px 8px;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(#ffd54a, #ffbe1a);
  box-shadow:
    0 4px 0 #d48f00,
    0 9px 14px rgb(150 90 0 / 0.2);
  color: #fff;
  font-size: 13.5px;
  letter-spacing: 1.1px;
  text-shadow: 0 2px 0 #b8790a;
}
/* The pointer keeps the tag's 4px lip under it. The pointer is a square turned
   45deg, so its shadow is offset 2.8px along both of its own sides, which
   lands it straight down. */
html:not([data-design]) #today .today-start::after {
  bottom: -5px;
  border: 0;
  background: #ffc21f;
  box-shadow: 2.8px 2.8px 0 #d48f00;
}
html[data-theme="dark"]:not([data-design]) #today .today-node {
  --node-soft-shadow: 0 0 0 transparent;
  box-shadow: 0 6px 0 var(--node-lip);
}
html[data-theme="dark"]:not([data-design]) #today .is-upcoming .today-node,
html[data-theme="dark"]:not([data-design]) #today .is-locked .today-node {
  --node-lip: #262e37;
  --node-face: #3a4452;
  background: var(--node-face);
  color: #aab4c2;
}
/* The press the coins have always had (today-is-complete-today-node-before.css):
   the face sinks into its 6px lip, so the bottom edge stays put, and a mouse
   over it sinks it a little. Restated here because the coin rules above
   outrank the original's shadows. With reduced motion a pressed coin darkens
   instead, as before. */
@media (hover: hover) and (pointer: fine) {
  html:not([data-design]) #today .today-lesson:hover .today-node {
    box-shadow: 0 4px 0 var(--node-lip);
  }
  html:not([data-design]) #today .is-current .today-lesson:hover .today-node {
    animation: none;
    box-shadow: 0 4px 0 var(--node-lip);
  }
}
@media (prefers-reduced-motion: no-preference) {
  html:not([data-design]) #today .today-lesson.is-pressed .today-node {
    transform: translateY(5px);
    box-shadow: 0 1px 0 var(--node-lip);
  }
  html:not([data-design]) #today .is-current .today-lesson.is-pressed .today-node {
    box-shadow: 0 1px 0 var(--node-lip);
  }
}

/* Invite a Start/Resume with one gentle half-press, then a long rest.
   The face moves 3px into its 6px lip, keeping the bottom edge still.
   Holding the real button and the completion sequence take priority. */
@media (prefers-reduced-motion: no-preference) {
  html:not([data-design]) #today .is-current:not(.is-next-cue) .today-start {
    animation: none;
  }
  html:not([data-design])
    #today.show
    :where(.is-current:not(.is-celebrating, .is-awaiting-reveal, .is-next-cue))
    .today-lesson:where(:not(.is-pressed, :active, :focus-visible, :disabled))
    .today-node {
    animation: today-lesson-invite 4.5s ease-in-out infinite;
  }
  @keyframes today-lesson-invite {
    0%,
    68%,
    84%,
    100% {
      transform: translateY(0);
      box-shadow:
        0 6px 0 var(--node-lip),
        var(--node-soft-shadow);
    }
    76% {
      transform: translateY(3px);
      box-shadow:
        0 3px 0 var(--node-lip),
        var(--node-soft-shadow);
    }
  }
}
/* Compact Learn layout; country section tokens supply the accent colours. */
#today .learn-list {
  --list-ring: var(--topic-icon, var(--brand-ink));
  --list-soft: var(--topic-rest, var(--brand-soft));
}
#today .lesson-list-section {
  margin-bottom: 24px;
}
#today .lesson-list-section,
#today .lesson-list-section-link {
  --list-banner: color-mix(in srgb, var(--topic-banner, var(--brand)), #000 30%);
}
#today .lesson-list-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px 12px;
  padding: 18px;
  border-radius: 20px;
  background: var(--list-banner);
  box-shadow: 0 5px 0 color-mix(in srgb, var(--list-banner), #000 20%);
  color: #fff;
}
#today .lesson-list-eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.7px;
}
#today .lesson-list-card h2 {
  margin: 0;
  font-size: clamp(22px, 5.8vw, 28px);
  font-weight: 900;
  line-height: 1.2;
  text-wrap: balance;
}
#today .lesson-list-notes {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: 24px;
  background: #fff;
  color: var(--list-banner);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
}
#today .lesson-list-notes svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}
#today .lesson-list-notes:hover {
  background: #eef6fc;
}
#today .lesson-list-progress {
  grid-column: 1 / -1;
  appearance: none;
  display: block;
  width: 100%;
  height: 10px;
  overflow: hidden;
  border: 0;
  border-radius: 10px;
  background: rgb(255 255 255 / 30%);
}
#today .lesson-list-progress::-webkit-progress-bar {
  background: rgb(255 255 255 / 30%);
  border-radius: 10px;
}
#today .lesson-list-progress::-webkit-progress-value {
  background: #fff;
  border-radius: 10px;
}
#today .lesson-list-progress::-moz-progress-bar {
  background: #fff;
  border-radius: 10px;
}
#today .lesson-list-count {
  grid-column: 1 / -1;
  margin: -6px 0 0;
  font-size: 16px;
  font-weight: 900;
}
#today .lesson-list-rows {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
}
#today .learn-list .lesson-list-row {
  position: relative;
  display: block;
  min-height: 0;
  margin: 0;
  padding: 0;
  --list-ring: var(--topic-icon, var(--brand-ink));
  --list-soft: var(--topic-rest, var(--brand-soft));
}
#today .learn-list .lesson-list-row::before,
#today .learn-list .lesson-list-row::after {
  content: "";
  position: absolute;
  left: 28px;
  width: 4px;
  background: var(--line-2);
  pointer-events: none;
}
#today .learn-list .lesson-list-row::before {
  top: 0;
  height: 50%;
}
#today .learn-list .lesson-list-row::after {
  top: 50%;
  bottom: 0;
}
#today .learn-list .lesson-list-row:first-child::before,
#today .learn-list .lesson-list-row:last-child::after {
  display: none;
}
#today .learn-list .lesson-list-row.is-link-complete::before,
#today .learn-list .lesson-list-row.is-next-complete::after {
  background: var(--list-ring);
}
#today .learn-list .lesson-list-button {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: auto;
  min-height: 62px;
  margin: 0;
  padding: 9px 8px;
  border: 0;
  border-radius: 16px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  transform: none;
  cursor: pointer;
}
#today .learn-list .lesson-list-button::before,
#today .learn-list .lesson-list-button::after {
  display: none;
}
#today .learn-list .is-current .lesson-list-button {
  min-height: 76px;
  background: var(--list-soft);
}
#today .learn-list .lesson-list-button:hover {
  background: var(--panel-2);
}
#today .learn-list .is-current .lesson-list-button:hover {
  background: var(--list-soft);
}
#today .lesson-list-marker {
  position: relative;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: auto;
  border: 3px solid var(--list-ring);
  border-radius: 50%;
  background: var(--paper);
  color: var(--list-ring);
}
#today .lesson-list-marker svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}
#today .is-complete .lesson-list-marker,
#today .is-current .lesson-list-marker {
  background: var(--list-ring);
  color: #fff;
}
#today .is-current .lesson-list-marker {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--list-ring), transparent 80%);
}
#today .lesson-list-title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
#today .lesson-list-title b {
  font-size: 17px;
  font-weight: 900;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
#today .lesson-list-meta {
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 800;
  text-align: right;
}
#today .lesson-list-done {
  color: var(--list-ring);
  font-size: 15px;
  font-weight: 900;
}
#today .lesson-list-start {
  display: grid;
  place-items: center;
  min-width: 72px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 12px;
  background: var(--brand-ink);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--brand-ink), #000 25%);
  color: var(--paper);
  font-size: 16px;
  font-weight: 900;
  transition:
    transform 0.12s var(--ease),
    box-shadow 0.12s var(--ease);
}
#today .lesson-list-button.is-pressed .lesson-list-start {
  transform: translateY(3px);
  box-shadow: none;
}
#today .lesson-list-button.is-pressed .lesson-list-marker {
  transform: scale(0.94);
}
#today .lesson-list-bookmark svg {
  width: 16px;
  height: 20px;
  fill: #ff5c5c;
}
#today .learn-list .is-gold .lesson-list-marker {
  background: #fbbf24;
  border-color: #b36b00;
  color: #563800;
}
:root[data-theme="dark"] #today .learn-list .lesson-list-row {
  --list-ring: var(--topic-ring, var(--brand-ink));
  --list-soft: var(--panel-2);
}
:root[data-theme="dark"] #today .is-complete .lesson-list-marker,
:root[data-theme="dark"] #today .is-current .lesson-list-marker {
  color: var(--paper);
}
#today .lesson-list-sections {
  margin: 28px 0 0;
}
#today .lesson-list-sections h2 {
  margin: 0 8px 8px;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}
#today .lesson-list-section-link {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 8px;
  border: 0;
  border-bottom: 1px solid var(--line-1);
  border-radius: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
#today .lesson-list-section-link:hover {
  background: var(--panel-2);
  border-radius: 12px;
}
#today .lesson-list-number {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--list-banner);
  color: #fff;
  font-size: 17px;
  font-weight: 900;
}
#today .lesson-list-section-link b {
  min-width: 0;
  font-size: 16px;
  font-weight: 900;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
#today .lesson-list-summary {
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 800;
  text-align: right;
}
#today .lesson-list-summary > span {
  padding-left: 4px;
}
#today .lesson-list-tools {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin: 24px 0 0;
}
#today .lesson-list-tools .ghost {
  min-height: 44px;
  padding: 8px 12px;
}
#today .lesson-list-notes:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}
#today .lesson-list-button:focus-visible,
#today .lesson-list-section-link:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}
/* A completed row uses the existing replay choices, placed in the list's flow. */
#today .learn-list .lesson-list-row.is-offering {
  z-index: 2;
}
#today .learn-list .gold-offer {
  position: relative;
  top: auto;
  left: auto;
  width: auto;
  margin: 8px 8px 20px 64px;
  transform: none;
  translate: none;
  animation: none;
}
#today .learn-list .gold-offer::before,
#today .learn-list .gold-offer::after {
  display: none;
}
@media (max-width: 359px) {
  #today .lesson-list-card {
    padding: 16px;
    gap: 12px 8px;
  }
  #today .lesson-list-notes {
    padding: 0 10px;
  }
  #today .learn-list .lesson-list-button {
    gap: 8px;
  }
  #today .lesson-list-title b {
    font-size: 16px;
  }
  #today .lesson-list-start {
    min-width: 62px;
    padding: 0 8px;
  }
  #today .lesson-list-meta {
    max-width: 66px;
  }
}
@media (prefers-reduced-motion: reduce) {
  #today .lesson-list-start {
    transition: none;
  }
}

#today .lesson-list-bookmark {
  position: static;
  width: auto;
  height: auto;
  filter: none;
  flex: none;
}
#today .today-lesson:disabled,
.saved-lesson-open:disabled {
  cursor: default;
}
#today .is-blocked .today-open {
  visibility: hidden;
}
/* Section entry callouts use Start's shape, with room below the banner. */
html:not([data-design]) #today .today-route .today-step.is-section-skip:first-child {
  --route-gap: 64px;
}
html[data-design="v1"] #today .today-step.is-section-skip {
  padding-top: 60px;
}
#today .today-skip {
  animation: none;
}
#confirmModal .confirm-navigation {
  --brand: #36bffa;
  --brand-lip: #0ba5ec;
  --on-brand: #fff;
}
/* SVG overlays follow the visible tile positions; the old borders remain a loading fallback. */
.today-connector {
  display: none;
}
html:not([data-design]) #today .today-connector {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
html:not([data-design]) #today .has-path-connector::before,
html:not([data-design]) #today .has-path-connector::after,
html:not([data-design]) #today .has-next-connector .today-lesson::after {
  display: none;
}
.today-connector path {
  fill: none;
  stroke-width: var(--route-line);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.today-connector-track {
  stroke: var(--line-2);
}
.today-connector-fill {
  stroke: var(--topic-node);
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}
[data-connector-tone="gold"] .today-connector-track {
  stroke: var(--topic-node);
}
[data-connector-tone="gold"] .today-connector-fill {
  stroke: #f5b81c;
}
[data-theme="dark"] [data-connector-tone="gold"] .today-connector-fill {
  stroke: #ffd23f;
}
[data-connector-tone="none"] .today-connector-fill {
  display: none;
}
.is-connector-pending .today-connector-fill {
  stroke-dashoffset: 1;
}
.is-connector-drawing .today-connector-fill {
  animation: path-connector-draw 1.1s cubic-bezier(0.4, 0, 0.2, 1) both;
}
.is-awaiting-reveal.is-connector-drawing .today-connector-fill {
  animation: none;
  stroke-dashoffset: 1;
}
@keyframes path-connector-draw {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .today-connector-fill,
  .is-connector-pending .today-connector-fill,
  .is-connector-drawing .today-connector-fill,
  .is-awaiting-reveal.is-connector-drawing .today-connector-fill {
    animation: none;
    stroke-dashoffset: 0;
  }
}
/* The picture path (app/path-style.js, the owner's pick, 6 Oct 2026): the
   classic route, but every coin is a round picture of what its lesson teaches
   (features/learn/path-art.js). The ring is the section colour once reached
   and grey ahead; a finished coin wears a tick and a paid one a padlock. */
html[data-path-style="pictures"]:not([data-design]) #today {
  --path-ring: #d6dee7;
  --path-ring-lip: #b8c4d1;
  --path-lock: #9aa7b6;
}
html[data-path-style="pictures"][data-theme="dark"]:not([data-design]) #today {
  --path-ring: #2f3c4c;
  --path-ring-lip: #1c2632;
  --path-lock: #56647a;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-lesson {
  height: 86px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-current .today-lesson {
  height: 104px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-node-wrap {
  left: calc(var(--route-x) - 40px);
  width: 80px;
  height: 80px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-current .today-node-wrap {
  left: calc(var(--route-x) - 48px);
  width: 96px;
  height: 96px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-node {
  --node-lip: var(--path-ring-lip);
  --node-soft-shadow: 0 12px 18px rgb(30 80 160 / 0.1);
  box-sizing: border-box;
  width: 80px;
  height: 80px;
  overflow: hidden;
  border: 4px solid var(--path-ring);
  border-radius: 50%;
  background: var(--paper);
  box-shadow:
    0 6px 0 var(--node-lip),
    var(--node-soft-shadow);
  color: var(--icon-quiet);
}
/* Night has no soft drop under the coins, as in the classic look. */
html[data-path-style="pictures"][data-theme="dark"]:not([data-design]) #today .today-route .today-node {
  --node-soft-shadow: 0 0 0 transparent;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route :is(.is-complete, .is-current) .today-node {
  --path-ring: var(--topic-node);
  --node-lip: var(--topic-lip);
  background: var(--topic-rest);
  color: var(--topic-icon);
}
/* The lesson you are on: a size up, a thicker ring and a soft halo, kept in
   the shadow the invite and press animations restate. */
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-current .today-node {
  --node-soft-shadow:
    0 0 0 10px color-mix(in srgb, var(--topic-node) 18%, transparent), 0 16px 24px rgb(30 80 160 / 0.14);
  width: 96px;
  height: 96px;
  border-width: 5px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-gold .today-node {
  --path-ring: #f5b81c;
  --node-lip: #cb8e13;
  background: color-mix(in srgb, #ffd23f 22%, var(--paper));
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-node::before,
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-node::after,
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-art ~ svg {
  display: none;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-node-shine {
  inset: 0;
  border-radius: 50%;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-art {
  width: 88%;
  height: 88%;
  object-fit: contain;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-locked .today-art {
  filter: grayscale(1);
  opacity: 0.45;
}
/* Names sit beside the bigger coins. */
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-lesson-title {
  --route-label: 56px;
  top: 40px;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-current .today-lesson-title {
  --route-label: 64px;
  top: 48px;
}
/* The tick or padlock pinned to the coin's lower right; it sinks with the coin. */
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-mark {
  display: none;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route :is(.is-complete, .is-locked) .today-mark {
  position: absolute;
  z-index: 2;
  top: 55px;
  left: calc(var(--route-x) + 15px);
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 28px;
  height: 28px;
  border: 3px solid var(--paper);
  border-radius: 50%;
  background: var(--topic-node);
  color: #fff;
  transition: transform 0.1s var(--ease);
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-gold .today-mark {
  background: #f5b81c;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-locked .today-mark {
  background: var(--path-lock);
}
/* A paid coin with no picture shows its padlock on its face already. */
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-locked:not(:has(.today-art)) .today-mark {
  display: none;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-mark svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}
html[data-path-style="pictures"]:not([data-design]) #today .today-route .is-complete .today-mark svg {
  fill: none;
}
/* The press the coins have always had, restated for the rings. */
@media (hover: hover) and (pointer: fine) {
  html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-lesson:hover .today-node {
    box-shadow:
      0 4px 0 var(--node-lip),
      var(--node-soft-shadow);
  }
}
@media (prefers-reduced-motion: no-preference) {
  html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-lesson.is-pressed .today-node {
    box-shadow:
      0 1px 0 var(--node-lip),
      var(--node-soft-shadow);
  }
  html[data-path-style="pictures"]:not([data-design]) #today .today-route .today-lesson.is-pressed .today-mark {
    transform: translateY(5px);
  }
}
/* Lesson cards (app/path-style.js, the owner's pick, 6 Oct 2026): one card per
   lesson, its picture on the left (features/learn/path-art.js), joined by the
   path's line. The card you are on is the section colour with its Start
   inside; the others end in a tick, an arrow or a padlock. */
html[data-path-style="cards"]:not([data-design]) #today {
  --route-line: 8px;
}
/* Inside each section, where its colours are set. */
html[data-path-style="cards"]:not([data-design]) #today .today-route {
  --path-card-lip: color-mix(in srgb, var(--topic-banner) 84%, #000);
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 20px 16px 26px;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-step {
  --route-gap: 0px;
  padding: 0;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-step::before,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-step::after,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson::after,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-start::after,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-node::before,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-node::after,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-art ~ svg,
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-mark:empty,
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-locked:not(:has(.today-art)) .today-mark,
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-current .today-lesson-status {
  display: none;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 14px;
  box-sizing: border-box;
  height: auto;
  min-height: 92px;
  padding: 12px 14px 12px 12px;
  border: 2px solid var(--line-2);
  border-radius: 22px;
  background: var(--paper);
  box-shadow: 0 5px 0 var(--line-2);
  transition:
    transform 0.1s var(--ease),
    box-shadow 0.1s var(--ease);
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-current .today-lesson {
  min-height: 104px;
  border-color: var(--path-card-lip);
  background: var(--topic-banner);
  box-shadow: 0 6px 0 var(--path-card-lip);
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-node-wrap {
  position: relative;
  top: auto;
  left: auto;
  grid-area: 1 / 1;
  width: 64px;
  height: 64px;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-node {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: var(--panel-2);
  box-shadow: none;
  color: var(--icon-quiet);
  animation: none;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-complete .today-node {
  background: var(--topic-rest);
  color: var(--topic-icon);
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-current .today-node {
  background: #fff;
  color: var(--topic-icon);
}
html[data-path-style="cards"]:not([data-design])
  #today
  .today-route
  :is(.is-gold, [data-path-id^="recap-"])
  .today-node {
  background: color-mix(in srgb, #ffd23f 22%, var(--paper));
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-art {
  width: 88%;
  height: 88%;
  object-fit: contain;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-locked .today-art {
  filter: grayscale(1);
  opacity: 0.45;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson-title,
html[data-path-style="cards"]:not([data-design]) #today .today-route [data-side="r"] .today-lesson-title {
  position: static;
  grid-area: 1 / 2;
  align-items: flex-start;
  gap: 3px;
  text-align: left;
  translate: none;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson-title b {
  font-size: 17px;
}
/* A title on the section colour is 19px, so white clears the banner's 3:1. */
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-current .today-lesson-title b {
  color: #fff;
  font-size: 19px;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-start {
  position: static;
  grid-area: 1 / 3;
  padding: 10px 14px 11px;
  font-size: 14px;
  transform: none;
  translate: none;
  animation: none;
}
/* Lesson cards, continued (path-style-cards.css): how a card ends — Start,
   Skip to here, a tick, an arrow or a padlock — where Start sits on a phone,
   the gold offer under a finished card, and the press. */
/* Skip to here is the longer label, so its pill is a size down. */
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-skip {
  padding: 9px 10px 10px;
  font-size: 12px;
  letter-spacing: 0.6px;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-mark {
  grid-area: 1 / 3;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--panel-2);
  color: var(--icon-quiet);
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .today-mark svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-complete .today-mark {
  background: var(--topic-node);
  color: #fff;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-complete .today-mark svg {
  fill: none;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route .is-gold .today-mark {
  background: #f5b81c;
}
/* On a phone, Start and Skip to here sit under the lesson's name, so the name keeps its words whole. */
@media (max-width: 430px) {
  html[data-path-style="cards"]:not([data-design])
    #today
    .today-route
    :is(.is-current, .is-section-skip)
    .today-node-wrap {
    grid-row: 1 / span 2;
  }
  html[data-path-style="cards"]:not([data-design])
    #today
    .today-route
    :is(.is-current, .is-section-skip)
    .today-lesson-title {
    grid-area: 1 / 2 / 2 / 4;
  }
  html[data-path-style="cards"]:not([data-design]) #today .today-route :is(.is-current, .is-section-skip) .today-start {
    grid-area: 2 / 2 / 3 / 4;
    justify-self: start;
    margin-top: 10px;
  }
}
/* A finished card's gold offer hangs under the whole card, its caret on the picture. */
html[data-path-style="cards"]:not([data-design]) #today .today-route [data-side] .gold-offer {
  right: 0;
  left: 0;
  width: auto;
  translate: none;
  animation-name: path-card-offer-in;
}
html[data-path-style="cards"]:not([data-design]) #today .today-route [data-side] .gold-offer::before {
  right: auto;
  left: 39px;
}
@keyframes path-card-offer-in {
  from {
    opacity: 0;
    translate: 0 -8px;
  }
}
/* The whole card presses into its lip, the way the app's buttons do. */
@media (hover: hover) and (pointer: fine) {
  html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson:hover .today-node {
    box-shadow: none;
  }
}
@media (prefers-reduced-motion: no-preference) {
  html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson.is-pressed {
    transform: translateY(4px);
    box-shadow: 0 1px 0 var(--line-2);
  }
  html[data-path-style="cards"]:not([data-design]) #today .today-route .is-current .today-lesson.is-pressed {
    box-shadow: 0 2px 0 var(--path-card-lip);
  }
  html[data-path-style="cards"]:not([data-design]) #today .today-route .today-lesson.is-pressed .today-node {
    transform: none;
    box-shadow: none;
  }
}
