/* Lekton — woff2 (the .ttf URLs previously here 404'd; on-disk files
   are the lekton-*-1.woff2 trio used by marker-client.css).
   font-display:swap so text renders immediately in the system fallback
   while the font downloads. */
@font-face {
    font-family: "Lekton";
    font-style:  normal;
    font-weight: 400;
    font-display: swap;
    src: url("/shared/e9295ac1c5bc825e707746d85a91c875571641e1044014c32d002220a8267f76.woff2") format("woff2");
}
@font-face {
    font-family: "Lekton";
    font-style:  normal;
    font-weight: 700;
    font-display: swap;
    src: url("/shared/50e3da72118ac99f5a5a7d8ba9050ac4aeb806f073b8cf5237e2e3548b2556a8.woff2") format("woff2");
}
@font-face {
    font-family: "Lekton";
    font-style:  italic;
    font-weight: 400;
    font-display: swap;
    src: url("/shared/ef7d4430052f6ef8166706d8fa188a61b78e1cade6ff9fa9e5257b7e9229aafc.woff2") format("woff2");
}
/* KrsKrt Magic Marker — Central Screen styles  v3.2 */

/* ---- Field flash highlight -------------------------------------------- */
@keyframes mm-field-flash {
    0%   { box-shadow: 0 0 0 2px #22c55e; }
    100% { box-shadow: none; }
}
.mm-field-updated {
    animation: mm-field-flash 0.8s ease-out forwards;
}

/* ---- Active part highlight (Phase 3) ---------------------------------- */
/* The `mm-part-active` class is applied to H1 elements ONLY (see
   central-screen.js: every `add('mm-part-active')` call sites a `h1`-only
   querySelectorAll first, so other heading levels H2..H6 never get the
   class and never get the scroll offset). The H1-prefixed rule is the
   only one that matters in practice — kept that way to make the
   intent unambiguous. */
h1.mm-part-active {
    scroll-margin-top: 24px;
}

/* ---- Magic Marker button pristine state (no markers yet) -------------- */
#krskrt-mm-panel > #krskrt-mm-btn.krskrt-mm-btn--pristine {
    background:   #dcfce7;
    border-color: #86efac;
}
#krskrt-mm-panel > #krskrt-mm-btn.krskrt-mm-btn--pristine:hover {
    background:   #bbf7d0;
    color:        #00374a;
}

/* ---- Session-QR panel button (#krskrt-sq-btn) ------------------------- */
#krskrt-mm-panel > #krskrt-sq-btn.krskrt-mm-btn--pristine {
    background:   #dcfce7;
    border-color: #86efac;
}
#krskrt-mm-panel > #krskrt-sq-btn.krskrt-mm-btn--pristine:hover {
    background:   #bbf7d0;
    color:        #00374a;
}

/* ---- Session-QR overlay (.mm-cs-sq-overlay) --------------------------- */
/* Use the favicon from --kf-sq-favicon (set inline from the page's session-qr
   block) if the Project published one; otherwise fall back to the KrsKrt
   brand favicon — NOT the marker's krskrt-sync.svg (the sync glyph signals
   "connecting a device"; the Project QR is the brand surface). Owner-ratified
   2026-06-15. */
.mm-cs-sq-overlay .mm-cs-qr-code-wrap::after {
    background-image: var(--kf-sq-favicon, url('favicon.svg'));
}

/* The session-QR link now shows the short /pp base (the CODE stands alone in
   the .mm-cs-qr-pin pill below), so it shares the magic-marker card's
   `.mm-cs-qr-or a` rule — no white-space:normal override is needed any more. */

/* ---- Phosphor icons inside the floating panel buttons ----------------- */
/* The Phosphor woff2 has the metric+y-shift fix baked in (see Phosphor
   notes in the mu-plugin CLAUDE.md), so no transform/vertical-align nudge
   is needed any more — the previous `transform: translateY(-1px)` was
   compensating for the un-fixed font and would now pull the icon a pixel
   too high. Just sets the panel-icon size + nukes the inline-baseline gap. */
#krskrt-mm-panel > button .ph {
    font-size: 22px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ---- Save-status indicator on #krskrt-dv-btn -------------------------- */
/* The button hosts three overlay slots (see dataview.js):
     .krskrt-dv-icon-main--cloud — plain cloud, only on --pending
                                   (paired with the green asterisk).
     .krskrt-dv-icon-main--check — cloud-check, on idle / saved.
     .krskrt-dv-delta            — green "*" pinned top-left, only on
                                   --pending, signals "unsent data exists".
   The two cloud variants are absolutely stacked on top of each other so the
   asterisk+cloud combo can crossfade smoothly into the cloud-check on the
   pending → saved transition. */
/* `#krskrt-mm-panel >` is here purely to outrank `#krskrt-mm-panel > button .ph`
   (1 ID + 1 elem + 1 class) — without it our `transform` loses the
   specificity tie and the icon stays anchored at the button's top-left. */
#krskrt-mm-panel > #krskrt-dv-btn .krskrt-dv-icon-main {
    position:   absolute;
    top:        50%;
    left:       50%;
    /* -50% centring + -1px to preserve the optical nudge from the panel
       `.ph` rule above (which our transform would otherwise override). */
    transform:  translate(-50%, calc(-50% - 1px));
    transition: opacity 0.3s ease, color 0.3s ease;
}
/* Default (idle / saved): show cloud-check, hide plain cloud. */
#krskrt-dv-btn .krskrt-dv-icon-main--cloud { opacity: 0; }
#krskrt-dv-btn .krskrt-dv-icon-main--check { opacity: 1; }
/* Pending: show plain cloud (asterisk overlay sits on top), hide cloud-check. */
#krskrt-mm-panel > #krskrt-dv-btn.krskrt-dv-btn--pending .krskrt-dv-icon-main--cloud { opacity: 1; }
#krskrt-mm-panel > #krskrt-dv-btn.krskrt-dv-btn--pending .krskrt-dv-icon-main--check { opacity: 0; }

/* `saved` — cloud-check goes green, then fades back to #00374a over 5 s. */
#krskrt-mm-panel > #krskrt-dv-btn.krskrt-dv-btn--saved {
    color: #00374a;
}
#krskrt-mm-panel > #krskrt-dv-btn.krskrt-dv-btn--saved .krskrt-dv-icon-main--check {
    animation: krskrt-dv-saved 5s ease-out forwards;
}
@keyframes krskrt-dv-saved {
    0%   { color: #22c55e; }
    35%  { color: #22c55e; }
    100% { color: #00374a; }
}

/* Delta indicator — green "*" pinned top-left of the cloud icon, visible
   only on .krskrt-dv-btn--pending. Signals "data entered but not yet
   confirmed-saved by the relay" — covers the whole interval from first
   keystroke to field_saved ack. Hidden on --saved. */
#krskrt-dv-btn .krskrt-dv-delta {
    position:       absolute;
    top:            6px;
    left:           9px;
    color:          #22c55e;
    font-size:      22px;
    font-weight:    700;
    line-height:    1;
    pointer-events: none;
    opacity:        0;
    transform:      scale(0.6);
    transition:     opacity 0.15s ease, transform 0.15s ease;
    z-index:        2;
    text-shadow:    0 0 2px rgba(0, 0, 0, 0.25);
}
#krskrt-mm-panel > #krskrt-dv-btn.krskrt-dv-btn--pending .krskrt-dv-delta {
    opacity:   1;
    transform: scale(1);
    /* Soft pulse so the eye picks it up without being noisy. */
    animation: krskrt-dv-delta-pulse 1.4s ease-in-out infinite;
}
@keyframes krskrt-dv-delta-pulse {
    0%, 100% { opacity: 1;    }
    50%      { opacity: 0.55; }
}

/* "Data saved every Ns" tooltip — appears the moment the spinning-arrows
   'saving' state begins and stays through the green 'saved' fade-out, then
   disappears together with the green. Modelled after .az-part-dot-tip in
   autozoom-scrollbar.css. pointer-events:none so it can never intercept
   clicks even when overlapping form fields. Positioned to the LEFT of the
   button (the panel sits in the top-right corner of the viewport). */
#krskrt-dv-btn .krskrt-dv-btn-tip {
    position:       absolute;
    right:          calc(100% + 10px);
    top:            50%;
    /* Match the cloud-button: same 44 px height, same 10 px radius. */
    height:         44px;
    box-sizing:     border-box;
    display:        flex;
    flex-direction: column;
    align-items:    center;
    justify-content: center;
    transform:      translateY(-50%) translateX(4px);
    background:     rgba(0, 55, 74, 0.90);
    color:          #fff;
    /* Inherit the page's default body font (avoid the icon-font and the
       UI-font Lekton — let the theme decide). */
    font-family:    inherit;
    font-size:      12px;
    line-height:    1.2;
    white-space:    nowrap;
    text-align:     center;
    padding:        0 12px;
    border-radius:  10px;
    pointer-events: none;
    opacity:        0;
    /* Identical to .az-part-dot-tip — symmetric on appear AND disappear:
       both opacity and transform tween for 0.18 s with the same easing,
       so showing and hiding mirror each other regardless of which CSS
       rule (state class, :hover, --tip-used) is driving the change. */
    transition:     opacity 0.18s ease, transform 0.18s ease;
    z-index:        10;
}
/* Two-line layout: "Data saved every" / "N seconds". Each child span
   is a block so they stack; the parent stays nowrap so neither line
   wraps mid-phrase. */
#krskrt-dv-btn .krskrt-dv-btn-tip__l1,
#krskrt-dv-btn .krskrt-dv-btn-tip__l2 {
    display: block;
}
#krskrt-dv-btn.krskrt-dv-btn--pending .krskrt-dv-btn-tip,
#krskrt-dv-btn.krskrt-dv-btn--saved   .krskrt-dv-btn-tip {
    opacity:   1;
    transform: translateY(-50%) translateX(0);
}
/* After the first save on a page, the button gains .krskrt-dv-btn--tip-used —
   subsequent pending/saved cycles still animate the icon but the tooltip
   stays hidden. Cleared on page reload.
   Resets BOTH opacity AND transform so the tip slides out as it fades —
   mirroring the appear animation (.az-part-dot-tip pattern). Without the
   transform reset, only opacity would tween while the tip stayed at its
   final translateX(0), giving an asymmetric "fade only" disappear. */
#krskrt-dv-btn.krskrt-dv-btn--tip-used .krskrt-dv-btn-tip {
    opacity:   0;
    transform: translateY(-50%) translateX(4px);
}
/* …but on hover, always re-surface the tooltip — even when --tip-used
   has suppressed it. Listed AFTER the suppress rule so it wins on tied
   specificity (both are 0,2,1). */
#krskrt-dv-btn:hover .krskrt-dv-btn-tip,
#krskrt-dv-btn:focus-visible .krskrt-dv-btn-tip {
    opacity:   1;
    transform: translateY(-50%) translateX(0);
}
/* `position: relative` so the tooltip's absolute positioning anchors here.
   `font-family: inherit` repairs the inheritance chain — UA stylesheets
   default <button> to a system-ui stack, which would otherwise be picked
   up by .krskrt-dv-btn-tip's own `font-family: inherit` and break parity
   with .az-part-dot-tip (which sits inside a <span> that already inherits
   the body font). With this in place both tooltips render in the theme's
   body font (currently `--wp--preset--font-family--cocracy`). */
#krskrt-dv-btn {
    position:    relative;
    font-family: inherit;
}

/* ---- Block visibility — hidden on central screen ---------------------- */
.krskrt-cs-hidden { display: none; }

/* ---- QR card (fixed, no backdrop) ------------------------------------- */
/* Lekton-only zone. The overlay (KrsKrt + Report variants on Central,
   reflected as mm-pass-card on Marker) renders PIN, addresses and QR
   guidance — content that should always be in the monospace UI font
   regardless of the per-form Used Fonts choice. The compound selector
   pairs the overlay class with every element targeted by the wp_head
   override, lifting specificity above the override (each becomes
   minimum 0,2,1 vs. the override's 0,1,1) so it wins even with
   `!important` on both sides. */
.mm-cs-qr-overlay,
.mm-cs-qr-overlay :is(
    p, blockquote, ul, ol, li, dl, dd, dt,
    h1, h2, h3, h4, h5, h6,
    button, .wp-block-button__link, input[type="submit"], input[type="button"],
    a, span, label, div, code, strong, em
) {
    font-family: "Lekton", ui-monospace, Menlo, Consolas, monospace !important;
}

.mm-cs-qr-overlay {
    display:        none;
    position:       fixed;
    background:     #fff;
    border:         1px solid #dedede;
    border-radius:  10px;
    overflow:       hidden;
    padding:        0;
    box-shadow:     0 1px 4px rgba(0,0,0,0.08);
    z-index:        99998;
    width:          fit-content;
    max-width:      320px;
    text-align:     center;
}
.mm-cs-qr-section-top    { padding: 12px; }
.mm-cs-qr-section-bottom { padding: 12px; background: #dedede; }
.mm-cs-qr-overlay.is-visible { display: block; }

/* ── Top bar: mode buttons left, close absolute top-right ─────────────── */
.mm-cs-qr-topbar {
    display:         flex;
    justify-content: flex-end;
    align-items:     center;
    gap:             4px;
    margin-bottom:   0;
    padding:         10px 36px 0;
}

.mm-cs-qr-mode-group {
    display: flex;
    gap:     4px;
}

.mm-cs-qr-mode-btn {
    width:         28px;
    height:        28px;
    border-radius: 7px;
    border:        1px solid #dedede;
    background:    transparent;
    font-size:     16px;
    cursor:        pointer;
    display:       flex;
    align-items:   center;
    justify-content: center;
    color:         #00374a;

    transition:    background 0.12s, border-color 0.12s;
    padding:       0;
    line-height:   1;
}
.mm-cs-qr-mode-btn:hover { background: #dcfce7; border-color: #86efac; }
.mm-cs-qr-mode-btn.is-active {
    background:   #dcfce7;
    border-color: #22c55e;
    color:        #166534;
}

/* Close: no border/bg, absolutely positioned in overlay corner */
.mm-cs-qr-close {
    position:    absolute;
    top:         6px;
    right:       8px;
    width:       28px;
    height:      36px;
    background:  none;
    border:      none;
    box-shadow:  none;
    cursor:      pointer;
    color:       #aaa;
    font-size:   30px;
    line-height: 1;
    padding:     0;
    display:     flex;
    align-items: center;
    justify-content: center;
}
.mm-cs-qr-close:hover { color: #00374a; }

/* ── Heading ──────────────────────────────────────────────────────────── */
/* The heading element is a <div> in central-screen.js (NOT a <p>) — UI
   chrome must not pick up the JFB inline rule
   `.jet-form-builder-template p { text-wrap: balance; max-width: 1000px; }`
   that ships on every /kk/* page. Keeping the heading off <p> means a
   plain single-class selector (specificity (0,1,0)) is enough — there
   is no JFB rule competing for it. If a future change reintroduces a
   <p>, that JFB rule wins and the QR card visibly bursts (see the
   "Known gotchas" section in CLAUDE.md). */
.mm-cs-qr-heading {
    max-width:   180px;
    box-sizing:  border-box;
    margin:      0 auto 10px;
    font-size:   28px;
    font-weight: 400;
    line-height: 1.15;
    color:       #00374a;
    white-space: nowrap;
}
/* The three text-bearing classes below get their final font-size from
   central-screen.js's fitOverlayText() — measured against the actual loaded
   Lekton metrics, accounting for letter-spacing, gated on document.fonts.ready,
   and refreshed via ResizeObserver. The static `font-size` here is just the
   first-paint fallback before the JS swap-in (and keeps a single line of text
   readable if JS is disabled). `white-space: nowrap` on each ensures the
   pre-fit fallback never wraps to two lines.                              */
.mm-cs-qr-heading strong {
    font-weight:      800;
    display:          block;
    font-size:        21px;
    white-space:      nowrap;
    color:            #fff;
    background-color: #00374a;
    border-radius:    5px;
    padding:          5px 10px;
    letter-spacing:   2px;
    text-transform:   uppercase;
    /* Constrain to parent .mm-cs-qr-heading max-width (180px). Without
       this the child's content-box + padding can compute to 200px wide
       (180 content + 2×10 padding) and burst the parent on the right,
       leaving the right edge of the dark pill sticking past the card.
       border-box makes the 10px padding eat into the 180px instead of
       extending it. */
    max-width:        100%;
    box-sizing:       border-box;
}
.mm-cs-qr-heading-sub {
    display:     block;
    font-size:   15px;
    font-style:  italic;
    white-space: nowrap;
    padding:     0 10px;
    margin-bottom: 4px;
    /* Same fix as `.mm-cs-qr-heading strong` above — without it the
       italic "Scan to …" sub-heading bursts the parent's 180 px cap on
       narrow inline-card columns because content-box adds the 20 px of
       horizontal padding outside the auto-computed width. */
    max-width:   100%;
    box-sizing:  border-box;
}

/* ── QR code ──────────────────────────────────────────────────────────── */
.mm-cs-qr-code-wrap { display: block; margin: 0 auto 4px; position: relative; }
.mm-cs-qr-code-wrap img,
.mm-cs-qr-code-wrap canvas { display: block; margin: 0 auto; }
.mm-cs-qr-code-wrap::after {
    content:             '';
    position:            absolute;
    top:                 50%;
    left:                50%;
    transform:           translate(-50%, -50%);
    width:               76px;
    height:              76px;
    background-color:    #fff;
    background-image:    url('../img/krskrt-sync.svg');
    background-position: center;
    background-size:     72px 72px;
    background-repeat:   no-repeat;
    border-radius:       0;
    pointer-events:      none;
}

/* Report variant: same square tile, different illustration, no animation. */
.mm-cs-report-inline-host .mm-cs-qr-code-wrap::after {
    background-image:    url('../img/krskrt-report.svg');
}

/* ── "Or go to..." sentence + PIN ────────────────────────────────────── */
.mm-cs-qr-or {
    /* Width matches the QR canvas (180 px) so a long URL inside the inner
       <a> can never push the overlay wider than the QR. fitOverlayText()
       in central-screen.js sizes the URL <a>'s font-size to fill this
       180 px exactly, clamped 14–24 px (see comment on the rules above). */
    width:       180px;
    margin:      0 auto 8px;
    color:       #00374a;
    line-height: 1.2;
}
.mm-cs-qr-or a {
    display:         block;
    font-size:       17px;     /* first-paint fallback — JS overrides */
    white-space:     nowrap;
    color:           #00374a;
    font-weight:     bold;
    text-transform:  uppercase;
    text-decoration: none;
    letter-spacing:  0.5px;
}
/* kf-session-qr URLs vary in length (per-event project slugs, possibly long).
   When the JS fit hits the 14 px floor and the URL still doesn't fit, allow
   the browser to break at the single <wbr> the PHP template emits right after
   "krskrt.com/kk/" — slashes and dots aren't break opportunities by default,
   so this is the only place a wrap can happen. The other overlay variants
   keep `white-space: nowrap` (their URLs are short and stable). */
.kf-session-qr .mm-cs-qr-or a {
    white-space: normal;
}
.mm-cs-qr-or a:hover { text-decoration: underline; }

.mm-cs-qr-pin {
    box-sizing:      border-box;
    display:         flex;
    align-items:     stretch;
    width:           180px;
    margin:          0 auto;
    line-height:     1;
    text-decoration: none;
    color:           #00374a;
}
.mm-cs-qr-pin-label {
    background-color: #00374a;
    color:            #fff;
    font-family:      "Lekton", sans-serif;
    font-weight:      700;
    font-size:        19px;
    letter-spacing:   0.1em;
    padding:          0 12px;
    border-radius:    5px;
    display:          flex;
    align-items:      center;
    justify-content:  center;
    margin-right:     8px;
}
.mm-cs-qr-pin-code {
    flex:           1;
    font-family:    "Lekton", sans-serif;
    font-weight:    700;
    font-size:      32px;
    letter-spacing: 0.2em;
    color:          #00374a;
    text-align:     center;
}

/* Session-QR (/pp) CODE pill ONLY: a 6-char [CODE] (e.g. IQHIIG) is wider than a
   5-char PIN and overflows the 180 px pill, so shrink the label + tighten the
   code's tracking. Applies to BOTH the floating overlay (.mm-cs-sq-overlay) AND
   the server-baked inline card (.kf-session-qr) — both are Session-QR surfaces and
   share the harmonized CODE pill. The /mm marker + /rr report PIN pills are
   neither, so they keep the larger PIN sizing. */
.mm-cs-sq-overlay .mm-cs-qr-pin-label,
.kf-sq-wrapper .kf-session-qr .mm-cs-qr-pin-label,
.kf-sq-modal   .kf-session-qr .mm-cs-qr-pin-label {
    padding:   0 7px 0 9px;
    font-size: 17px;
}
/* The baked legacy bundle ships its OWN `.kf-session-qr .mm-cs-qr-pin-code`
   (0.2em / 32px) at specificity (0,2,0), which would tie+beat a matching rule
   here on source order. The inline card always sits in `.kf-sq-wrapper`, so scope
   to that for (0,3,0) — wins over the baked rule at serve time (no re-publish).
   The 6-char CODE overflows at the baked 0.2em tracking; dropping to 0.1em and
   zeroing the code cell's padding lets the full CODE fit the 180px pill at 32px. */
.mm-cs-sq-overlay .mm-cs-qr-pin-code,
.kf-sq-wrapper .kf-session-qr .mm-cs-qr-pin-code,
/* The fullscreen modal clones the card OUTSIDE .kf-sq-wrapper, so the rule
 * above doesn't reach the clone — the baked legacy `.kf-session-qr
 * .mm-cs-qr-pin-code` (0.2em / 32px) wins, and the 6-char CODE overflows
 * the 180 px pill. Scope here too so the fullscreen card uses the tighter
 * tracking just like the inline one. */
.kf-sq-modal   .kf-session-qr .mm-cs-qr-pin-code {
    font-size:      32px;
    letter-spacing: 0.1em;
    padding:        0;
}

/* ── Marker list ──────────────────────────────────────────────────────── */
.mm-cs-qr-marker-list {
    margin-top:      8px;
    display:         flex;
    flex-wrap:       wrap;
    justify-content: center;
    gap:             6px;
    min-height:      0;
}
.mm-cs-qr-marker-list:empty { display: none; }

.mm-cs-qr-marker-chip {
    display:       inline-flex;
    align-items:   center;
    gap:           5px;
    font-size:     12px;
    font-weight:   600;
    color:         #888;
    padding:        0 7px;
    border-radius: 20px;
    border:        1px solid #e0e0e0;
    background:    #f5f5f5;
}
.mm-cs-qr-marker-chip.is-connected {
    color:        #166534;
    border-color: #86efac;
    background:   #dcfce7;
}

.mm-cs-qr-marker-dot {
    width:         7px;
    height:        7px;
    border-radius: 50%;
    background:    #ccc;
    flex-shrink:   0;
}
.mm-cs-qr-marker-chip.is-connected .mm-cs-qr-marker-dot {
    background: #22c55e;
}

/* ---- Inline variant (jet-forms/magic-marker-field block) -------------- */
.mm-cs-qr-overlay.mm-cs-qr-inline {
    display:       block;          /* always visible (no .is-visible gating) */
    position:      static;
    z-index:       auto;
    border-radius: 5px;             /* per spec (overlay is 10px) */
    width:         fit-content;
    min-width:     unset;
    margin:        0 auto;
    right:         auto;
    top:           auto;
    box-shadow:    unset;
}
.mm-cs-qr-overlay.mm-cs-qr-inline .mm-cs-qr-topbar,
.mm-cs-qr-overlay.mm-cs-qr-inline .mm-cs-qr-close { display: none; }
.mm-cs-qr-inline-host:empty { min-height: 0; }

/* ---- Report variant (Report & Finish block, download mode) ----------- */
/* Same card chrome as the Magic Marker QR; the bottom section differs only in
   the centre SVG (krskrt-report.svg, above) and that it carries no marker
   list — its bottom is just the link + PIN, harmonized with the other cards.
   (The old segmented "Open KrsKrt Report" action pill was removed; the link
   and the QR already open /rr/{PIN}.)                                       */
.mm-cs-report-inline-host:empty { min-height: 0; }

/* ---- Scroll-lock while start-gate is visible -------------------------- */
html.mm-start-locked,
body.mm-start-locked {
    overflow:     hidden;
    touch-action: none;
}

/* ---- Start-gate / Finish button (shared look) -------------------------- */
/* The Finish button (rendered inside the Email & Finish block) shares the
   green pulse / sparkle / fade animation with the start gate, but is laid
   out inline (no fixed positioning). Position-related rules are scoped to
   `.mm-start-btn`; everything else is shared.                              */
.mm-start-btn,
.mm-cs-finish-btn {
    display:         inline-flex;
    align-items:     center;
    justify-content: center;
    padding:         15px 30px 13px;
    border:          none;
    border-radius:   10px;
    cursor:          pointer;
    white-space:     nowrap;

    background:      #00374a;
    color:           #4ade80;

    font-family:     inherit;
    font-size:       24px;
    font-weight:     800;
    letter-spacing:  2px;
    text-transform:  uppercase;
    line-height:     1;

    box-shadow:      0 6px 0 #00262D, 0 8px 14px rgba(0,0,0,0.25);
    transform:       translateY(0);
    transition:      transform 0.08s ease-out,
                     box-shadow 0.08s ease-out,
                     opacity 0.35s ease-out;

    animation:       mm-start-pulse 1.6s ease-in-out infinite;
    position:        relative; /* scope sparkle ::after for both variants */
}

/* The Start / Resume button no longer pins itself — it sits inside the
   `.mm-start-actions` wrapper, which handles bottom-left fixed positioning
   so the privacy balloon can dock directly above the button. The Finish
   button stays inline within the Email & Finish row. */
.mm-start-btn {
    position:        relative;
    z-index:         100000;
}

.mm-start-btn:hover,
.mm-cs-finish-btn:hover { color: #6aeeaa; }
.mm-start-btn:focus,
.mm-cs-finish-btn:focus { outline: none; }

.mm-start-btn:active,
.mm-start-btn.is-pressed,
.mm-cs-finish-btn:active,
.mm-cs-finish-btn.is-pressed {
    transform:  translateY(6px);
    box-shadow: 0 0 0 #00262D, 0 2px 4px rgba(0,0,0,0.25);
    animation:  none;
}

@keyframes mm-start-pulse {
    0%, 100% {
        box-shadow: 0 6px 0 #00262D, 0 8px 14px rgba(0,0,0,0.25),
                    0 0 0 0  rgba(74,222,128,0.55);
    }
    50% {
        box-shadow: 0 6px 0 #00262D, 0 8px 14px rgba(0,0,0,0.25),
                    0 0 0 14px rgba(74,222,128,0);
    }
}

.mm-start-btn.is-sparkling::after,
.mm-cs-finish-btn.is-sparkling::after {
    content:         '';
    position:        absolute;
    inset:           -4px;
    border-radius:   14px;
    pointer-events:  none;
    animation:       mm-start-sparkle 0.7s ease-out forwards;
}
@keyframes mm-start-sparkle {
    0%   { box-shadow: 0 0 0 0   rgba(74,222,128,0.55), 0 0 0 0   rgba(255,255,255,0.5); opacity: 1;   }
    60%  { box-shadow: 0 0 0 18px rgba(74,222,128,0),    0 0 0 10px rgba(255,255,255,0);   opacity: 0.9; }
    100% { box-shadow: 0 0 0 26px rgba(74,222,128,0),    0 0 0 18px rgba(255,255,255,0);   opacity: 0;   }
}

.mm-start-btn.is-gone,
.mm-cs-finish-btn.is-gone {
    opacity:        0;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .mm-start-btn,
    .mm-cs-finish-btn { animation: none; }
    .mm-start-btn.is-sparkling::after,
    .mm-cs-finish-btn.is-sparkling::after { animation: none; }
}

/* ---- Resume gate ------------------------------------------------------ */
/* Shown on every refresh of an already-started central session. Its sole
   purpose is to acquire a user gesture (sticky activation) so marker-
   triggered videos can autoplay with sound. */
.mm-resume-overlay {
    position:   fixed;
    inset:      0;
    background: rgba(0, 55, 74, 0.85);   /* #00374a with opacity */
    z-index:    99998;
    cursor:     pointer;
    transition: opacity 0.35s ease-out;
}
.mm-resume-overlay.is-gone {
    opacity:        0;
    pointer-events: none;
}
.mm-start-btn.mm-start-btn--resume {
    position: relative;
    z-index:  99999;
}

/* ---- Start / Resume bottom-left dock (wraps balloon + button) -------- */
.mm-start-actions {
    position:        fixed;
    bottom:          13px;
    left:            7px;
    z-index:         100000;
    width:           180px;
    display:         flex;
    flex-direction:  column;
    align-items:     stretch;
    gap:             8px;
    pointer-events:  auto;
    transition:      opacity 0.35s ease-out;
}
.mm-start-actions .mm-start-btn {
    width:      180px;
    box-sizing: border-box;
}
.mm-start-actions.is-gone {
    opacity:         0;
    pointer-events:  none;
}
.mm-start-actions--resume {
    z-index: 99999;
}
/* Dock to the right of the screen instead of the left (per-form setting
   _krskrt_start_button_position). */
.mm-start-actions--right {
    left:  auto;
    right: 7px;
}

/* ---- JFB action button (hidden on Magic Marker forms) -----------------
   The new FINISH button programmatically clicks `.jet-form-builder__submit`
   to fire JFB's AJAX submit (Form Records still save, before-send hook
   still emails). Authors keep their action-button block in the form; we
   just hide it visually. central-screen.css is enqueued only on KrsKrt
   form pages, so non-MM forms are unaffected. */
.jet-form-builder__submit-wrap,
button.jet-form-builder__submit {
    display: none !important;
}

/* ---- Finish-block content ----------------------------------------------
   Rendered by the new `jet-forms/krskrt-finish-content` block. The plugin
   tags the surrounding container with `mm-finish-container` at runtime,
   defaulting it to a 100vh viewport pane so the lock lands on a clean
   screen even if the author hasn't sized their wrapper. */
.mm-finish-container {
    display:         flex;
    align-items:     center;
    justify-content: center;
}
/* The inner finish block (SVG check + heading + buttons) is hidden
   until central-screen.js calls showFinishLanding (FINISH press or
   session_finished broadcast). The wrapping container stays in place
   so the surrounding background / padding aren't lost — only the
   visible UI is suppressed, and the container collapses to whatever
   height its remaining content needs (no forced 100vh pane). */
.mm-finish-block-content.mm-finish-hidden { display: none; }
/* Fade-out applied during hideFinishLanding — JS adds this class first,
   then swaps to .mm-finish-hidden once the opacity transition has had
   time to play. Without this the block snaps out the moment the user
   clicks "Return to KrsKrt". */
.mm-finish-block-content.mm-finish-fading {
    opacity:        0;
    pointer-events: none;
}

/* Two-column post-finish landing.
   Left column: the inline Magic-Marker-style report card (mounted by
                central-screen.js into .mm-cs-report-inline-host).
   Right column: the green checkmark, the two-line "KrsKrt" / "Finished!"
                heading, the privacy notice, and the Return / Restart
                action row. Whole block is hidden via .mm-finish-hidden
                until showFinishLanding fires; both columns then appear
                together. */
/* Sized to its own content — checkmark on the left, a stacked column
   on the right with a single-line "KrsKrt Finished!" heading on top
   and the Return / Restart buttons directly below. No wrapping anywhere
   (`white-space: nowrap` on the heading + `flex-wrap: nowrap` on the
   action row). */
.mm-finish-block-content {
    padding:      0;
    display:      inline-flex;
    width:        max-content;
    max-width:    100%;
    gap:          16px;
    align-items:  center;
    text-align:   left;
    transition:   opacity 0.4s ease-out;
}
.mm-finish-block-content__right {
    display:        flex;
    flex-direction: column;
    align-items:    flex-start;
    gap:            12px;
    min-width:      0;
}
.mm-finish-heading {
    font-size:    48px;
    font-weight:  800;
    line-height:  1.0;
    margin:       0;
    white-space:  nowrap;
}

/* Animated green checkmark — matches the marker-screen done-modal SVG so
   both screens show the same finish indicator. Circle draws first, then
   tick draws on top. Circle is rotated -90° so the stroke starts at
   12 o'clock instead of 3 o'clock. */
.mm-finish-check {
    display:        block;
    flex-shrink:    0;
    overflow:       visible;
}
.mm-finish-check__circle {
    stroke-dasharray:  226;
    stroke-dashoffset: 226;
    animation:         mm-finish-circle 0.55s ease-out forwards;
    transform-origin:  50% 50%;
    transform:         rotate(-90deg);
}
.mm-finish-check__tick {
    stroke-dasharray:  56;
    stroke-dashoffset: 56;
    animation:         mm-finish-tick 0.35s 0.45s ease-out forwards;
}
@keyframes mm-finish-circle { to { stroke-dashoffset: 0; } }
@keyframes mm-finish-tick   { to { stroke-dashoffset: 0; } }

/* Pop gesture: triggered by JS adding `.is-popping` to the SVG on every
   FINISH press. The check itself was already drawn earlier in the session
   by the one-shot circle / tick keyframes above, so this only calls
   attention to it — a quick scale up + back with a short green glow. JS
   removes + force-reflows + re-adds the class for replay. */
.mm-finish-check { transform-origin: center; }
.mm-finish-check.is-popping {
    animation: mm-finish-pop 600ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes mm-finish-pop {
    0%   { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(74,222,128,0)); }
    40%  { transform: scale(1.18); filter: drop-shadow(0 0 8px rgba(74,222,128,0.65)); }
    100% { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(74,222,128,0)); }
}

.mm-finish-actions {
    display:         flex;
    gap:             12px;
    justify-content: flex-start;
    flex-wrap:       nowrap;
}
.mm-finish-btn {
    display:         inline-flex;
    align-items:     center;
    justify-content: center;
    gap:             8px;
    padding:         14px 22px;
    border:          1px solid currentColor;
    border-radius:   10px;
    cursor:          pointer;
    font-family:     inherit;
    font-size:       16px;
    font-weight:     700;
    letter-spacing:  0.05em;
    line-height:     1;
    background:      transparent;
    color:           inherit;
    transition:      transform 0.08s ease-out, box-shadow 0.12s ease-out,
                     background 0.15s ease-out, color 0.15s ease-out;
}
.mm-finish-btn:hover  { transform: translateY(-1px); }
.mm-finish-btn:active { transform: translateY(1px); }
.mm-finish-btn:focus  { outline: none; box-shadow: 0 0 0 3px rgba(74,222,128,0.35); }
.mm-finish-btn .ph    { font-size: 18px; line-height: 1; }

.mm-finish-btn--primary {
    background:   #00374a;
    color:        #4ade80;
    border-color: #4ade80;
}
.mm-finish-btn--primary:hover { color: #6aeeaa; }

.mm-finish-btn--secondary {
    background: transparent;
}

/* Pulse used to draw attention to the finish-landing buttons when the
   operator scrolls up against the scroll-floor — same green ring as the
   start / finish button pulse, just scoped to .mm-finish-btn. */
@keyframes mm-finish-btn-blink {
    0%, 100% { box-shadow: 0 0 0 0  rgba(74,222,128,0.55); }
    50%      { box-shadow: 0 0 0 12px rgba(74,222,128,0);  }
}
.mm-finish-btn.is-blinking {
    animation: mm-finish-btn-blink 0.6s ease-in-out 2;
}
@media (prefers-reduced-motion: reduce) {
    .mm-finish-btn.is-blinking { animation: none; }
}

/* ---- Typing-mutex overlay (other side is typing here) -------------------- */
.jet-form-builder-row { position: relative; }
.mm-typing-host       { position: relative; }

.mm-typing-shield {
    position: absolute;
    inset: 0;
    background: transparent;
    cursor: not-allowed;
    z-index: 5;
}

.mm-typing-indicator {
    position: absolute;
    right: 10px;
    bottom: 8px;
    display: flex;
    gap: 4px;
    pointer-events: none;
    z-index: 6;
}
.mm-typing-indicator span {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: #9aa0a6;
    animation: mm-typing-blink 1.2s infinite ease-in-out;
}
.mm-typing-indicator span:nth-child(2) { animation-delay: .2s; }
.mm-typing-indicator span:nth-child(3) { animation-delay: .4s; }
@keyframes mm-typing-blink {
    0%, 80%, 100% { opacity: .25; transform: translateY(0); }
    40%           { opacity: 1;   transform: translateY(-2px); }
}

/* ============================================================
   Hashtag command: FLIP
   ============================================================ */

html.mm-flipped {
    transform:        rotate(180deg);
    transform-origin: center center;
}

/* ============================================================
   Hashtag command: KLOKKY timer
   ============================================================ */

#mm-klokky-overlay {
    position:      fixed;
    bottom:        7px;
    right:         7px;
    z-index:       99997;
    background:    #00374a;
    color:         #fff;
    border-radius: 10px;
    border:        1px solid #dedede;
    padding:       20px 10px 0;
    box-shadow:    0 1px 4px rgba(0,0,0,0.12);
    font-family:   "Lekton", sans-serif;
    text-align:    center;
    width:         fit-content;
    overflow:      hidden;
}

#mm-klokky-display {
    display:        flex;
    flex-direction: column;
    align-items:    center;
    line-height:    1;
    gap:            0;
    padding-bottom: 8px;

}

.mm-klokky-mm,
.mm-klokky-ss {
    font-size:      6rem;
    font-weight:    700;
    letter-spacing: 0;
    line-height:    0.82;
    display:        block;
}

.mm-klokky-btns {
    display:  flex;
    gap:      0;
    margin:      0 -10px;
    border-top:  1px solid #dedede;
    position: relative;
    z-index:  1;
}

.mm-klokky-btn {
    flex:           1;
    padding:        8px 14px;
    border-radius:  0;
    background:     none;
    border:         none;
    border-right:   1px solid #dedede;
    color:          #fff;
    font-family:    "Lekton", sans-serif;
    font-size:      15px;
    font-weight:    700;
    cursor:         pointer;
    line-height:    1.3;
    letter-spacing: 0.5px;
}
.mm-klokky-btn:last-child { border-right: none; }
.mm-klokky-btn:hover  { background: rgba(255,255,255,0.12); }
.mm-klokky-btn:active { background: rgba(255,255,255,0.22); }
.mm-klokky-reset      { font-size: 20px; padding: 6px 12px; }

@keyframes mm-klokky-flash {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.35; }
}
.mm-klokky-zero #mm-klokky-display {
    animation: mm-klokky-flash 1.8s ease-in-out infinite;
    color:     #ffffff3d;
}

/* ============================================================
   Hashtag command: PAUSE
   ============================================================ */

body.mm-paused > *:not(#mm-pause-overlay) {
    filter:         blur(8px);
    pointer-events: none;
}

#mm-pause-overlay {
    position:    fixed;
    top:         50%;
    left:        50%;
    transform:   translate(-50%, -50%);
    z-index:     99999;
    text-align:  center;
    user-select: none;
}

.mm-pause-icon {
    display:        block;
    font-size:      18vmin;
    line-height:    1;
    pointer-events: none;
}

.mm-pause-close {
    position:      absolute;
    top:           -1.2rem;
    right:         -1.2rem;
    width:         2.4rem;
    height:        2.4rem;
    border-radius: 50%;
    background:    rgba(0,0,0,0.55);
    border:        2px solid rgba(255,255,255,0.4);
    color:         #fff;
    font-size:     1.4rem;
    line-height:   1;
    cursor:        pointer;
    display:       flex;
    align-items:   center;
    justify-content: center;
    pointer-events: auto;
}
.mm-pause-close:hover { background: rgba(0,0,0,0.8); }

/* ============================================================
   Central screen command palette (floating dropdown)
   ============================================================ */

#mm-cs-cmd-palette {
    display:       none;
    /* Anchored inside the focused input's row so it inherits autozoom's
       per-section `zoom`. JS sets `top` and `left` to the caret position
       (mirror-div technique) so the palette tracks the typed `#`, even on
       tall textareas. */
    position:      absolute;
    z-index:       99996;
    background:    #1a1a2e;
    border:        1px solid #2a2a40;
    border-radius: 8px;
    box-shadow:    0 4px 16px rgba(0,0,0,0.25);
    min-width:     220px;
    overflow:      hidden;
}

.mm-cs-cmd-item {
    display:        flex;
    flex-direction: column;
    align-items:    flex-start;
    padding:        10px 14px;
    background:     transparent;
    border:         none;
    border-bottom:  1px solid #2a2a40;
    cursor:         pointer;
    text-align:     left;
    width:          100%;
    color:          #e8e8f0;
    font-family:    "Lekton", sans-serif;
}
.mm-cs-cmd-item:last-child  { border-bottom: none; }
.mm-cs-cmd-item:hover       { background: #00374a; }

.mm-cs-cmd-name {
    font-size:   15px;
    font-weight: 700;
    color:       #22c55e;
    line-height: 1.2;
}
.mm-cs-cmd-desc {
    font-size:  12px;
    color:      #8888a0;
    margin-top: 2px;
}


/* ---- Klokky close button ------------------------------------------------ */
.mm-klokky-close {
    position:    absolute;
    top:         4px;
    right:       6px;
    background:  none;
    border:      none;
    box-shadow:  none;
    color:       rgba(255,255,255,0.5);
    font-size:   20px;
    line-height: 1;
    padding:     2px 4px;
    cursor:      pointer;
    z-index:     1;
}
.mm-klokky-close:hover { color: #fff; }

/* ============================================================
   Number field — stepper buttons (overlaid inside the field)
   ============================================================ */

.mm-cs-number-row {
    position: relative;
    display:  block;
}

/* Hide browser native up/down spin arrows; leave room for stepper group */
.mm-cs-number-row input[type="number"] {
    -moz-appearance: textfield;
    padding-right:   56px;
    width:           100%;
    box-sizing:      border-box;
}
.mm-cs-number-row input[type="number"]::-webkit-outer-spin-button,
.mm-cs-number-row input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Stepper group: absolute overlay on the right edge */
.mm-cs-stepper-group {
    position:    absolute;
    right:       5px;
    top:         0;
    bottom:      0;
    display:     flex;
    align-items: center;
    gap:         0;
    padding:     0 4px;
}

.mm-cs-stepper-btn {
    width:       24px;
    height:      24px;
    border:      none;
    background:  transparent;
    color:       #00374a;
    font-size:   17px;
    cursor:      pointer;
    display:     flex;
    align-items: center;
    justify-content: center;
    padding:     0;
    line-height: 1;
    border-radius: 4px;
    transition:  background 0.1s;
}
.mm-cs-stepper-btn:hover {
    background: rgba(0, 55, 74, 0.08);
}
.mm-cs-stepper-btn:active {
    background: rgba(0, 55, 74, 0.15);
}
.mm-cs-stepper-btn .ph {
    pointer-events: none;
}

/* ----------------------------------------------------------------------- */
/* Repeater — row-remove button overlay (inside field, right-aligned)      */
/* ----------------------------------------------------------------------- */

/* Give the row a positioning context so the absolute button stays inside */
.jet-form-builder-repeater__row {
    position:          relative;
    margin-bottom:     var(--jfb-rep-row-gap, 8px);
}
.jet-form-builder-repeater__row:last-child {
    margin-bottom: 0;
}

/* Multi-column: CSS Grid handles row- and column-gap uniformly,
   so there is no trailing gap and the add button never shifts. */
.jfb-rep-multi-col {
    display:               grid;
    grid-template-columns: repeat(var(--jfb-rep-columns, 1), 1fr);
    row-gap:               var(--jfb-rep-row-gap, 8px);
    column-gap:            var(--jfb-rep-col-gap, 8px);
}
/* Grid gap owns the spacing; remove margin-based gap from rows inside grid. */
.jfb-rep-multi-col > .jet-form-builder-repeater__row {
    margin-bottom:     0;
    break-inside:      avoid;
    page-break-inside: avoid;
}

@media (max-width: 767px) {
    .jfb-rep-multi-col {
        grid-template-columns: 1fr;
    }
}

/* ----------------------------------------------------------------------- */
/* Repeater inline add cell (multi-column, add_button_inline toggle)        */
/* The cell is rendered as the last child of __items in PHP and always      */
/* appears last visually via CSS order:9999 — new rows added by JFB JS get  */
/* the default order:0 and naturally appear before the cell.                */
/* ----------------------------------------------------------------------- */
.jfb-rep-inline-add-cell {
    order:      9999; /* always last in the CSS Grid regardless of DOM order */
    box-sizing: border-box;
}
/* Hide the cell (not just the button) when the add button is disabled,
   so there is no empty grid hole visible to the user. */
.jfb-rep-inline-add-cell:has(> button.jet-form-builder-repeater__new:disabled) {
    display: none;
}

/* Pin the remove button to the top-right corner of the field area.
   top matches the block-group margin-top that separates the field from the
   row edge; right gives a consistent margin from the field border.
   No height or centering — the button simply docks to the corner regardless
   of textarea height. */
.jet-form-builder-repeater__row-remove {
    position:       absolute;
    right:          9px;
    top:            9px;
    pointer-events: none;
}

/* Style the inner button to match .mm-cs-stepper-btn.
   The Phosphor ph-x icon is a real <i class="ph ph-x"> child element. */
.jet-form-builder-repeater__row-remove button.jet-form-builder-repeater__remove {
    pointer-events:  all;
    width:           24px;
    height:          24px;
    border:          none;
    background:      transparent;
    color:           #00374a;
    cursor:          pointer;
    display:         flex;
    align-items:     center;
    justify-content: center;
    padding:         0;
    line-height:     1;
    border-radius:   4px;
    margin:          0;
    text-decoration: none;
    transition:      background 0.1s;
}
.jet-form-builder-repeater__row-remove button.jet-form-builder-repeater__remove > .ph {
    font-size:      18px;
    pointer-events: none;
}
.jet-form-builder-repeater__row-remove button.jet-form-builder-repeater__remove:hover {
    background: rgba(0, 55, 74, 0.08);
}
.jet-form-builder-repeater__row-remove button.jet-form-builder-repeater__remove:active {
    background: rgba(0, 55, 74, 0.15);
}

/* "Added rows only" mode: the first `min` rows are the DEFAULT rows — locked
   against deletion. central.ts tags them at render time; central-screen.js
   re-applies the class after every add / remove + renumber so the lock
   tracks position-in-list, not row identity. The X stays out of the DOM-
   facing layout so the row looks identical to a fixed-count repeater for
   those slots, even though the SAME repeater allows adding/removing the
   trailing ones. */
.jet-form-builder-repeater__row.jfb-rep-row-locked > .jet-form-builder-repeater__row-remove {
    display: none;
}

/* ----------------------------------------------------------------------- */
/* GDPR — privacy-notice balloon + Clear-data button (Finish block)        */
/* ----------------------------------------------------------------------- */

/* Default balloon look — used by the Start / Resume gate.  Width follows
   the Start button (auto via the flex column wrapper); the triangle on the
   bottom edge points down at the button. */
.krskrt-privacy-balloon {
    --kp-bg: var(--krskrt-finish-balloon-bg, #00374a);
    position:   relative;
    box-sizing: border-box;
    padding:    8px;
    background: var(--kp-bg);
    color:      #fff;
    border-radius: 6px;
    font-size:  0.9em;
    line-height: 1.1;
    text-align: center;
}
.krskrt-privacy-balloon--gate::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -7px;
    transform: translateX(-50%);
    border-left:  8px solid transparent;
    border-right: 8px solid transparent;
    border-top:   8px solid var(--kp-bg);
}

/* In the Finish block, the notice should NOT be a balloon — keep it as
   flat white text above the action buttons.  Strips the box, triangle and
   spacing back to the bare line(s) of text. */
.krskrt-privacy-balloon--finish {
    background: none;
    padding:    0;
}
.krskrt-privacy-balloon--finish::after { content: none; }

/* The `[krskrt_terms]` shortcode emits an <a> inside the balloon — let it
   inherit the balloon's text colour (white on the dark gate, brand petrol
   on the flat finish) instead of the browser default link blue. Underline
   stays so the link is still recognisable as a click target. */
.krskrt-privacy-balloon a {
    color:           inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}
.krskrt-privacy-balloon a:hover {
    text-decoration-thickness: 2px;
}

@media ( max-width: 760px ) {
    .krskrt-privacy-balloon--finish { text-align: center; }
}

.mm-finish-btn--clear {
    background:   transparent;
    color:        #f87171;
    border-color: #f87171;
}
.mm-finish-btn--clear:hover { color: #fca5a5; border-color: #fca5a5; }

/* -------------------------------------------------------------------------
 * Binary-mode finish confirmation modal (Phase 3) — full-screen overlay
 * mirrored across Central + Marker via the relay. Triggered by clicks on
 * [data-action="finish"] (krskrt mode) or [data-action="clear-session"]
 * (jfb mode) inside the KrsKrt Finished block.
 * ------------------------------------------------------------------------- */
.mm-finish-confirm[hidden] { display: none; }
.mm-finish-confirm {
    position: fixed; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0, 0.55);
    z-index: 100000;
    padding: 24px;
    opacity: 0; pointer-events: none;
    transition: opacity 160ms ease-out;
}
.mm-finish-confirm.is-open {
    opacity: 1; pointer-events: auto;
}
.mm-finish-confirm__panel {
    background: #fff;
    color: #111;
    max-width: 520px; width: 100%;
    border-radius: 14px;
    padding: 28px 32px;
    box-shadow: 0 20px 50px rgba(0,0,0, 0.35);
}
.mm-finish-confirm__text {
    font-size: 1.05rem;
    line-height: 1.5;
    margin: 0 0 24px;
    word-break: break-word;
}
.mm-finish-confirm__actions {
    display: flex; gap: 12px; justify-content: flex-end;
    flex-wrap: wrap;
}
.mm-finish-confirm__btn {
    appearance: none;
    border: 2px solid currentColor;
    border-radius: 8px;
    padding: 10px 20px;
    font: inherit; font-weight: 600;
    cursor: pointer;
    background: transparent;
}
.mm-finish-confirm__btn--cancel { color: #555; border-color: #ccc; }
.mm-finish-confirm__btn--cancel:hover { background: #f4f4f4; }
.mm-finish-confirm__btn--ok {
    color: #fff; background: #f87171; border-color: #f87171;
}
.mm-finish-confirm__btn--ok:hover { background: #ef4444; border-color: #ef4444; }

/* -------------------------------------------------------------------------
 * Krskrt-mode "Finish" button — same big-pulse / press / sparkle / gone
 * styling as the old `.mm-cs-finish-btn`, scoped to
 * `.mm-finish-block-content[data-mode="krskrt"]`. Fills the row
 * horizontally so it reads as the form's terminal action.
 * ------------------------------------------------------------------------- */
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-actions {
    width:           100%;
    justify-content: stretch;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"] {
    width:           100%;
    flex:            1 1 auto;
    padding:         15px 30px 13px;
    border:          none;
    border-radius:   10px;
    cursor:          pointer;
    white-space:     nowrap;

    background:      #00374a;
    color:           #4ade80;

    font-family:     inherit;
    font-size:       24px;
    font-weight:     800;
    letter-spacing:  2px;
    text-transform:  uppercase;
    line-height:     1;

    box-shadow:      0 6px 0 #00262D, 0 8px 14px rgba(0,0,0,0.25);
    transform:       translateY(0);
    transition:      transform 0.08s ease-out,
                     box-shadow 0.08s ease-out,
                     opacity 0.35s ease-out;

    animation:       mm-start-pulse 1.6s ease-in-out infinite;
    position:        relative;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"]:hover {
    color: #6aeeaa;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"]:focus {
    outline: none;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"]:active,
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"].is-pressed {
    transform:  translateY(6px);
    box-shadow: 0 0 0 #00262D, 0 2px 4px rgba(0,0,0,0.25);
    animation:  none;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"].is-sparkling::after {
    content:         '';
    position:        absolute;
    inset:           -4px;
    border-radius:   14px;
    pointer-events:  none;
    animation:       mm-start-sparkle 0.7s ease-out forwards;
}
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"].is-gone {
    opacity:        0;
    pointer-events: none;
}
/* The old FINISH button had no icon; suppress the inherited rotate icon
   (`.ph-arrow-counter-clockwise`) on the krskrt-mode button. */
.mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"] .ph {
    display: none;
}
@media (prefers-reduced-motion: reduce) {
    .mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"] { animation: none; }
    .mm-finish-block-content[data-mode="krskrt"] .mm-finish-btn[data-action="finish"].is-sparkling::after { animation: none; }
}

/* =========================================================================
   Interactive image fullscreen overlay
   (matches .krskrt-video-modal color palette and close-button style)
   ========================================================================= */
.mm-cs-image-overlay {
    display:         none;
    position:        fixed;
    inset:           0;
    z-index:         99999;
    background:      rgba(0, 0, 0, 0.88);
    align-items:     center;
    justify-content: center;
    cursor:          zoom-out;
    overflow:        hidden;
    padding:         7px;
    box-sizing:      border-box;
    animation:       mm-cs-image-in 0.18s ease-out;
}
@keyframes mm-cs-image-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.mm-cs-image-overlay.is-visible { display: flex; }

/* White card wrapper. JS (sizeOverlayFrame) sets its width/height to the
   image's contained dimensions, so the frame hugs the image exactly — no
   letterbox bars in any direction — while still scaling the image up to fill
   the padded overlay. max-width/height are a safety cap. The zoom transform
   lives here. */
.mm-cs-image-overlay__frame {
    display:          block;
    max-width:        100%;
    max-height:       100%;
    box-sizing:       border-box;
    background-color: #fff;
    border:           1px solid #dedede;
    border-radius:    10px;
    overflow:         hidden;
    cursor:           zoom-in;
    transform-origin: center center;
    transition:       transform 0.32s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    will-change:      transform;
}
/* Fallback for images with no intrinsic size (some SVGs): fill the area
   frameless + transparent so there are still no white bars. */
.mm-cs-image-overlay__frame.is-fill {
    background-color: transparent;
    border:           0;
}
/* The image sizes to its own (capped) dimensions rather than filling the
   overlay, so the white card backs EXACTLY the image area — no letterbox bars,
   and transparent SVGs get a solid white backing instead of showing the dark
   backdrop. (The old approach put the white on a separate __frame wrapper +
   an is-fill transparency hack for sizeless SVGs; that wrapper no longer
   exists, so the background lives on the img itself.) */
.mm-cs-image-overlay__img {
    display:          block;
    width:            auto;
    height:           auto;
    max-width:        100%;
    max-height:       100%;
    background-color: #fff;
    border:           1px solid #dedede;
    border-radius:    5px;
}

/* Slider prev/next when maximized — same chrome as the data-viz zoom modal
   nav (.kf-viz-zoom-prev/next): round, translucent, centred on each edge.
   Shown / disabled by JS; only present when the field has >1 image. */
.mm-cs-image-overlay__nav {
    position:        absolute;
    top:             50%;
    transform:       translateY(-50%);
    width:           56px;
    height:          56px;
    border-radius:   50%;
    background:      rgba(255, 255, 255, 0.14);
    color:           #fff;
    border:          0;
    display:         none;
    align-items:     center;
    justify-content: center;
    font-size:       28px;
    cursor:          pointer;
    z-index:         1;
    transition:      background-color 0.15s ease-in-out;
}
.mm-cs-image-overlay__nav:hover { background: rgba(255, 255, 255, 0.26); }
.mm-cs-image-overlay__nav--prev { left:  24px; }
.mm-cs-image-overlay__nav--next { right: 24px; }
.mm-cs-image-overlay__nav[disabled] { opacity: 0.35; cursor: default; }
.mm-cs-image-overlay__nav .ph { pointer-events: none; line-height: 1; }

/* Close button — matches .krskrt-video-modal__close */
.mm-cs-image-overlay__close {
    position:        absolute;
    top:             16px;
    right:           16px;
    width:           44px;
    height:          44px;
    border-radius:   50%;
    background:      rgba(255, 255, 255, 0.18);
    color:           #fff;
    border:          none;
    cursor:          pointer;
    display:         flex;
    align-items:     center;
    justify-content: center;
    line-height:     1;
    transition:      background-color 0.15s ease-in-out;
    z-index:         1;
}
.mm-cs-image-overlay__close:hover {
    background: rgba(255, 255, 255, 0.32);
}

/* Close-zoom button — sits underneath the X close, visible only when zoomed.
   Same chrome as .mm-cs-image-overlay__close; toggled via inline display by JS. */
.mm-cs-image-overlay__close-zoom {
    position:        absolute;
    top:             68px; /* 16 (close top) + 44 (close height) + 8 (gap) */
    right:           16px;
    width:           44px;
    height:          44px;
    border-radius:   50%;
    background:      rgba(255, 255, 255, 0.18);
    color:           #fff;
    border:          none;
    cursor:          pointer;
    display:         none;
    align-items:     center;
    justify-content: center;
    line-height:     1;
    font-size:       22px;
    transition:      background-color 0.15s ease-in-out;
    z-index:         1;
}
.mm-cs-image-overlay__close-zoom:hover {
    background: rgba(255, 255, 255, 0.32);
}
.mm-cs-image-overlay__close-zoom .ph {
    font-size: 22px;
    line-height: 1;
}

/* -------------------------------------------------------------------------
 * JFB repeater action buttons — same dark "lift + press" chrome as the
 * krskrt-mode FINISH button (.mm-finish-block-content[data-mode="krskrt"]
 * .mm-finish-btn[data-action="finish"]) but WITHOUT the pulsating animation
 * and WITHOUT overriding the current font-size — those buttons live inline
 * in repeater rows and don't need to attract terminal-action attention.
 * ------------------------------------------------------------------------- */
.jet-form-builder-repeater__actions {
    margin: 8px 0 0 0;
}

/* Shared style for all "add new row" buttons — covers both the regular
   (__actions) variant and the inline (jfb-rep-inline-add-cell) variant.
   height:36px + 6px bottom box-shadow = exactly 42px total visual height.
   font-size intentionally NOT set — inherits whatever the form theme uses. */
button.jet-form-builder-repeater__new {
    height:         38px;
    min-width:      38px;
    padding:        0 10px;
    gap:            6px;
    display:        flex;
    align-items:    center;
    border:         1px solid #dedede;
    border-radius:  5px;
    cursor:         pointer;
    white-space:    nowrap;
    background:     #fff;
    color:          #a0a0a0;
    font-family:    inherit;
    font-weight:    bold;
    letter-spacing: 2px;
    text-transform: uppercase;
    line-height:    1;
    box-shadow:     0 4px 0 #a0a0a0, 0 6px 8px rgba(0,0,0,0.25);
    transform:      translateY(0);
    transition:     transform 0.08s ease-out, box-shadow 0.08s ease-out;
    position:       relative;
}
button.jet-form-builder-repeater__new > .ph {
    font-size:   17px;
    color:       #00374a;
    line-height: 1;
    flex-shrink: 0;
}
button.jet-form-builder-repeater__new:hover {
    background: #f6f6f6;
    color:      #00374a;
}
button.jet-form-builder-repeater__new:focus {
    outline: none;
}
button.jet-form-builder-repeater__new:active,
button.jet-form-builder-repeater__new.is-pressed {
    transform:  translateY(4px);
    box-shadow: 0 0 0 #a0a0a0, 0 2px 4px rgba(0,0,0,0.25);
}


/* =========================================================================
 * Stacking sections — each form section sticks to the top of the screen; the
 * next section slides up over it to cover it, and un-stacks on scroll up.
 *
 * The sticky targets are tagged `.mm-sticky-section` by
 * central-screen.js::recomputePartTops — the actual per-section wrapper
 * (outermost ancestor of each heading wrapping only that section), at whatever
 * depth the theme nests it. (A CSS `form > .wp-block-group:has(h1)` selector
 * only caught sections that are DIRECT children of the form, so forms whose
 * sections sit inside an extra group wrapper never stacked — img-pres.)
 *
 * The per-section `top` is HEIGHT-AWARE and set inline by recomputePartTops to
 * `min(0, viewportH - sectionH)`:
 *   - short section (fits): top = 0  → sticks flush at the top.
 *   - tall section: top is negative → scrolls fully through (still readable,
 *     scroll buttons still work) and only pins once its BOTTOM reaches the
 *     viewport bottom, then the next slides over.
 * `top: 0` here is only the fallback before JS runs. Source order gives the
 * cover effect (later section paints over earlier); no z-index needed.
 * ========================================================================= */
.mm-sticky-section {
    position: sticky;
    top:      0;
}

/* Measurement guard: while recomputePartTops() reads section geometry it adds
 * this class to <body> so the wrappers fall back to static and
 * getBoundingClientRect returns true document positions (a pinned sticky box
 * would otherwise corrupt partTops/partBottoms → the scroll-button greying).
 * Added + removed within one synchronous pass, so there is no paint flash. */
body.mm-measuring-parts .mm-sticky-section {
    position: static !important;
}

/* On devices with an on-screen keyboard the JS disables sticky entirely
 * (recomputePartTops removes .mm-sticky-section and tags nothing), so the form
 * scrolls as a plain vertical page. No extra CSS needed for that mode. */

/* =========================================================================
 * B2 — kk-choice polished appearance
 *
 * Renderer emits `.jet-form-builder__fields-group.checkradio-wrap.kk-choice
 * .kk-choice--{list|grid|cards}` containing `<label>` elements (not the
 * legacy `ul > li[role]` shape). The JFB bundle already sets the flex-column
 * layout + gap; this block adds the card-like look, hover/focus states, and
 * checked highlight that the WP ul/li shape carried via head.html.
 * ========================================================================= */

/* Each label is a full-width flex row (icon + text horizontally centred). */
.kk-choice label.jet-form-builder__field-label {
    display:         flex;
    align-items:     center;
    width:           100%;
    padding:         0.5rem 0.75rem;
    border-radius:   8px;
    border:          1px solid #dedede;
    box-sizing:      border-box;
    cursor:          pointer;
    transition:      border-color 0.15s, background-color 0.15s;
    user-select:     none;
}

/* When a per-option borderColor is set the renderer injects an inline style
 * that already carries border + border-radius + padding — don't override. */
.kk-choice label.jet-form-builder__field-label[style] {
    border:          none;
}

.kk-choice label.jet-form-builder__field-label:hover {
    border-color:    #a0a0a0;
    background-color: rgba(0,0,0,0.03);
}

/* Checked state: thicker accent border using the brand teal as a fallback. */
.kk-choice label.jet-form-builder__field-label:has(input:checked) {
    border-color:    var(--wp--preset--color--krskrt-dark, #00374a);
    border-width:    2px;
}

/* Focus ring on the hidden native input bubbles to the label. */
.kk-choice label.jet-form-builder__field-label:focus-within {
    outline:         2px solid var(--wp--preset--color--krskrt-dark, #00374a);
    outline-offset:  2px;
}

/* Input sits before the option text; the JFB bundle gives it margin-right:5px. */
.kk-choice label.jet-form-builder__field-label input {
    flex-shrink:     0;
}

/* Grid variant: items wrap in a two-column grid. */
.kk-choice.kk-choice--grid {
    flex-direction:  row;
    flex-wrap:       wrap;
}
.kk-choice.kk-choice--grid label.jet-form-builder__field-label {
    flex:            1 1 calc(50% - 0.35em);
    min-width:       120px;
}

/* Cards variant: same flex-column as list but gap between cards is tighter. */
.kk-choice.kk-choice--cards {
    gap:             0.4em;
}

/* ── Content-QR fullscreen overlay (iframe of the /cc page) ────────────────── */
.mm-cs-content-qr-overlay {
    display:         none;
    position:        fixed;
    inset:           0;
    z-index:         99999;
    background:      rgba(0, 0, 0, 0.88);
    align-items:     center;
    justify-content: center;
    padding:         24px;
    box-sizing:      border-box;
}
.mm-cs-content-qr-overlay.is-visible { display: flex; }
/* The frame is `display:contents` — its element box is discarded so the iframe
   becomes a direct child of the overlay and fills the FULL viewport. That gives
   the embedded /cc page a real viewport width to autozoom against, so text
   inside the modal renders at the same size as standalone /cc instead of being
   shrunk into a 1100×92vh box (the reason the earlier sized-frame version was
   "unreadable inside the viewport"). The frame chrome (border/radius/shadow) is
   dropped intentionally — the overlay backdrop provides plenty of separation. */
.mm-cs-content-qr-overlay__frame { display: contents; }
.mm-cs-content-qr-overlay__iframe {
    flex:       1 1 auto;
    width:      100%;
    height:     100%;
    border:     0;
    display:    block;
    background: #fff;
}
.mm-cs-content-qr-overlay__close {
    position:        absolute;
    top:             16px;
    right:           16px;
    width:           44px;
    height:          44px;
    border:          0;
    border-radius:   50%;
    background:      rgba(255, 255, 255, 0.18);
    color:           #fff;
    font-size:       22px;
    cursor:          pointer;
    display:         flex;
    align-items:     center;
    justify-content: center;
}
.mm-cs-content-qr-overlay__close:hover { background: rgba(255, 255, 255, 0.32); }

/* ─────────────────────────────────────────────────────────────────────────── */
/* Inline Session-QR controls — corners-out + eye buttons on top-right of the
 * card (mirrors `.kf-viz-expand` shape & hover-fade-in from krskrt-data-viz.css
 * line 289). Replaces the previous "click-anywhere-on-card to toggle blur"
 * gesture — the eye button is now the only blur affordance, leaving the rest
 * of the card free to host pointer events on the URL link, etc.
 * The toolbar lives as a SIBLING of the card (inside the wrapper) so the
 * card's `.is-blurred` filter doesn't blur the buttons too — same shape as
 * the existing `.kf-sq-blur-btn` sibling pattern. Owner-ratified 2026-06-18. */
.kf-sq-wrapper { position: relative; }
.kf-sq-toolbar {
    position:        absolute;
    top:             8px;
    right:           8px;
    z-index:         3;
    display:         flex;
    flex-direction:  column;
    gap:             6px;
    opacity:         0;
    transition:      opacity 0.15s ease;
    pointer-events:  none;
}
.kf-sq-wrapper:hover .kf-sq-toolbar,
.kf-sq-toolbar:focus-within,
.kf-sq-toolbar.is-pinned { opacity: 1; pointer-events: auto; }
.kf-sq-toolbar-btn {
    width:           44px;
    height:          44px;
    padding:         0;
    background:      #fff;
    color:           #00374a;
    border:          1px solid #dedede;
    border-radius:   10px;
    cursor:          pointer;
    display:         flex;
    align-items:     center;
    justify-content: center;
    font-size:       22px;
    line-height:     1em;
    box-shadow:      0 1px 4px rgba(0, 0, 0, 0.08);
    transition:      background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.kf-sq-toolbar-btn:hover {
    background:   #00a9bb;
    border-color: #00a9bb;
}
.kf-sq-toolbar-btn:active {
    background:   #00262d;
    color:        #fff;
    border-color: #00262d;
}
.kf-sq-toolbar-btn > i {
    display:        block;
    line-height:    1;
    pointer-events: none;
}

/* The fullscreen modal — mirrors .kf-viz-modal (krskrt-data-viz.css line 556):
 * fixed inset:0, white backdrop, z-index above the floating mm panel (100002),
 * centred QR card scaled to "contained" via flex auto-size. Close button reuses
 * the .kf-viz-modal-close circle pattern (top-right, semi-transparent teal). */
.kf-sq-modal {
    position:        fixed;
    inset:           0;
    z-index:         100002;
    background:      #fff;
    display:         flex;
    flex-direction:  column;
    align-items:     center;
    justify-content: center;
    padding:         48px;
    box-sizing:      border-box;
}
.kf-sq-modal[hidden] { display: none; }
/* The cloned card keeps its natural inline width (fit-content per the
 * `.mm-cs-qr-overlay.mm-cs-qr-inline` rule) and its hard-coded 180px QR canvas
 * — so to "enlarge until contained" we scale the whole card uniformly. The
 * scale factor is set by JS at open time from the viewport vs. natural-size
 * ratio, with a 1.0 floor so a tiny card never shrinks. */
.kf-sq-modal > .kf-session-qr {
    position:        relative;
    margin:          0;
    box-shadow:      0 8px 32px rgba(0, 0, 0, 0.18);
    transform-origin: center center;
    transform:        scale(var(--kf-sq-modal-scale, 1));
    /* The carried `.mm-cs-qr-overlay.mm-cs-qr-inline` rule sets `width:
     * fit-content`. Inside the modal's flex parent that can resolve to a
     * width narrower than the widest unbreakable child (the CODE pill + the
     * 6-letter CODE), which clipped the trailing letter at fullscreen.
     * `max-content` sizes the card to its longest intrinsic line so the
     * bottom strip always fits. */
    width:           max-content;
    max-width:       90vw;
}
.kf-sq-modal-close {
    position:        absolute;
    top:             12px;
    right:           12px;
    width:           44px;
    height:          44px;
    border-radius:   50%;
    background:      rgba(0, 55, 74, 0.28);
    color:           #fff;
    border:          0;
    cursor:          pointer;
    font-size:       22px;
    display:         flex;
    align-items:     center;
    justify-content: center;
    z-index:         2;
}
.kf-sq-modal-close:hover { background: rgba(0, 55, 74, 0.42); }
.kf-sq-modal-close > i { display: block; line-height: 1; pointer-events: none; }

/* ─────────────────────────────────────────────────────────────────────────── */
/* Multi-card Session-QR flyout — when the page carries >1 kf-sq-config the
 * topbar grows left/right chevrons + a "i / N" counter; the X close lives in
 * the topbar regardless of card count. Slice 3 of the QR UX refactor
 * (owner-ratified 2026-06-18). */
.mm-cs-sq-shell .mm-cs-sq-topbar {
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    gap:             8px;
    padding:         6px 8px 0;
    background:      transparent;
    border:          0;
}
.mm-cs-sq-nav {
    display:        inline-flex;
    align-items:    center;
    gap:            4px;
    min-height:     32px;   /* reserve height even when N=1 (nav is empty) */
}
.mm-cs-sq-nav-btn,
.mm-cs-sq-close {
    width:           32px;
    height:          32px;
    padding:         0;
    background:      transparent;
    color:           #00374a;
    border:          1px solid transparent;
    border-radius:   6px;
    cursor:          pointer;
    display:         inline-flex;
    align-items:     center;
    justify-content: center;
    font-size:       18px;
    line-height:     1;
}
.mm-cs-sq-nav-btn:hover,
.mm-cs-sq-close:hover {
    background:   #00a9bb;
    color:        #fff;
    border-color: #00a9bb;
}
.mm-cs-sq-nav-btn > i,
.mm-cs-sq-close > i { display: block; line-height: 1; pointer-events: none; }
.mm-cs-sq-counter {
    font:         600 13px/1 var(--wp--preset--font-family--lekton, ui-monospace, Menlo, monospace);
    color:        #00374a;
    min-width:    36px;
    text-align:   center;
    padding:      0 4px;
    user-select:  none;
}
.mm-cs-sq-slides { display: block; }
.mm-cs-sq-slide  { display: block; }
/* Inside the shell each card is a slide, NOT a free-floating overlay — the
 * outer card chrome (border, bg, padding) still applies, only the
 * fixed-positioning rules from `.mm-cs-qr-overlay` shouldn't. The card's
 * .mm-cs-qr-overlay class is stripped in buildSessionQROverlay; this rule
 * is a defensive backstop so any future code path that leaves the class on
 * still flows in the slides container. */
.mm-cs-sq-shell .mm-cs-sq-slide.mm-cs-qr-overlay { position: static; right: auto; top: auto; }

/* ────────────────────────────────────────────────────────────────────────
   Phosphor-Fill (global mapping)

   The shared head registers @font-face Phosphor-Fill but only dataview.css
   maps `.ph-fill` → that family inside `#krskrt-mm-panel`. The favicon-
   adjacent ? chip needs the fill weight on the central layer too, so we
   widen the rule. Scoped to <i.ph-fill> only (no class collision with
   `.ph` which keeps the regular weight). */
.ph-fill { font-family: "Phosphor-Fill" !important; }

/* ────────────────────────────────────────────────────────────────────────
   `?` help chip — pinned at the top-right corner of the favicon inside
   #az-chrome (the autozoom scrollbar chrome at the bottom-left). No
   background; the Phosphor-Fill question glyph carries its own shape, and
   the colour matches the inactive `.az-part-dot` translucent petrol so the
   chip reads as a sibling of the section dots without screaming for
   attention. Hover bumps the alpha + a small scale, mirroring the dot's
   hover-language. */
#az-help {
    position:        absolute;
    top:             -5px;
    left:            35px;
    width:           18px;
    height:          18px;
    padding:         0;
    border:          none;
    background:      transparent;
    color:           rgba(0, 55, 74, 0.4);
    cursor:          pointer;
    display:         flex;
    align-items:     center;
    justify-content: center;
    line-height:     1;
    pointer-events:  auto;
    transition:      color 0.15s ease, transform 0.15s ease;
    z-index:         1501;
}
#az-help > i {
    font-size:      18px;
    line-height:    1;
    display:        block;
    pointer-events: none;
}
#az-help:hover {
    color:     rgba(0, 55, 74, 0.85);
    transform: scale(1.15);
}
#az-help:focus-visible {
    outline:        2px solid #00374a;
    outline-offset: 2px;
    border-radius:  50%;
}

/* ────────────────────────────────────────────────────────────────────────
   Help overlay — a reusable centered modal. The current content is the
   keyboard-shortcuts table; the next tenant will likely be a /cc iframe,
   so the layout treats `.krskrt-help-overlay__body` as a free-form slot.

   Mounted on <html> (NOT <body>) so the autozoom `zoom: ratio` on body
   never gets inherited — the modal stays in real viewport pixels, like
   the marker's content-QR + central's content-QR overlays already do. */
.krskrt-help-overlay {
    display:         none;
    position:        fixed;
    inset:           0;
    z-index:         2500;
    background:      rgba(0, 55, 74, 0.55);
    backdrop-filter: blur(2px);
    align-items:     center;
    justify-content: center;
    padding:         24px;
    box-sizing:      border-box;
}
.krskrt-help-overlay.is-visible { display: flex; }

.krskrt-help-overlay__card {
    background:    #ffffff;
    color:         #00374a;
    border-radius: 14px;
    box-shadow:    0 24px 60px rgba(0, 0, 0, 0.35);
    max-width:     520px;
    width:         100%;
    max-height:    90vh;
    display:       flex;
    flex-direction: column;
    overflow:      hidden;
    font-family:   var(--wp--preset--font-family--lekton, ui-monospace, Menlo, monospace);
}
.krskrt-help-overlay__bar {
    flex:            0 0 auto;
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    gap:             12px;
    padding:         12px 14px;
    background:      #00374a;
    color:           #ffffff;
}
.krskrt-help-overlay__title {
    font-size:    16px;
    font-weight:  700;
    letter-spacing: 0.5px;
}
.krskrt-help-overlay__close {
    appearance:      none;
    border:          0;
    background:      #00a9bb;
    color:           #ffffff;
    font:            inherit;
    font-weight:     700;
    font-size:       13px;
    line-height:     1;
    padding:         8px 12px;
    border-radius:   8px;
    display:         inline-flex;
    align-items:     center;
    gap:             6px;
    cursor:          pointer;
    box-shadow:      0 2px 0 rgba(0, 0, 0, 0.20);
}
.krskrt-help-overlay__close:hover { background: #00bccf; }
.krskrt-help-overlay__close:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }
.krskrt-help-overlay__close .ph { font-size: 14px; }

.krskrt-help-overlay__body {
    flex:    1 1 auto;
    overflow-y: auto;
    padding: 16px 18px;
}

.krskrt-help-shortcuts {
    border-collapse: collapse;
    width:           100%;
    font-size:       14px;
}
.krskrt-help-shortcuts th {
    text-align:    left;
    font-weight:   500;
    vertical-align: top;
    padding:       8px 14px 8px 0;
    white-space:   nowrap;
    color:         #00374a;
}
.krskrt-help-shortcuts td {
    padding:       8px 0;
    color:         #00374a;
    vertical-align: top;
}
.krskrt-help-shortcuts tr + tr th,
.krskrt-help-shortcuts tr + tr td {
    border-top: 1px solid rgba(0, 55, 74, 0.10);
}
.krskrt-help-shortcuts kbd {
    display:        inline-block;
    font-family:    var(--wp--preset--font-family--lekton, ui-monospace, Menlo, monospace);
    font-size:      12px;
    line-height:    1;
    padding:        4px 8px;
    border-radius:  6px;
    background:     #f1f5f7;
    color:          #00374a;
    border:         1px solid rgba(0, 55, 74, 0.18);
    box-shadow:     0 1px 0 rgba(0, 55, 74, 0.15);
    white-space:    nowrap;
}
.krskrt-help-sep {
    color:       rgba(0, 55, 74, 0.45);
    padding:     0 4px;
    font-weight: 700;
}
