/**
 * The course runtime: outline, step, locked.
 *
 * ⚠ IT BORROWS THE CARD SYSTEM RATHER THAN INVENTING ONE. The tokens are the page's own —
 * --ce-radius-card, --ce-border, --ce-shadow-card — declared locally so this renders correctly
 * wherever it is placed, including outside a .ce-cohort wrapper. Three shadows and two radii on one
 * site is what the card pass on 2026-09-12 spent its time undoing.
 */
.ce-run {
    --ce-brand: #046bd2;
    --ce-brand-dark: #0357a8;
    --ce-brand-soft: #e6f1fb;
    /* ⚠ DONE IS GREEN, NOT BRAND BLUE — Scott, 2026-09-14. On a page where blue means
       "this is the course" and blue also means "finished", a student has to read the row to
       tell the two apart; green is the tick they already know. */
    --ce-done: #1a7f40;
    --ce-done-soft: #e7f6ec;
    --ce-ink: #0a2540;
    --ce-muted: #5b6b7f;
    --ce-surface: #ffffff;
    --ce-border: rgba(2, 53, 111, 0.12);
    --ce-radius-card: 16px;
    --ce-shadow-card: 0 10px 30px rgba(2, 53, 111, 0.10);
    color: var(--ce-ink);
    background: var(--ce-surface);
    border: 1px solid var(--ce-border);
    border-radius: var(--ce-radius-card);
    box-shadow: var(--ce-shadow-card);
    padding: calc(1.5rem + 4px) 1.75rem 1.5rem;
    position: relative;
    overflow: hidden;
}
.ce-run::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--ce-brand);
}
.ce-run__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ce-run__eyebrow { display: block; font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ce-muted); }
.ce-run .ce-run__title { margin: 4px 0 0; font-size: 24px; line-height: 1.25; color: var(--ce-ink); }
.ce-run__badge { flex: none; padding: 5px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; }
.ce-run__badge--done { background: var(--ce-done-soft); color: var(--ce-done); }

/* The meter is the only place a percentage appears — a number and a bar saying different things is
   how a progress display loses trust. */
.ce-run__meter { margin: 18px 0 6px; height: 8px; border-radius: 999px; background: var(--ce-brand-soft); overflow: hidden; }
.ce-run__meter-fill { display: block; height: 100%; background: var(--ce-brand); transition: width .3s ease; }
.ce-run .ce-run__meter-label { margin: 0 0 18px; font-size: 13px; color: var(--ce-muted); }

/* The flat step list these rules styled was replaced by the grouped course page at the foot of
   this file. Nothing renders `.ce-run__step*` any more; the rules are gone rather than kept
   "just in case", because CSS for markup that no longer exists is the kind a later change
   edits in the belief it is doing something. */

/* ⚠ font-family AND line-height ARE INHERITED EXPLICITLY, because this class is worn by an <a> and by
   a <button> and a button inherits NEITHER by default — it takes the browser's own UI font and its own
   line box. The two controls at the ends of the foot are meant to be the same control facing opposite
   ways; without these they are the same colour in different typefaces, at different heights, and the
   rule that set font-size and font-weight looks like it should already have covered it. */
.ce-run__cta { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 8px; margin-top: 18px; padding: 12px 22px; border: 0; border-radius: 999px; background: var(--ce-brand); color: #fff; font-family: inherit; font-size: 15px; font-weight: 600; line-height: 1.25; text-decoration: none; cursor: pointer; }
/* ⚠ EVERY LINK STATE, NOT JUST :hover. Scott, 2026-09-14: "when I press the button, the text goes to
   blue." The CTA is an <a> inside page content, and the theme colours a:visited / a:active / a:focus —
   states this rule never claimed — so the label turned brand blue on blue the moment it was pressed,
   and stayed that way on a link already followed. Qualified with .ce-run so it outranks the theme's
   own `.entry-content a:visited`, and text-decoration is restated for the same reason: a rule that
   only holds until the first click is not a fix. */
.ce-run a.ce-run__cta,
.ce-run a.ce-run__cta:link,
.ce-run a.ce-run__cta:visited,
.ce-run a.ce-run__cta:hover,
.ce-run a.ce-run__cta:focus,
.ce-run a.ce-run__cta:active {
    color: #fff;
    text-decoration: none;
}
/* ⚠ :not(--ghost), OR THIS RULE EATS THE GHOST BUTTON. Scott, 2026-09-14: "View completed course"
   went solid blue with an invisible label on hover, and it was this rule that did it — added in
   v1.279.0 to fix the link colours and written one class too broad. `.ce-run a.ce-run__cta:hover` is
   (0,3,1); the ghost's own `.ce-run .ce-run__cta--ghost:hover` is (0,3,0), so the fill came from here
   while the TEXT colour came from the ghost rule at equal specificity later in the file. Dark on dark.
   A fix that creates a worse defect than the one it removes is worth the extra selector. */
.ce-run__cta:hover,
.ce-run a.ce-run__cta:not(.ce-run__cta--ghost):hover { background: var(--ce-brand-dark); color: #fff; }
/* the ghost twin: brand text on nothing at rest, and — Scott's call — WHITE on a solid fill the
   moment it is hovered or focused, so it reads exactly like the primary under the pointer */
.ce-run a.ce-run__cta--ghost,
.ce-run a.ce-run__cta--ghost:link,
.ce-run a.ce-run__cta--ghost:visited { color: var(--ce-brand); }
.ce-run .ce-run__cta--ghost:hover,
.ce-run .ce-run__cta--ghost:focus,
.ce-run .ce-run__cta--ghost:active,
.ce-run a.ce-run__cta--ghost:hover,
.ce-run a.ce-run__cta--ghost:focus,
.ce-run a.ce-run__cta--ghost:active {
    background: var(--ce-brand);
    color: #fff;
    box-shadow: inset 0 0 0 1.5px var(--ce-brand);
}
/* a keyboard user still gets a ring — removing the underline must not remove the focus signal */
.ce-run a.ce-run__cta:focus-visible,
.ce-run button.ce-run__cta:focus-visible {
    outline: 3px solid rgba(4, 107, 210, .35);
    outline-offset: 2px;
}

.ce-run__crumbs { display: flex; gap: 8px; font-size: 13px; color: var(--ce-muted); margin-bottom: 6px; }
.ce-run__crumbs a { color: var(--ce-brand); text-decoration: none; }
.ce-run__body { margin: 16px 0 24px; font-size: 16px; line-height: 1.7; }
.ce-run__body img { max-width: 100%; height: auto; }
/* ⚠ THE TWO BUTTONS SIT ON ONE LINE. Scott, 2026-09-14. Each end of the foot is now a column — small
   text over a pill — but the columns are different heights: the left has one line above its button,
   the right has "Up next" AND "✓ Completed". Centred, that put the two pills at different heights and
   the foot looked askew. Aligned to the BOTTOM, the last child of each column — the button — lands on
   the same line whatever is stacked above it. */
/* ⚠ STRETCH, THEN SPACE-BETWEEN INSIDE EACH COLUMN. Scott, 2026-09-14: the contents link should be
   centred on its button and in line with "Up next". Aligning the columns on their bottoms (v1.285.0)
   levelled the buttons but left the left-hand link beside "✓ Completed" — the right column carries
   TWO lines above its button and the left carries one, so the two stacks could not agree. Stretched
   to a common height, each column then pushes its first child to the top and its button to the
   bottom: first lines level, buttons level, whatever is between them. */
/* ⚠ CENTRED, NOT STRETCHED, AND THE PILLS CARRY NO TOP MARGIN IN HERE. The foot used to stretch its
   columns and let each one place its own child, which was fine while each column held a stack. Now
   both hold a single button, and `.ce-run__cta`'s 18px top margin applied to only one of them —
   `--back` zeroes it — so the forward pill started 18px lower than the one opposite. Two identical
   controls, visibly out of line, for a reason neither rule mentions.
   Centring the row and zeroing BOTH margins here makes them a pair by construction rather than by two
   rules happening to agree. */
/* ⚠ THE RULE NEEDS AIR ABOVE IT. The foot's top border sat tight against whatever the lesson ended
   with — a card, a table, a closing paragraph — so the separator read as part of the content rather
   than the line between the lesson and its controls. */
/* ⚠ A GRID, BECAUSE FLEX CANNOT CENTRE THE MIDDLE ITEM ON THE PAGE. With `justify-content:space-between`
   the contents link lands midway between the two BUTTONS, and the buttons are not the same width — the
   back pill is ~202px against Continue's ~140 — so it sat 38px right of the foot's centre. Three columns
   of `minmax(0,1fr) auto minmax(0,1fr)` give the side columns equal width by definition, which puts the
   middle one on the container's centre line whatever the buttons say. `minmax(0,…)` rather than plain
   `1fr` so a long button shrinks instead of pushing the centre off. Scott, 2026-09-28. */
.ce-run__foot { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 16px; border-top: 1px solid var(--ce-border); margin-top: 32px; padding-top: 16px; }
.ce-run__foot > .ce-run__foot-nav { justify-self: start; }
.ce-run__foot > .ce-run__link--contents { justify-self: center; }
.ce-run__foot > .ce-run__foot-action { justify-self: end; }
.ce-run__foot .ce-run__cta { margin-top: 0; }
.ce-run__form { margin: 0; }
.ce-run__link { color: var(--ce-brand); text-decoration: none; font-size: 14px; }
.ce-run__pending { background: var(--ce-brand-soft); border-radius: 12px; padding: 18px 20px; margin: 16px 0 24px; }
.ce-run .ce-run__pending-title { margin: 0 0 6px; font-weight: 700; }

/* ⚠ THE FINAL EXAM DOES NOT LOOK LIKE A ONE-QUESTION PRACTICE CHECK. Scott, 2026-09-14: the start
   screen for the step that decides the certificate was pixel-for-pixel the panel a student had
   already dismissed three times on the way there — same tint, same one line, same button. It is
   marked the way the contents page marks it, so the two screens agree about which step this is. */
.ce-run__pending--exam { border: 1px solid var(--ce-brand); }
.ce-run .ce-run__pending--exam .ce-run__pending-title { font-size: 17px; }
.ce-run .ce-run__exam-notes {
    margin: 10px 0 16px;
    padding-left: 20px;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--ce-ink);
}
.ce-run .ce-run__exam-notes li { margin: 0 0 4px; }
.ce-run .ce-run__exam-notes li:last-child { margin: 0; }
.ce-run .ce-run__locked-title { margin: 0 0 6px; font-size: 18px; font-weight: 700; }

@media (max-width: 560px) {
    .ce-run { padding: calc(1.25rem + 4px) 1.1rem 1.25rem; }
    /* ⚠ ONE COLUMN ON A PHONE. `flex-direction` means nothing to a grid — this is the rule that stacks
       it now, and the `order` values below still apply because they are grid items. */
    .ce-run__foot { grid-template-columns: 1fr; align-items: stretch; }
    .ce-run__foot > .ce-run__foot-nav,
    .ce-run__foot > .ce-run__link--contents,
    .ce-run__foot > .ce-run__foot-action { justify-self: stretch; }
    /* on a phone the primary action comes first and the way back follows it */
    .ce-run__foot-nav { order: 2; align-items: stretch; }
    /* ⚠ LAST ON A PHONE. Stacked, the two buttons want to be adjacent — a link wedged between them
       separates the pair it is meant to sit beside. */
    .ce-run__link--contents { order: 3; }
    .ce-run .ce-run__cta--back { white-space: normal; text-align: center; }
    .ce-run__foot-action { order: 1; align-items: stretch; }
    /* on a phone a long name may genuinely not fit; there it wraps rather than overflow the card */
    /* ⚠ AND `width:100%` NEEDS border-box, WHICH THIS CLASS DID NOT HAVE. Measured at 375px on
       2026-09-28: 100% of a 289.8px column plus 22px of padding each side rendered a 333.8px button —
       44px wider than the column holding it, on every phone. It went unseen because the harness used to
       check this had no viewport meta, so the browser laid it out at 980px and never stacked at all. */
    .ce-run__cta { width: 100%; }
    /* ⚠ DIRECTLY ABOVE THE BUTTON IT DESCRIBES. Stacked, the controls run Continue, Back, Progress —
       so "Up next" belongs at the top, where it is read immediately before the click. It had order 0 by
       default rather than by decision, which is the same place for the wrong reason. */
    .ce-run__upnext--row { order: 0; }
}

/* ── sitting a quiz ─────────────────────────────────────────────────────────────────────────── */
.ce-run__quiz { margin: 18px 0 0; }
.ce-run__q { border: 1px solid var(--ce-border); border-radius: 12px; padding: 16px 18px; margin: 0 0 14px; }
.ce-run__q-text { display: flex; gap: 10px; align-items: baseline; font-weight: 600; font-size: 16px; padding: 0; margin-bottom: 10px; }
.ce-run__q-num { flex: none; width: 24px; height: 24px; border-radius: 50%; background: var(--ce-brand-soft); color: var(--ce-brand-dark); font-size: 13px; display: inline-flex; align-items: center; justify-content: center; }
.ce-run .ce-run__q-hint { margin: 0 0 8px; font-size: 13px; color: var(--ce-muted); }
.ce-run__opt { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border-radius: 8px; cursor: pointer; }
.ce-run__opt:hover { background: color-mix(in srgb, var(--ce-brand) 5%, transparent); }
.ce-run__opt input { margin-top: 3px; }
.ce-run__result { border-radius: 12px; padding: 18px 20px; margin: 16px 0 24px; background: var(--ce-brand-soft); }
.ce-run__result.is-pass { background: #e7f6ec; }
.ce-run .ce-run__result-title { margin: 0 0 6px; font-weight: 700; font-size: 18px; color: #1a7f40; }
.ce-run .ce-run__result-meta { margin: 6px 0 0; font-size: 13px; color: var(--ce-muted); }
.ce-run__flash { margin: 0 0 16px; padding: 12px 16px; border-radius: 10px; font-weight: 600; }
.ce-run__flash--pass { background: #e7f6ec; color: #1a7f40; }
.ce-run__flash--fail { background: #fdf0e7; color: #8a4b16; }
.ce-run .ce-run__warn { margin: 8px 0 0; font-size: 13px; color: #8a4b16; }

/* ── The entry card: the same object as the outline, on the course page ──────────────────────────
   ⚠ NO STEP LIST HERE ON PURPOSE. The landing's job is "where am I, and one way in"; the whole
   outline belongs behind the button, which is what makes the button worth pressing. */
.ce-run--entry .ce-run__entry-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 4px;
}
.ce-run--entry .ce-run__cta { margin-top: 0; }
/* The step the button opens, beside it rather than inside it: the button stays one short phrase at
   any width, and the title can be long. */
.ce-run__next { color: var(--ce-muted); font-size: 14px; }

/* Access window and exam requirement. One line, separated by a middot — two lines of small grey text
   under a progress bar reads as fine print, and these are the two facts a self-paced student most
   needs. */
.ce-run .ce-run__meta {
    margin: 0 0 16px;
    font-size: 13.5px;
    color: var(--ce-muted);
}
.ce-run__meta-sep { opacity: .5; padding: 0 2px; }

/* ⚠ THE CERTIFICATE IS NOT A SECOND "CONTINUE". It is the end of the journey, so it reads as its own
   action — green, on its own line — rather than competing with the button that moves a student
   forward. */
/* ⚠ `display:flex` ON AN ANCHOR MAKES IT FULL WIDTH. That, plus sitting outside the actions row,
   is what turned "Download your certificate" into a green bar twice the weight of the primary
   button. It is a pill in the row with everything else now. */
/* ⚠ THE SIZE LIVES HERE, NOT ON THE TAG. An inline <svg> with no width/height and no CSS size
   stretches to fill its flex line — on the course page's certificate button that came out as a
   188px blue disc swallowing the label. The entry card's icon only ever looked right because it
   happened to carry width="16" height="16" attributes, which is not a property a stylesheet should
   depend on every future icon remembering. */
.ce-run__cta-icon {
    flex: none;
    width: 16px;
    height: 16px;
    margin-right: -2px;
}

/* The quiet twin of the primary button: same shape and height, no fill. Used for "Review the
   course" once the certificate has taken the lead. */
.ce-run .ce-run__cta--ghost {
    background: transparent;
    color: var(--ce-brand);
    box-shadow: inset 0 0 0 1.5px var(--ce-border);
}
/* hover/focus/active for this variant is stated once, up with the primary's — see the note there */

/* ── The step head: what it is, and where it sits in the course ──────────────────────────────────
   ⚠ THE POSITION IS NOT DECORATION. A lesson page with no place in a sequence is one a student
   cannot pace themselves against — "Step 3 of 10" is the difference between finishing tonight and
   putting it off. It sits beside the title rather than under it so the title keeps the line. */
.ce-run__step-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.ce-run__position {
    flex: none;
    font-size: 13px;
    font-weight: 600;
    color: var(--ce-muted);
    letter-spacing: .04em;
    text-transform: uppercase;
}
.ce-run--step .ce-run__meter { margin: 14px 0 22px; }

/* "All lessons" sits with the previous-step link: both are ways back, and a student who wants the
   contents should not have to find the breadcrumb. */
/* ⚠ A COLUMN, NOT A ROW. Scott, 2026-09-14: the contents link belongs above the previous step, and
   the previous step should be a button to match the right-hand side. Stacked, the two stop competing
   — the standing whole-course link reads first, the step-by-step move sits under it with the weight
   of a control. Both ends of the foot are now a line of small text over a pill. */
.ce-run__foot-nav {
    display: flex;
    flex-direction: column;
    /* ⚠ CENTRE, NOT SPACE-BETWEEN. With one child `space-between` is `flex-start`, which pinned the
       button to the top of a stretched column — half of why the two pills sat on different lines. */
    align-items: center;
    justify-content: center;
    gap: 8px;
}
/* ⚠ THE MIDDLE OF THE ROW, AND IT TAKES THE SLACK. `flex:1` is what centres it between two pills of
   unequal width: the buttons size to their text at each end and this absorbs whatever is left, so the
   link sits on the row's centre rather than on the midpoint between the two buttons' inner edges.
   `align-self:center` holds it on the buttons' centre line, which are taller than it. */
/* ⚠ NO `flex:1` ANY MORE. Absorbing the slack is exactly what pulled it off the page's centre; the grid
   column decides where it sits now. */
.ce-run__link--contents { font-weight: 600; text-align: center; }
/* ⚠ THE SAME SIZE AND FILL AS THE BUTTON OPPOSITE, not merely the same colour — the two ends of the
   foot are a pair of directions. At 10px/14.5px it measured 44px tall against the primary's 49, so
   aligned on their bottoms the tops were 5px out: close enough to look like a mistake. It carries no
   --ghost class, so it takes the primary fill and every one of the primary's link-state rules.
   nowrap is what keeps it one line; back_label() keeps the text short enough for that to hold. */
/* ⚠ THE ONLY DIFFERENCE FROM THE BUTTON OPPOSITE IS THAT THIS ONE DOES NOT WRAP. Everything else —
   fill, padding, radius, type, every link state — comes from .ce-run__cta, so the two cannot drift
   apart by one of them being restyled. If this rule ever needs a second property, ask whether the
   pair is still meant to be identical. */
.ce-run .ce-run__cta--back { white-space: nowrap; }

/* ──────────────────────────────────────────────────────────────────────────────────────────────
   Embedded builder content.

   ⚠ THE BUILDER'S OWN WRAPPER ARRIVES ABSOLUTELY POSITIONED, and that silently empties the lesson.
   Measured on course 37406 lesson 1: `.elementor.elementor-35983` computed `position:absolute`, so
   it left the flow, `.ce-run__body` collapsed to 0px, and the card — 245px tall and `overflow:hidden`
   — clipped 27,913px of content out of sight. Nothing errored and the markup was all present in the
   DOM, which is what made it look like the content had not been copied at all.

   Some stylesheet on the page puts it there; it is not in the generated Elementor CSS and not inline,
   and the rule could not be read back from the page (cross-origin sheets in the harness). Rather than
   guess at the source, this states what the runtime requires of content it embeds: it is part of the
   page's flow. Scoped to our own container so nothing else is touched.
   ────────────────────────────────────────────────────────────────────────────────────────────── */
.ce-run__body > .elementor {
    position: relative;
    /* ⚠ AND THE OFFSETS WITH IT. The wrapper arrives carrying `inset: 130px 0 -130px`, a shove down
       the page that some rule uses to clear a sticky header on a lesson URL. Switching it from
       absolute to relative put it back in the flow but INHERITED that shove: 130px of blank band
       between the progress meter and the first line of the lesson, and the same 130px hanging off
       the bottom. Measured — body top 595, content top 725, and the body's own height unchanged at
       13,989px, so the content was simply sitting lower than the box holding it.
       `inset: auto` zeroes the offsets while `relative` keeps the wrapper a containing block, which
       anything inside it positioning against `.elementor` still needs. */
    inset: auto;
}

/* ⚠ ONE RHYTHM WITH THE SECTIONS AROUND IT. Scott, 2026-09-13, measured from his screenshot: the
   instructor card sat 5px above this card while Course Includes sat 30px below it and Digital
   Downloads 39px below that — four blocks in a column, three different gaps. The cards carried NO
   margin at all; only `.ceasap-course-section` did.

   BOTTOM MARGIN ONLY, deliberately. These blocks are each alone inside an Elementor container, so
   whether adjacent margins collapse depends on that container's display mode — with top AND bottom
   margins the gap is 30px in flow and 60px in flex, which is how a column ends up with three
   different gaps in the first place. One side can only ever produce one answer. */
.ce-run--entry {
    margin: 0 0 30px;
}

/* ──────────────────────────────────────────────────────────────────────────────────────────────
   Inside the course, the page stops being a page.

   ⚠ WHAT FOLLOWS THE LESSON IS THE COURSE PAGE INTERRUPTING IT. Scott, 2026-09-13. One URL carries
   both the course page and the lesson a student studies in, so a lesson ended with the package
   upsell (686px) and the newsletter block (380px) hanging under it. The sections this plugin
   renders stand down in PHP; these two belong to the Elementor template, and editing somebody's
   template from a plugin is how a design becomes unmaintainable.

   ⚠ EXPRESSED AS "AFTER THE LESSON", NOT AS ELEMENT IDS. `elementor-element-f4c6b09` means nothing
   next week — the ids change the moment the template is edited, and a rule keyed to them fails
   silently. This says what is actually meant: on a page where the reader is inside the course, every
   top-level container after the one holding the course card is not part of the lesson. Measured:
   the lesson sits at index 3 of 8, with the upsell and the newsletter at 5 and 6.

   If :has() is ever unavailable the rule is simply ignored and the sections come back — visible,
   not broken.
   ────────────────────────────────────────────────────────────────────────────────────────────── */
.ce-in-course .elementor > *:has(.ce-run) ~ * {
    display: none;
}

/* ⚠ THE `ce-no-lesson-nav` BLOCK WAS HERE and went with the lesson_toc switch, 2026-09-26. A
   lesson now owns its own contents panel and reading bar; the runtime's bar stands down by itself
   when the lesson brings one. Nothing platform-side hides lesson furniture any more. */

/* ── the reading-progress bar the RUNTIME owns ────────────────────────────────────────────────────
   ⚠ NOT THE SAME BAR AS `.ce-run__meter`. That one is progress through the COURSE — steps done. This
   is progress through THIS lesson's text. They sit near each other deliberately (one band of
   furniture) and must never be styled as one control.

   ⚠ IT EXISTS BECAUSE THE WIDGET VERSION CANNOT BE RELIED ON. A lesson only got a bar if its author
   added an Elementor Progress Tracker AND set a container's CSS ID to `lesson-body`. Course 47022's
   three lessons, copied from a course built without one, had `lesson-body` nowhere — so the toggle
   was on and there was nothing to show. The runtime measures `.ce-run__body`, which every step has.

   ⚠ `data-ce-own-tracker` IS THE COEXISTENCE RULE. A migrated lesson carrying its own widget keeps
   it and this stands down, so nobody gets two bars stacked at the top of one page. */
/* ⚠ FIXED, NOT STICKY, AND THAT WAS NOT THE FIRST GUESS. Sticky put the bar in the document flow
   inside `.ce-run`, where any ancestor with `overflow: hidden` — which Elementor containers have all
   over them — silently stops it sticking. The bar then scrolled away before it had filled anything,
   so it rendered correctly and was never seen. Pinned to the viewport it cannot be defeated by an
   ancestor, and it is where every reader already expects a reading bar to be. */
.ce-run__read {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* ⚠ ABOVE EVERYTHING ON THIS SITE, MEASURED RATHER THAN GUESSED. 9999 looked generous and was
       not: the course page carries z-index 99999 AND 999999 in its own inline CSS, so the bar was
       painted underneath them and read as "not pinned" — the only bar still visible being
       `.ce-run__meter`, which is in the flow and is supposed to scroll. */
    z-index: 2147483000;
    height: 5px;
    margin: 0;
    border-radius: 0;
    background: rgba(15, 23, 42, 0.10);
    overflow: hidden;
    pointer-events: none;       /* a 5px strip across the top must never eat a click */
}

.ce-run__read[data-ce-own-tracker] {
    display: none;
}

.ce-run__read-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: var(--ce-brand, #1668c1);
    /* ⚠ No transition on width. The bar is driven from scroll, so an eased width lags the page and
       reads as the bar being broken rather than smooth. */
}

@media (prefers-reduced-motion: reduce) {
    .ce-run__read-fill { transition: none; }
}

/* ⚠ THE GREY BAR ACROSS THE CONTENTS PANEL WAS A SCROLLBAR. Scott spotted it, 2026-09-14.
   Measured on lesson 1: `.elementor-toc__body` is 954px wide with `overflow-x: auto`, and the list
   inside it is a 940px <ul> carrying Elementor's default 48px left indent — 988px of box in a 954px
   hole. The browser drew a 16px horizontal scrollbar along the bottom of the panel, which on a
   light-blue card reads as a grey slab somebody meant to put there.

   ⚠ NOTHING IS CLIPPED BY HIDING IT, and that was checked rather than assumed: the rightmost entry
   ends at 966px against a box edge of 1027px. The overflow is the UL's BOX, not its text, so there
   is nothing out there to scroll to — the scrollbar was offering a trip to 41px of empty margin.

   ⚠ overflow-Y IS LEFT ALONE. A long lesson can genuinely overflow the panel vertically, and that
   scrollbar is doing a job. */
.ce-in-step .ce-run__body .elementor-toc__body {
    overflow-x: hidden;
}

/* ⚠ THE CONTENTS PANEL AND THE READING BAR ARE HIDDEN ON A PHONE BY THIS RULE, NOT BY LUCK. Scott, 2026-09-14. Every
   lesson captured so far happens to carry Elementor's own `elementor-hidden-mobile` on that widget,
   so it already disappeared at 375px — but that class lives in PASTED CONTENT. The plan is to
   rebuild every active course in the builder and paste the lesson bodies in, and one paste from a
   layout where the author never set that visibility control would put a pinned, half-screen contents
   panel on top of a phone's reading area. A rule in the runtime's own stylesheet is true for every
   lesson, including the ones not written yet.

   767px is Elementor's own mobile breakpoint, so "mobile" means here what it means everywhere else
   on the site.

   ⚠ THE READING-PROGRESS BAR GOES WITH IT — Scott, 2026-09-14, and it is the same rule the Features
   switch follows: the panel and the bar are ONE band of furniture at the top of the reading area,
   and half of it on its own reads as a bug. On a phone the bar would be a line of colour pinned
   above the text with nothing to explain it, which is worse than no bar at all. The step meter on
   the lesson card is untouched — that reports progress through the COURSE, not through the page,
   and it is the one a phone reader still wants. */
@media (max-width: 767px) {
    .ce-in-step .ce-run__body .elementor-widget-table-of-contents,
    .ce-in-step .ce-run__body .elementor-widget-progress-tracker,
    .ce-in-step .ceasap-toc-show-tab {
        display: none !important;
    }
}

/* ⚠ THE LESSON CLEARS A HEADER THAT IS NOT HERE. The container after the scroll-progress tracker
   carries `margin-top: 207px` — measured on course 37406 lesson 1, and 268px on the LearnDash render
   of the same lesson. It is clearance for LearnDash's sticky lesson header. This runtime has no such
   header, so the margin is simply a blank band between the progress meter and the first line of the
   lesson, which is what it looked like.

   Written as "the container after the progress tracker", not as an element id: ids change when the
   template is edited, and a lesson with no tracker matches nothing and is left alone. */
.ce-run__body .elementor > :has([data-widget_type^="progress-tracker"]) + * {
    /* !important, and not for want of trying a cleaner way: the lesson's own stylesheet is printed
       INLINE, inside the step, so it always comes after this file. At equal specificity the later
       rule wins, and there is no specificity available here that the generated selector
       (`.elementor-35983 .elementor-element.elementor-element-b8c263f`) does not already match. */
    margin-top: 0 !important;
}

/* ⚠ THE STICKIES ARE CALIBRATED FOR A HEADER WE DO NOT HAVE — SO RE-AIM THEM, DO NOT KILL THEM.
   Scott, 2026-09-13. Both the scroll-progress tracker and the contents panel are meant to pin, and
   on a LearnDash lesson they pin at top:132px and top:142px — clearance for that page's ~130px
   sticky header. This page's header is `position: static` and scrolls away, so the same numbers
   leave the tracker floating a third of the way down the viewport with nothing above it, and the
   panel overlapping the lesson beneath it.

   An earlier attempt simply stopped them sticking. That fixed the overlap and lost the feature,
   which is not the trade anyone wanted: the contents panel exists to stay reachable while reading.
   They pin to the top of the viewport here — the tracker at 0, the panel immediately under its 5px.

   `!important` because Elementor's sticky writes `top` inline from JavaScript on every scroll. */
/* ⚠ AND THE ADMIN BAR IS 32px OF FIXED CHROME. Scott, viewing as an administrator: the tracker is
   5px tall, so pinning it at 0 put it ENTIRELY underneath the bar — indistinguishable from "the
   tracker is not sticky" — and the contents panel had its top edge clipped by the same 32px.
   Students never see the bar, so the offset has to be conditional, which is what `.admin-bar` on
   <body> is for. WordPress widens it to 46px below 782px.

   ⚠ I did not see this for several rounds because my own screenshots REMOVED the admin bar to make
   them look like a student's. A harness that tidies the page it is inspecting cannot be trusted to
   find what is wrong with the page. */
:root {
    --ce-sticky-offset: 0px;
}

.admin-bar {
    --ce-sticky-offset: 32px;
}

@media screen and (max-width: 782px) {
    .admin-bar {
        --ce-sticky-offset: 46px;
    }
}

.ce-run__body .elementor-widget-progress-tracker.elementor-sticky {
    top: var(--ce-sticky-offset) !important;
    z-index: 100;
}

/* ⚠ AND A STACKING ORDER, WHICH IS THE "TRANSPARENT" PANEL. Pinned with `z-index: auto` the panel
   paints BELOW the lesson that scrolls past it: proven by asking the browser what it renders at the
   centre of the panel — a lesson <p> before, the panel's own list after. The background was always
   rgb(214,230,249); the text simply came over the top of it, which looks exactly like a see-through
   box. Nothing to do with the colour, which is why re-checking the colour kept saying it was fine. */
.ce-run__body .elementor-widget-table-of-contents.elementor-sticky {
    top: calc(var(--ce-sticky-offset) + 5px) !important;
    z-index: 99;
}


/* "Up next" — what follows this step, named before the student commits to it. */
.ce-run .ce-run__upnext {
    margin: 0 0 10px;
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}
.ce-run .ce-run__upnext-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ce-muted);
}
.ce-run .ce-run__upnext-title {
    font-weight: 650;
    color: var(--ce-ink);
}

/* The "Up next" line and the button it describes are one column at the end of the foot row, so the
   line is read immediately before the click rather than beside it. */
.ce-run__foot-action {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 6px;
}
.ce-run__foot-action .ce-run__upnext { margin: 0; justify-content: flex-end; }
/* ⚠ THE "UP NEXT" LINE TAKES A ROW OF ITS OWN, BENEATH THE THREE CONTROLS. `flex-basis:100%` is what
   wraps it; centring it puts it under the middle of the foot rather than trailing off one end. It was
   inside the action column until 2026-09-28, stacked over the button, which made a finished step the
   only footer in the course with a different shape. */
/* spans all three columns, so it is a row of its own beneath the controls */
.ce-run__upnext--row { grid-column: 1 / -1; justify-content: center; margin: 4px 0 0; }

/* ── the marked paper ───────────────────────────────────────────────────────────────────────────
   Shown only after a sitting has passed. Correct answers are marked plainly rather than colour
   alone — a tick and the words "Correct answer", because colour is not available to every reader. */
.ce-run__review { margin: 18px 0 0; }
.ce-run .ce-run__review-head {
    margin: 0 0 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ce-muted);
}
.ce-run__review-q { border: 1px solid var(--ce-border); border-radius: 12px; padding: 14px 16px; margin: 0 0 12px; }
.ce-run .ce-run__review-q-text { display: flex; gap: 10px; align-items: baseline; font-weight: 600; margin: 0 0 10px; }
.ce-run .ce-run__review-opts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ce-run__review-opt {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 8px;
    color: var(--ce-muted);
}
.ce-run__review-mark { flex: none; width: 1em; font-weight: 700; }
.ce-run__review-opt.is-correct { background: #e7f6ec; color: #14532d; font-weight: 600; }
.ce-run__review-opt.is-correct .ce-run__review-mark { color: #1a7f40; }
.ce-run__review-opt.is-chosen-wrong { background: #fdecec; color: #7f1d1d; }
.ce-run__review-opt.is-chosen-wrong .ce-run__review-mark { color: #b42318; }
.ce-run__review-tag {
    margin-left: auto;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    white-space: nowrap;
}
.ce-run__review-tag--yours { opacity: .75; }

/* A step held back until a knowledge check is passed. */
.ce-run .ce-run__locked-copy { margin: 4px 0 18px; color: var(--ce-body, var(--ce-muted)); }

/* ⚠ ROOM BETWEEN THE LAST CONTROL AND THE RULE BELOW IT. The submit button sat hard against the
   foot's border, which reads as the button belonging to the navigation rather than to the quiz. */
.ce-run__quiz .ce-run__cta { margin-top: 4px; margin-bottom: 22px; }

/* The author's explanation for this question, shown with the marked paper. */
.ce-run__review-note {
    margin: 12px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--ce-brand);
    background: var(--ce-brand-soft);
    border-radius: 0 8px 8px 0;
    font-size: 15px;
}
.ce-run__review-note.is-wrong { border-left-color: #b42318; background: #fdecec; }
.ce-run__review-note p { margin: 0 0 8px; }
.ce-run__review-note p:last-child { margin: 0; }

/* The question heading is a <p> inside the box now, not a <legend> straddling its border. */
.ce-run .ce-run__q-text { margin: 0 0 12px; }

.ce-run .ce-run__review-withheld { margin: 10px 0 0; font-size: 14px; color: var(--ce-muted); }

/* A question that is not in this attempt, because the Q&A file was re-imported after the paper
   was sat. DELIBERATELY NEUTRAL, NOT RED: the student did nothing wrong, and on a passing attempt
   the red treatment read as a failure against a question they were never asked. */
.ce-run__review-q.is-revised { border-style: dashed; }
.ce-run .ce-run__review-revised {
    margin: 12px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--ce-muted);
    background: #f6f7f9;
    border-radius: 0 8px 8px 0;
    font-size: 14px;
    color: var(--ce-muted);
}

/* Why a finished course has no certificate yet — a rule that will release, not an error. */
.ce-run .ce-run__hold {
    margin: 0 0 14px;
    padding: 10px 14px;
    border-left: 3px solid var(--ce-brand);
    background: var(--ce-brand-soft);
    border-radius: 0 8px 8px 0;
    font-size: 15px;
    color: var(--ce-ink);
}

/* ──────────────────────────────────────────────────────────────────────────────
   THE COURSE PAGE — the screen a self-paced student returns to between sittings.

   ⚠ IT IS A COURSE, NOT A CHECKLIST. The lesson carries its topics and its
   knowledge check inside it, indented under one heading, because that is how the
   material is taught. The flat list this replaced gave a lesson and its own check
   the same weight and read as a pile of unrelated errands.
   ────────────────────────────────────────────────────────────────────────────── */

.ce-out__head { margin-bottom: 4px; }
.ce-out .ce-out__done-line {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 10px 0 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--ce-done);
}
.ce-out__done-line .ce-out__icon { fill: var(--ce-done); }

.ce-out__progress { margin-top: 14px; }
.ce-out .ce-out__progress .ce-run__meter-label { margin-bottom: 0; }
/* A full bar is a finished course, and on this page finished is green. */
.ce-out__progress.is-complete .ce-run__meter-fill { background: var(--ce-done); }
.ce-out__progress.is-complete .ce-run__meter { background: var(--ce-done-soft); }

/* ⚠ THE RESUME BUTTON IS ABOVE THE LIST. A returning student's first question is
   "where was I", and answering it should not require reading the whole course. It
   is a block rather than a pill because it carries two lines: the act, then the
   step it opens. */
.ce-out__resume {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 18px 0 0;
    padding: 14px 18px;
    border-radius: 12px;
    background: var(--ce-brand);
    color: #fff;
    text-decoration: none;
    transition: background .15s ease;
}
.ce-out__resume:hover, .ce-out__resume:focus { background: var(--ce-brand-dark); color: #fff; }
.ce-out__resume-label { font-size: 16px; font-weight: 700; }
.ce-out__resume-next { font-size: 13.5px; opacity: .92; }

.ce-out .ce-run__meta { margin: 14px 0 0; }

.ce-out .ce-out__section-title {
    margin: 26px 0 12px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ce-muted);
}

.ce-out .ce-out__groups { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ce-out .ce-out__rows { list-style: none; margin: 6px 0 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 6px; }

.ce-out__group { border: 1px solid var(--ce-border); border-radius: 14px; padding: 12px 14px; }
.ce-out__group.is-current { border-color: var(--ce-brand); box-shadow: 0 0 0 3px var(--ce-brand-soft); }
.ce-out__group.is-done { background: color-mix(in srgb, var(--ce-done) 3%, var(--ce-surface)); }
/* The exam decides completion, so it does not look like another lesson. */
.ce-out__group.is-exam { border-color: var(--ce-brand); background: var(--ce-brand-soft); }

.ce-out .ce-out__label {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ce-muted);
}

.ce-out__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
    transition: background .15s ease;
}
a.ce-out__row:hover, a.ce-out__row:focus { background: color-mix(in srgb, var(--ce-brand) 6%, var(--ce-surface)); color: inherit; }
.ce-out__row--head .ce-out__row-title { font-size: 16px; font-weight: 700; }
.ce-out__row--child .ce-out__row-title { font-size: 15px; font-weight: 600; }

/* ⚠ A LOCKED ROW IS RENDERED AS A SPAN, so this is the only styling that says so.
   It must not look like a link that failed — it is a rule, and the note beside it
   names the check that opens it. */
.ce-out__row.is-locked { cursor: default; color: var(--ce-muted); }
.ce-out__row.is-locked .ce-out__row-title { font-weight: 600; }

.ce-out__state {
    flex: none;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1.5px solid var(--ce-border);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ce-surface);
}
.ce-out__icon { width: 18px; height: 18px; fill: currentColor; }
.ce-out__row.is-done .ce-out__state { background: var(--ce-done); border-color: var(--ce-done); color: #fff; }
.ce-out__row.is-locked .ce-out__state { color: var(--ce-muted); background: transparent; }
/* Where they are, marked on the circle itself so the row reads at a glance. */
.ce-out__row.is-current .ce-out__state { border-color: var(--ce-brand); border-width: 2px; box-shadow: inset 0 0 0 3px var(--ce-brand); }

.ce-out__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ce-out__row-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 12.5px; color: var(--ce-muted); }
.ce-out__kind { text-transform: uppercase; letter-spacing: .06em; }
/* "Passed" is a done state, so it takes the done colour rather than the brand one. */
.ce-out__note { font-weight: 600; color: var(--ce-done); text-transform: none; letter-spacing: 0; }
.ce-out__row.is-locked .ce-out__note { color: var(--ce-muted); }
/* ⚠ ITS OWN LINE. Run in beside the kind label it reads as a subtitle of the word LESSON; on its
   own line it reads as what it is — the reason this row is not a link. */
.ce-out__lock-note { flex-basis: 100%; text-transform: none; letter-spacing: 0; font-style: italic; }

.ce-out__here {
    flex: none;
    margin-left: auto;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--ce-brand-soft);
    color: var(--ce-brand-dark);
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}

.ce-out__finish { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--ce-border); }
.ce-out__finish .ce-run__cta { margin-top: 0; }

@media (max-width: 600px) {
    .ce-out .ce-out__rows { padding-left: 10px; }
    .ce-out__here { margin-left: 0; }
    .ce-out__row { flex-wrap: wrap; }
}

/* ──────────────────────────────────────────────────────────────────────────────
   THE COMPLETION MOMENT — the arrival back from filing the evaluation.

   ⚠ IT BORROWS THE LIVE PANEL'S CELEBRATION RATHER THAN INVENTING ONE. The
   confetti and `.ceasap-today-congrats` come from today-live.css, enqueued by
   Session_Panel::confetti(), so a self-paced student and a cohort student see
   the same thing at the same point. Only what genuinely differs differs.

   ⚠ THE CARD NEEDS position:relative FOR IT. The confetti is inset:0 absolute;
   without a positioned ancestor it falls against the page instead of the card.
   ────────────────────────────────────────────────────────────────────────────── */

.ce-run--celebrate { position: relative; overflow: hidden; }
.ce-run__celebrate { position: relative; z-index: 1; margin: 0 0 18px; }
/* today-live.css sizes this for a compact home-page row; on the course card it is the headline. */
.ce-run .ce-run__celebrate .ceasap-today-congrats { font-size: 17px; margin: 0 0 6px; }
.ce-run .ce-run__celebrate-line { margin: 0; font-size: 15px; color: var(--ce-muted); }

/* The review invitation, quiet on purpose: it is an ask, not an instruction, and it sits below the
   thing the student actually came back for. */
.ce-run__review {
    margin: 20px 0 0;
    padding: 16px 18px 18px;
    border: 1px dashed var(--ce-border);
    border-radius: 12px;
    background: color-mix(in srgb, var(--ce-brand) 3%, var(--ce-surface));
}
.ce-run .ce-run__review-text { margin: 0 0 12px; font-size: 15px; color: var(--ce-ink); }
.ce-run__review .ce-run__cta { margin-top: 0; }
/* The Trustindex widget paints itself; give it room only when it actually does, so a widget that
   never loads leaves no empty gap above the link. */
.ce-run__review-widget:not(:empty) { margin: 0 0 14px; }

/* ──────────────────────────────────────────────────────────────────────────────
   THE STUDENT DASHBOARD — ceLearning courses as ROWS, live kept apart from
   self-paced, with what was cancelled and what was missed beneath.

   ⚠ ROWS BECAUSE OF THE REAL NUMBERS: six self-paced, six live, plus history.
   A card each was unreadable past the third course. One line each means the
   course somebody is mid-way through is always near the top of the screen.

   ⚠ FOUR COLUMNS ON ONE LINE, and each answers a different question: what is
   it, where am I, what is next, and the way in. They collapse to two lines on a
   phone rather than shrinking, because a title truncated to fit is a course a
   student cannot recognise.
   ────────────────────────────────────────────────────────────────────────────── */

/* ⚠ OUR OWN VISUALLY-HIDDEN CLASS, NOT THE THEME'S `screen-reader-text`. That class belongs to
   whatever theme is active; leaning on it means the hidden word prints in plain sight anywhere the
   theme is not — which is exactly what happened the first time this shipped. */
.ce-sr {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ⚠ 1200px, THE COURSE PAGE'S OWN MEASURE. Scott, 2026-09-14: it needs to be wider for longer course
   titles. It was 880 — chosen for scanning a column of rows — and a two-line clamp on a 15.5px title
   meant the longest Nevada CE titles wrapped or got cut. The title track is minmax(0, 1fr), so every
   pixel added here goes to the title and none to the columns beside it. 1200 is not a round number
   picked to be wide: it is what `.ce-cohort__hero` measures on a rendered course page, so the
   dashboard now sits on the same measure as the pages it links to. */
.ce-dash { max-width: 1200px; margin: 0 auto; }

/* ── the header hero ─────────────────────────────────────────────────────────
   ⚠ THE COURSE PAGE'S HERO, MEASURED OFF IT. Scott, 2026-09-14: "Is the hero larger than other
   pages… Look at a course page." It was, and it was the wrong SHAPE as well as the wrong size. I
   had copied templates/calendar/hero.php — a full-bleed band, 100vw, 46/66 padding, a 34px/700
   title and two decorative glows. The course and product pages use `.ce-cohort__hero`, which is a
   CONTAINED rounded card: radius 16px, padding 36px 32px, the same two-layer background, one deep
   brand shadow, a pill row, then a 38.4px/600 title. Those numbers are read off the rendered page,
   not guessed, and they are mirrored here rather than shared because the two stylesheets load
   independently — if cohort-product.css moves, move this with it. */
.ce-dash__hero {
    position: relative;
    margin: 0 0 22px;
    padding: 36px 32px;
    border-radius: 16px;
    overflow: hidden;
    background:
        radial-gradient(120% 130% at 0% 0%, rgba(255, 255, 255, .16) 0%, rgba(255, 255, 255, 0) 46%),
        linear-gradient(135deg, #046bd2 0%, #02356f 100%);
    box-shadow: 0 18px 42px rgba(2, 53, 111, .30);
    color: #fff;
}
.ce-dash .ce-dash__title {
    margin: 0;
    font-size: 2.4rem;
    line-height: 1.1;
    font-weight: 600;
    color: #fff;
}
.ce-dash .ce-dash__hero-sub {
    margin: 14px 0 0;
    font-size: 1.15rem;
    line-height: 1.4;
    font-weight: 600;
    color: #fff;
}

/* ⚠ THE COURSE PAGE'S PILL, COPIED EXACTLY. Scott, 2026-09-14: the badge has to read the same as
   the one on the course pages. That is `.ce-cohort__pill--badge` in assets/product/cohort-product.css
   — 14px, sentence case, translucent white over the blue, and a 9px green dot with a ring. Values
   are mirrored rather than shared because the two stylesheets load independently and neither owns
   the other's tokens; if that pill changes, change this with it.

   ⚠ THE DOT NEEDS THE PILL TO BE A FLEX CONTAINER. Its width and height do nothing on an inline
   element, so if this rule ever goes missing the dot silently collapses to a 0px sliver rather than
   disappearing outright — which is how it went unnoticed for one deploy. */
.ce-dash__hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 17.6px;
    padding: 7px 15px;
    border: 1px solid rgba(255, 255, 255, .45);
    border-radius: 999px;
    background: rgba(255, 255, 255, .16);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
}
.ce-dash__hero-dot {
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #22c55e;
    box-shadow: 0 0 0 3px rgba(34, 197, 94, .25);
}

/* ⚠ THE STRIP SITS UNDER THE CARD, IT DOES NOT OVERLAP IT. It rode up into the band by -34px while
   the hero was full-bleed, which was the thing that made the two read as one header. A contained
   card has its own edge and its own shadow, and pulling a second card up over that corner is how
   you get a seam. */
.ce-dash__stats {
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    margin: 0 0 26px;
    border-radius: 14px;
    overflow: hidden;
    background: var(--ce-border, rgba(2, 53, 111, .12));
    box-shadow: 0 10px 30px rgba(2, 53, 111, .13);
}
.ce-dash__stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 16px 18px;
    background: var(--ce-surface, #fff);
    text-align: center;
}
.ce-dash__stat-n {
    font-size: 26px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ce-ink, #0a2540);
    font-variant-numeric: tabular-nums;
}
.ce-dash__stat-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ce-muted, #5b6b7f);
}
.ce-dash__stat--active .ce-dash__stat-n { color: var(--ce-brand, #046bd2); }
.ce-dash__stat--done .ce-dash__stat-n,
.ce-dash__stat--cert .ce-dash__stat-n { color: var(--ce-done, #1a7f40); }

/* ── continue where you left off ─────────────────────────────────────────── */
.ce-dash__resume {
    display: flex;
    align-items: center;
    gap: 20px;
    margin: 0 0 30px;
    padding: 20px 22px;
    border: 1px solid color-mix(in srgb, var(--ce-brand, #046bd2) 28%, transparent);
    border-radius: 14px;
    background: linear-gradient(135deg, var(--ce-brand-soft, #e6f1fb) 0%, var(--ce-surface, #fff) 68%);
}
.ce-dash__resume-body { flex: 1 1 auto; min-width: 0; }
.ce-dash__resume-eyebrow {
    display: block;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ce-brand-dark, #0357a8);
}
.ce-dash .ce-dash__resume-title {
    margin: 5px 0 0;
    font-size: 19px;
    line-height: 1.3;
    font-weight: 700;
    color: var(--ce-ink, #0a2540);
}
.ce-dash__resume-meter { display: flex; align-items: center; gap: 10px; margin: 12px 0 0; }
.ce-dash__bar--wide { width: min(280px, 100%); height: 8px; }
.ce-dash a.ce-dash__resume-cta {
    flex: none;
    padding: 12px 22px;
    border-radius: 999px;
    background: var(--ce-brand, #046bd2);
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 6px 16px rgba(4, 107, 210, .28);
}
/* ⚠ EVERY STATE HERE TOO. Same shape of bug as .ce-run__cta: an <a> in page content that claimed
   only its base and :hover colour, so the theme's a:visited / a:active coloured the label after the
   first click. Audited 2026-09-14 across every link-as-button this plugin renders. */
.ce-dash a.ce-dash__resume-cta,
.ce-dash a.ce-dash__resume-cta:link,
.ce-dash a.ce-dash__resume-cta:visited,
.ce-dash a.ce-dash__resume-cta:hover,
.ce-dash a.ce-dash__resume-cta:focus,
.ce-dash a.ce-dash__resume-cta:active { color: #fff; text-decoration: none; }
.ce-dash a.ce-dash__resume-cta:hover { background: var(--ce-brand-dark, #0357a8); }

.ce-dash__section { margin: 0 0 26px; }
.ce-dash__section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 9px;
    background: var(--ce-brand-soft, #e6f1fb);
    color: var(--ce-brand-dark, #0357a8);
}
.ce-dash__section-icon svg { width: 16px; height: 16px; }
.ce-dash__section--past .ce-dash__section-icon { display: none; }
.ce-dash .ce-dash__section-title {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 10px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ce-ink, #0a2540);
}
.ce-dash__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--ce-brand-soft, #e6f1fb);
    color: var(--ce-brand-dark, #0357a8);
    font-size: 11.5px;
    letter-spacing: 0;
}

.ce-dash .ce-dash__list {
    list-style: none;
    margin: 0;
    padding: 0;
    border: 1px solid var(--ce-border, rgba(2, 53, 111, .12));
    border-radius: 14px;
    overflow: hidden;
    background: var(--ce-surface, #fff);
    /* ⚠ A CARD, NOT A HAIRLINE BOX. At 880px on a white page a 1px border alone left the list
       looking like an unstyled table; the shadow is what separates it from the page. */
    box-shadow: 0 2px 10px rgba(2, 53, 111, .06);
}
.ce-dash__row { display: flex; align-items: stretch; border-top: 1px solid var(--ce-border, rgba(2, 53, 111, .12)); }
.ce-dash__row:first-child { border-top: 0; }
.ce-dash__row-main {
    flex: 1 1 auto;
    display: grid;
    /* ⚠ THE STATE COLUMN IS `auto`, NOT A FIXED WIDTH. At 132px the "Completed September 2, 2026"
       chip — which must not wrap — simply overflowed its track and printed on top of the next
       column. A grid track does not clip its contents, so a too-narrow fixed column does not
       truncate, it collides. */
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 16px;
    padding: 13px 16px;
    text-decoration: none;
    color: inherit;
    min-width: 0;
    transition: background .15s ease;
}
.ce-dash__row-main:hover { background: color-mix(in srgb, var(--ce-brand, #046bd2) 4%, var(--ce-surface, #fff)); color: inherit; }
/* ⚠ THE THEME UNDERLINES LINKS IN PAGE CONTENT, and every row here is a link. On the real page that
   turned 87 course titles into 87 underlined blue lines — a wall of hyperlinks rather than a table.
   Stated at a specificity the theme's `.entry-content a` cannot outrank, and repeated for the states,
   because a rule that only holds until :hover is not a fix. */
.ce-dash a.ce-dash__row-main,
.ce-dash a.ce-dash__row-main:hover,
.ce-dash a.ce-dash__row-main:focus,
.ce-dash a.ce-dash__square,
.ce-dash a.ce-dash__square:hover { text-decoration: none; }
.ce-dash a.ce-dash__row-main .ce-dash__row-title { color: var(--ce-ink, #0a2540); }

/* ⚠ A DATED ROW GAINS A COLUMN IN FRONT. Live classes carry their date first; self-paced rows have
   none and start at the title, so the two shapes cannot share one track list. */
/* ⚠ THE DATE COLUMN SIZES TO THE LONGEST DATE, with 96px only as a floor. At a fixed 96px the site's
   own date format — "September 12, 2026" — overflowed its track and printed across the course title.
   The same collision the state column had: a grid track does not clip, it collides. `auto` keeps the
   dates aligned with each other while fitting whatever format the site is set to. */
.ce-dash__row--dated .ce-dash__row-main { grid-template-columns: minmax(96px, auto) minmax(0, 1fr) auto auto auto; }
.ce-dash__row-when {
    font-size: 13px;
    font-weight: 700;
    color: var(--ce-ink, #0a2540);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* A class still to come is the one being looked for. */
.ce-dash__row--dated.ce-dash__row--new .ce-dash__row-when { color: var(--ce-brand-dark, #0357a8); }

.ce-dash__row-time {
    font-size: 12.5px;
    color: var(--ce-muted, #5b6b7f);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.ce-dash__row-title { font-weight: 600; font-size: 15.5px; min-width: 0; line-height: 1.35; }
/* ⚠ TWO LINES AT MOST, AND NEVER MID-WORD. `overflow-wrap: anywhere` broke "Cybercrime" across
   lines to satisfy a narrow column; a course title chopped through a word is harder to scan than
   one that wraps cleanly. */
.ce-dash__row-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* A started course keeps a marker in the gutter so the eye finds it without reading. */
/* ⚠ NO ACCENT DOT BEFORE THE TITLE. It was a 6px brand square hung off the title's left edge to
   mark the row in progress; at 15.5px it reads as a hyphen typed in front of the course name, and
   on a page that now opens with a "continue where you left off" card it was saying a third time
   what the meter and that card already say. */

.ce-dash__row-state { display: flex; align-items: center; gap: 8px; justify-self: start; }
/* The bar needs a width of its own now that the column sizes to content. */
.ce-dash__bar { flex: none; width: 92px; height: 6px; border-radius: 999px; background: var(--ce-brand-soft, #e6f1fb); overflow: hidden; }
.ce-dash__bar-fill { display: block; height: 100%; background: var(--ce-brand, #046bd2); }
.ce-dash__pct { font-size: 12.5px; color: var(--ce-muted, #5b6b7f); font-variant-numeric: tabular-nums; }

.ce-dash__chip {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.ce-dash__chip--done { background: var(--ce-done-soft, #e7f6ec); color: var(--ce-done, #1a7f40); }
.ce-dash__chip--past { background: rgba(2, 53, 111, .06); color: var(--ce-muted, #5b6b7f); }


.ce-dash__row-note { font-size: 13px; color: var(--ce-muted, #5b6b7f); min-width: 0; }
/* ⚠ THE HISTORY ROWS CARRY ONE CELL MORE THAN A COURSE ROW — they have a reason to explain — so they
   need their own track count. Left on the three-column course grid the fourth cell wrapped to a
   second line and "Book again" sat alone under the title. */
.ce-dash__row--past .ce-dash__row-main { grid-template-columns: minmax(0, 1fr) auto minmax(0, 250px) auto; }
.ce-dash__row-go { font-size: 13.5px; font-weight: 600; color: var(--ce-brand, #046bd2); white-space: nowrap; }

/* ⚠ ONE SQUARE AT THE END OF THE ROW, AND ITS COLOUR IS THE STATE OF THE CERTIFICATE. Green means
   the document exists and this is the way to it; amber means something is still between the student
   and it. A finished row therefore carries ONE signal rather than a green date, a yellow badge and a
   grey icon all describing the same course.

   ⚠ FIXED WIDTH, so the squares line up down the page. A column of indicators that jitters by a few
   pixels per row is harder to read at a glance than no column at all. */
.ce-dash__square {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 96px;
    border-left: 1px solid var(--ce-border, rgba(2, 53, 111, .12));
    font-size: 12.5px;
    font-weight: 700;
    text-decoration: none;
    text-align: center;
    line-height: 1.2;
}
.ce-dash__square--done {
    background: var(--ce-done-soft, #e7f6ec);
    color: var(--ce-done, #1a7f40);
}
.ce-dash__square--done:hover { background: #d7efdf; color: var(--ce-done, #1a7f40); }
.ce-dash__square--todo {
    background: #fef3c7;
    color: #92400e;
}
a.ce-dash__square--todo:hover { background: #fde9a9; color: #92400e; }
.ce-dash__square-icon { width: 18px; height: 18px; }

/* History reads quieter than the work still to do. */
.ce-dash__section--past .ce-dash__row-title { font-weight: 500; color: var(--ce-muted, #5b6b7f); }

.ce-dash .ce-dash__empty-text { margin: 0 0 16px; font-size: 15px; color: var(--ce-ink, #0a2540); }
.ce-dash__empty { padding: 22px 24px; }

/* ⚠ AND IT NEEDS ROOM UNDER IT. Measured on /my-live-ce/ 2026-09-20: `.ce-dash__foot` ended at the
   same pixel as `.ce-dash`, and the site footer began at that pixel too — a 0px gap, so the two
   buttons sat directly on the footer's edge with nothing between them. Nothing above was wrong; this
   block simply had no bottom margin and was the last thing on the page. Scott, from the rendered
   page.

   ⚠ 26px BECAUSE THAT IS THIS PAGE'S OWN RHYTHM — `.ce-dash__section` already uses `0 0 26px`
   between sections, so the space under the last block matches the space between the others rather
   than introducing a number that exists nowhere else. */
.ce-dash__foot {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    margin: 4px 0 26px;
    padding-top: 18px;
    border-top: 1px solid var(--ce-border, rgba(2, 53, 111, .12));
}
/* ⚠ THE DISCLOSURE FOR COURSES NEVER OPENED. Closed it is one line; open it is the same list as
   above, so the rows inside keep the list's own border treatment. */
.ce-dash__fold { margin: 8px 0 0; }
.ce-dash .ce-dash__fold-summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border: 1px solid var(--ce-border, rgba(2, 53, 111, .12));
    border-radius: 999px;
    background: var(--ce-surface, #fff);
    font-size: 13px;
    font-weight: 600;
    color: var(--ce-muted, #5b6b7f);
}
.ce-dash .ce-dash__fold-summary::-webkit-details-marker { display: none; }
.ce-dash .ce-dash__fold-summary::before {
    content: "";
    width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s ease;
}
.ce-dash__fold[open] > .ce-dash__fold-summary::before { transform: rotate(90deg); }
.ce-dash .ce-dash__fold-summary:hover { border-color: var(--ce-brand, #046bd2); color: var(--ce-brand-dark, #0357a8); }
.ce-dash__list--folded { margin-top: 10px; }

.ce-dash a.ce-dash__link {
    display: inline-flex;
    align-items: center;
    padding: 10px 18px;
    border: 1px solid var(--ce-border, rgba(2, 53, 111, .12));
    border-radius: 999px;
    background: var(--ce-surface, #fff);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--ce-brand, #046bd2);
    text-decoration: none;
}
.ce-dash a.ce-dash__link:hover {
    border-color: var(--ce-brand, #046bd2);
    background: var(--ce-brand-soft, #e6f1fb);
    text-decoration: none;
}

@media (max-width: 720px) {
    /* ⚠ TWO LINES, NOT FOUR SQUEEZED COLUMNS. A course title cropped to fit a 90px column is a
       course the student cannot identify, which defeats the page. */
    .ce-dash__row-main {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas: "when go" "title title" "state next";
        /* the note only exists on the cancelled / not-attended rows */
        row-gap: 7px;
    }
    .ce-dash__row--dated .ce-dash__row-main { grid-template-columns: minmax(0, 1fr) auto; }
    /* ⚠ A ROW WITH NO DATE STARTS WITH ITS TITLE. The three-row areas were drawn for live classes,
       where the date fills the top-left and the action sits beside it. A self-paced row has no date,
       so that same grid printed "Resume course" on a line of its own ABOVE the course name — the
       action before the thing it acts on. */
    .ce-dash__row:not(.ce-dash__row--dated) .ce-dash__row-main {
        grid-template-areas: "title title" "state go";
        align-items: center;
    }
    .ce-dash__row-when  { grid-area: when; font-size: 12.5px; }
    /* the window follows the date on a phone, where there is no room for a column of its own */
    .ce-dash__row-time  { grid-area: state; }
    .ce-dash__row-title { grid-area: title; }
    .ce-dash__row-go    { grid-area: go; }
    .ce-dash__row-state { grid-area: state; }
    .ce-dash__row-note  { grid-area: next; text-align: right; }
    .ce-dash__square    { width: 76px; }
}

@media (max-width: 720px) {
    /* ⚠ THE HERO SHRINKS, IT DOES NOT GO. Scott asked for the header band; a phone still gets one,
       just at a size that leaves the first course row above the fold. */
    .ce-dash__hero { padding: 24px 20px; border-radius: 14px; }
    .ce-dash .ce-dash__title { font-size: 1.75rem; }
    .ce-dash .ce-dash__hero-sub { margin-top: 10px; font-size: 1rem; }
    .ce-dash__hero-badge { gap: 5px; padding: 5px 11px; font-size: 12px; }
    .ce-dash__hero-dot { width: 7px; height: 7px; box-shadow: 0 0 0 2px rgba(34, 197, 94, .25); }

    /* two up rather than auto-fit: four stats at 120px each wrap to a ragged 3 + 1 */
    .ce-dash__stats { grid-template-columns: 1fr 1fr; margin: 0 0 22px; }
    .ce-dash__stat { padding: 13px 15px; }
    .ce-dash__stat-n { font-size: 22px; }

    .ce-dash__resume { flex-direction: column; align-items: stretch; gap: 14px; }
    .ce-dash a.ce-dash__resume-cta { text-align: center; }
    /* ⚠ THE BAR SHARES THE LINE, IT DOES NOT TAKE IT. At width:100% the meter pushed "88% complete"
       off the right edge of the card, where it read as "88% comp". */
    .ce-dash__bar--wide { flex: 1 1 120px; width: auto; min-width: 0; }
    .ce-dash__resume-meter { flex-wrap: wrap; }
}

/* ⚠ THE FINISH NOTE SITS OVER ITS BUTTON, like "Up next" does. It is the sentence that explains why
   the button says "evaluation" rather than "certificate", so it has to be read immediately before
   the click, not beside it. */
.ce-run__finish-note {
    margin: 0 0 10px;
    max-width: 46ch;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--ce-muted, #5b6b7f);
    text-align: right;
}
@media (max-width: 560px) {
    .ce-run__finish-note { text-align: left; }
}

/* ⚠ THE CONFETTI RULES ARE GONE WITH THE MARKUP. They sized `.ceasap-confetti` to the card and gave
   it a keyframe that fell its full height; the self-paced finish no longer renders any confetti
   (Scott, 2026-09-15), and CSS for markup that no longer exists is the kind a later change edits in
   the belief it is doing something. The live session panel's own confetti is untouched — it has its
   own rules in today-live.css. */

/* ─────────────────────────────────────────────────────────────────────────
   STUDENT DASHBOARD — CARD LAYOUT
   Behind the `dashboard_cards` feature flag. The row rules above still ship;
   nothing here changes them, so turning the flag off restores them exactly.

   ⚠ THESE PILLS ARE NOT .ce-cohort__pill, AND MUST NOT BE. The hero's pill is
   rgba(255,255,255,.16) with white text and a backdrop blur — built for a blue
   hero, invisible on a white card. Same vocabulary, same dots, same kinds,
   inverted. The LABELS come from one builder (pills_for_course); only the paint
   differs.
   ───────────────────────────────────────────────────────────────────────── */

.ce-dash__list--cards {
	display: grid;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ce-card {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 4px 20px;
	align-items: start;
	padding: 16px 20px;
	background: #fff;
	border: 1px solid rgba(2, 53, 111, .10);
	border-radius: 12px;
	box-shadow: 0 1px 3px rgba(2, 53, 111, .08);
}

/* ⚠ THE DATE RAIL IS A THIRD COLUMN, AND ONLY A LIVE CARD HAS ONE. Scott,
   2026-09-14: on a list of live classes the question is "when". A self-paced
   card has no date, so it keeps two columns and its title starts at the edge —
   an empty rail would be a column of nothing on the courses most students
   hold most of. */
.ce-card--dated {
	grid-template-columns: 118px minmax(0, 1fr) auto;
}

.ce-card__when {
	grid-column: 1;
	grid-row: 1 / span 3;
	display: block;
	padding: 8px 6px;
	text-align: center;
	background: #f1f5f9;
	border: 1px solid #dbe3ec;
	border-radius: 9px;
}

.ce-card__when-d {
	display: block;
	font-size: 14px;
	font-weight: 700;
	line-height: 1.2;
	color: #0a2540;
}

/* ⚠ WIDE ENOUGH FOR A REAL TIME RANGE. window_label() prints "9:00 AM – 12:00 PM", which at the
   first draft's 96px wrapped onto three lines and turned the date column into a block of text — the
   one thing the rail exists to avoid. Two lines is the budget. */
.ce-card__when-t {
	display: block;
	margin-top: 2px;
	font-size: 11px;
	line-height: 1.35;
	color: #475569;
}

/* a class that has already run is history, and reads like it */
.ce-card__when--past {
	background: #f8fafc;
	border-color: #e6ebf2;
}

.ce-card__when--past .ce-card__when-d,
.ce-card__when--past .ce-card__when-t {
	color: #94a3b8;
}

.ce-card__title {
	grid-column: 2;
	margin: 0;
	font-size: 16.5px;
	font-weight: 600;
	line-height: 1.3;
}

.ce-card:not(.ce-card--dated) .ce-card__title {
	grid-column: 1;
}

.ce-card__title-link {
	color: #0a2540;
	text-decoration: none;
}

.ce-card__title-link:hover,
.ce-card__title-link:focus-visible {
	color: #046bd2;
	text-decoration: underline;
}

.ce-card__pills {
	grid-column: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: 9px 0 0;
	padding: 0;
	list-style: none;
}

.ce-card:not(.ce-card--dated) .ce-card__pills {
	grid-column: 1;
}

.ce-card__pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 11px;
	font-size: 12.5px;
	font-weight: 600;
	white-space: nowrap;
	color: #334155;
	background: #f1f5f9;
	border: 1px solid #dbe3ec;
	border-radius: 999px;
}

/* ⚠ MEASURED, NOT PICKED. #166534 on #fff is 7.4:1 and on #f1f5f9 is 7.0:1;
   #334155 on #f1f5f9 is 9.4:1; #475569 on #f1f5f9 is 7.2:1. Every one clears
   WCAG AA for small text, which the hero's own first draft did not. */
.ce-card__pill--badge {
	color: #166534;
	background: #fff;
	border-color: #bbf7d0;
	font-weight: 700;
}

.ce-card__pill--free {
	color: #713f12;
	background: #fde68a;
	border-color: #fbbf24;
	font-weight: 700;
}

.ce-card__pill--number {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 12px;
	color: #475569;
}

.ce-card__dot {
	display: inline-block;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: #22c55e;
}

.ce-card__dot--category {
	background: var(--ce-event-color, #046bd2);
}

/* ── the action column: one button, or a sentence ───────────────────────── */

.ce-card__act {
	grid-column: -2 / -1;
	grid-row: 1 / span 3;
	align-self: center;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 6px;
	text-align: right;
}

.ce-card__btn {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 8px 16px;
	font-size: 13.5px;
	font-weight: 700;
	white-space: nowrap;
	text-decoration: none;
	border: 1px solid transparent;
	border-radius: 999px;
}

.ce-card__btn--quiet {
	color: #334155;
	background: #fff;
	border-color: #cfd9e5;
}

.ce-card__btn--go {
	color: #fff;
	background: #046bd2;
}

/* ⚠ RED IS RESERVED FOR "NOW". It is the only state in the sequence that
   expires — every other button is still there tomorrow. Spending the loudest
   colour anywhere else is what makes a student stop reading the loud one. */
.ce-card__btn--live {
	color: #fff;
	background: #dc2626;
}

.ce-card__btn--eval {
	color: #fff;
	background: #0357a8;
}

.ce-card__btn--cert {
	color: #fff;
	background: #16a34a;
}

.ce-card__btn:hover,
.ce-card__btn:focus-visible {
	filter: brightness(.94);
}

/* ⚠ THE THEME OWNS `a`, AND IT OUTRANKED EVERY RULE ABOVE. `.ce-card__btn--go` is one class —
   (0,1,0) — while a theme rule as ordinary as `.entry-content a` is (0,1,1) and wins. So the label
   took the theme's link colour on top of our blue fill (blue on blue, the button looked empty) and
   its underline came back. Hover was worse: the rule above sets only `filter`, so nothing of ours
   defended the colour there at all.

   Fixed by specificity rather than `!important`, so a later rule can still win on purpose:
   `.ce-card a.ce-card__btn--go` is (0,2,1). Every state is named, because a theme that styles
   `a:hover` and `a:visited` separately will otherwise reach the ones we left out.

   ⚠ STILL AN ANCHOR. It navigates, so `<a>` is the right element — a <button> would need JavaScript
   to go anywhere and would lose middle-click, open-in-new-tab and copy-link. It is a button in
   appearance and a link in behaviour, which is what this control actually is. */
.ce-card a.ce-card__btn,
.ce-card a.ce-card__btn:link,
.ce-card a.ce-card__btn:visited,
.ce-card a.ce-card__btn:hover,
.ce-card a.ce-card__btn:focus,
.ce-card a.ce-card__btn:active {
	text-decoration: none;
	border-bottom: 0;
	box-shadow: none;
}

.ce-card a.ce-card__btn--go,
.ce-card a.ce-card__btn--go:link,
.ce-card a.ce-card__btn--go:visited,
.ce-card a.ce-card__btn--go:hover,
.ce-card a.ce-card__btn--go:focus,
.ce-card a.ce-card__btn--go:active { color: #fff; background: #046bd2; }

.ce-card a.ce-card__btn--live,
.ce-card a.ce-card__btn--live:link,
.ce-card a.ce-card__btn--live:visited,
.ce-card a.ce-card__btn--live:hover,
.ce-card a.ce-card__btn--live:focus,
.ce-card a.ce-card__btn--live:active { color: #fff; background: #dc2626; }

.ce-card a.ce-card__btn--eval,
.ce-card a.ce-card__btn--eval:link,
.ce-card a.ce-card__btn--eval:visited,
.ce-card a.ce-card__btn--eval:hover,
.ce-card a.ce-card__btn--eval:focus,
.ce-card a.ce-card__btn--eval:active { color: #fff; background: #0357a8; }

.ce-card a.ce-card__btn--cert,
.ce-card a.ce-card__btn--cert:link,
.ce-card a.ce-card__btn--cert:visited,
.ce-card a.ce-card__btn--cert:hover,
.ce-card a.ce-card__btn--cert:focus,
.ce-card a.ce-card__btn--cert:active { color: #fff; background: #16a34a; }

.ce-card a.ce-card__btn--quiet,
.ce-card a.ce-card__btn--quiet:link,
.ce-card a.ce-card__btn--quiet:visited,
.ce-card a.ce-card__btn--quiet:hover,
.ce-card a.ce-card__btn--quiet:focus,
.ce-card a.ce-card__btn--quiet:active { color: #334155; background: #fff; border-color: #cfd9e5; }

/* The darkening on hover is the whole hover state, and it must not change the ink. */
.ce-card a.ce-card__btn:hover,
.ce-card a.ce-card__btn:focus-visible { filter: brightness(.94); }

.ce-card__pulse {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
	animation: ce-card-pulse 1.4s ease-in-out infinite;
}

@keyframes ce-card-pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: .35; }
}

/* ⚠ A STUDENT WHO HAS ASKED FOR LESS MOTION HAS ASKED FOR LESS MOTION. The dot
   still prints; it simply stops moving, so the button loses nothing it says. */
@media ( prefers-reduced-motion: reduce ) {
	.ce-card__pulse {
		animation: none;
	}
}

.ce-card__bar {
	display: block;
	width: 140px;
	height: 6px;
	overflow: hidden;
	background: #e2e8f0;
	border-radius: 999px;
}

.ce-card__bar-fill {
	display: block;
	height: 100%;
	background: #046bd2;
}

.ce-card__pct {
	font-size: 12.5px;
	font-weight: 700;
	color: #0357a8;
}

.ce-card__sub {
	font-size: 12px;
	color: #64748b;
}

.ce-card__note {
	max-width: 30ch;
	font-size: 12px;
	line-height: 1.45;
	color: #b45309;
}

/* ⚠ WIDER WHEN IT IS THE WHOLE ANSWER. With no button above it the sentence IS
   the action column, and 30ch of amber text squeezed against the right edge
   reads as a footnote rather than as the thing the card is telling them. */
.ce-card__note--alone {
	max-width: 40ch;
}

/* ── narrow screens ─────────────────────────────────────────────────────── */

/* ⚠ THE ACTION DROPS BELOW, IT DOES NOT SHRINK. Scott, 2026-09-14, on the CE
   number pill: on a phone five pills cost three rows. A button squeezed into
   the corner beside them is the first thing to become untappable, so on a
   narrow screen the card becomes one column and the button gets a full line of
   its own, left-aligned with everything else. */
@media ( max-width: 620px ) {
	.ce-card,
	.ce-card--dated {
		grid-template-columns: minmax(0, 1fr);
	}

	.ce-card__when,
	.ce-card__title,
	.ce-card__pills,
	.ce-card--dated .ce-card__title,
	.ce-card--dated .ce-card__pills {
		grid-column: 1;
		grid-row: auto;
	}

	.ce-card__when {
		display: flex;
		gap: 8px;
		justify-content: flex-start;
		width: -moz-fit-content;
		width: fit-content;
		padding: 5px 11px;
		margin: 0 0 8px;
	}

	.ce-card__when-t {
		margin-top: 0;
	}

	.ce-card__act {
		grid-column: 1;
		grid-row: auto;
		align-items: flex-start;
		margin-top: 12px;
		text-align: left;
	}

	.ce-card__note,
	.ce-card__note--alone {
		max-width: none;
	}
}

/* The per-question history on a reviewed exam: one sentence, then a mark per sitting. */
.ce-run__review-history { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 8px; }
.ce-run__review-pill { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
	padding: 3px 9px; border-radius: 999px; border: 1px solid; }
.ce-run__review-pill.is-ok   { background: #E6F3EC; color: #1A7A4F; border-color: #A8D5BE; }
.ce-run__review-pill.is-warn { background: #FBF2DF; color: #8A5A12; border-color: #E8CE94; }
.ce-run__review-pill.is-bad  { background: #FBEBE6; color: #A33415; border-color: #EFBCA9; }
.ce-run__review-marks { display: inline-flex; gap: 3px; }
.ce-run__review-mark-dot { width: 20px; height: 20px; border-radius: 4px; display: inline-grid; place-items: center;
	font-size: 11px; font-weight: 600; background: #FBEBE6; color: #A33415; border: 1px solid #EFBCA9; }
.ce-run__review-mark-dot.is-right { background: #E6F3EC; color: #1A7A4F; border-color: #A8D5BE; }

/* ⚠ A <button> INHERITS NOTHING. Unlike an anchor it arrives with the browser's own font, a border,
   a grey fill and centred text, so the shared `.ce-card__btn` rules above are not enough on their
   own. The form wrapper is laid out as nothing at all so the button sits exactly where the link did. */
.ce-card__act-form { display: contents; }
.ce-card button.ce-card__btn {
	font: inherit;
	font-size: 13.5px;
	font-weight: 700;
	line-height: normal;
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
	border: 1px solid transparent;
	text-align: center;
}
.ce-card button.ce-card__btn--go    { color: #fff; background: #046bd2; }
.ce-card button.ce-card__btn--live  { color: #fff; background: #dc2626; }
.ce-card button.ce-card__btn--eval  { color: #fff; background: #0357a8; }
.ce-card button.ce-card__btn--cert  { color: #fff; background: #16a34a; }
.ce-card button.ce-card__btn--quiet { color: #334155; background: #fff; border-color: #cfd9e5; }
.ce-card button.ce-card__btn:hover,
.ce-card button.ce-card__btn:focus-visible { filter: brightness(.94); }

/* ⚠ THE THEME STYLES `ul` AND `li` INSIDE POST CONTENT, AND IT OUTRANKED THE LIST RULES ABOVE.
   `.ce-dash__list--cards` is one class — (0,1,0) — while `.entry-content ul` is (0,1,1) and wins.
   Two things broke visibly on /my-live-ce/ with several courses: the theme's `display` reset killed
   the grid, so `gap` stopped applying and the cards stacked edge to edge; and its list chrome drew a
   border and background around the whole group, which read as a second box outside the cards.

   Pinned by specificity rather than !important. `.ce-dash .ce-dash__list` is (0,2,0) and
   `.ce-dash ul.ce-dash__list` is (0,2,1), which clears an `.entry-content ul`. Every property the
   theme is likely to set is named, because leaving one out is how the last one got through. */
.ce-dash ul.ce-dash__list,
.ce-dash ul.ce-dash__list--cards {
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	box-shadow: none;
}

.ce-dash ul.ce-dash__list--cards {
	display: grid;
	grid-auto-rows: min-content;
	gap: 12px;
}

/* The row is the card; the <li> is only a slot and must add nothing of its own. */
/* ⚠ MARGIN YES, PADDING NO. The <li> IS the card and the card's own `padding: 16px 20px` is what
   holds the title off the border — zeroing it here put the text hard against the edge. Only the
   theme's list margin and bullet are stripped. */
.ce-dash ul.ce-dash__list > li,
.ce-dash ul.ce-dash__list--cards > li {
	margin: 0;
	border: 0;
	background: none;
	list-style: none;
}
.ce-dash ul.ce-dash__list > li::before,
.ce-dash ul.ce-dash__list > li::marker,
.ce-dash ul.ce-dash__list--cards > li::before,
.ce-dash ul.ce-dash__list--cards > li::marker {
	content: none;
}

/* ⚠ AND THE CARD KEEPS ITS OWN EDGE. If the theme ever wins on `.ce-card` too, the cards lose the
   border that separates them and the group becomes one undivided block.

   ⚠ THE EDGE HAS TO BE VISIBLE AT REST, NOT ON HOVER. It was `rgba(2, 53, 111, .10)` — a tenth of
   an opacity of navy on a white card on a white page — so a student with several courses saw a
   column of text with no card around any of it, and the shape only appeared under the pointer.
   Hover is not available on a phone at all. The border is now a solid tone and the shadow carries
   a second, wider pass, so the card reads as an object before anyone touches it.

   ⚠ EVERY DELIVERY, ONE TREATMENT. Self-paced, live/streamed and live/classroom cards share this
   rule; the delivery only ever changes what is INSIDE the card — the date rail, the pills, which
   button — never whether it looks like a card. */
.ce-dash .ce-card {
	border: 1px solid #d4dde8;
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 1px 2px rgba(2, 53, 111, .06), 0 2px 8px rgba(2, 53, 111, .07);
}

/* A hover is a nudge on top of a card that was already there, not the thing that draws it. */
.ce-dash .ce-card:hover {
	border-color: #b9cbdf;
	box-shadow: 0 1px 2px rgba(2, 53, 111, .08), 0 4px 14px rgba(2, 53, 111, .11);
}

/* The past rows stay lighter on purpose — history, listed last — but they are still rows with an
   edge, not loose text. */
.ce-dash .ce-dash__section--past .ce-card {
	border-color: #e2e8f0;
	box-shadow: none;
}

/* ⚠ ONE CARD PER COURSE, NOT ONE CARD PER LIST. `.ce-dash__list` was itself the card — a bordered,
   rounded, shadowed box with `overflow: hidden` — and each course was a `.ce-dash__row` separated
   from the next by a single `border-top`. With one course that reads fine. With twelve it reads as
   a table: an outer box around everything, hairlines between rows, and no course owning an edge of
   its own. Scott, from the screen: "the cards run into each other, and the Live section has an
   additional border around all of it", then "I still want distinct cards with a border for each
   course."

   So the list stops being a card and becomes a stack, and every row becomes the card. Same
   treatment for every delivery and for the past sections, which stay lighter but are still cards. */
.ce-dash ul.ce-dash__list {
	display: grid;
	gap: 12px;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	overflow: visible;
}

/* ⚠ NEVER SET `display` HERE. The <li> IS the card, and `.ce-card` is a GRID whose first column is
   the date rail — `118px minmax(0, 1fr) auto`. Forcing `display: block` collapsed that grid, so the
   date rail stretched full width across the top of every live card and the action button fell onto
   a row of its own. Give the <li> its edge and nothing else; the card owns its own layout. */
.ce-dash ul.ce-dash__list > li,
.ce-dash ul.ce-dash__list > li.ce-dash__row {
	border: 1px solid #d4dde8;
	border-top: 1px solid #d4dde8;   /* overrides the old divider-only rule */
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 1px 2px rgba(2, 53, 111, .06), 0 2px 8px rgba(2, 53, 111, .07);
}

/* The date rail stays the left column at every width above the phone breakpoint — it is the most
   compact place for a date and keeps the title on one line. */
/* ⚠ REMOVED: an unscoped `.ce-dash .ce-card--dated { grid-template-columns: 118px … }` lived here.
   Added in v1.380.157, then superseded in .161 by a 152px copy behind `min-width: 621px` — but this
   one was left behind, unscoped and at (0,2,0). It beat the 620px stack at (0,1,0) at EVERY width, so
   a phone kept the three-column grid: the date rail squeezed to 118px, the title crushed beside it,
   and the badges forced one per line. Found by reading the cascade off the live page rather than the
   source, after four guesses did not. The width now lives only in the min-width block below. */
.ce-dash .ce-card { display: grid; }

.ce-dash ul.ce-dash__list > li:hover {
	border-color: #b9cbdf;
	box-shadow: 0 1px 2px rgba(2, 53, 111, .08), 0 4px 14px rgba(2, 53, 111, .11);
}

/* History stays quieter — a flatter edge, no lift — but it is still a card per course. */
.ce-dash .ce-dash__section--past ul.ce-dash__list > li {
	border-color: #e2e8f0;
	box-shadow: none;
}
.ce-dash .ce-dash__section--past ul.ce-dash__list > li:hover {
	border-color: #cbd5e1;
	box-shadow: none;
}

/* The row fills its card now, so the radius has something to clip and the hairline is gone. */
.ce-dash ul.ce-dash__list > li > .ce-dash__row-main { border-radius: 12px; }

/* ⚠ THE PILLS ARE A NESTED <ul>, AND THE THEME REACHES THEM TOO. `.ce-card__pills` sits inside the
   card, so `.entry-content ul li` applies to every badge: a bullet, a left indent and a line of
   margin each, which is what turns a row of pills into a stacked list. The outer list was pinned in
   v1.380.154 and this one was missed — same fault, one level down.

   The badge set is identical for every delivery: NRED-Approved, the delivery, the category, the CE
   hours and the CE number. Only the delivery pill's text differs. */
.ce-dash ul.ce-card__pills {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	box-shadow: none;
}
.ce-dash ul.ce-card__pills > li {
	margin: 0;
	padding: 4px 11px;
	border: 1px solid #dbe3ec;
	border-radius: 999px;
	background: #f8fafc;
	box-shadow: none;
	list-style: none;
}
.ce-dash ul.ce-card__pills > li::before,
.ce-dash ul.ce-card__pills > li::marker { content: none; }

/* The badge variants keep their own treatment on top of that shared shape. */
.ce-dash ul.ce-card__pills > li.ce-card__pill--badge { background: #fff; border-color: #a8d5be; }
.ce-dash ul.ce-card__pills > li.ce-card__pill--number {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 12px;
	letter-spacing: .02em;
}

/* ⚠ THE DATE RAIL HAS TO FIT A DATE. 118px wrapped "October 22, 2026" onto a second line and pushed
   the year under the day, so the rail grew taller than the content beside it. 152px holds the
   longest month on one line at this size, and the rail is still the narrowest place to put a date.

   ⚠ BEHIND A min-width, OR IT EATS THE PHONE LAYOUT. There is a 620px breakpoint below that stacks
   the card to one column and turns the rail into a compact inline pill. `.ce-dash .ce-card--dated`
   is (0,2,0) against its (0,1,0), and a media query adds no specificity — so stated unconditionally
   this rule kept the 152px column on a 375px screen and squeezed the title to nothing. */
@media ( min-width: 621px ) {
	.ce-dash .ce-card--dated { grid-template-columns: 152px minmax(0, 1fr) auto; }
	.ce-dash .ce-card__when-d { white-space: nowrap; }

	/* ⚠ CENTRED AGAINST THE WHOLE CARD. The rail spans all three rows, so left to itself it sat at
	   the top while the title, badges and button filled the height beside it — the taller the card,
	   the more it looked dropped rather than placed. */
	.ce-dash .ce-card__when {
		align-self: center;
		display: flex;
		flex-direction: column;
		justify-content: center;
	}
}

/* ⚠ AND THE CARD KEEPS ITS INSET. Said twice on purpose: the <li> rule above strips theme padding
   from ordinary rows, and this restores the card's own so the title never touches the border. */
.ce-dash ul.ce-dash__list > li.ce-card { padding: 16px 20px; }

/* The badge row on a not-attended card: a span, not a ul, so it needs the flex row saying here. */
.ce-dash .ce-dash__row-pills {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 6px 0 0;
}
.ce-dash .ce-dash__row-pills .ce-card__pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 11px;
	border: 1px solid #dbe3ec;
	border-radius: 999px;
	background: #f8fafc;
	font-size: 12.5px;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────
   PHONE. Everything above raises specificity to get past the theme, which means it also gets past
   the site's own responsive rules unless it is repeated here. Photographed on an iPhone at 390px:
   the date pill wrapped "October 22, 2026" over three lines with the time stacked beside it over
   four more, and every badge took a row of its own, so one class filled the screen.
   ───────────────────────────────────────────────────────────────────────────────────────────── */
@media ( max-width: 620px ) {

	/* ⚠ THE DATE AND THE TIME EACH STAY ON ONE LINE. They were two flex children inside a
	   `width: fit-content` box, so they competed for a narrow column and both broke up. They wrap
	   as whole units now, and the pill may use the full width of the card. */
	/* ⚠ CENTRED, AND THE PILL TAKES THE FULL WIDTH SO CENTRING MEANS SOMETHING. A shrink-wrapped
	   pill has nothing to centre inside; it is the row of date + time that gets centred here. */
	.ce-dash .ce-card__when {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: baseline;
		justify-content: center;
		text-align: center;
		gap: 4px 10px;
		width: 100%;
		max-width: 100%;
		padding: 7px 12px;
		margin: 0 0 10px;
	}
	.ce-dash .ce-card__when-d,
	.ce-dash .ce-card__when-t { white-space: nowrap; }

	/* ⚠ BADGES WRAP, THEY DO NOT STACK. Each one was taking a full row. */
	.ce-dash ul.ce-card__pills {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		gap: 6px;
		width: 100%;
	}
	.ce-dash ul.ce-card__pills > li {
		display: inline-flex;
		align-items: center;
		width: auto;
		flex: 0 0 auto;
		padding: 3px 9px;
		font-size: 12px;
	}

	/* The action sits under the badges with room to breathe, and the caption clears the button
	   rather than colliding with whatever floats at the bottom-left of the viewport. */
	/* ⚠ `align-items` IS THE HORIZONTAL AXIS HERE, the column being the main one. The button and its
	   caption centre together — a centred button over a left-aligned "Completed" reads as a mistake. */
	.ce-dash .ce-card__act {
		display: flex;
		flex-direction: column;
		align-items: center;
		text-align: center;
		gap: 6px;
		margin-top: 12px;
		width: 100%;
	}
	.ce-dash .ce-card__act .ce-card__btn { width: auto; }

	/* A little less inset on a narrow screen buys a useful amount of line length. */
	.ce-dash ul.ce-dash__list > li.ce-card { padding: 14px 14px; }
}
