/*
 * The card course catalog (protected/views/courses/catalog_cards.php, every source since
 * 2026-10-14; jscripts/catalog.js). Loaded through $this->headers after the layout's own
 * stylesheets, then, where the theme has one, css/custom/<theme>/catalog.css on top of it. Sizes
 * are px on purpose (feedback_avoid_rem_font_sizes).
 *
 * This file is the DEFAULT design, for every source (2026-10-15): a brand-tinted well holds the
 * requirement card and the course list inside the theme's column; everything in the well is a
 * white surface (course cards one level up, the requirement card one more), everything outside it
 * (the h1 above, the notes, "How our courses work" and the regulator card below) stays on the
 * page. Colour is borrowed, never invented: every colour is the theme's one brand colour or a
 * color-mix() of it with white or black, and the neutrals are the family's cool greys. Numbers are
 * the voice: the hour figures are big, brand-coloured and tabular; prices are bold ink; the rest
 * is quiet. Type families come from the theme (its h1/h2/h3 rules for headings, --theme-font-display
 * for the figure, hours and price spans).
 *
 * Section 0 declares the --cat-* tokens on .card-catalog, and every colour, font and shadow rule
 * below reads ONLY those tokens, so a theme overrides the catalog with tokens, never by re-styling
 * elements:
 *   - a theme stylesheet sets --theme-brand, --theme-brand-strong and --theme-font-display on :root
 *     (the generated custom.css does it for the horizontal templates); without them the brand is
 *     the family's blue #275A9C (never Bootstrap's stock link blue) and the figures inherit the
 *     body face;
 *   - a theme with its own look remaps the --cat-* tokens in css/custom/<theme>/catalog.css and
 *     overrides the handful of element rules that differ (InsuranceStudy: its cream page is the
 *     tint, so its well is transparent; green figures, gold rules, a white page-head band).
 * Section 10 (.card-catalog--legacy) is the "inside a theme column" modifier the view adds on every
 * theme but InsuranceStudy: container nesting and the 10px-root metric fixes only, no look.
 * Section 13 (.card-catalog--compact) is the smaller type and tighter cards of the pages that
 * list short cards: the curated course and class catalogs, the class schedule, the curriculum.
 */

/* 0. Tokens ------------------------------------------------------------------------------- */
.card-catalog {
    --cat-accent: var(--theme-brand, #275A9C);
    --cat-accent-strong: var(--theme-brand-strong, color-mix(in srgb, var(--cat-accent) 78%, #000));
    --cat-on-accent: #fff;    /* text on a brand fill */
    --cat-ink: #1F2428;       /* headings, titles, prices */
    --cat-text: #2B2F33;      /* body copy */
    --cat-muted: #5D646B;     /* blurbs, labels, courtesy */
    --cat-subtle: #7C848C;    /* counts, struck prices, tag icons */
    --cat-faint: #CBD0D5;     /* an unticked box's border, the empty state's icon */
    --cat-success: #3F7A44;   /* a bundle's saving */
    --cat-surface: #fff;      /* cards, rail */
    --cat-well: color-mix(in srgb, var(--cat-accent) 8%, #fff);
    --cat-buy: color-mix(in srgb, var(--cat-accent) 4%, #fff);       /* a course card's price panel */
    --cat-tint: color-mix(in srgb, var(--cat-accent) 11%, #fff);     /* chips, hover fills, step numbers */
    --cat-line: color-mix(in srgb, var(--cat-accent) 16%, #DCE1E6);  /* card and rail borders */
    --cat-rule: color-mix(in srgb, var(--cat-accent) 10%, #E6EAEE);  /* hairlines inside cards */
    --cat-sunken: #EFF1F3;    /* a progress bar's track (curriculum.css) */
    --cat-panel: var(--cat-well);   /* the trainings block inside the requirement card */
    /* roles (InsuranceStudy remaps these to its green / gold split) */
    --cat-link: var(--cat-accent);
    --cat-link-hover: var(--cat-accent-strong);
    --cat-link-active: var(--cat-accent-strong);
    --cat-figure: var(--cat-accent);          /* .req-big, .course-hours and their icons */
    --cat-figure-numerals: tabular-nums;      /* font-variant-numeric of the figures and prices */
    --cat-weight-title: 600;                  /* a course title (a theme's h3 may set no weight) */
    --cat-price: var(--cat-ink);              /* ink, not the brand: on a red-brand site a red price reads as a warning */
    --cat-control: var(--cat-accent);         /* ticked boxes, the segment that is on */
    --cat-control-focus: var(--cat-accent);   /* a focused control's border or outline */
    --cat-bullet: var(--cat-accent);          /* .req-notes dots */
    --cat-chip-bg: var(--cat-tint);
    --cat-chip-border: var(--cat-accent);
    --cat-chip-text: var(--cat-accent-strong);
    --cat-chip-hover: color-mix(in srgb, var(--cat-accent) 18%, #fff);
    --cat-focus: 0 0 0 3px color-mix(in srgb, var(--cat-accent) 40%, transparent);
    --cat-shade: rgba(31, 36, 40, .12);       /* the rail's scroll shadows */
    --cat-shadow-xs: 0 1px 2px rgba(31, 36, 40, .06);
    --cat-shadow-sm: 0 1px 3px rgba(31, 36, 40, .08), 0 1px 2px rgba(31, 36, 40, .04);
    --cat-shadow-md: 0 8px 24px rgba(31, 36, 40, .10), 0 2px 6px rgba(31, 36, 40, .05);
    --cat-shadow-panel: var(--cat-shadow-sm);              /* the requirement card */
    --cat-radius-card: 6px;
    --cat-radius-panel: 8px;
    /* the DOI review sites' courses under review: the one hue not borrowed from the brand, a pale
       amber that reads as "pending" against both the brand-tinted well and the white approved cards */
    --cat-review-fill: #FFF9EB;
    --cat-review-buy: #FCF1D6;
    --cat-review-line: #E6D3A1;
    --cat-review-rule: #EEDFB6;
    /* families: the theme's heading face for the figures, hours and prices (the family token
       --font-display where the theme has no --theme-font-display; else they inherit the body
       face); the body face for the filter legend */
    --cat-font-display: var(--theme-font-display, var(--font-display, inherit));
    --cat-font-body: inherit;
    --cat-header-height: 0px;   /* the sticky rail's offset; InsuranceStudy sets its header height */
    --cat-ease: cubic-bezier(.2, .8, .2, 1);
}
/* A browser without color-mix() (before 2023) gets neutral greys for the tinted tokens. A token
   cannot fall back by itself, and a second plain declaration on the consuming rule would not help
   (a var() that fails at computed-value time unsets the property; it does not fall back to the
   declaration before it), so the tokens are redeclared where the function is unsupported. */
@supports not (color: color-mix(in srgb, #000 10%, #fff)) {
    .card-catalog {
        --cat-accent-strong: var(--theme-brand-strong, #1C4478);
        --cat-well: #F1F3F6;
        --cat-buy: #F7F8FA;
        --cat-tint: #E9EDF2;
        --cat-line: #D3DAE2;
        --cat-rule: #E2E6E9;
        --cat-chip-hover: #DCE3EA;
        --cat-focus: 0 0 0 3px rgba(39, 90, 156, .4);
    }
}

/* 1. Page head ----------------------------------------------------------------------------- */
/* on the page's own surface, above the well: the h1 (and the lead, on CE catalogs) anchor it */
.page-head {
    padding: 28px 0 20px;
}
.page-head-row {
    display: flex;
    flex-direction: column;
    gap: 20px;
}
/* size from the theme's h1 rule */
.page-head h1 {
    margin: 0 0 10px;
}
.page-head h1:only-child {
    margin-bottom: 0;
}
.page-head .lead {
    max-width: 68ch;
    margin: 0;
}
/* phones: one size down, so the four selling points take four lines rather than five */
@media (max-width: 575.98px) {
    .page-head .lead {
        font-size: 16px;
    }
}

/* 2. Notices ------------------------------------------------------------------------------- */
/* Staff-written catalog messages are Bootstrap 3-era HTML (their own .alert box, glyphicon
   spans, inline colour, floated images): render them as one quiet note in the new voice. */
.catalog-notice {
    margin: 24px 0 0;
}
.catalog-notice p:last-child,
.catalog-notice div:last-child > p:last-child {
    margin-bottom: 0;
}
.catalog-notice .alert,
.catalog-notice-after .alert {
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0;
    margin: 0;
    color: inherit;
    font-size: inherit;
}
/* staff-written media carries a fixed desktop width (a 650px <video>): shrink it to the column on
   a phone. An iframe keeps its height (an embed has no intrinsic ratio to fall back on). */
.catalog-notice img,
.catalog-notice-after img,
.catalog-notice video,
.catalog-notice-after video,
.catalog-intro-text img,
.catalog-intro-text video {
    max-width: 100%;
    height: auto;
}
.catalog-notice iframe,
.catalog-notice-after iframe,
.catalog-intro-text iframe {
    max-width: 100%;
}
.catalog-notice [style*="color"],
.catalog-notice-after [style*="color"] {
    color: inherit !important;
}
.catalog-notice .glyphicon,
.catalog-notice-after .glyphicon {
    display: inline-block;
    font-family: "Font Awesome 7 Free", "Font Awesome 5 Free";
    font-weight: 900;
    font-style: normal;
    margin-right: 6px;
}
.catalog-notice .glyphicon-bell::before,
.catalog-notice-after .glyphicon-bell::before {
    content: "\f0f3";
}
.catalog-notice .glyphicon-exclamation-sign::before,
.catalog-notice-after .glyphicon-exclamation-sign::before {
    content: "\f06a";
}
.catalog-notice .glyphicon-info-sign::before,
.catalog-notice-after .glyphicon-info-sign::before {
    content: "\f05a";
}
/* after the well, on the page: staff-written notes and footer messages, ruled off from the list.
   They run the full column like the header message (Jason 2026-10-19: a reading measure left the
   right third of the page empty). */
.catalog-notice-after {
    margin: 36px 0 0;
    padding-top: 24px;
    border-top: 1px solid var(--cat-rule);
    color: var(--cat-muted);
    font-size: 15px;
}

/* 2b. The well ------------------------------------------------------------------------------ */
/* The one bold move: a flat, square-cornered band in the brand's tint holding the notices, the
   requirement card and the course list. Its negative margin is the theme container's gutter and
   its side padding the same, so it bleeds to the container's edges (edge to edge on a phone) while
   its content stays aligned with the h1. Everything inside it is a white surface; the after-notice,
   "How our courses work" and the regulator card stay outside, on the page. A well with nothing
   after the requirement card (an LTC state without courses) keeps the same padding. */
.catalog-well {
    background: var(--cat-well);
    margin: 0 calc(var(--bs-gutter-x, 30px) * -.5);
    padding: 24px calc(var(--bs-gutter-x, 30px) * .5) 32px;
}
.catalog-well > :first-child {
    margin-top: 0;
}

/* 3. "What <state> requires" --------------------------------------------------------------- */
.req-card {
    background: var(--cat-surface);
    border: 1px solid var(--cat-line);
    /* no coloured top bar (Jason 2026-10-19: reads as AI-made): the white surface, its border and
       shadow lift it off the well */
    border-radius: var(--cat-radius-panel);
    box-shadow: var(--cat-shadow-panel);
    padding: 24px;
    margin: 28px 0 0;
}
/* Two columns from 992px: the rules (.req-main, with the full requirements and the product
   trainings collapsed under the figures) and the next step + courtesy note (.req-side). Running
   text keeps its 72ch measure; the side column uses the width the measure leaves. Phones stack
   main, then side. */
.req-layout {
    display: grid;
    gap: 24px;
}
.req-main {
    min-width: 0;
}
.req-side {
    border-top: 1px solid var(--cat-rule);
    padding-top: 20px;
}
.req-title {
    font-size: 22px;
    margin: 0 0 14px;
}
.req-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin-bottom: 22px;
}
.req-picker .form-label {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    color: var(--cat-muted);
}
.req-picker .form-select {
    width: auto;
    min-width: 240px;
    max-width: 100%;
}
.req-figures {
    display: flex;
    flex-wrap: wrap;
    gap: 20px 36px;
    margin-bottom: 18px;
}
.req-figure {
    display: flex;
    gap: 10px;
    align-items: flex-start;
}
.req-figure[hidden] {
    display: none;
}
/* the hero of the page: the hours, in the brand, in the theme's display face */
.req-big {
    font-family: var(--cat-font-display);
    font-weight: 700;
    font-size: 44px;
    line-height: 1;
    letter-spacing: -.02em;
    font-variant-numeric: var(--cat-figure-numerals);
    color: var(--cat-figure);
}
/* phones: the hours and the ethics figure share one row instead of stacking */
@media (max-width: 575.98px) {
    .req-figures {
        gap: 16px 20px;
    }
    .req-big {
        font-size: 36px;
    }
    .req-figure {
        gap: 8px;
    }
    .req-figure-label {
        font-size: 13px;
    }
}
.req-figure-label {
    font-size: 14px;
    line-height: 1.35;
    color: var(--cat-muted);
    padding-top: 4px;
}
/* the final-exam rule: proctor required or not */
.req-exam {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    max-width: 72ch;
    margin: 0 0 16px;
    font-size: 15px;
}
.req-exam > i {
    flex: 0 0 auto;
    margin-top: 4px;
    color: var(--cat-figure);
    font-size: 15px;
}
.req-exam strong {
    font-weight: 600;
    color: var(--cat-ink);
}
.req-exam-detail {
    margin-top: 4px;
}
/* in the profile card the rule sits on the figures' line, to their right: it takes the room left
   over and drops under the figures when that is under 220px (phones). Centred on the big numbers. */
.req-figures .req-exam {
    flex: 1 1 220px;
    align-self: center;
    margin: 0;
}
.req-exam-detail summary {
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    color: var(--cat-link);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.req-exam-detail summary:hover {
    color: var(--cat-link-hover);
}
.req-exam-detail summary:focus-visible {
    outline: none;
    box-shadow: var(--cat-focus);   /* the shared ring: 3:1 on cream and white (a gold outline alone was ~2.1:1) */
    border-radius: 2px;
}
.req-exam-detail p {
    margin: 6px 0 0;
    font-size: 14px;
    color: var(--cat-muted);
}
/* "Show full requirements": the summary, notes and product trainings, collapsed under the figures
   so the courses stay near the fold. A native <details>: works without the script, and the
   browser announces expanded / collapsed. */
/* a leading chevron that turns down when open, like the native marker of "Who can be your
   proctor?" above it; a label that wraps on a phone hangs beside it. Only the words are
   underlined, never the chevron. */
.req-toggle {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    max-width: 100%;
    list-style: none;
    cursor: pointer;
    font-size: 15px;
    font-weight: 600;
    color: var(--cat-link);
}
.req-toggle-closed,
.req-toggle-open {
    text-decoration: underline;
    text-underline-offset: 3px;
}
.req-toggle::-webkit-details-marker {
    display: none;
}
.req-toggle::marker {
    content: "";
}
.req-toggle i {
    flex: 0 0 auto;
    font-size: 12px;
    transition: transform 180ms var(--cat-ease);
}
.req-toggle:hover {
    color: var(--cat-link-hover);
}
.req-toggle:active {
    color: var(--cat-link-active);
}
.req-toggle:focus-visible {
    outline: none;
    box-shadow: var(--cat-focus);
    border-radius: 2px;
}
.req-toggle-open,
.req-more[open] .req-toggle-closed {
    display: none;
}
.req-more[open] .req-toggle-open {
    display: inline;
}
.req-more[open] > .req-toggle i {
    transform: rotate(90deg);
}
.req-toggle [hidden] {
    display: none;
}
.req-more-body {
    padding-top: 16px;
}
.req-summary {
    max-width: 72ch;
    margin: 0 0 10px;
}
.req-summary:empty {
    display: none;
}
.req-notes {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 15px;
    color: var(--cat-muted);
    max-width: 72ch;
}
.req-notes:empty {
    display: none;
}
/* the state's own proctor qualifications and its repeat rule, inside "Show full requirements" */
.req-proctor-rule,
.req-repeat-rule {
    max-width: 72ch;
    margin: 14px 0 0;
    font-size: 15px;
    color: var(--cat-muted);
}
.req-proctor-rule strong,
.req-repeat-rule strong {
    font-weight: 600;
    color: var(--cat-ink);
}
.req-notes li::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--cat-bullet);
    margin: 0 10px 2px 0;
}
.req-trainings-block {
    border: 1px solid var(--cat-rule);
    border-radius: var(--cat-radius-card);
    background: var(--cat-panel);
    padding: 16px 18px;
    margin: 24px 0 0;
}
.req-trainings-block[hidden] {
    display: none;
}
.req-subtitle {
    font-weight: 600;
    font-size: 16px;
    line-height: 1.3;
    color: var(--cat-ink);
    margin: 0 0 4px;
}
.req-trainings {
    list-style: none;
    padding: 0;
    margin: 0;
}
.req-training {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 0;
    border-top: 1px solid var(--cat-rule);
    font-size: 15px;
}
.req-training:first-child {
    border-top: 0;
}
.req-training-text {
    flex: 1 1 auto;
    min-width: 0;
}
.req-training-text strong {
    font-weight: 600;
}
.req-training-rule {
    color: var(--cat-text);
}
.req-training-note {
    display: block;
    color: var(--cat-muted);
    font-size: 14px;
    margin-top: 2px;
}
.req-training-action {
    flex: 0 0 auto;
}
.req-training-none {
    font-size: 14px;
    color: var(--cat-muted);
}
.req-training-link {
    font-size: 14px;
    font-weight: 500;
    color: var(--cat-link);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.req-training-link:hover {
    color: var(--cat-link-hover);
}
.req-training-link:active {
    color: var(--cat-link-active);
}
.req-training-link:focus-visible {
    outline: none;
    box-shadow: var(--cat-focus);
    border-radius: 2px;
}
@media (min-width: 768px) {
    .req-training {
        flex-direction: row;
        align-items: center;
        gap: 20px;
    }
    .req-training-action {
        text-align: right;
        min-width: 160px;
    }
}
.req-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    margin-bottom: 16px;
}
.req-link {
    align-self: flex-start;
    font-size: 15px;
    font-weight: 500;
}
.req-courtesy {
    font-size: 13px;
    line-height: 1.5;
    color: var(--cat-muted);
    margin: 0;
}
/* the card with structured requirements keeps its courtesy note with the full rules it qualifies, and
   only the provider number beside the figures (Jason 2026-10-22) */
.req-more-body .req-courtesy {
    margin-top: 16px;
}
.req-provider {
    font-size: 14px;
    line-height: 1.5;
    color: var(--cat-muted);
    margin: 0;
}
.req-main > .req-summary:last-child {
    margin-bottom: 0;
}
@media (min-width: 768px) {
    .req-card {
        padding: 28px 32px;
    }
}
/* between phone and desktop the stacked button keeps its natural width */
@media (min-width: 576px) and (max-width: 991.98px) {
    .req-actions {
        align-items: flex-start;
    }
}
@media (min-width: 992px) {
    .req-layout {
        grid-template-columns: minmax(0, 1fr) 340px;
        gap: 40px;
    }
    .req-side {
        border-top: 0;
        padding-top: 0;
        border-left: 1px solid var(--cat-rule);
        padding-left: 32px;
    }
}
/* A state without structured requirements has only a line or two of rules: the card stays one
   column at every width so a short main column never sits beside a tall side column. */
@media (min-width: 576px) {
    .req-card-plain .req-actions {
        align-items: flex-start;
    }
}
@media (min-width: 992px) {
    .req-card-plain .req-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }
    .req-card-plain .req-side {
        border-left: 0;
        padding-left: 0;
        border-top: 1px solid var(--cat-rule);
        padding-top: 20px;
    }
    .req-card-plain .req-courtesy {
        max-width: 80ch;
    }
}
/* An LTC catalog's card (LtcRequirementData): a resident / non-resident picker (the CE card's
   .req-picker select), then that residency's initial certification and renewal side by side from
   768px, each a figure (the same .req-figure / .req-big as the CE card); their summaries and the
   courtesy note are collapsed under "Show full requirements". Both residency panels (figures and
   summaries) are in the page; the picker's selected option picks one (:has), so the card works
   before the script runs and without it. A browser without :has shows both panels, one after the
   other. */
/* two short options (Resident / Non-resident): the select is as wide as they are, so the label
   and the select share a line on a phone */
.req-card-ltc .req-picker .form-select {
    min-width: 0;
}
.req-card-ltc .req-main:has(#reqResidency) [data-ltc-panel] {
    display: none;
}
.req-card-ltc .req-main:has(#reqResidency option[value="resident"]:checked) [data-ltc-panel="resident"],
.req-card-ltc .req-main:has(#reqResidency option[value="non-resident"]:checked) [data-ltc-panel="non-resident"] {
    display: block;
}
/* a state with rules for one residency only: its name in place of the picker */
.ltc-panel-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--cat-muted);
    margin: 0 0 14px;
}
.ltc-stages {
    display: grid;
    gap: 22px 32px;
}
.ltc-stage {
    min-width: 0;
}
.ltc-stage-title {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cat-ink);
    margin: 0 0 10px;
}
/* a cell with no figure (no requirement, or a rule without an hour count): words in the figure's
   place, the summary says why */
.req-figure-none {
    display: inline-block;
    padding: 9px 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cat-muted);
}
.req-card-ltc .req-more {
    margin-top: 18px;
}
.ltc-more-stage + .ltc-more-stage {
    margin-top: 14px;
}
.ltc-stage-summary {
    max-width: 72ch;
    font-size: 15px;
    line-height: 1.6;
    margin: 0;
}
.ltc-stage-summary strong,
.ltc-stage-note strong {
    font-weight: 600;
    color: var(--cat-ink);
}
.ltc-stage-note {
    max-width: 72ch;
    font-size: 14px;
    line-height: 1.5;
    color: var(--cat-muted);
    margin: 8px 0 0;
}
.ltc-stage-note:first-child {
    margin-top: 0;
}
@media (min-width: 768px) {
    .ltc-stages {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
/* a source without the every-state rules page has nothing beside the figures: one column */
@media (min-width: 992px) {
    .req-layout--single {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* 4. Bundles ------------------------------------------------------------------------------- */
.bundles {
    margin: 44px 0 0;
}
.bundles .section-head {
    margin-bottom: 20px;
}
.bundles .section-head h2 {
    font-size: 26px;
}
.bundle-grid {
    display: grid;
    gap: 20px;
}
@media (min-width: 768px) {
    .bundle-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (min-width: 992px) {
    .bundle-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.bundle-card .card-body {
    display: flex;
    flex-direction: column;
    height: 100%;
}
.bundle-title {
    font-size: 20px;
    margin: 0 0 6px;
}
.bundle-courses {
    margin-bottom: 20px;
}
.bundle-courses summary {
    cursor: pointer;
    color: var(--cat-link);
    font-size: 14px;
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.bundle-courses summary:hover {
    color: var(--cat-link-hover);
}
.bundle-courses ul {
    list-style: none;
    padding: 0;
    margin: 10px 0 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
}
.bundle-courses li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
}
.bundle-courses li span {
    flex: none;
    color: var(--cat-muted);
}
.bundle-buy {
    margin-top: auto;
}
.bundle-price {
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.price-lg {
    font-size: 28px;
}
.bundle-was {
    color: var(--cat-subtle);
    font-size: 15px;
}
.bundle-saving {
    color: var(--cat-success);
    font-size: 14px;
    font-weight: 500;
    margin: 4px 0 14px;
}

/* 5. Catalog layout: filter rail + list ----------------------------------------------------- */
.catalog {
    margin: 44px 0 0;
}
.catalog-title {
    font-size: 24px;
    margin: 0;
}
/* the course heading and the sort on one row above both columns (Jason 2026-10-14), so the
   filter rail and the first course card start level. Below 992px the toolbar wraps to its own
   full-width row (the Filters button left, the sort right); a catalog with no heading keeps the
   sort on the right. */
.catalog-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 14px 24px;
    margin-bottom: 20px;
}
.catalog-head .catalog-title {
    flex: 1 1 auto;
    min-width: 0;
}
.catalog-title:focus {
    outline: none;   /* a programmatic focus target after the list changes, never a control */
}
.catalog-layout {
    display: grid;
    gap: 24px;
}
@media (min-width: 992px) {
    .catalog-layout {
        grid-template-columns: 272px minmax(0, 1fr);
        gap: 32px;
        align-items: start;
    }
    .catalog-layout--full {
        grid-template-columns: minmax(0, 1fr);
    }
    .catalog-filters {
        position: sticky;
        top: calc(var(--cat-header-height) + 16px);
    }
    /* Bootstrap makes the ≥lg offcanvas body a flex row; the rail stacks. One class more than
       Bootstrap's .offcanvas-lg .offcanvas-body: some layouts (the horizontal template) print this
       file before bootstrap.min.css, and a tie went to Bootstrap there */
    .catalog-filters .offcanvas-lg .offcanvas-body {
        display: block;
        padding: 0;
        overflow: visible;
    }
    /* The rail scrolls inside itself when it is taller than the window (a laptop or a landscape
       tablet). Scroll shadows say so: a soft edge shows at the bottom (or top) only while more of
       the rail lies that way, so the rail never just looks cut off part way through a filter. */
    .filters {
        background:
            linear-gradient(var(--cat-surface) 30%, transparent) center top / 100% 40px no-repeat local,
            linear-gradient(transparent, var(--cat-surface) 70%) center bottom / 100% 40px no-repeat local,
            linear-gradient(var(--cat-shade), transparent) center top / 100% 12px no-repeat scroll,
            linear-gradient(transparent, var(--cat-shade)) center bottom / 100% 12px no-repeat scroll,
            var(--cat-surface);
        border: 1px solid var(--cat-line);
        border-radius: var(--cat-radius-card);
        box-shadow: var(--cat-shadow-xs);
        padding: 18px 20px 8px;
        max-height: calc(100vh - var(--cat-header-height) - 32px);
        overflow: auto;
    }
}
.catalog-filters .offcanvas-footer {
    padding: 14px 20px;
    border-top: 1px solid var(--cat-rule);
    background: var(--cat-surface);
}
.filter-group {
    border: 0;
    border-top: 1px solid var(--cat-rule);
    padding: 16px 0;
    margin: 12px 0 0;
    min-width: 0;
}
/* the rail opens on its first group: no space above it, but the same rule beside its legend and the
   same 26px under it as every other group (it had neither, so its first option crowded its legend).
   The first group is the first in-view group (.filter-inview: the staff-made groups, then the credit
   group) when there is one, else the panel's first, which also opens the phone panel; a second
   in-view group, and from 992px the panel continuing the rail under them, keep the 12px between
   groups. */
.filter-inview > .filter-group:first-child,
.catalog-filters .offcanvas-body > .filter-group:first-child {
    margin-top: 0;
}
@media (min-width: 992px) {
    .filter-inview + .offcanvas-lg .offcanvas-body > .filter-group:first-child {
        margin-top: 12px;
    }
}
/* below 992px the in-view groups are the filters shown (Jason 2026-10-22: the credit group; 2026-11-01:
   the staff-made groups too; the rest are behind "More filters"): the rail's card, on its own above
   the course list */
@media (max-width: 991.98px) {
    .filter-inview {
        background: var(--cat-surface);
        border: 1px solid var(--cat-line);
        border-radius: var(--cat-radius-card);
        box-shadow: var(--cat-shadow-xs);
        padding: 16px 18px 0;
    }
}
.filter-legend {
    float: none;
    width: auto;
    font-family: var(--cat-font-body);
    font-weight: 600;
    font-size: 12px;
    line-height: 1.3;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cat-muted);
    margin: 0 0 10px;
    padding: 0;
}
.filter-group .form-check {
    margin-bottom: 8px;
    padding-left: 28px;
    min-height: 24px;
}
.filter-group .form-check:last-child {
    margin-bottom: 0;
}
.filter-group .form-check-input {
    width: 18px;
    height: 18px;
    margin-top: 3px;
    margin-left: -28px;
    border-color: var(--cat-faint);
}
/* Bootstrap rings a box (and recolours its border) on any focus, a click included: off, so the
   ring below is keyboard-only */
.filter-group .form-check-input:focus {
    border-color: var(--cat-faint);
    box-shadow: none;
}
.filter-group .form-check-input:checked {
    background-color: var(--cat-control);
    border-color: var(--cat-control);
}
.filter-group .form-check-input:focus-visible {
    border-color: var(--cat-control-focus);
    box-shadow: var(--cat-focus);
}
.filter-group .form-check-label {
    font-size: 15px;
    line-height: 1.5;
    cursor: pointer;
}
#fTopic {
    font-size: 15px;
}
.filter-count {
    color: var(--cat-subtle);
    font-size: 14px;
}
.filter-group-clear {
    padding-top: 10px;
    padding-bottom: 6px;
}
.filter-group-clear .btn {
    padding-left: 0;
    padding-right: 0;
}

/* 6. Toolbar, chips, empty state ----------------------------------------------------------- */
.catalog-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 16px;
    flex: 1 1 100%;
}
@media (min-width: 992px) {
    .catalog-toolbar {
        flex: 0 0 auto;
    }
}
.catalog-sort {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--cat-muted);
    white-space: nowrap;
}
.catalog-sort .form-select {
    width: auto;
    min-width: 0;
    font-size: 14px;
    padding: 6px 32px 6px 10px;
}
.catalog-toolbar [data-filter-badge] {
    margin-left: 4px;
    padding: 3px 7px;
    font-size: 12px;
    line-height: 1;
}
/* phones: the Filters button and the sort stay on one line, also once the button carries its
   count badge; the sort gives way first, and under 360px its "Sort by" label goes (it stays the
   select's accessible name) */
@media (max-width: 575.98px) {
    .catalog-toolbar {
        flex-wrap: nowrap;
        gap: 10px;
    }
    .catalog-toolbar > .btn {
        flex: 0 0 auto;
    }
    .catalog-sort {
        min-width: 0;
        flex: 0 1 auto;
    }
}
@media (max-width: 359.98px) {
    .catalog-sort-label {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }
}
.catalog-toolbar [data-filter-badge][hidden] {
    display: none;
}
.catalog-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
    margin-bottom: 16px;
}
.catalog-chips[hidden] {
    display: none;
}
/* desktop: the rail is open beside the list and its ticked boxes already show the active filters,
   so the chip row would only repeat them (and push the first card below the rail's top) */
@media (min-width: 992px) {
    .catalog-chips:not([hidden]) {
        display: none;
    }
}
.chip-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--cat-chip-bg);
    border: 1px solid var(--cat-chip-border);
    color: var(--cat-chip-text);
    border-radius: 3px;
    padding: 5px 10px;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.3;
    cursor: pointer;
}
.filter-chip:hover {
    background: var(--cat-chip-hover);
}
.filter-chip:focus-visible {
    outline: none;
    box-shadow: var(--cat-focus);
}
.filter-chip i {
    font-size: 12px;
}
.link-btn {
    background: none;
    border: 0;
    padding: 0;
    color: var(--cat-link);
    text-decoration: underline;
    text-underline-offset: 2px;
    font-size: 14px;
    cursor: pointer;
}
.link-btn:hover {
    color: var(--cat-link-hover);
}
.link-btn:focus-visible {
    outline: none;
    box-shadow: var(--cat-focus);
    border-radius: 2px;
}
.empty-state {
    background: var(--cat-surface);
    border: 1px solid var(--cat-line);
    border-radius: var(--cat-radius-card);
    padding: 40px 24px;
    text-align: center;
}
.empty-state[hidden] {
    display: none;
}
.empty-state > i {
    font-size: 26px;
    color: var(--cat-faint);
}
.empty-state h3 {
    margin: 12px 0 6px;
}
.empty-state h3 + .btn {
    margin-top: 10px;
}
.empty-state p {
    color: var(--cat-muted);
    max-width: 44ch;
    margin: 0 auto 16px;
}

/* 7. Course cards -------------------------------------------------------------------------- */
/* the second surface level: white on the well, a brand-tinted hairline border, a small shadow;
   a hover lifts a card one level (the bundle cards share the surface) */
.card-catalog .card {
    background: var(--cat-surface);
    border: 1px solid var(--cat-line);
    border-radius: var(--cat-radius-card);
    box-shadow: var(--cat-shadow-xs);
    margin-bottom: 0;   /* the lists space their cards with a gap; bootstrap-legacy.css gives every .card 20px more */
}
/* newmain.css still styles an old .course-card class (15px of padding, a pale blue hover): the card
   body here has its own padding, so that rule put an inset around the price panel, and a card stays
   white under the pointer; the hover is the lift alone (2026-10-19) */
.card-catalog .course-card,
.card-catalog .course-card:hover {
    padding: 0;
    background-color: var(--cat-surface);
}
.course-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.course-card {
    transition: transform 180ms var(--cat-ease);
}
.course-card[hidden] {
    display: none;
}
.course-card:hover {
    box-shadow: var(--cat-shadow-md);
    transform: translateY(-2px);
}
/* a card with a keyboard-focused link or button lifts too; a click's focus does not */
.course-card:has(:focus-visible) {
    box-shadow: var(--cat-shadow-md);
}
.course-card-body {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 20px;
}
.course-info {
    min-width: 0;
}
/* a card with no PDF / CFP® tags ends on its description: no trailing margin under it */
.course-info > :last-child {
    margin-bottom: 0;
}
/* Under the title: "4 hours – Long Term Care". The hours are the second thing a buyer looks for,
   so they get the display face, semibold, in the figures' colour; the credit type stays quiet. */
.course-title {
    font-size: 19px;
    font-weight: var(--cat-weight-title);
    line-height: 1.3;
    margin: 0 0 6px;
}
/* Plain inline text with a hanging indent, not a flex row: a long credit name ("(CE0218) CE 2-18 -
   Life and Health") wraps inside itself, so the en dash stays on the hours line and the second
   line starts under the hours, not under the clock. */
.course-meta {
    margin: 0 0 10px;
    padding-left: 23px;
    text-indent: -23px;
}
/* no icon (InsuranceStudy): the hours line starts on the title's left edge, a long credit name wraps under it */
.course-meta--plain {
    padding-left: 0;
    text-indent: 0;
}
.course-meta > i {
    width: 15px;
    margin-right: 8px;
    text-indent: 0;
    color: var(--cat-figure);
    font-size: 15px;
}
.course-hours {
    font-family: var(--cat-font-display);
    font-weight: 600;
    font-size: 17px;
    line-height: 1.3;
    font-variant-numeric: var(--cat-figure-numerals);
    color: var(--cat-figure);
}
.course-credit {
    margin-left: 6px;
    font-size: 15px;
    color: var(--cat-muted);
}
.course-title a {
    color: var(--cat-ink);
    text-decoration: none;
}
.course-title a:hover {
    color: var(--cat-link);
    text-decoration: underline;
}
/* a bundle card with no hours line keeps the line's 10px gap above its description (course cards
   carry no description: the plain card) */
.course-title + .course-blurb {
    margin-top: 10px;
}
.course-blurb {
    font-size: 15px;
    color: var(--cat-muted);
    margin: 0 0 12px;
    max-width: 68ch;
}
/* The price panel: the price, the button and the details link on a faint brand tint that runs to
   the card's edges (a bottom band on a phone, the right-hand column from 768px), so a wide card
   with a short description reads as "course | price" rather than text and air. */
.course-buy {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px 16px;
    align-items: center;
    background: var(--cat-buy);
    border-top: 1px solid var(--cat-rule);
    border-radius: 0 0 calc(var(--cat-radius-card) - 1px) calc(var(--cat-radius-card) - 1px);
    margin: 0 -20px -20px;
    padding: 14px 20px 16px;
}
.course-price {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* a price (a course's, a bundle's): bold, in the display face, in heading ink */
.card-catalog .price {
    font-family: var(--cat-font-display);
    font-variant-numeric: var(--cat-figure-numerals);
    color: var(--cat-price);
}
/* every card's price sits just below its 19px heading (Jason 2026-10-19: the heading leads, on
   course and class cards alike) */
.course-price .price {
    font-weight: 600;
    font-size: 18px;
    line-height: 1;
}
.price-was {
    color: var(--cat-subtle);
    font-size: 14px;
}
.course-buy .btn-cart {
    white-space: nowrap;
}
.course-details-link {
    grid-column: 1 / -1;
    font-size: 14px;
    text-align: center;
}
/* the course details link: the last line of the course's own column, under the title and hours
   (InsuranceStudy's layout, every source since 2026-11-01) */
.course-info > .course-details-link {
    display: inline-block;
    text-align: left;
}
/* underlined on every theme, as on InsuranceStudy: a lone text link reads as a link (on ltcc,
   legacy-pages.css `.maincontent .catalog a` drops the underline, so this needs .card-catalog) */
.card-catalog .course-info > .course-details-link,
.card-catalog .course-format-row > .course-details-link {
    text-decoration: underline;
    text-underline-offset: 2px;
}
/* straight under the title (no hours line: LTC): the hours line's gap, so the link sits 12px under
   the title as it sits under the hours elsewhere */
.course-info > .course-title + .course-details-link {
    margin-top: 6px;
}
/* the format on an LTC catalog that also lists webinars (Jason 2026-11-01): "Webinar" /
   "Online self-study" in quiet grey with a small grey icon. A course card's label leads the details
   link's line (.course-format-row), so it costs no height; a webinar card, with no link, has it
   alone under its title. Plain text, not a pill: Jason found the tinted pill crowded and too blue. */
.course-format {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    color: var(--cat-muted);
    font-size: 14px;
    line-height: 1.5;
}
.course-format > i {
    color: var(--cat-subtle);
    font-size: 13px;
}
.course-info > .course-format {
    display: flex;
    width: fit-content;
    margin-top: 6px;
}
.course-format-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 24px;
    margin-top: 6px;
}
@media (min-width: 768px) {
    .course-card-body {
        flex-direction: row;
        align-items: stretch;
        gap: 24px;
        padding: 22px 24px;
    }
    .course-info {
        flex: 1 1 auto;
    }
    .course-buy {
        flex: 0 0 232px;
        display: flex;
        flex-direction: column;
        align-items: stretch;
        text-align: center;
        gap: 10px;
        border-top: 0;
        border-left: 1px solid var(--cat-rule);
        border-radius: 0 calc(var(--cat-radius-card) - 1px) calc(var(--cat-radius-card) - 1px) 0;
        margin: -22px -24px -22px 0;
        padding: 22px 20px;
    }
    .course-price {
        align-items: center;
    }
    .course-details-link {
        text-align: center;
    }
}

/* 8. How the courses work ---------------------------------------------------------------------- */
/* no bottom margin: the footer's own 72px top margin is the gap (since the sticky footer, a margin
   here adds to it instead of merging with it) */
.catalog-how {
    margin: 48px 0 0;
}
.catalog-how h2 {
    font-size: 24px;
    margin-bottom: 18px;
}
/* three white boxes on the page; they describe a sequence (study, exam, filing), so each carries
   its step number: a small tinted disc with a brand numeral above its heading */
.catalog-how-grid {
    display: grid;
    gap: 20px;
    counter-reset: catalog-step;
}
.catalog-how-grid > div {
    background: var(--cat-surface);
    border: 1px solid var(--cat-line);
    border-radius: var(--cat-radius-card);
    padding: 20px 22px;
}
.catalog-how-grid > div::before {
    counter-increment: catalog-step;
    content: counter(catalog-step);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    margin-bottom: 12px;
    border-radius: 50%;
    background: var(--cat-tint);
    color: var(--cat-accent);
    font-family: var(--cat-font-display);
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
}
.catalog-how-grid h3 {
    font-size: 17px;
    margin: 0 0 8px;
}
.catalog-how-grid p {
    font-size: 15px;
    color: var(--cat-muted);
    margin: 0;
}
@media (min-width: 768px) {
    .catalog-how-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* 8b. Add to Cart in the background: the button while its request is out ------------------- */
.btn.is-busy {
    opacity: .7;
    pointer-events: none;
}

/* 9. Motion preferences -------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .course-card,
    .offcanvas,
    .req-toggle i {
        transition: none;
    }
    .course-card:hover {
        transform: none;
    }
}

/* 10. Inside a theme column -----------------------------------------------------------------
   Outside the InsuranceStudy theme the view adds .card-catalog--legacy: the page renders inside
   the theme's own column layout (.container.maincontent) on css/bootstrap-legacy.css, whose 10px
   root turns Bootstrap's rem-sized form, offcanvas, badge and close-button metrics tiny. Metrics
   and nesting only: the look above is the same on every theme. */
/* the layout's container already sets the width and gutters; the view's own containers only nest */
.card-catalog--legacy .page-head > .container,
.card-catalog--legacy > .container {
    max-width: none;
    width: auto;
    padding-left: 0;
    padding-right: 0;
}
/* room under the last section: some column layouts (the horizontal theme's white card) end a
   few pixels below their content */
.card-catalog--legacy {
    padding-bottom: 24px;
}
/* From 768px the column is narrower than the screen, so the well's bleed into the gutter (2b) read
   as the band running past the page's left edge (Jason 2026-10-29): its edges sit on the column's,
   in line with the page's text and the after-notice's rule, and its content keeps the well's own
   24px inside them. Narrower, the column is the screen less its gutters and the bleed runs the
   well edge to edge. */
@media (min-width: 768px) {
    .card-catalog--legacy .catalog-well {
        margin-left: 0;
        margin-right: 0;
        padding-left: 24px;
        padding-right: 24px;
    }
}
.card-catalog--legacy .page-head h1 {
    font-size: 32px;
    line-height: 1.15;
    margin-top: 0;
}
.card-catalog--legacy .page-head .lead {
    font-size: 17px;
    line-height: 1.6;
}
.card-catalog--legacy .form-select {
    font-size: 15px;
    line-height: 1.5;
    min-height: 0;
    padding: 7px 36px 7px 12px;
    background-size: 16px 12px;
}
.card-catalog--legacy .catalog-sort .form-select {
    font-size: 14px;
    padding: 6px 32px 6px 10px;
}
/* the requirement card's picker at InsuranceStudy's size (44px, 16px: no zoom on focus in iOS) */
.card-catalog--legacy .req-picker .form-select {
    font-size: 16px;
    padding: 9px 40px 9px 12px;
}
.card-catalog--legacy .form-check-label {
    font-weight: normal;
}
.card-catalog--legacy .offcanvas-header,
.card-catalog--legacy .offcanvas-body {
    padding: 18px 20px;
}
.card-catalog--legacy .offcanvas-title {
    font-size: 20px;
    line-height: 1.3;
    margin: 0;
}
.card-catalog--legacy .btn-close {
    font-size: 16px;
}
.card-catalog--legacy .badge {
    font-size: 12px;
    padding: 3px 7px;
}
.card-catalog--legacy .course-title,
.card-catalog--legacy .catalog-how h3,
.card-catalog--legacy .catalog-how h2,
.card-catalog--legacy .catalog-title,
.card-catalog--legacy .req-title,
.card-catalog--legacy .req-subtitle,
.card-catalog--legacy .ltc-stage-title,
.card-catalog--legacy .bundle-title {
    margin-top: 0;
}
/* a theme's ".maincontent h3/h4" margin outranks .course-title's own; keep the card's 6px */
.card-catalog--legacy .course-title {
    margin-bottom: 6px;
}
/* these themes never styled Bootstrap 5's outline button or primary badge (they would be its stock
   blue): the brand instead, which is what the rest of the catalog's accents use. .btn-primary stays
   as the theme paints it. */
.card-catalog--legacy .btn-outline-primary {
    --bs-btn-color: var(--cat-accent);
    --bs-btn-border-color: var(--cat-accent);
    --bs-btn-hover-color: var(--cat-on-accent);
    --bs-btn-hover-bg: var(--cat-accent);
    --bs-btn-hover-border-color: var(--cat-accent);
    --bs-btn-active-color: var(--cat-on-accent);
    --bs-btn-active-bg: var(--cat-accent-strong);
    --bs-btn-active-border-color: var(--cat-accent-strong);
    --bs-btn-focus-box-shadow: var(--cat-focus);
}
.card-catalog--legacy .text-bg-primary {
    background-color: var(--cat-accent) !important;
    color: var(--cat-on-accent) !important;
}
.card-catalog--legacy .filter-group-clear .btn {
    background: none;
    border: 0;
    color: var(--cat-link);
    box-shadow: none;
}
.card-catalog--legacy .filter-group-clear .btn:hover {
    text-decoration: underline;
}
@media (max-width: 575.98px) {
    .card-catalog--legacy .page-head h1 {
        font-size: 26px;
    }
}

/* 11. Curated catalogs (protected/views/catalog/view_courses.php) --------------------------
   A source_catalog page (the NABIP topic catalogs): the staff-written header message is the lead,
   with the catalog's logo beside or above it as staff chose; the toolbar carries the source's
   catalog picker in place of a filter rail; a card's price panel can show a member price beside
   the non-member price. Everything else is the card catalog above. */
/* the staff header message runs the full column (Jason 2026-10-17: these are multi-paragraph
   introductions with lists and boxes, and a reading measure left the right third empty); only the
   state catalogs' one-sentence lead keeps its measure (.page-head .lead) */
.catalog-intro {
    margin-top: 16px;
}
.catalog-intro-text > :last-child {
    margin-bottom: 0;
}
.catalog-intro-logo img {
    display: block;
    max-width: 100%;
    height: auto;
}
/* the logo beside the text: a small one takes a narrow column, a wide one (over 250px) more; the
   text takes what is left and both stack on a phone */
.catalog-intro--side {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 20px 32px;
}
.catalog-intro--side .catalog-intro-text {
    flex: 1 1 320px;
    min-width: 0;
}
.catalog-intro-logo--side {
    flex: 0 0 auto;
    max-width: 180px;
}
.catalog-intro-logo--wide {
    flex: 0 0 auto;
    max-width: 320px;
}
/* the logo above the text, left or centred */
.catalog-intro-logo--left,
.catalog-intro-logo--center {
    margin-bottom: 20px;
}
.catalog-intro-logo--center img {
    margin: 0 auto;
}
/* the toolbar spans the row at every width: the catalog picker on the left, the sort on the
   right (the sort's own margin pushes it there) */
.catalog-head--tools .catalog-toolbar {
    flex: 1 1 100%;
}
.catalog-jump {
    display: flex;
    align-items: center;
    min-width: 0;
    margin: 0;
}
.catalog-jump .form-select {
    width: auto;
    max-width: 100%;
    font-size: 14px;
    padding: 6px 32px 6px 10px;
}
/* phones: the picker gives way to the sort and trims its long option names */
@media (max-width: 575.98px) {
    .catalog-jump {
        flex: 1 1 auto;
    }
    .catalog-jump .form-select {
        width: 100%;
        min-width: 0;
    }
}
/* under the price, the member price: "Member price $304.70" is ONE quiet line, its amount in the
   line's own font, weight and colour (Jason 2026-10-19: a second bold figure competed with the
   price); the price is the panel's only bold number. The lines sit 6px apart and 14px above the
   button. "Members only" takes the same quiet line under a class card's price (Jason 2026-10-29: the
   class card's left keeps to its name, date and time); a course card says it under its title. */
.price-alt {
    font-size: 14px;
    color: var(--cat-muted);
}
.price-alt strong {
    font-family: inherit;
    font-weight: inherit;
    font-variant-numeric: inherit;
    color: inherit;
}
.course-buy--ledger .course-price {
    gap: 6px;
}
.course-buy--ledger {
    row-gap: 14px;
}
/* a second list on the page (the webinars after the in-person classes) opens with its own heading */
.catalog-head--later {
    margin-top: 36px;
}
/* a third-party form embed in place of an empty schedule (the CLTC Accelerator's "tell me when") */
.catalog-embed {
    margin-top: 20px;
}
/* an empty schedule with a "tell me when" form (the CLTC Accelerator's Zoho embed): message and
   form in ONE card, left-aligned on one edge. The form lays itself out inside its iframe (left
   aligned, narrower fields below a width Zoho decides), so it gets the card's full width and the
   message follows its alignment rather than centring above it. */
.empty-state--form {
    text-align: left;
    padding: 28px 32px;
}
.empty-state--form h3 {
    margin-top: 0;
}
.empty-state--form p {
    max-width: 60ch;
    margin: 0;
}
.empty-state--form .catalog-embed {
    margin: 12px 0 0;
}
.catalog-embed iframe {
    display: block;
    width: 100%;
}
@media (max-width: 575.98px) {
    .empty-state--form {
        padding: 20px;
    }
}
/* phones: a panel with two prices is a small ledger across the card's width (the price and its
   label on one line, the member price on the next, the button full width under them) rather than
   three short lines squeezed beside the button */
@media (max-width: 767.98px) {
    .course-buy--ledger {
        grid-template-columns: minmax(0, 1fr);
    }
    .course-buy--ledger .course-price {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 6px 10px;
    }
    .course-buy--ledger .price-alt {
        flex: 1 1 100%;
    }
}

/* 12. Class cards (protected/views/catalog/_classCards.php) -------------------------------
   A scheduled class on the course card, with ONE bold line (Jason 2026-10-19: too much bold made
   the cards impossible to scan): the heading is the course name on a list of different courses
   and the date in words on a one-course schedule; under a course-name heading the date follows in
   regular ink; everything else is two muted rows of facts, when (the hours of the day, the number
   of days) and then where and who (the format or place, the presenter). The price panel and button
   are the course card's. */
/* the date under a course-name heading: second in importance, so ink at body weight, a step below
   the 17px heading (scoped to the card so a theme's p:last-of-type margin cannot outrank it) */
.class-card .class-when {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--cat-ink);
}
/* month dividers, once a schedule runs into a second month: a small label in the display face
   with a hairline running to the card's edge, quieter than the date headings it groups */
.course-month {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.course-month + .course-month {
    margin-top: 12px;
}
/* the list head of a schedule: the course name and the one price every class costs ("Registration
   cost: $100"; Jason 2026-10-19). Jason 2026-10-29: in body type under the name the price was easy
   to miss, so the amount is a price figure in the display face, and from 768px the line sits at the
   row's right end, level with the name, over the cards' buttons it applies to (its right edge on
   theirs: the card's 1px border and 24px padding). On a phone it follows the name. */
.catalog-head--schedule {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 6px;
}
.catalog-head--schedule .catalog-title {
    flex: 0 0 auto;
}
.catalog-price-line {
    margin: 0;
    font-size: 16px;
    font-weight: 400;
    line-height: 1.3;
    color: var(--cat-muted);
}
.catalog-price-amount {
    margin-left: 2px;
    font-family: var(--cat-font-display);
    font-size: 24px;
    font-weight: 700;
    font-variant-numeric: var(--cat-figure-numerals);
    color: var(--cat-price);
    white-space: nowrap;
}
@media (min-width: 768px) {
    .catalog-head--schedule {
        flex-direction: row;
        align-items: baseline;
        gap: 6px 32px;
    }
    .catalog-head--schedule .catalog-title {
        flex: 1 1 auto;
    }
    /* margin-left: on a list of several courses there is no name, and the price still keeps right */
    .catalog-price-line {
        flex: 0 0 auto;
        margin-left: auto;
        padding-right: 25px;
        text-align: right;
    }
}
/* a card without a price (the page states it once, or the catalog hides prices): no price panel,
   the button alone at the card's right, centred on its height; full width under the date on a phone */
.class-card.class-card--noprice .course-buy {
    background: none;
    border: 0;
}
@media (max-width: 767.98px) {
    .class-card.class-card--noprice .course-buy {
        display: block;
        margin: 0;
        padding: 0;
    }
    .class-card.class-card--noprice .course-buy .btn {
        width: 100%;
    }
}
@media (min-width: 768px) {
    .class-card.class-card--noprice .course-buy {
        flex: 0 0 auto;
        justify-content: center;
        margin: 0;
        padding: 0;
    }
    .class-card.class-card--noprice .course-buy .btn {
        white-space: nowrap;
        padding-left: 18px;
        padding-right: 18px;
    }
}
.course-month-title {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    font-family: var(--cat-font-display);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cat-muted);
}
.course-month-title::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--cat-line);
}
.card-catalog--legacy .course-month-title {
    margin-top: 0;
}
/* a row of facts (when and how long; then where and who): muted, body weight, wrapping on a phone */
.class-facts {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.5;
    color: var(--cat-muted);
}
/* scoped to the card so a theme's list spacing cannot outrank it (cltcnew's .maincontent li puts
   1.5em under every item: a blank line between the rows and under the last one). Any course card:
   the DOI review sites' course cards use the row for the publisher and provider. */
.course-card .class-facts li {
    margin: 0;
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
}
.class-facts i {
    color: var(--cat-subtle);
    font-size: 13px;
}
/* a date heading has no date line under it: a touch more room before the facts; the second row
   sits as close as a wrapped line of the first (the list's row gap) */
.course-card .course-title + .class-facts,
.class-card .class-facts + .class-facts {
    margin-top: 4px;
}
/* a class over several days: each day and its hours, the days in a column so the hours line up
   (subgrid: every row shares the widest date's width). The date in text ink, the hours muted like
   the one-day time row; nothing bold, the heading stays the card's one bold line. Scoped to the
   card so a theme's list spacing cannot outrank it (cltcnew's .maincontent li). */
.class-card .class-days {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 2px 16px;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.5;
    font-variant-numeric: var(--cat-figure-numerals);
    color: var(--cat-muted);
}
.class-card .class-days li {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    margin: 0;
    padding: 0;
}
.class-card .class-days time {
    color: var(--cat-text);
}
.class-card .class-when + .class-days {
    margin-top: 0;
}
.class-card .class-days + .class-facts {
    margin-top: 8px;
}
/* From 992px a class card's facts are schedule columns (Jason 2026-10-29: stacked on the left, they
   left the middle of the card empty): the heading and the date line across the top, then the hours
   or the days on the left and where and who in a column of their own, starting at the same point
   on every card so the list reads as a schedule. The where column's first line sits level with the
   first hours (4px under a date heading, flush under a date line). Narrower, a priced card's left
   column cannot hold "Thu, Nov 19  11:00 am – 4:00 pm ET", so the rows stay stacked. */
@media (min-width: 992px) {
    .class-card .course-info {
        display: grid;
        grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
        column-gap: 32px;
        align-content: start;
    }
    .class-card .course-info > .course-title,
    .class-card .course-info > .class-when {
        grid-column: 1 / -1;
    }
    .class-card .course-info > .class-days,
    .class-card .course-info > .class-facts--when {
        grid-column: 1;
    }
    .class-card .course-info > .class-facts--where {
        grid-column: 2;
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 2px;
        margin-top: 0;
    }
    .class-card .course-title + * + .class-facts--where {
        margin-top: 4px;
    }
    /* a card of dates without hours (CLTC's classes at a glance): nothing to sit beside under the
       name and date, so where and who move up beside them, from the card's top */
    .class-card--dates .course-info > .course-title,
    .class-card--dates .course-info > .class-when {
        grid-column: 1;
    }
    .class-card--dates .course-info > .class-facts--where {
        grid-row: 1 / span 2;
        margin-top: 0;
    }
}
/* The DOI review sites (Jason 2026-10-28): two lists in one well, the courses under review above the
   approved ones. The section headings step up from the 19px card titles, a hairline parts the two
   lists, and the review cards take the amber "pending" tint (price panel a shade deeper), their
   title and button centred in the card's height. */
.catalog--review .catalog-title,
.catalog--approved .catalog-title {
    font-size: 24px;
    letter-spacing: -.02em;
}
@media (min-width: 768px) {
    .catalog--review .catalog-title,
    .catalog--approved .catalog-title {
        font-size: 28px;
    }
}
.catalog--review + .catalog {
    margin-top: 40px;
    padding-top: 36px;
    border-top: 1px solid var(--cat-line);
}
.card-catalog .course-card--review,
.card-catalog .course-card--review:hover {
    background-color: var(--cat-review-fill);
    border-color: var(--cat-review-line);
}
.course-card--review .course-buy {
    background: var(--cat-review-buy);
    border-color: var(--cat-review-rule);
}
/* the brand link on the deeper tint needs the strong shade to keep its contrast */
.course-card--review .course-details-link {
    color: var(--cat-link-hover);
}
/* side by side only: on a phone the card stacks and the title keeps its left edge */
@media (min-width: 768px) {
    .course-card--review .course-info {
        align-self: center;
    }
    .course-card--review .course-buy {
        justify-content: center;
    }
}
/* the testimonial video (the CLTC catalogs): a fixed black frame over the page, opened once per
   day by itself and from the link under the list; --video-width is the catalog's own desktop
   width, set by catalog.js from data-video-width */
.catalog-video-link {
    margin: 12px 0 0;
}
.video-popup {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1050;
    width: 85vw;
    background: #000;
}
.video-popup[hidden] {
    display: none;
}
.video-popup-close {
    margin: 0;
    padding: 10px 10px 5px 0;
    text-align: right;
    background: #000;
}
.video-popup-player {
    display: block;
    width: 100%;
    border: 10px solid #000;
}
.video-popup-text {
    margin: 0;
    padding: 5px;
    text-align: center;
    color: #fff;
    background: #000;
}
.video-popup-text[hidden] {
    display: none;
}
@media (min-width: 992px) {
    .video-popup {
        width: var(--video-width, 800px);
    }
}

/* 13. Lists of short cards (.card-catalog--compact) ----------------------------------------
   A page whose cards are short (a title, a date or the hours, beside a price): the curated course
   and class catalogs, a source's class schedule and a designation's curriculum. Jason 2026-10-28:
   the catalogs' sizes read too big there, so the type is one step down throughout (h1 28px, the
   card heading and its price 17px), and the cards are tight (Jason 2026-10-19: less scrolling):
   12px between cards, 16px above and below a card's content, the price panel following the
   card's edges. The state catalogs keep the scale above. */
.card-catalog--compact .page-head h1 {
    font-size: 28px;
}
.card-catalog--compact .course-title {
    font-size: 17px;
}
.card-catalog--compact .course-price .price {
    font-size: 17px;
}
.card-catalog--compact .course-list {
    gap: 12px;
}
.card-catalog--compact .course-card-body {
    padding-top: 16px;
    padding-bottom: 16px;
}
@media (max-width: 575.98px) {
    .card-catalog--compact .page-head h1 {
        font-size: 24px;
    }
}
/* The buy column is InsuranceStudy's, not a tinted panel (Jason 2026-10-29): beside a short card's
   one or three lines, a panel running to the card's edges read as a crowded box next to an empty
   one. The price and the button sit on the card's own white behind a hairline inside the card's
   padding (above them on a phone, beside them from 768px), in the middle of the card's height,
   and a course card's title sits in the middle with them; a class card's facts stay at its top. */
.card-catalog--compact .course-buy {
    background: none;
    border-radius: 0;
    margin: 0;
    padding: 12px 0 0;
}
@media (min-width: 768px) {
    .card-catalog--compact .course-buy {
        flex-basis: 216px;
        justify-content: center;
        padding: 0 0 0 24px;
    }
    .card-catalog--compact .course-card:not(.class-card) .course-info {
        align-self: center;
    }
}
/* A second line under the price ("Member price $795.00", "Members only") changes nothing else
   (Jason 2026-10-29): it sits close under the price, the button keeps a single price's distance
   below it from 768px, and on a phone the button keeps its size beside the price rather than
   running the card's width under it. */
.card-catalog--compact .course-buy--ledger {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 10px;
}
.card-catalog--compact .course-buy--ledger .course-price {
    flex-direction: column;
    gap: 2px;
}

/* 14. Print -------------------------------------------------------------------------------- */
/* on paper the filter rail stops following the page and the video frame is never printed */
@media print {
    .catalog-filters {
        position: static;
    }
    .video-popup {
        display: none !important;
    }
}
