/**
 * PPF Pro Blueprint LMS - lesson-flow stylesheet (v0.3.3).
 *
 * The single centralized stylesheet for the lesson, locked-lesson, and
 * dashboard renders (C16). Versioned via PPFB_VERSION on enqueue.
 *
 * Normative tokens (panel consensus §2/§7, every ratio measured, WCAG 2.2 AA).
 * v0.3.56 (seat I): the --ppfb-* values below alias the Fall 2026 palette
 * contract (palette-tokens-v0.3.56.css); names retained, values retargeted:
 *   --ppfb-paper:              var(--course-egret)  (page field)
 *   --ppfb-ink:                var(--course-text-primary)  (Kiln Ink, 14.61:1 on Egret)
 *   --ppfb-quiet:              var(--course-text-muted)  (5.67:1 on Egret)
 *   --ppfb-eyebrow:            var(--course-link)  (5.87:1 on Egret)
 *   --ppfb-quiet-on-charcoal:  var(--course-text-on-deep)  (Egret; rule 1)
 *   --ppfb-charcoal:           var(--course-surface-deep)  (Toffee)
 *   --ppfb-gold:               var(--course-gold-accent)  (decorative only)
 *
 * Normative constraints honored here:
 *   - gold text on paper: prohibited
 *   - gold borders on paper: prohibited (quiet-outline uses --ppfb-quiet)
 *   - paper tokens are paper-surface-only, never on charcoal
 *   - eyebrows on deep surfaces use Egret (contract rule 1; was gold #c9a227)
 *   - quiz-gated aria-disabled control: quiz lead owns its palette
 *     (untouched in v0.3.56; see seat I report)
 */

/* ============ Tokens ============ */
/* Declared on every plugin surface, not just .ppfb-scope: the chrome bar and
   the footer render OUTSIDE .ppfb-scope (siblings inside .ppfb-page, the
   dashboard shortcode, the account hook), and an undeclared var() is
   guaranteed-invalid, which is why the old chrome shipped with a transparent
   background and inherited colors. Same values, wider scope. */
.ppfb-scope,
.ppfb-chrome,
.ppfb-footer {
    /* v0.3.56 (seat I): lesson-chrome tokens alias the Fall 2026 palette
       contract (palette-tokens-v0.3.56.css, handle ppfb-palette-tokens).
       Token names retained; values are the palette retarget. Navy #003965
       is brand-locked and untouched (see S4). */
    --ppfb-paper: var(--course-egret);
    --ppfb-ink: var(--course-text-primary);
    --ppfb-quiet: var(--course-text-muted);
    --ppfb-eyebrow: var(--course-link);
    --ppfb-quiet-on-charcoal: var(--course-text-on-deep);
    --ppfb-charcoal: var(--course-surface-deep);
    --ppfb-gold: var(--course-gold-accent);
    --ppfb-gold-deep: #a8871c;
    --ppfb-line: var(--course-candied-ginger);
    --ppfb-card: var(--course-surface-card);
    /* Type scale (Module 0 lesson-surface redesign, 2026-09-19; type review
       §7 - scale lives as custom properties in one place). The old φ/Fibonacci
       scale is retired (panel-approved build spec S2); ×1.25 adopted. */
    --ppfb-text-h1: 31px;           /* lesson H1, ≤767px (was 1.75rem/28px) */
    --ppfb-text-h1-wide: 39px;      /* lesson H1, ≥768px (was 2.25rem/36px) */
    --ppfb-text-h2: 25px;           /* (was 1.25rem/20px) */
    --ppfb-text-h3: 20px;           /* (was 1.125rem/18px) */
    --ppfb-text-lead: 20px;         /* lead paragraph */
    --ppfb-text-small: 14px;        /* small print / quiz options */
}

/* ============ Scope / type scale (normative, all viewports) ============ */
.ppfb-scope {
    max-width: 680px;
    margin: 0 auto;
    padding: 1.25rem;
    /* v0.3.48 (Apple Phase 1A): safe-area completion. The theme owns
       viewport-fit=cover; these additive env() insets keep plugin surfaces
       clear of the notch and home indicator on cover-fit viewports.
       calc()+env() is supported everywhere env() is (iOS 11.2+); where the
       env() values are 0 the rules collapse to the 1.25rem base. The
       full-bleed player inherits the scope insets through its bleed
       margins, so it never renders under the notch. */
    padding-left: calc(1.25rem + env(safe-area-inset-left));
    padding-right: calc(1.25rem + env(safe-area-inset-right));
    font-size: 17px;
    line-height: 1.65;
    color: var(--ppfb-ink);
    background: var(--ppfb-paper);
    box-sizing: border-box;
    /* Source fix for long unbroken strings (plain-text URLs in the tools
       list, tracking codes, pasted links): wrap instead of pushing the page
       wider than the viewport. Inherited by everything in the scope. */
    overflow-wrap: anywhere;
    /* Safety net: sideways scroll is never allowed. Every known offender is
       fixed at the source (see the small-phone block); this guard only stops
       future content from reintroducing it. `clip` (not `hidden`) keeps the
       vertical axis untouched and creates no scroll container. */
    overflow-x: clip;
}
.ppfb-scope * {
    box-sizing: border-box;
}
.ppfb-scope p {
    margin: 0 0 1.125rem;
}
.ppfb-scope h1,
.ppfb-scope h2,
.ppfb-scope h3 {
    line-height: 1.25;
    margin: 0 0 1rem;
    color: var(--ppfb-ink);
}
.ppfb-scope h1 {
    font-size: 1.75rem;
}
.ppfb-scope h2 {
    font-size: 1.25rem;
}
.ppfb-scope h3 {
    font-size: 1.0625rem;
}
.ppfb-scope section,
.ppfb-scope .ppfb-block {
    margin: 0 0 2rem;
}
.ppfb-scope li {
    margin: 0 0 0.5rem;
}
.ppfb-scope a {
    color: var(--ppfb-ink);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.ppfb-scope a:hover {
    color: var(--course-link-hover);
}

/* Visible focus on every surface (C22). */
.ppfb-scope :focus-visible {
    outline: 3px solid var(--ppfb-eyebrow);
    outline-offset: 2px;
    border-radius: 2px;
}
.ppfb-scope .ppfb-on-charcoal :focus-visible,
.ppfb-scope.ppfb-on-charcoal :focus-visible {
    outline-color: var(--course-focus-ring-on-deep);
}

/* ============ Skip link (A1) ============ */
.ppfb-skip {
    position: absolute;
    left: 1rem;
    top: -4rem;
    z-index: 200;
    background: var(--ppfb-charcoal);
    color: var(--course-text-on-deep);
    padding: 0.75rem 1.25rem;
    border-radius: 6px;
    font-weight: 700;
    text-decoration: none;
    transition: top 0.15s ease;
}
.ppfb-skip:focus-visible {
    top: 0.75rem;
    color: var(--course-text-on-deep);
    outline-color: var(--course-focus-ring-on-deep);
}

/* ============ Lesson page wrapper: horizontal-scroll guard ============ */
.ppfb-page {
    /* Safety net for the chrome + footer siblings that live outside
       .ppfb-scope. `clip` (not `hidden`) leaves vertical behavior alone. */
    overflow-x: clip;
}

/* ============ Premium plugin chrome (v0.3.5) ============ */
/* A crafted product header, not a floating box: a full-bleed paper band with
   a hairline bottom border, generous vertical padding, and the content held
   to the 680px measure. Brand lockup left, quiet Dashboard control right:
   balanced whitespace, clear hierarchy, nothing crowded. */
.ppfb-chrome {
    background: var(--ppfb-paper);
    border-bottom: 1px solid var(--ppfb-line);
    margin: 0 0 1.75rem;
}
.ppfb-chrome-inner {
    max-width: 680px;
    margin: 0 auto;
    padding: 0.875rem 1.25rem;
    /* v0.3.48: safe-area completion, same contract as .ppfb-scope above. */
    padding-left: calc(1.25rem + env(safe-area-inset-left));
    padding-right: calc(1.25rem + env(safe-area-inset-right));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.ppfb-chrome-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 44px;
    min-width: 0;
    text-decoration: none;
}
.ppfb-chrome-logo {
    width: 40px;
    height: 40px;
    border-radius: 11px;
    display: block;
    flex: none;
}
/* Wordmark, typeset like a brand: semibold (never bold), ink, a touch of
   letterspacing, comfortable size. */
.ppfb-chrome-wordmark {
    color: var(--ppfb-ink);
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: 0.015em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Beta pill beside the course wordmark (course is in beta; marine side is not). */
.ppfb-beta-pill {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #6e6e73;
    border: 1px solid #d2d2d7;
    border-radius: 999px;
    padding: 2px 9px;
    line-height: 1.5;
    white-space: nowrap;
}
/* v0.3.113: text column inside the brand lockup — wordmark over the quiet
   tier line (dashboard only). The anchor stays single-row inline-flex; the
   column keeps badge and text vertically centered. */
.ppfb-chrome-text {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.125rem;
    min-width: 0;
    line-height: 1.2;
}
.ppfb-chrome-tier {
    color: var(--ppfb-quiet);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}
/* The Dashboard link is a deliberate quiet control: a hairline pill with a
   real hover state, never a bare text link. Gold stays an accent only (the
   focus ring); the pill itself lives in the paper/ink/line language. */
.ppfb-chrome-dash {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 1.125rem;
    border: 1px solid var(--ppfb-line);
    border-radius: 999px;
    background: transparent;
    color: var(--ppfb-quiet);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-decoration: none;
    white-space: nowrap;
    flex: none;
    transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.ppfb-chrome-dash:hover {
    color: var(--ppfb-ink);
    border-color: var(--ppfb-ink);
    background: rgba(34, 26, 18, 0.04);
}
.ppfb-chrome-dash:focus-visible {
    outline: 2px solid var(--course-focus-ring);
    outline-offset: 2px;
}

/* ============ Breadcrumb (A3) ============ */
.ppfb-crumbs {
    font-size: 0.875rem;
    color: var(--ppfb-quiet);
    margin: 0 0 1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ppfb-crumbs a {
    color: var(--ppfb-quiet);
}
.ppfb-crumbs .ppfb-crumb-sep {
    margin: 0 0.4em;
    color: var(--ppfb-quiet);
}
.ppfb-crumbs [aria-current="page"] {
    color: var(--ppfb-ink);
    font-weight: 600;
}

/* ============ Position + progress (A4) ============ */
.ppfb-eyebrow {
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ppfb-eyebrow);
    margin: 0 0 0.5rem;
}
.ppfb-position {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0 0 0.5rem;
}
.ppfb-progress {
    margin: 0 0 1.5rem;
}
.ppfb-progress-track {
    background: var(--course-candied-ginger);
    border-radius: 999px;
    height: 3px;
    overflow: hidden;
}
.ppfb-progress-fill {
    background: var(--course-text-primary);
    height: 100%;
    border-radius: 999px;
}
.ppfb-progress-text {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0.5rem 0 0;
}

/* ============ Media-truth row (A7) ============ */
.ppfb-media-truth {
    font-size: 0.875rem;
    color: var(--ppfb-quiet);
    margin: 0 0 1.5rem;
}

/* ============ Objective (A8; v0.3.99 professional treatment) ============ */
.ppfb-objective {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-left: 3px solid var(--course-gold-accent, #E2B33D);
    border-radius: 13px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
    padding: 1.25rem 1.5rem;
    margin: 0 0 2rem;
}
.ppfb-objective .ppfb-eyebrow {
    margin-bottom: 0.5rem;
}
.ppfb-objective-text {
    font-size: 1.0625rem;
    line-height: 1.65;
    color: var(--ppfb-ink);
    margin: 0;
}
.ppfb-objective p:last-child {
    margin-bottom: 0;
}

/* ============ Lesson covers (v0.3.100) ============ */
.ppfb-covers {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 13px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
    padding: 1.25rem 1.5rem;
    margin: 0 0 2rem;
}
.ppfb-covers .ppfb-eyebrow {
    margin-bottom: 0.75rem;
}
.ppfb-covers-body > :last-child {
    margin-bottom: 0;
}

/* ============ Tools needed (A8T) ============ */
.ppfb-tools {
    margin: 0 0 2rem;
}
.ppfb-tools h2 {
    margin-bottom: 0.25rem;
}
.ppfb-tools-disclosure {
    font-size: 7pt;
    color: var(--ppfb-quiet);
    margin: 0 0 0.75rem;
}
.ppfb-tools-intro {
    margin: 0 0 0.75rem;
}
.ppfb-tools-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.ppfb-tools-list li {
    margin: 0;
    border-bottom: 1px solid var(--ppfb-line);
}
.ppfb-tools-list a {
    display: block;
    padding: 1rem 0.25rem;
    min-height: 56px;
    font-weight: 600;
}
.ppfb-tools-note {
    color: var(--ppfb-quiet);
    font-weight: 400;
}

/* ============ Lesson body (A9) ============ */
.ppfb-lesson-content {
    margin: 0 0 2rem;
}
.ppfb-lesson-content img,
.ppfb-lesson-content iframe {
    max-width: 100%;
    height: auto;
}

/* ============ Worksheets and references (A10) ============ */
.ppfb-downloads {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
    padding: 1.25rem;
    margin: 0 0 2rem;
}
.ppfb-downloads h2 {
    margin-bottom: 0.75rem;
}
.ppfb-downloads-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.ppfb-downloads-list li {
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--ppfb-line);
    margin: 0;
}
.ppfb-downloads-list li:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}
.ppfb-download-meta {
    font-size: 0.875rem;
    color: var(--ppfb-quiet);
    margin-left: 0.5em;
}

/* ============ Quiz card (A11) ============ */
.ppfb-quiz {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
    padding: 1.25rem;
    margin: 0 0 2rem;
}
.ppfb-quiz h2 {
    margin-bottom: 0.5rem;
}
.ppfb-quiz-meta {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0 0 0.5rem;
}
.ppfb-quiz-helper {
    font-size: 0.9375rem;
    margin: 0 0 1rem;
}
.ppfb-quiz-cooldown {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0 0 1rem;
    padding: 0.625rem 0.875rem;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
}
.ppfb-quiz-status {
    font-weight: 700;
    margin: 0 0 1rem;
}
.ppfb-quiz-status.passed {
    color: #1e6b34;
}
.ppfb-quiz .fluentform {
    margin-top: 1rem;
}
/* Quiz question-label restore: the theme globally screen-reader-hides every
   Fluent Forms field label (.fluentform .ff-el-input--label, written for the
   landing page's dark hero forms), which made quiz questions invisible on
   lesson pages. Inside the quiz container the labels must render normally.
   ID+class specificity (1,1,0) beats the theme's class+class (0,2,0)
   regardless of stylesheet load order. */
#ppfb-quiz .ff-el-input--label {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    margin: 0 0 0.5em;
    overflow: visible;
    clip: auto;
    white-space: normal;
    border: 0;
}

/* Quiz submit-button ownership (v0.3.15, T1): the theme's !important
   .fluentform .ff-btn-submit override is being removed, so the plugin takes
   ownership of the quiz submit with a scoped, variable-driven rule.
   Specificity (1,1,0) beats Fluent Forms' injected rule (0,2,0) on its own;
   the 'fluent-form-styles' stylesheet dependency on the enqueue additionally
   guarantees source order. Colors reproduce the current computed rendering
   exactly: #fcb514 gold fill (--ppfb-10k-gold-flare) with #0e1116 ink
   (--ppfb-10k-charcoal-900); the hover tint #ffd34d matches current behavior
   (no --ppfb-10k-* token exists for that tint yet). The var() fallbacks lock
   the current rendering until the --ppfb-10k-* token foundation is declared;
   #ppfb-quiz renders inside .ppfb-scope, so the tokens take over once they
   ship. No !important anywhere here. */
#ppfb-quiz .ff-btn-submit {
    background-color: var(--ppfb-10k-gold-flare, #fcb514);
    border-color: var(--ppfb-10k-gold-flare, #fcb514);
    color: var(--ppfb-10k-charcoal-900, #0e1116);
}
#ppfb-quiz .ff-btn-submit:hover,
#ppfb-quiz .ff-btn-submit:focus-visible,
#ppfb-quiz .ff-btn-submit:focus {
    background-color: #ffd34d;
    border-color: #ffd34d;
    color: var(--ppfb-10k-charcoal-900, #0e1116);
}

/* ============ Notices, toast ============ */
.ppfb-notice {
    padding: 1rem 1.25rem;
    border-radius: 8px;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-quiet);
    margin: 0 0 1.5rem;
}
.ppfb-notice p {
    margin: 0 0 0.5rem;
}
.ppfb-notice p:last-child {
    margin-bottom: 0;
}
.ppfb-preview-banner {
    border: 2px solid var(--ppfb-eyebrow);
}
.ppfb-toast {
    background: var(--ppfb-charcoal);
    color: var(--course-text-on-deep);
    border-radius: 8px;
    padding: 0.875rem 1.25rem;
    margin: 0 0 1.5rem;
    font-weight: 600;
}

/* ============ Completion block (A12, C8) ============ */
.ppfb-complete {
    margin: 0 0 2rem;
}
.ppfb-complete-done {
    font-weight: 600;
    color: var(--ppfb-ink);
    margin: 0;
    padding: 0.75rem 0;
}
.ppfb-complete form {
    margin: 0;
}
/* Quiz-gated control: focusable aria-disabled, never the HTML disabled
   attribute. Charcoal container carries the gold-on-charcoal treatment. */
.ppfb-complete-gated {
    background: var(--ppfb-charcoal);
    border-radius: 8px;
    padding: 1.25rem;
    /* v0.3.92: gold hairline top accent + soft lift for depth. */
    border-top: 2px solid var(--ppfb-10k-gold-500, #c9a227);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.ppfb-quiz-reason {
    color: var(--ppfb-quiet-on-charcoal);
    font-size: 1rem;
    line-height: 1.6;
    margin: 0 0 1.25rem;
    /* v0.3.92: flex row for the decorative lock glyph. */
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
}
/* v0.3.92: decorative lock glyph; aria-hidden in markup. */
.ppfb-gated-lock {
    flex: 0 0 auto;
    margin-top: 0.2rem;
    color: var(--ppfb-10k-gold-500, #c9a227);
}
.ppfb-quiz-reason:focus {
    outline: none;
}
.ppfb-quiz-reason:focus-visible {
    outline: 3px solid var(--course-focus-ring-on-deep);
    outline-offset: 2px;
}

/* ============ Buttons: exactly one gold per screen state (AD-1) ============
 * v0.3.17 (T2 slice 1): the button component rules lived here through
 * v0.3.16. They now live in assets/css/ppfb-buttons.css, the single button
 * authority, re-expressed on the --ppfb-10k-* tokens with identical computed
 * values (see that file's zero-change rule). The quiz-submit rule above
 * stays here: quiz-submit authority is plugin-scoped and was claimed in T1.
 * The #ppfb-quiz .ff-el-input--label restore above stays byte-identical and
 * untouchable (spec §1.8/38). */

/* ============ Navigation row + Up next (A12/A13) ============ */
.ppfb-nav {
    margin: 0 0 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
.ppfb-upnext {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-left: 3px solid var(--course-gold-accent, #E2B33D);
    border-radius: 13px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
    padding: 1.25rem 1.5rem;
}
.ppfb-upnext .ppfb-eyebrow {
    margin-bottom: 0.5rem;
}
/* v0.3.95: the up-next nav moved below the video (owner order). It keeps
   breathing room above (the video block margin) and below; the top margin
   rule below is unchanged. */
.ppfb-nav {
    margin-top: 1.25rem;
}
.ppfb-upnext-title {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.4;
    margin: 0 0 1rem;
}
/* v0.3.93: decorative arrow on the up-next Continue link. aria-hidden in
   the template; the .ppfb-btn-quiet component itself is untouched. */
.ppfb-upnext .ppfb-continue-arrow {
    margin-left: 0.25rem;
}
.ppfb-upnext p:last-child {
    margin-bottom: 0;
}
/* v0.3.17: moved to assets/css/ppfb-buttons.css (button authority). */
/* Boundary + end cards (3.10). */
.ppfb-endcard {
    background: var(--ppfb-charcoal);
    border-radius: 8px;
    padding: 1.5rem;
    margin: 0 0 2rem;
    color: var(--course-text-on-deep);
}
.ppfb-endcard h2 {
    color: var(--course-text-on-deep);
}
.ppfb-endcard p {
    color: var(--ppfb-quiet-on-charcoal);
}
.ppfb-endcard .ppfb-expectation {
    font-size: 0.9375rem;
}
/* v0.3.17: moved to assets/css/ppfb-buttons.css (button authority). */
.ppfb-drip-line {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0 0 1rem;
}

/* ============ Preview CTA ============ */
.ppfb-preview-cta {
    margin: 2rem 0;
    text-align: center;
}

/* ============ Locked lesson ============ */
.ppfb-locked .ppfb-locked-card {
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
    padding: 2rem 1.5rem;
    text-align: center;
    margin: 0 0 2rem;
}
.ppfb-locked .ppfb-expectation {
    color: var(--ppfb-quiet);
    font-size: 0.9375rem;
}

/* ============ Quiet footer (A15) ============ */
/* v0.3.92: hairline divider + refined link treatment. */
.ppfb-footer {
    max-width: 680px;
    margin: 0.5rem auto 0;
    padding: 1.5rem 1.25rem 2.5rem;
    font-size: 0.875rem;
    color: var(--ppfb-quiet);
    border-top: 1px solid var(--ppfb-line);
}
.ppfb-footer p {
    margin: 0 0 0.5rem;
}
.ppfb-footer a {
    color: var(--ppfb-quiet);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}
.ppfb-footer a:hover {
    color: var(--ppfb-ink);
}
.ppfb-footer .ppfb-footer-grader {
    font-style: italic;
}

/* ============ Dashboard ============ */
.ppfb-dashboard .ppfb-dash-title {
    font-size: 1.75rem;
    margin: 0 0 1rem;
}
.ppfb-dashboard .ppfb-module {
    margin: 0 0 1.5rem;
}
.ppfb-dashboard .ppfb-module-title {
    font-size: 1.25rem;
    margin: 0 0 0.5rem;
}
.ppfb-dashboard .ppfb-lesson-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.ppfb-dashboard .ppfb-lesson-item {
    padding: 0.6rem 0.25rem;
    border-bottom: 1px solid var(--ppfb-line);
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
    flex-wrap: wrap;
    min-height: 44px;
}
.ppfb-dashboard .ppfb-lesson-item a {
    font-weight: 600;
}
.ppfb-dashboard .ppfb-status {
    font-size: 0.9rem;
    white-space: nowrap;
    color: var(--ppfb-quiet);
}
.ppfb-dashboard .ppfb-status.done {
    color: var(--course-text-success);
}
.ppfb-dashboard .ppfb-next {
    margin: 1.5rem 0 0;
}
.ppfb-dashboard .ppfb-module-locked {
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
    padding: 1.25rem;
    background: var(--ppfb-card);
}
.ppfb-dashboard .ppfb-waitlist-quiet {
    font-size: 0.9375rem;
}

/* ============ Sticky action proxy (A14) ============
   Ships OFF behind the PPFB_STICKY_BAR constant (default false) until the
   mutual-exclusivity visibility rule is proven in browser verification.
   Markup is emitted only when the constant is true; the styles below stay
   dormant otherwise. */
.ppfb-stickybar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    min-height: 52px;
    padding: 0.5rem 1rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    background: rgba(243, 236, 224, 0.92);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--ppfb-line);
    z-index: 100;
}
.ppfb-stickybar[hidden] {
    display: none;
}

/* ============ Reduced motion (C21) ============ */
@media (prefers-reduced-motion: reduce) {
    .ppfb-scope *,
    .ppfb-scope *::before,
    .ppfb-scope *::after {
        animation: none;
        transition: none;
        scroll-behavior: auto;
    }
}

/* ============ Module 0 lesson-surface redesign (2026-09-19) ============
   Binding: ~/workspace/ops/module-sweeps/BUILD-SPEC-lesson-redesign-2026-09-19.md
   (panel 5/5 signed). Every rule below cites its spec item. This whole section
   sits BEFORE the ≤480px media block per the spec's placement constraint.
   Palette discipline: navy #003965 (brand-locked), gold #E2B33D via
   var(--course-gold-accent) (decorative rules only), bronze roles retargeted
   to the Fall 2026 palette (v0.3.56, seat I): functional fills/focus use
   --course-* tokens, ink is Kiln Ink, cream is Egret, warm grays follow
   --course-text-muted / --course-candied-ginger. No new colors; shipped
   tokens are left untouched. */

/* ---- S2: Mattone Bold @font-face (brand guide §5: display type = Mattone) ----
   Source: ~/workspace/fonts/mattone/Mattone-Bold.woff2 (SIL OFL-1.1, license
   text mirrored at fonts/OFL.txt). font-display: swap - text is never
   invisible. Only the 700 face is registered, so a missing file falls back
   to the Inter/system stack and can never faux-bold Mattone Regular
   (type review §3). Deploy layout: this sheet ships as
   assets/css/ppfb-lesson.css, the font as assets/fonts/Mattone-Bold.woff2. */
@font-face {
    font-family: "Mattone";
    src: url("../fonts/Mattone-Bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* ---- S1: lesson rhythm (spacing diagnosis R1-R4; CSS review; integration C1-C3) ----
   title→video 12px, video→body 20px. Tight above (owner's complaint),
   breathing room below. Values are the minimal diff from shipped, not a
   ratio system (red-team phase 2: the φ label is tiebreaker-only). */
/* S1 Rule 1 + S2 H1 spec. (0,2,1) beats .ppfb-scope h1 (0,1,1) at every
   width, including the ≤480px 1.4rem rule - no placement dependency. */
.ppfb-scope h1.ppfb-lesson-title {
    font-family: "Mattone", "Inter", system-ui;
    font-weight: 700;
    font-size: var(--ppfb-text-h1);
    line-height: 1.18;
    letter-spacing: -0.02em;
    color: var(--ppfb-ink); /* audited token (type review §1); NOT #141414 */
    text-wrap: balance;
    margin-bottom: 0.5rem; /* 8px authored → ~12px perceived with line-box trailing */
}
@media (min-width: 768px) {
    .ppfb-scope h1.ppfb-lesson-title {
        font-size: var(--ppfb-text-h1-wide);
    }
}
/* S1 Rule 2: guard - no theme or future rule may inflate this gap. Rendered
   in the entitled branch only (single-ppf_lesson.php:353); harmless no-op
   elsewhere (CSS review §1). */
#ppfb-video-wrap {
    margin-top: 0;
}
/* v0.3.88: legacy .ppfb-video player removed - the S1 Rule 3 frame->truth
   margin lived on the old player box; the PPF Video Player owns its own
   chrome and spacing now. */
/* S1 Rule 5, scoped per integration C1. The unscoped .ppfb-scope p hits the
   dashboard (dashboard.php:252, includes/dashboard.php:454+). Compound form
   is C1's explicit prescription - ppfb-lesson/ppfb-locked sit on the SAME
   <main> as ppfb-scope, so the spec's descendant form cannot match.
   Rule 4 (.ppfb-media-truth) DROPPED per integration C3: the truth row is a
   <p class="ppfb-media-truth"> inside main.ppfb-scope.ppfb-lesson
   (single-ppf_lesson.php:367), so this 20px already governs it - truth-row
   branch verified in source, no separate rule (BUILD-SPEC S1). */
.ppfb-scope.ppfb-lesson p,
.ppfb-scope.ppfb-locked p {
    margin: 0 0 1.25rem; /* 20px ladder (was 1.125rem/18px) */
}

/* ---- S2: type scale (type review §1; φ type scale KILLED, ×1.25 adopted) ----
   Lesson-scoped (2026-09-19, independent verification FAIL 3 / acceptance
   #8): the unscoped form moved dashboard headings (dashboard renders inside
   .ppfb-scope.ppfb-dashboard). The compound form restores the dashboard
   (dashboard keeps base 1.25rem/1.0625rem) and preserves S2's type intent
   on every lesson surface (entitled, locked, free-preview, quiz H2). */
.ppfb-scope.ppfb-lesson h2,
.ppfb-scope.ppfb-locked h2 {
    font-size: var(--ppfb-text-h2);
    line-height: 1.2;
    font-weight: 700;
}
.ppfb-scope.ppfb-lesson h3,
.ppfb-scope.ppfb-locked h3 {
    font-size: var(--ppfb-text-h3);
    line-height: 1.3;
    font-weight: 700;
}
/* Type-scale utilities for template use (type review §7: scale lives as
   custom properties in one place). No existing selectors changed. */
.ppfb-scope .ppfb-lead {
    font-size: var(--ppfb-text-lead);
    line-height: 1.4;
}
.ppfb-scope .ppfb-small {
    font-size: var(--ppfb-text-small);
    line-height: 1.4;
    color: var(--ppfb-quiet);
}
/* S2: module eyebrow (NEW element, replaces the breadcrumb line).
   .ppfb-eyebrow is TAKEN ("Up next", bronze; integration C4) - new class.
   Template seat emits:
     <p class="ppfb-module-eyebrow">MODULE 0 · PREREQUISITES</p>
   (0,2,1) beats .ppfb-scope p (0,1,1), so the eyebrow keeps its own margin
   even as a <p>. Eyebrow→H1 gap 12px: binding scale {8,12,20,32,48,64}
   (red-team phase 2); the φ-system's header-air table was retired as stale.
   Gold here is the GUIDE's ratified #E2B33D (DarkStar 2026-09-16 sign-off),
   not the shipped --ppfb-gold (#c9a227) token - decorative rule, and gold
   text on paper stays banned (guide §5). */
.ppfb-scope .ppfb-module-eyebrow {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 0 0 1rem;
    font-family: "Inter", system-ui, sans-serif;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #003965;
}
.ppfb-scope .ppfb-module-eyebrow::before {
    content: "";
    width: 28px;
    height: 3px;
    flex: none;
    border-radius: 2px;
    background: var(--course-gold-accent);
}

/* ---- S3: progress bar, one row (visual pass cheap-read 3; a11y B1) ----
   Track + label share a baseline. v0.3.56 (seat I): track is Candied
   Ginger, fill is Kiln Ink at 7.52:1 on the track (contract-measured,
   WCAG 1.4.11). This supersedes the v0.3.5x bronze #7c6115 lock: bronze on
   ginger is 2.57:1 and spice on ginger 2.20:1, both failing 1.4.11, so the
   palette's on-tint ink is the non-regressive fill. The visual pass's gold
   #E2B33D fill stays killed (1.48:1, a contrast regression).
   Scoped to lesson surfaces: the dashboard renders its own .ppfb-progress
   block (includes/dashboard.php:528-534) and acceptance #8 keeps the
   dashboard unchanged. Label text "0 of 77" is a template edit
   (single-ppf_lesson.php:332); the progressbar aria-label stays verbose. */
.ppfb-scope.ppfb-lesson .ppfb-progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 1.5rem;
}
.ppfb-scope.ppfb-lesson .ppfb-progress-track {
    flex: 1 1 auto;
    min-width: 0;
    height: 6px;
    border-radius: 3px;
    background: var(--course-candied-ginger);
    overflow: hidden;
}
.ppfb-scope.ppfb-lesson .ppfb-progress-fill {
    height: 100%;
    border-radius: 3px;
    background: var(--course-text-primary);
}
.ppfb-scope.ppfb-lesson .ppfb-progress-text {
    flex: none;
    margin: 0; /* (0,3,0) beats .ppfb-scope p (0,1,1): the dead 8px gap stays dead, deliberately */
    font-family: "Inter", system-ui, sans-serif;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ppfb-quiet); /* measured --ppfb-quiet (type review §1); NOT #6B6257 */
    white-space: nowrap;
}

/* ---- S4: "My Lessons" pill (visual pass cheap-read 4; a11y B3) ----
   Solid navy #003965, white Inter SemiBold 14px, 10px 18px padding,
   min-height 44px, radius 999px. Lesson surfaces ONLY (PM adjudication).
   BUILDER NOTE: the spec's ".ppfb-lesson .ppfb-chrome-dash" cannot match -
   the chrome bar renders OUTSIDE <main> (sibling inside .ppfb-page; the
   token-block comment says so, and single-ppf_lesson.php:231 echoes the
   bar before <main>). Scoped to the single-ppf_lesson body class instead:
   the theme outputs body_class() (header.php:48), and locked-lesson.php
   loads via template_include on the same single-post query
   (gating.php:1066-1077), so both lesson templates qualify while
   dashboard/account bodies do not. (0,2,0) also beats the ≤480px
   .ppfb-chrome-dash override (0,1,0), so the 14px spec holds on the
   iPhone sign-off device. */
.single-ppf_lesson .ppfb-chrome-dash {
    background: #003965;
    border-color: #003965;
    color: #ffffff;
    font-family: "Inter", system-ui, sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.01em;
    padding: 10px 18px;
    min-height: 44px;
    border-radius: 999px;
}
/* Flat navy on hover: the old quiet-pill hover (ink on a paper wash) would
   be wrong on navy. Spec is silent; keeping the navy fill is the minimal
   non-regressive choice. */
.single-ppf_lesson .ppfb-chrome-dash:hover {
    background: #003965;
    border-color: #003965;
    color: #ffffff;
}
/* Locked-lesson twin (independent verification FAIL 2, 2026-09-19): the
   locked template fires on is_404() (gating.php:1027-1029) and the body
   class is locked-lesson (gating.php:1113-1124), never single-ppf_lesson -
   so the pill rule above cannot match the locked branch. The chrome bar
   renders outside <main> (locked-lesson.php:33), so the body class is the
   source-correct twin. Same declarations as the entitled pill rule. */
.locked-lesson .ppfb-chrome-dash {
    background: #003965;
    border-color: #003965;
    color: #ffffff;
    font-family: "Inter", system-ui, sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.01em;
    padding: 10px 18px;
    min-height: 44px;
    border-radius: 999px;
}
/* Flat navy on hover: same minimal non-regressive choice as the entitled twin. */
.locked-lesson .ppfb-chrome-dash:hover {
    background: #003965;
    border-color: #003965;
    color: #ffffff;
}

/* ---- S5: focus + touch floors (a11y review) ---- */

/* Quiz option rows + submit: 44px floors on CONFIRMED Fluent Forms markup.
   Source: ff-diag/fluentform - option rows are div.ff-el-form-check >
   label.ff-el-form-check-label (Checkable.php:108-153); submit is
   button.ff-btn-submit (SubmitButton.php:137). #ppfb-quiz .fluentform is the
   embed wrapper (queried by ppfb-quiz-result.js). The label gets inline-flex
   so the 44px floor is a real touch target, not just row whitespace. */
#ppfb-quiz .fluentform .ff-el-form-check {
    min-height: 44px;
}
#ppfb-quiz .fluentform .ff-el-form-check-label {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}
#ppfb-quiz .fluentform .ff-btn-submit {
    min-height: 44px;
}
/* Tool-row anchors: 44px floors on confirmed tools-needed.php markup.
   The image path is already ≥44px via the 56/48px thumbnail (belt and
   braces); the imageless fallback (tools-needed.php:113) is a bare ~24px
   text link - inline elements ignore min-height, hence inline-flex. */
.ppfb-tools-needed .ppfb-tool-row a {
    min-height: 44px;
}
.ppfb-tools-needed li:not(.ppfb-tool-row) > a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

/* ---- S6: chrome brand lockup ----
   Wordmark was already 600/16px/ink (verified against the base rule) -
   only the Inter stack is added per the spec's "Inter SemiBold" line.
   Shield 40px → 32px (the ≤480px 34px override is updated to match below). */
.ppfb-chrome-logo {
    width: 32px;
    height: 32px;
}
.ppfb-chrome-wordmark {
    font-family: "Inter", system-ui, sans-serif;
}

/* ============ Small-phone behavior (390-440px) ============ */
@media (max-width: 480px) {
    .ppfb-scope {
        padding: 1.25rem;
    }
    .ppfb-scope h1,
    .ppfb-dash-title {
        font-size: 1.4rem;
    }
    /* A3: breadcrumb collapses to "< Module {n}: {title}", one line. */
    .ppfb-crumbs .ppfb-crumb-dash,
    .ppfb-crumbs .ppfb-crumb-current,
    .ppfb-crumbs .ppfb-crumb-sep {
        display: none;
    }
    .ppfb-crumbs .ppfb-crumb-module::before {
        content: "\2039  ";
    }
    /* iPhone tap target: the collapsed breadcrumb is a single link; give it
       a 44px tap height without changing its visual line. */
    .ppfb-crumbs a {
        display: inline-block;
        padding: 0.65rem 0;
    }
    /* v0.3.88: legacy .ppfb-video player removed - the A6 edge-to-edge
       bleed rules lived on the old player box. The PPF Video Player owns
       its own responsive chrome now. */
    /* The chrome's containing block is the theme's unpadded #main, so a
       negative-margin bleed would push the page past the viewport (40px of
       sideways scroll at 390/440px). Full-width bar instead; no overflow. */
    /* Premium chrome, slim on small phones: tighter vertical padding and a
       slightly smaller badge so the bar never steals vertical space, but the
       hairline border stays and both controls keep their 44px tap targets.
       (The old floating box is gone, so there is no radius/border reset.) */
    .ppfb-chrome-inner {
        padding: 0.625rem 1.25rem;
        /* v0.3.48: keep the safe-area insets at phone widths; the shorthand
           above would otherwise reset them to the bare 1.25rem. */
        padding-left: calc(1.25rem + env(safe-area-inset-left));
        padding-right: calc(1.25rem + env(safe-area-inset-right));
    }
    .ppfb-chrome-logo {
        width: 32px;
        height: 32px;
        border-radius: 9px;
    }
    .ppfb-chrome-wordmark {
        font-size: 1rem; /* S6 phone parity: 16px like base, was 15px */
    }
    .ppfb-chrome-dash {
        padding: 0.375rem 0.875rem;
        font-size: 0.8125rem;
    }
    /* v0.3.88: legacy .ppfb-play-overlay player removed - the phone-size
       overlay rules are dead with it. The PPF Video Player ships its own
       44px+ tap targets. */
}

/* Tools-needed thumbnails (v0.3.6, Feature 2; card redesign v0.3.96).
   A 64px card-style thumbnail sits beside each tool name; 56px on phones.
   No fixed widths anywhere: rows size to their content and never force
   horizontal scroll. Gold is fill-only in this theme, so the thumbnail
   uses the card surface and a neutral line border (no gold text, no gold
   borders on paper). */
/* v0.3.50: product-links list audit. The tools <ul> carries role="list"
   in the template to preserve list semantics where list-style:none
   applies.
   - Markers: removed for the whole product-links list (owner decision) -
     the native marker was rendering as a stray dot beside each product
     thumbnail. list-style:none on the <ul>, the same pattern the older
     .ppfb-tools-list block uses.
   - Alignment: the browser's default ~40px list inset is reset so the
     thumbnails align flush with the section heading and intro text -
     no bullet, no mystery gutter.
   - Spacing: rows were stacking with zero vertical rhythm (56px
     thumbnails touching edge to edge); a uniform 0.75rem gap makes the
     rhythm deliberate. Thumbnail size, card style, link destinations,
     and target/rel are untouched. */
.ppfb-tools-needed ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.75rem;
}
.ppfb-tools-needed .ppfb-tool-name {
    /* Long product names wrap inside the flex row instead of forcing the
       row wider than the viewport at 390px. */
    min-width: 0;
}
.ppfb-tools-needed .ppfb-tool-row a {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
}
.ppfb-tools-needed .ppfb-tool-thumb {
    width: 56px;
    height: 56px;
    flex: none;
    object-fit: contain;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
}
@media (max-width: 480px) {
    .ppfb-tools-needed .ppfb-tool-thumb {
        width: 48px;
        height: 48px;
    }
}

/* ============ Tools needed: phi card redesign (v0.3.96) ============
   Golden-ratio (phi = 1.618) spacing scale: 0.382 / 0.618 / 1 / 1.618 /
   2.618rem. Cards echo the 0.3.93 up-next card (13px radius, soft shadow,
   gold accent on hover). Tokens only: existing --ppfb-* names (which the
   lesson scope re-expresses from --course-*) plus neutral rgba shadows,
   the accepted pattern. No new hues. */
.ppfb-tools-needed {
    --ppfb-phi: 1.618;
    margin: 0 0 2.618rem;
}
.ppfb-tools-needed h2 {
    margin-bottom: 0.382rem;
}
.ppfb-tools-needed .ppfb-tools-disclosure {
    margin-bottom: 0.618rem;
    max-width: 65ch;
}
.ppfb-tools-needed .ppfb-tools-intro {
    margin-bottom: 1.618rem;
    max-width: 65ch;
}
.ppfb-tools-needed ul {
    gap: 1rem;
}
.ppfb-tools-needed .ppfb-tool-row {
    margin: 0;
}
.ppfb-tools-needed a.ppfb-tool-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 13px;
    /* v0.3.96b: the phi token is live here, not decorative. */
    padding: 1rem calc(1rem * var(--ppfb-phi));
    text-decoration: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    min-height: 44px;
}
.ppfb-tools-needed a.ppfb-tool-card:hover {
    border-color: var(--course-gold-accent, #E2B33D);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}
.ppfb-tools-needed a.ppfb-tool-card:focus-visible {
    outline: 3px solid var(--course-link, #2997FF);
    outline-offset: 2px;
}
.ppfb-tools-needed .ppfb-tool-thumb {
    width: 64px;
    height: 64px;
    border-radius: 12px;
}
.ppfb-tools-needed .ppfb-tool-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}
.ppfb-tools-needed .ppfb-tool-name {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ppfb-ink, var(--course-text-primary));
}
.ppfb-tools-needed .ppfb-tool-note {
    margin-top: 0.382rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--ppfb-quiet);
}
.ppfb-tools-needed .ppfb-tool-open {
    flex: none;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--ppfb-quiet);
}
@media (max-width: 480px) {
    .ppfb-tools-needed a.ppfb-tool-card {
        padding: 0.75rem 1rem;
        gap: 0.75rem;
    }
    .ppfb-tools-needed .ppfb-tool-thumb {
        width: 56px;
        height: 56px;
    }
}
@media (prefers-reduced-motion: reduce) {
    .ppfb-tools-needed a.ppfb-tool-card {
        transition: none;
    }
}

/* v0.3.8: immediate quiz result panel */
.ppfb-quiz-average {
    font-size: 0.9375rem;
    margin: 0 0 1rem;
}
.ppfb-quiz-result {
    position: relative;
    margin: 1.25rem 0 0;
    padding: 1rem 1.125rem;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 10px;
}
/* v0.3.50: first-attempt perfect-score celebration. The confetti canvas is
   absolutely positioned over the result panel (which is position:relative
   above), pointer-transparent, and removed from the DOM when the burst
   ends. No sound is ever produced. With prefers-reduced-motion the JS
   renders the static message only. */
.ppfb-qr-confetti {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.ppfb-qr-perfect {
    font-weight: 600;
}
.ppfb-quiz-result[hidden] {
    display: none;
}
.ppfb-qr-head {
    margin: 0 0 0.5rem;
    font-size: 1.25rem;
}
.ppfb-qr-pass {
    color: #1e7e34;
}
.ppfb-qr-fail {
    color: #b02a37;
}
.ppfb-qr-score {
    font-weight: 700;
    margin: 0 0 0.75rem;
}
.ppfb-qr-note {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0 0 0.75rem;
}
.ppfb-qr-correct {
    margin: 0 0 0.75rem 1.25rem;
    padding: 0;
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
}
.ppfb-qr-missed {
    margin: 0 0 1rem;
    padding: 0.75rem 0.875rem;
    border: 1px solid var(--ppfb-line);
    border-radius: 8px;
}
.ppfb-qr-missed h4 {
    margin: 0 0 0.5rem;
    font-size: 1rem;
}
.ppfb-qr-missed h5 {
    margin: 0.625rem 0 0.25rem;
    font-size: 0.9375rem;
}
.ppfb-qr-missed p {
    margin: 0 0 0.25rem;
    font-size: 0.9375rem;
}
.ppfb-qr-mine {
    color: #b02a37;
}
.ppfb-qr-correct-answer {
    color: #1e7e34;
    font-weight: 600;
}
.ppfb-qr-expl {
    color: inherit;
}
.ppfb-qr-study {
    margin: 0 0 1rem;
}
.ppfb-qr-study h4 {
    margin: 0 0 0.5rem;
    font-size: 1rem;
}
.ppfb-qr-study ul {
    margin: 0 0 0 1.25rem;
    padding: 0;
    font-size: 0.9375rem;
}
.ppfb-qr-average {
    font-size: 0.9375rem;
    margin: 0 0 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--ppfb-line);
}
.ppfb-qr-next {
    font-weight: 600;
    margin: 0;
}
.ppfb-qr-cooldown {
    font-size: 0.9375rem;
    color: var(--ppfb-quiet);
    margin: 0.75rem 0 0;
}
.ppfb-qr-retake-wrap {
    margin: 0.75rem 0 0;
}
.ppfb-qr-reviewed-label {
    font-size: 0.9375rem;
    margin-right: 0.5rem;
}

/* ============ Lesson 0.2 kit-total formatting (v0.3.58, seat 4) ============ */
/* Starter-kit "Estimated kit total" section: callout, price table, note,
   excluded-items list. v0.3.57 Apple design language, iPhone 390px first. */
.ppfb-kit-callout {
    background: color-mix(in srgb, var(--course-candied-ginger, #1D1D1F) 22%, var(--ppfb-paper));
    border: 1px solid var(--ppfb-line);
    border-radius: 16px;
    padding: 1rem 1.25rem;
    margin: 0 0 1.25rem;
    box-shadow: 0 1px 3px rgba(34, 26, 18, 0.08);
}
.ppfb-kit-callout p {
    margin: 0;
}
.ppfb-kit-callout ul {
    margin: 0.5rem 0 0 1.25rem;
    padding: 0;
    font-size: 0.9375rem;
}
.ppfb-kit-callout ul li {
    margin: 0 0 0.25rem;
}
.ppfb-kit-excluded {
    background: var(--ppfb-paper);
    border-style: dashed;
}
.ppfb-kit-excluded > p {
    color: var(--ppfb-quiet);
}
table.ppfb-price-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 0.5rem;
    font-size: 0.9375rem;
    line-height: 1.5;
}
.ppfb-price-table th,
.ppfb-price-table td {
    padding: 0.5rem 0;
    text-align: left;
    vertical-align: top;
}
.ppfb-price-table thead th {
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ppfb-quiet);
    border-bottom: 2px solid var(--ppfb-line);
}
.ppfb-price-table thead th:last-child,
.ppfb-price-table tbody td:last-child,
.ppfb-price-table tfoot td:last-child {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    padding-left: 1rem;
}
.ppfb-price-table tbody td {
    border-bottom: 1px solid var(--ppfb-line);
}
.ppfb-price-table tfoot th,
.ppfb-price-table tfoot td {
    padding-top: 0.625rem;
    font-weight: 700;
    border-top: 2px solid var(--ppfb-ink);
}
.ppfb-price-note {
    font-size: 0.8125rem;
    color: var(--ppfb-quiet);
    margin: 0 0 1.25rem;
}

/* ============ v0.3.60: "Play chapter audio" button removed (owner order
   2026-09-20) ============
   The mini-player's play control is now the single play control for chapter
   audio. The button node is created by the player plugin's JS (v0.1.12),
   which this LMS patch must not touch, so the LMS suppresses it here; the
   proper removal (never create the node) belongs to the player v0.1.13
   track, after which this rule retires. display:none also drops the button
   from the tab order and the accessibility tree; the mini-player toggle
   (#ppfb-player-toggle, aria-labeled "Play chapter audio") stays the
   focusable, labeled playback control. The video figure's own gold play
   overlay (.ppfb-play-overlay) is video and is untouched. */
#ppfb-lesson-audio-btn {
    display: none !important;
}

/* ============ v0.3.103: inline Amazon product cards ============
   Inline cards reuse the tools-needed card component. Each rule below
   appends an unscoped alternative to the existing scoped selector; the
   original .ppfb-tools-needed selectors stay first so tools-needed
   specificity and behavior are unchanged. */
a.ppfb-tool-card,
.ppfb-tools-needed a.ppfb-tool-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--ppfb-card);
    border: 1px solid var(--ppfb-line);
    border-radius: 13px;
    /* v0.3.96b: the phi token is live here, not decorative. */
    padding: 1rem calc(1rem * var(--ppfb-phi));
    text-decoration: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    min-height: 44px;
}
a.ppfb-tool-card:hover,
.ppfb-tools-needed a.ppfb-tool-card:hover {
    border-color: var(--course-gold-accent, #E2B33D);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}
a.ppfb-tool-card:focus-visible,
.ppfb-tools-needed a.ppfb-tool-card:focus-visible {
    outline: 3px solid var(--course-link, #2997FF);
    outline-offset: 2px;
}
.ppfb-tool-text,
.ppfb-tools-needed .ppfb-tool-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}
.ppfb-tool-name,
.ppfb-tools-needed .ppfb-tool-name {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ppfb-ink, var(--course-text-primary));
}
.ppfb-tool-note,
.ppfb-tools-needed .ppfb-tool-note {
    margin-top: 0.382rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--ppfb-quiet);
}
.ppfb-tool-open,
.ppfb-tools-needed .ppfb-tool-open {
    flex: none;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--ppfb-quiet);
}
/* Converted rows live outside .ppfb-tools-needed: drop the list marker and
   keep the 1rem rhythm of the lesson body. */
li.ppfb-tool-row {
    list-style: none;
    margin-bottom: 1rem;
}
/* Breathing room for cards appended after prose. Converted rows are
   first-children so they are unaffected. */
p > a.ppfb-tool-card:not(:first-child),
li > a.ppfb-tool-card:not(:first-child),
blockquote > a.ppfb-tool-card:not(:first-child) {
    margin-top: 1rem;
}
@media (max-width: 480px) {
    a.ppfb-tool-card,
    .ppfb-tools-needed a.ppfb-tool-card {
        padding: 0.75rem 1rem;
        gap: 0.75rem;
    }
}
@media (prefers-reduced-motion: reduce) {
    a.ppfb-tool-card,
    .ppfb-tools-needed a.ppfb-tool-card {
        transition: none;
    }
}
