/* ════════════════════════════════════════════════════════════
   Crownforge — Card Frames ("Template D": Standard "Fusion" + Alt Art "Royal Proof" + landscape Quest)
   Adapted from the Claude-Design hi-fi handoff (design_handoff_template_d_cards) into Blazor.

   This is a self-contained illuminated-manuscript visual system: it does NOT use the app's muted
   --cf-* SURFACE tokens. Each frame carries its own faction "hue ramp" (field/trim/ink/light), a
   universal skill palette, and a gold-leaf palette, all as card-frame-local custom properties so the
   markup can reference var(--cf-frame-*) the way the JSX reference used its inline `hue` object. Like
   deck-editor.css this is one cohesive FEATURE stylesheet (loaded globally in App.razor) rather than
   per-component scoped CSS — the frames + parts share these tokens and the parent frames style their
   part children. The component family is a flat-BEM block `cf-frame` (portrait card) with a sibling
   block `cf-frame-quest` (landscape plot) and a set of reusable part sub-blocks (`cf-frame-sigil`,
   `cf-frame-coin`, `cf-frame-shield`, `cf-frame-skill(s)`, `cf-frame-body`, `cf-frame-art`,
   `cf-frame-typeplate`, `cf-frame-corner`, `cf-frame-seal`, `cf-frame-loyalty`).

   Frames render at a fixed size (600x900 portrait / 900x630 quest) and are shrunk to fit via
   transform: scale() on a sized mount, so every offset below is an absolute 1:1 pixel value matching
   the reference.
   Fonts (Cinzel Decorative / IM Fell English[ SC] / Cinzel / Cormorant Garamond) are loaded in App.razor.

   TOKENS: the --cf-frame-* family is card-frame-LOCAL (defined here, like the old --fc-/--sk-/--gold-).
     --cf-frame-field/-trim/-ink/-light .... the per-faction hue ramp (overridden by .cf-fac-*)
     --cf-frame-gold-* ...................... the constant gold-leaf palette
     --cf-frame-skill-COMBAT-trim/-ink/-light (and guile/sorcery/faith) .. the per-struggle ramp; the
                                              -field stop links the GLOBAL --cf-struggle-COMBAT token
                                              (app.css notes the ramp was meant to match, and the four
                                              values are exactly equal)
   COLOURS: card frames are heavy on bespoke gold/foil/parchment/holo gradients with NO --cf-* token
   equivalent; those are kept literal and tagged `bespoke:` at the use site (see each gradient below).
   Z-INDEX: the small ints here (1–7) are LOCAL stacking inside a single frame's own stacking context
   (the .cf-frame / .cf-frame-quest root is positioned + transform: scale() + overflow: hidden, so it
   establishes its own context). They never cross surfaces, so they stay literal (commented at use).

   Contents — Cmd-F the ═══ banner text to jump (titles match the banners; no line numbers, which rot):
     · TOKENS                       skill (struggle) ramp · per-faction hue ramps
     · MOUNT / ROOT                 .cf-frame-mount · .cf-frame (600×900 portrait root)
     · SHARED PARTS                 reused by every frame:
         – Sigil · Cost coin + loyalty stripes · Power shield (heater)
         – Skill column · Body block · Art slot · Type plate
     · STANDARD ("Fusion")          the default portrait frame
     · ALT ART ("Royal Proof")      foil/holo portrait variant + organized-play seal
     · QUEST — ALT ART              landscape 900×630 plot sibling (.cf-frame-quest)
   ════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════ TOKENS ════════════════════════════════════════════════════════════ */

.cf-frame, .cf-frame-quest {
    /* gold-leaf palette (--cf-frame-gold-*) now lives in :root (app.css) so the live board's hand cards
       reuse the same constant ramp; the frames just inherit it here. */

    /* universal skill (struggle) palette — consistent across factions; Template D uses purple sorcery.
       The -field stop references the GLOBAL --cf-struggle-{X} token (values are exactly equal — see
       app.css); the -trim/-ink/-light stops are frame-local (no global equivalent). */
    --cf-frame-skill-combat-field: var(--cf-struggle-combat); --cf-frame-skill-combat-trim: #5a1305; --cf-frame-skill-combat-ink: #3a0a02; --cf-frame-skill-combat-light: #f8c8b8;
    --cf-frame-skill-guile-field: var(--cf-struggle-guile);   --cf-frame-skill-guile-trim: #163813;  --cf-frame-skill-guile-ink: #0a1f08;  --cf-frame-skill-guile-light: #c5d8b5;
    --cf-frame-skill-sorcery-field: var(--cf-struggle-sorcery);--cf-frame-skill-sorcery-trim: #2a103a;--cf-frame-skill-sorcery-ink: #180524; --cf-frame-skill-sorcery-light: #dbc0ee;
    --cf-frame-skill-faith-field: var(--cf-struggle-faith);   --cf-frame-skill-faith-trim: #0b2a52;  --cf-frame-skill-faith-ink: #0a1a35;   --cf-frame-skill-faith-light: #bccaee;

    /* default faction ramp (overridden by .cf-fac-*) — neutral stone fallback. bespoke faction hues. */
    --cf-frame-field: #5f513a; --cf-frame-trim: #3a3024; --cf-frame-ink: #221c14; --cf-frame-light: #d8cdb5;
}

/* faction hue ramps — slugs match Crownforge's FactionLabel.Slug(...). Shared by both the portrait
   card frames (.cf-frame) and the landscape quest frame (.cf-frame-quest). bespoke faction hues. */
.cf-frame.cf-fac-camelot,            .cf-frame-quest.cf-fac-camelot            { --cf-frame-field: #84150e; --cf-frame-trim: #3f0805; --cf-frame-ink: #260403; --cf-frame-light: #f0c8c0; }
.cf-frame.cf-fac-thewintercourt,     .cf-frame-quest.cf-fac-thewintercourt     { --cf-frame-field: #1d4a66; --cf-frame-trim: #0b283b; --cf-frame-ink: #0a1b25; --cf-frame-light: #bcdfee; }
.cf-frame.cf-fac-thesummercourt,     .cf-frame-quest.cf-fac-thesummercourt     { --cf-frame-field: #a8400e; --cf-frame-trim: #5a1d05; --cf-frame-ink: #3a1304; --cf-frame-light: #f8d3a4; }
.cf-frame.cf-fac-keepersoftheoldway, .cf-frame-quest.cf-fac-keepersoftheoldway { --cf-frame-field: #2d5226; --cf-frame-trim: #163013; --cf-frame-ink: #0e1f0a; --cf-frame-light: #c5d8b5; }
.cf-frame.cf-fac-saracenenvoy,       .cf-frame-quest.cf-fac-saracenenvoy       { --cf-frame-field: #9c7615; --cf-frame-trim: #523a05; --cf-frame-ink: #2b1f02; --cf-frame-light: #f1dc94; }
.cf-frame.cf-fac-theeleven,          .cf-frame-quest.cf-fac-theeleven          { --cf-frame-field: #1a2870; --cf-frame-trim: #0a1342; --cf-frame-ink: #080d28; --cf-frame-light: #b9c4eb; }
.cf-frame.cf-fac-lefayscircle,       .cf-frame-quest.cf-fac-lefayscircle       { --cf-frame-field: #4a1a66; --cf-frame-trim: #260a3a; --cf-frame-ink: #180524; --cf-frame-light: #dbc0ee; }
.cf-frame.cf-fac-neutral,            .cf-frame-quest.cf-fac-neutral            { --cf-frame-field: #5f513a; --cf-frame-trim: #3a3024; --cf-frame-ink: #221c14; --cf-frame-light: #d8cdb5; }

/* ════════════════════════════════════════════════════════════ MOUNT / ROOT ════════════════════════════════════════════════════════════ */

/* The mount reserves the *scaled* footprint so the scaled frame doesn't overflow its container.
   .cf-frame is absolutely positioned (out of flow), so the unscaled 600x900 reserves no space — the
   mount's calc() box and the child's scale() must both read --cf-scale so they never desync. */
.cf-frame-mount {
    position: relative;
    width: calc(600px * var(--cf-scale, 1));
    height: calc(900px * var(--cf-scale, 1));
    flex: 0 0 auto;
}

.cf-frame {
    position: absolute;
    top: 0;
    left: 0;
    width: 600px;
    height: 900px;
    overflow: hidden;
    border-radius: 6px;
    background: var(--cf-frame-ink);
    color: var(--cf-frame-light);
    font-family: 'IM Fell English', 'Cormorant Garamond', serif;
    transform: scale(var(--cf-scale, 1));
    transform-origin: top left;
}

/* ════════════════════════════════════════════════════════════ SHARED PARTS ════════════════════════════════════════════════════════════ */

/* ---- Sigil: gilt roundel + faction silhouette ---- */
.cf-frame-sigil { position: relative; }
.cf-frame-sigil__disc {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, var(--cf-frame-light), var(--cf-frame-field) 50%, var(--cf-frame-ink) 100%);
    border: 2px solid var(--cf-frame-gold-warm);
    box-shadow: inset 0 -4px 8px var(--cf-frame-ink), 0 3px 5px rgb(0 0 0 / 0.5);
}
.cf-frame-sigil__img {
    position: absolute;
    opacity: 0.95;
    filter: drop-shadow(0 1px 0 var(--cf-frame-ink));
}

/* ---- Cost coin + loyalty stripes ---- */
.cf-frame-coin { display: flex; flex-direction: column; align-items: center; }
.cf-frame-coin__disc { position: relative; }
.cf-frame-coin__face {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    /* bespoke: struck-gold coin gradient (4-stop ramp, no --cf-* token equal) */
    background: radial-gradient(circle at 38% 28%, #fff0bd 0%, #f4d97a 35%, #a06f24 80%, #4a2e0a 100%);
    border: 2px solid var(--cf-frame-ink);
    box-shadow: inset 0 -5px 10px rgb(0 0 0 / 0.45), 0 3px 5px rgb(0 0 0 / 0.55);
}
.cf-frame-coin__num {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: Cinzel, serif;
    font-weight: 800;
    color: #3a2510; /* bespoke: dark coin-ink (no token equal) */
    text-shadow: 0 1px 0 #fff5d6; /* bespoke: warm coin highlight */
}
.cf-frame-loyalty { display: flex; align-items: center; justify-content: center; gap: 5px; }
.cf-frame-loyalty__pip {
    width: 9px;
    /* bespoke: gilt loyalty-pip gradient (no --cf-* token equal) */
    background: linear-gradient(90deg, #a06f24 0%, #fff0bd 35%, #f4d97a 60%, #a06f24 100%);
    border: 0.6px solid var(--cf-frame-ink);
    border-radius: 1px;
    box-shadow: inset 0 0 0 0.5px rgb(255 245 214 / 0.4), 0 1px 2px color-mix(in srgb, var(--cf-frame-ink) 80%, transparent);
}

/* ---- Power shield (heater) ---- */
.cf-frame-shield { position: relative; filter: drop-shadow(0 5px 7px rgb(0 0 0 / 0.6)); }
.cf-frame-shield > svg { position: absolute; inset: 0; }
.cf-frame-shield__num {
    position: absolute;
    inset: 0;
    padding-top: 4%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: Cinzel, serif;
    font-weight: 800;
    color: var(--cf-frame-light);
    text-shadow: 0 1px 0 var(--cf-frame-ink), 0 0 6px var(--cf-frame-ink);
}

/* ---- Skill column (roundel badges, fixed 4-slot grid) ---- */
.cf-frame-skills { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; }
.cf-frame-skill {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.cf-frame-skill--combat  { --cf-frame-skill-field: var(--cf-frame-skill-combat-field);  --cf-frame-skill-trim: var(--cf-frame-skill-combat-trim);  --cf-frame-skill-ink: var(--cf-frame-skill-combat-ink);  --cf-frame-skill-light: var(--cf-frame-skill-combat-light);  --cf-frame-skill-icon-url: url('/img/struggles/combat.png'); }
.cf-frame-skill--guile   { --cf-frame-skill-field: var(--cf-frame-skill-guile-field);   --cf-frame-skill-trim: var(--cf-frame-skill-guile-trim);   --cf-frame-skill-ink: var(--cf-frame-skill-guile-ink);   --cf-frame-skill-light: var(--cf-frame-skill-guile-light);   --cf-frame-skill-icon-url: url('/img/struggles/guile.png'); }
.cf-frame-skill--sorcery { --cf-frame-skill-field: var(--cf-frame-skill-sorcery-field); --cf-frame-skill-trim: var(--cf-frame-skill-sorcery-trim); --cf-frame-skill-ink: var(--cf-frame-skill-sorcery-ink); --cf-frame-skill-light: var(--cf-frame-skill-sorcery-light); --cf-frame-skill-icon-url: url('/img/struggles/sorcery.png'); }
.cf-frame-skill--faith   { --cf-frame-skill-field: var(--cf-frame-skill-faith-field);   --cf-frame-skill-trim: var(--cf-frame-skill-faith-trim);   --cf-frame-skill-ink: var(--cf-frame-skill-faith-ink);   --cf-frame-skill-light: var(--cf-frame-skill-faith-light);   --cf-frame-skill-icon-url: url('/img/struggles/faith.png'); }
.cf-frame-skill--present {
    background: radial-gradient(circle at 35% 30%, var(--cf-frame-skill-light), var(--cf-frame-skill-field) 55%, var(--cf-frame-skill-ink) 100%);
    border: 1.5px solid var(--cf-frame-skill-ink);
    box-shadow: 0 3px 5px rgb(0 0 0 / 0.45);
    --cf-frame-skill-icon: var(--cf-frame-skill-light);
}
.cf-frame-skill--ghost {
    background: transparent;
    border: 1.2px dashed var(--cf-frame-skill-trim);
    opacity: 0.42;
    --cf-frame-skill-icon: var(--cf-frame-skill-trim);
}
.cf-frame-skill__icon {
    width: 24px;
    height: 24px;
    background-color: var(--cf-frame-skill-icon);
    -webkit-mask: var(--cf-frame-skill-icon-url) no-repeat center / contain;
    mask: var(--cf-frame-skill-icon-url) no-repeat center / contain;
}

/* ---- Body block: traits / keywords / divider / paragraphs ---- */
.cf-frame-body__traits {
    font-family: 'IM Fell English SC', serif;
    /* --cf-text-scale (default 1) lets a read surface enlarge the rules text WITHOUT growing the
       decorative frame (which rides --cf-scale): the popover/detail/inspect set it >1 so the traits
       become legible while the ornament stays compact. See the read-surface sheets. Base 13px (was 11)
       clears the ~10px legibility floor at the read scales — traits gate many interactions. */
    font-size: calc(13px * var(--cf-text-scale, 1));
    letter-spacing: 0.14em; /* was 0.3em — heavy tracking shears the line apart once downscaled */
    color: var(--cf-frame-trim);
    text-align: left;
    text-transform: uppercase;
}
.cf-frame-body__keywords {
    font-family: 'IM Fell English', serif;
    font-style: italic;
    font-size: calc(16px * var(--cf-text-scale, 1));
    color: var(--cf-frame-trim); /* was --cf-frame-field — that fill hue fails text contrast on light factions (Saracen 3.4:1) */
    margin-top: 4px;
}
.cf-frame-body__divider {
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--cf-frame-trim), transparent);
    margin: 8px 0;
}
.cf-frame-body__para {
    margin: 0;
    /* Cormorant Garamond leads now: a markedly higher x-height + steadier stroke than IM Fell English,
       which is what keeps the rules legible at the small effective sizes these frames are read at. The
       decorative IM Fell voice stays on the name/traits. Weight 500 = Cormorant's loaded body cut. */
    font-family: 'Cormorant Garamond', 'IM Fell English', serif;
    font-weight: 500;
    font-size: calc(18px * var(--cf-text-scale, 1));
    line-height: 1.30;
    color: #2a1c0c; /* bespoke: warm body-ink on parchment (no token equal) */
    text-wrap: pretty;
}
.cf-frame-body__para + .cf-frame-body__para { margin-top: 10px; }
.cf-frame-body__lead { font-weight: 600; font-style: italic; }

/* Dense bucket — a wordy card (CardBodyText adds .cf-frame-body--dense past a length threshold) steps the
   rules text down a notch so it still fits the fixed plate; short cards keep full size. Still rides
   --cf-text-scale, so a read surface enlarges dense text too, just from a lower base. */
.cf-frame-body--dense .cf-frame-body__para { font-size: calc(15.5px * var(--cf-text-scale, 1)); line-height: 1.30; /* match normal — kill the mixed leading across the dense boundary */ }
.cf-frame-body--dense .cf-frame-body__para + .cf-frame-body__para { margin-top: 7px; }
.cf-frame-body--dense .cf-frame-body__keywords { font-size: calc(14px * var(--cf-text-scale, 1)); margin-top: 3px; }

/* ---- Art slot (placeholder until real card art) ---- */
.cf-frame-art { position: absolute; inset: 0; overflow: hidden; }
.cf-frame-art__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cf-frame-art__ground {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(60% 50% at 50% 30%, color-mix(in srgb, var(--cf-frame-light) 40%, transparent) 0%, transparent 70%),
        radial-gradient(80% 80% at 50% 100%, var(--cf-frame-ink) 0%, var(--cf-frame-trim) 60%, var(--cf-frame-field) 100%);
}
.cf-frame-art__lines { position: absolute; inset: 0; width: 100%; height: 100%; }
.cf-frame-art__label {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'IM Fell English SC', serif;
    color: var(--cf-frame-light);
    font-size: 13px;
    letter-spacing: 0.42em;
    opacity: 0.65;
    text-transform: uppercase;
}

/* ---- Type plate (hex champlevé) ---- */
.cf-frame-typeplate { position: absolute; inset: 0; }
.cf-frame-typeplate > svg { width: 100%; height: 100%; }
.cf-frame-typeplate__label {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    font-family: Cinzel, serif;
    font-weight: 800;
    font-size: 14px;
    letter-spacing: 0.5em;
}
.cf-frame-typeplate__diamond { opacity: 0.7; }
.cf-frame-typeplate--enamel .cf-frame-typeplate__label { color: var(--cf-frame-light); text-shadow: 0 1px 0 var(--cf-frame-ink); }
.cf-frame-typeplate--gold .cf-frame-typeplate__label { color: #3a2510; text-shadow: 0 1px 0 var(--cf-frame-gold-pale); } /* bespoke: dark gold-plate ink */

/* ════════════════════════════════════════════════════════════ STANDARD ("Fusion") ════════════════════════════════════════════════════════════ */

.cf-frame__ground {
    position: absolute;
    inset: 0;
    background: radial-gradient(120% 100% at 50% 30%, var(--cf-frame-field) 0%, var(--cf-frame-trim) 55%, var(--cf-frame-ink) 100%);
}
.cf-frame__damask { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.18; }
.cf-frame__vignette {
    position: absolute;
    inset: 0;
    background: radial-gradient(120% 100% at 50% 50%, transparent 50%, var(--cf-frame-ink) 100%);
    pointer-events: none;
}
.cf-frame__orphrey {
    position: absolute;
    inset: 14px;
    border: 1px solid var(--cf-frame-gold-warm);
    box-shadow: inset 0 0 0 1px var(--cf-frame-ink), 0 0 0 1px color-mix(in srgb, var(--cf-frame-ink) 33%, transparent);
}
.cf-frame__hairline {
    position: absolute;
    inset: 22px;
    border: 0.6px solid color-mix(in srgb, var(--cf-frame-light) 33%, transparent);
}

/* header band */
.cf-frame__header { position: absolute; left: 30px; right: 30px; top: 30px; height: 92px; }
.cf-frame__band {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, var(--cf-frame-field) 0%, var(--cf-frame-trim) 100%);
    border-top: 2px solid var(--cf-frame-ink);
    border-bottom: 2px solid var(--cf-frame-ink);
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--cf-frame-light) 40%, transparent),
                inset 0 -2px 6px color-mix(in srgb, var(--cf-frame-ink) 80%, transparent);
}
.cf-frame__band-damask { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.18; }
.cf-frame__thread { position: absolute; left: 0; right: 0; height: 1px; background: var(--cf-frame-gold-warm); }
.cf-frame__thread--top { top: 4px; }
.cf-frame__thread--bottom { bottom: 4px; }

.cf-frame__sigil { position: absolute; left: 14px; top: 12px; width: 68px; height: 68px; }
.cf-frame__heading {
    position: absolute;
    inset: 0 96px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    color: var(--cf-frame-light);
    line-height: 1;
}
.cf-frame__name {
    font-family: 'Cinzel Decorative', serif;
    font-weight: 800;
    font-size: 26px;
    letter-spacing: 0.02em;
    text-shadow: 0 1px 0 var(--cf-frame-ink), 0 0 6px var(--cf-frame-ink);
    text-wrap: balance;
}
.cf-frame__name--long { font-size: 22px; }
.cf-frame__star { color: #f7d984; margin-right: 6px; } /* bespoke: bright gilt star (no token equal) */
.cf-frame__subtitle {
    font-family: 'IM Fell English', serif;
    font-style: italic;
    font-size: 13px;
    margin-top: 6px;
    opacity: 0.92;
}

.cf-frame__coin { position: absolute; right: 44px; top: 35px; width: 60px; }

/* oval reliquary art window */
.cf-frame__art-window { position: absolute; left: 36px; right: 36px; top: 140px; height: 480px; }
.cf-frame__art-molding {
    position: absolute;
    inset: 0;
    border-radius: 50% / 26%;
    /* bespoke: gold molding gradient (no --cf-* token equal) */
    background: linear-gradient(180deg, #f7e2a4 0%, #a06f24 50%, #f7d984 100%);
    box-shadow: inset 0 0 0 1.5px var(--cf-frame-ink), 0 8px 16px rgb(0 0 0 / 0.55);
}
.cf-frame__art-bevel {
    position: absolute;
    inset: 10px;
    border-radius: 50% / 26%;
    background: linear-gradient(180deg, var(--cf-frame-trim), var(--cf-frame-ink));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--cf-frame-light) 53%, transparent), inset 0 4px 10px var(--cf-frame-ink);
}
.cf-frame__art-clip { position: absolute; inset: 16px; border-radius: 50% / 26%; overflow: hidden; }
.cf-frame__acanthus { position: absolute; filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.5)); }
.cf-frame__acanthus--left { left: -14px; top: calc(50% - 28px); }
.cf-frame__acanthus--right { right: -14px; top: calc(50% - 28px); }

.cf-frame__shield { position: absolute; right: 46px; top: 588px; width: 60px; height: 80px; z-index: 2; /* local: shield breaches the oval art window */ }

/* champlevé rules plate */
.cf-frame__plate { position: absolute; inset: 630px 34px 60px; }
.cf-frame__plate-enamel {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, var(--cf-frame-trim), var(--cf-frame-ink));
    box-shadow: inset 0 0 0 1.5px var(--cf-frame-gold-warm), inset 0 0 0 3px var(--cf-frame-ink), 0 4px 8px rgb(0 0 0 / 0.5);
}
.cf-frame__plate-parch {
    position: absolute;
    inset: 8px;
    /* bespoke: parchment gradient (no --cf-* token equal) */
    background: linear-gradient(180deg, #f4e8c2 0%, #e6d4a3 100%);
    box-shadow: inset 0 0 0 0.5px color-mix(in srgb, var(--cf-frame-trim) 53%, transparent);
}
.cf-frame__parch-noise {
    position: absolute;
    inset: 8px;
    width: calc(100% - 16px);
    height: calc(100% - 16px);
    mix-blend-mode: multiply;
    opacity: 0.4;
    pointer-events: none;
}
.cf-frame__plate-rail {
    position: absolute;
    left: 12px;
    top: 14px;
    bottom: 14px;
    width: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.cf-frame__plate-body { position: absolute; inset: 16px 18px 16px 100px; overflow: hidden; /* safety: clip at the plate edge rather than spill over the border/type plate (the dense bucket keeps realistic cards inside) */ }

.cf-frame__type { position: absolute; left: 130px; right: 130px; bottom: 26px; height: 36px; filter: drop-shadow(0 3px 4px rgb(0 0 0 / 0.5)); }

/* ════════════════════════════════════════════════════════════ ALT ART ("Royal Proof") ════════════════════════════════════════════════════════════ */

.cf-frame__holo {
    position: absolute;
    inset: 0;
    mix-blend-mode: color-dodge;
    opacity: 0.06;
    pointer-events: none;
    /* bespoke: prismatic holo conic-gradient (foil treatment, no --cf-* token equal) */
    background: conic-gradient(from 0deg at 50% 40%, #ff4d4d, #ffd24d, #4dff88, #4dd2ff, #b14dff, #ff4d4d);
}
.cf-frame__scrim-top {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 230px;
    pointer-events: none;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--cf-frame-ink) 95%, transparent) 0%,
        color-mix(in srgb, var(--cf-frame-ink) 67%, transparent) 42%,
        transparent 100%);
}
.cf-frame__scrim-bottom {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 380px;
    pointer-events: none;
    background: linear-gradient(0deg,
        color-mix(in srgb, var(--cf-frame-ink) 97%, transparent) 0%,
        color-mix(in srgb, var(--cf-frame-ink) 88%, transparent) 40%,
        color-mix(in srgb, var(--cf-frame-ink) 33%, transparent) 78%,
        transparent 100%);
}
.cf-frame__gilt {
    position: absolute;
    inset: 0;
    border-radius: 6px;
    pointer-events: none;
    z-index: 7; /* local: gilt edge above the painting + scrims, below nothing in-card */
    box-shadow:
        inset 0 0 0 3px var(--cf-frame-gold-mid),
        inset 0 0 0 5px var(--cf-frame-ink),
        inset 0 0 0 6px color-mix(in srgb, var(--cf-frame-gold-bright) 60%, transparent),
        inset 0 0 26px color-mix(in srgb, var(--cf-frame-gold-dark) 33%, transparent);
}
.cf-frame__gilt-inner {
    position: absolute;
    inset: 16px;
    border: 0.6px solid color-mix(in srgb, var(--cf-frame-gold-warm) 40%, transparent);
    border-radius: 3px;
    pointer-events: none;
    z-index: 7; /* local: pairs with the gilt edge */
}
.cf-frame-corner { position: absolute; filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6)); pointer-events: none; z-index: 6; /* local: gold-leaf corners over the painting, under the gilt edge */ }
.cf-frame-corner--tl { left: 8px; top: 8px; }
.cf-frame-corner--tr { right: 8px; top: 8px; }
.cf-frame-corner--bl { left: 8px; bottom: 8px; }
.cf-frame-corner--br { right: 8px; bottom: 8px; }

/* Alt raises the sigil + coin proud of the painting with a slightly heavier outer shadow. */
.cf-frame--alt .cf-frame-sigil__disc { box-shadow: inset 0 -4px 8px var(--cf-frame-ink), 0 3px 6px rgb(0 0 0 / 0.6); }
.cf-frame--alt .cf-frame-coin__face { box-shadow: inset 0 -5px 10px rgb(0 0 0 / 0.45), 0 3px 6px rgb(0 0 0 / 0.6); }

.cf-frame__alt-sigil { position: absolute; left: 38px; top: 36px; width: 66px; height: 66px; z-index: 5; /* local: header floats over the art */ }
.cf-frame__alt-coin { position: absolute; right: 40px; top: 36px; width: 64px; z-index: 5; /* local: header floats over the art */ }

.cf-frame__cartouche {
    position: absolute;
    left: 116px;
    right: 116px;
    top: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    z-index: 5; /* local: header floats over the art */
}
.cf-frame__cartouche-plate {
    position: relative;
    padding: 8px 14px 9px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--cf-frame-trim) 80%, transparent), color-mix(in srgb, var(--cf-frame-ink) 87%, transparent));
    border: 1px solid var(--cf-frame-gold-warm);
    border-radius: 3px;
    box-shadow: inset 0 0 0 2px var(--cf-frame-ink), inset 0 1px 0 color-mix(in srgb, var(--cf-frame-gold-warm) 33%, transparent), 0 3px 8px rgb(0 0 0 / 0.55);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
.cf-frame__alt-name {
    font-family: 'Cinzel Decorative', serif;
    font-weight: 900;
    font-size: 27px;
    line-height: 1;
    letter-spacing: 0.02em;
    color: var(--cf-frame-gold-lite);
    text-shadow: 0 1px 0 var(--cf-frame-ink), 0 0 8px var(--cf-frame-ink);
    text-wrap: balance;
}
.cf-frame__alt-name--long { font-size: 23px; }
.cf-frame__alt-star { color: var(--cf-frame-gold-bright); margin-right: 6px; }
.cf-frame__alt-subtitle {
    font-family: 'IM Fell English', serif;
    font-style: italic;
    font-size: 13px;
    margin-top: 5px;
    color: var(--cf-frame-light);
    opacity: 0.95;
}

.cf-frame__alt-shield { position: absolute; right: 46px; top: 600px; width: 64px; height: 85px; z-index: 5; /* local: floats over the text scrim */ }

/* organized-play seal */
.cf-frame-seal { position: absolute; left: 40px; top: 540px; width: 84px; display: flex; flex-direction: column; align-items: center; z-index: 5; /* local: floats over the painting */ }
.cf-frame-seal__disc { position: relative; width: 76px; height: 76px; filter: drop-shadow(0 4px 7px rgb(0 0 0 / 0.6)); }
.cf-frame-seal__halo {
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--cf-frame-gold-bright) 33%, transparent) 0%, transparent 68%);
}
.cf-frame-seal__medallion {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(from 210deg, var(--cf-frame-gold-lite), var(--cf-frame-gold-mid), var(--cf-frame-gold-pale), var(--cf-frame-gold-dark), var(--cf-frame-gold-lite));
    border: 2px solid var(--cf-frame-ink);
    box-shadow: inset 0 0 0 3px var(--cf-frame-gold-dark), inset 0 2px 5px var(--cf-frame-gold-pale);
}
.cf-frame-seal__ring, .cf-frame-seal__crown { position: absolute; inset: 0; width: 76px; height: 76px; }
.cf-frame-seal__serial {
    margin-top: 6px;
    padding: 2px 9px;
    background: linear-gradient(180deg, var(--cf-frame-trim), var(--cf-frame-ink));
    border: 1px solid var(--cf-frame-gold-warm);
    border-radius: 2px;
    font-family: Cinzel, serif;
    font-weight: 700;
    font-size: 11px;
    letter-spacing: 0.12em;
    color: var(--cf-frame-gold-lite);
    white-space: nowrap;
    box-shadow: 0 2px 4px rgb(0 0 0 / 0.5);
}

/* translucent vellum rules scrim */
.cf-frame__scrim-rules { position: absolute; inset: 686px 30px 64px; z-index: 3; /* local: rules scrim above the painting, below the header (5) */ }
.cf-frame__scrim-thread { position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: linear-gradient(90deg, transparent, var(--cf-frame-gold-bright), transparent); }
.cf-frame__scrim-vellum {
    position: absolute;
    inset: 0;
    /* bespoke: translucent vellum gradient (no --cf-* token equal) */
    background: linear-gradient(180deg, rgb(244 232 194 / 0.93) 0%, rgb(230 212 163 / 0.9) 100%);
    box-shadow: inset 0 0 0 1px var(--cf-frame-gold-warm), 0 -2px 10px rgb(0 0 0 / 0.4);
    border-radius: 2px;
}
.cf-frame__scrim-noise {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    mix-blend-mode: multiply;
    opacity: 0.32;
    border-radius: 2px;
    pointer-events: none;
}
.cf-frame__scrim-rail {
    position: absolute;
    left: 12px;
    top: 14px;
    bottom: 14px;
    width: 70px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.cf-frame__scrim-divider {
    position: absolute;
    left: 92px;
    top: 14px;
    bottom: 14px;
    width: 1px;
    background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--cf-frame-trim) 53%, transparent), transparent);
}
.cf-frame__scrim-body { position: absolute; inset: 15px 18px 15px 104px; overflow: hidden; /* see .cf-frame__plate-body */ }

.cf-frame__alt-type { position: absolute; left: 130px; right: 130px; bottom: 26px; height: 36px; filter: drop-shadow(0 3px 5px rgb(0 0 0 / 0.6)); z-index: 5; /* local: type plate over the scrim */ }

/* ════════════════════════════════════════════════════════════ QUEST — ALT ART ("Royal Proof", landscape) ════════════════════════════════════════════════════════════ */
/* Plot-card sibling of the Alt frame: a landscape 900×630 quest card. Full-bleed art, vellum rules
   scrim, gilt edge + gold-leaf corners + organized-play seal — carrying the four plot stats the board
   reads off a revealed quest. Reuses the token layer (--cf-frame-*) and the shared parts (CardSigil,
   CardGoldCorner, RoyalProofSeal, CardBodyText, CardTypePlate). Like the portrait frames, it renders
   at a fixed size shrunk via transform: scale() on a sized mount. From template-quest-alt.jsx. */

.cf-frame-quest-mount {
    position: relative;
    width: calc(900px * var(--cf-scale, 1));
    height: calc(630px * var(--cf-scale, 1));
    flex: 0 0 auto;
}
.cf-frame-quest {
    position: absolute;
    top: 0;
    left: 0;
    width: 900px;
    height: 630px;
    overflow: hidden;
    border-radius: 6px;
    background: var(--cf-frame-ink);
    color: var(--cf-frame-light);
    font-family: 'IM Fell English', 'Cormorant Garamond', serif;
    transform: scale(var(--cf-scale, 1));
    transform-origin: top left;
}

/* prismatic holo + legibility scrims (mirror the Alt frame's, sized for landscape) */
.cf-frame-quest__holo {
    position: absolute;
    inset: 0;
    mix-blend-mode: color-dodge;
    opacity: 0.06;
    pointer-events: none;
    /* bespoke: prismatic holo conic-gradient (foil treatment, no --cf-* token equal) */
    background: conic-gradient(from 0deg at 50% 40%, #ff4d4d, #ffd24d, #4dff88, #4dd2ff, #b14dff, #ff4d4d);
}
.cf-frame-quest__scrim-top {
    position: absolute;
    left: 0; right: 0; top: 0;
    height: 190px;
    pointer-events: none;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--cf-frame-ink) 95%, transparent) 0%,
        color-mix(in srgb, var(--cf-frame-ink) 60%, transparent) 46%,
        transparent 100%);
}
.cf-frame-quest__scrim-bottom {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 300px;
    pointer-events: none;
    background: linear-gradient(0deg,
        color-mix(in srgb, var(--cf-frame-ink) 97%, transparent) 0%,
        color-mix(in srgb, var(--cf-frame-ink) 85%, transparent) 42%,
        color-mix(in srgb, var(--cf-frame-ink) 27%, transparent) 80%,
        transparent 100%);
}
/* (left/right edge scrims removed — the stat rail carries its own dark panel for legibility) */

/* gilt double edge + inner keyline (identical treatment to the Alt frame) */
.cf-frame-quest__gilt {
    position: absolute;
    inset: 0;
    border-radius: 6px;
    pointer-events: none;
    z-index: 7; /* local: gilt edge above the painting + scrims */
    box-shadow:
        inset 0 0 0 3px var(--cf-frame-gold-mid),
        inset 0 0 0 5px var(--cf-frame-ink),
        inset 0 0 0 6px color-mix(in srgb, var(--cf-frame-gold-bright) 60%, transparent),
        inset 0 0 26px color-mix(in srgb, var(--cf-frame-gold-dark) 33%, transparent);
}
.cf-frame-quest__gilt-inner {
    position: absolute;
    inset: 16px;
    border: 0.6px solid color-mix(in srgb, var(--cf-frame-gold-warm) 40%, transparent);
    border-radius: 3px;
    pointer-events: none;
    z-index: 7; /* local: pairs with the gilt edge */
}

/* LEFT STAT RAIL — sigil + four plot yields + struggle icons, gathered on one edge so the pile
   stays readable when fanned. A self-contained gilt-edged panel over the full-bleed art. */
.cf-frame-quest__rail {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 156px;
    z-index: 5; /* local: stat rail over the painting */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    padding: 20px 0 18px;
}
.cf-frame-quest__rail-panel {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--cf-frame-ink) 90%, transparent) 0%,
        color-mix(in srgb, var(--cf-frame-trim) 86%, transparent) 100%);
    border-right: 2px solid var(--cf-frame-gold-mid);
    box-shadow:
        inset -1px 0 0 color-mix(in srgb, var(--cf-frame-gold-bright) 55%, transparent),
        2px 0 14px rgb(0 0 0 / 0.5);
}
.cf-frame-quest__rail-sigil { position: relative; z-index: 1; /* local: rail content above its own panel */ }
.cf-frame-quest__rail-stats {
    position: relative;
    z-index: 1; /* local: rail content above its own panel */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}
.cf-frame-quest__rail-skills {
    position: relative;
    z-index: 1; /* local: rail content above its own panel */
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    gap: 8px;
    max-width: 124px;
}
.cf-frame-quest__rail-skills .cf-frame-skill { width: 30px; height: 30px; }
.cf-frame-quest__rail-skills .cf-frame-skill__icon { width: 19px; height: 19px; }
.cf-frame-quest__seal { position: absolute; right: 24px; top: 22px; z-index: 5; display: flex; flex-direction: column; align-items: center; /* local: seal over the painting */ }
/* The reused RoyalProofSeal owns absolute placement for the portrait frame; in the quest rail it sits
   in-flow inside .cf-frame-quest__seal, so neutralise that placement. */
.cf-frame-quest .cf-frame-seal { position: static; left: auto; top: auto; width: auto; }

/* plot stat — struck disc + uppercase label ribbon */
.cf-frame-quest__stat { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.cf-frame-quest__stat-disc {
    position: relative;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: Cinzel, serif;
    font-weight: 800;
    font-size: 28px;
    box-shadow: inset 0 -5px 10px rgb(0 0 0 / 0.4), 0 3px 6px rgb(0 0 0 / 0.6);
    /* enamel (faction) treatment — Initiative / Claim / Reserve */
    background: radial-gradient(circle at 35% 30%, var(--cf-frame-light), var(--cf-frame-field) 52%, var(--cf-frame-ink) 100%);
    border: 2px solid var(--cf-frame-gold-warm);
    color: var(--cf-frame-gold-lite);
    text-shadow: 0 1px 0 var(--cf-frame-ink), 0 0 6px var(--cf-frame-ink);
}
.cf-frame-quest__stat-disc--gold {
    /* bespoke: struck-gold coin gradient — Income (no --cf-* token equal) */
    background: radial-gradient(circle at 38% 28%, #fff0bd 0%, #f4d97a 35%, #a06f24 80%, #4a2e0a 100%);
    border: 2px solid var(--cf-frame-ink);
    color: #3a2510; /* bespoke: dark coin-ink */
    text-shadow: 0 1px 0 #fff5d6; /* bespoke: warm coin highlight */
}
.cf-frame-quest__stat-label {
    padding: 2px 8px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--cf-frame-trim) 93%, transparent), color-mix(in srgb, var(--cf-frame-ink) 93%, transparent));
    border: 1px solid color-mix(in srgb, var(--cf-frame-gold-warm) 60%, transparent);
    border-radius: 2px;
    font-family: 'IM Fell English SC', serif;
    font-size: 10px;
    letter-spacing: 0.2em;
    color: var(--cf-frame-gold-lite);
    text-transform: uppercase;
    white-space: nowrap;
}

/* header — name cartouche across the top of the art, right of the stat rail */
.cf-frame-quest__header {
    position: absolute;
    left: 176px; right: 24px; top: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    z-index: 5; /* local: header over the painting */
}
.cf-frame-quest__cartouche {
    position: relative;
    max-width: 540px;
    padding: 8px 22px 9px;
    text-align: center;
    background: linear-gradient(180deg, color-mix(in srgb, var(--cf-frame-trim) 80%, transparent), color-mix(in srgb, var(--cf-frame-ink) 87%, transparent));
    border: 1px solid var(--cf-frame-gold-warm);
    border-radius: 3px;
    box-shadow: inset 0 0 0 2px var(--cf-frame-ink), inset 0 1px 0 color-mix(in srgb, var(--cf-frame-gold-warm) 33%, transparent), 0 3px 8px rgb(0 0 0 / 0.55);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
.cf-frame-quest__name {
    font-family: 'Cinzel Decorative', serif;
    font-weight: 900;
    font-size: 31px;
    line-height: 1;
    letter-spacing: 0.02em;
    color: var(--cf-frame-gold-lite);
    text-shadow: 0 1px 0 var(--cf-frame-ink), 0 0 8px var(--cf-frame-ink);
    text-wrap: balance;
}
.cf-frame-quest__name--long { font-size: 26px; }
.cf-frame-quest__subtitle {
    font-family: 'IM Fell English', serif;
    font-style: italic;
    font-size: 14px;
    margin-top: 5px;
    color: var(--cf-frame-light);
    opacity: 0.95;
}

/* rules — vellum scrim between the rails: traits + struggle rail · divider · body */
.cf-frame-quest__rules { position: absolute; inset: 396px 24px 62px 176px; z-index: 3; /* local: rules scrim above the painting, below the header (5) */ }
.cf-frame-quest__rules-thread { position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: linear-gradient(90deg, transparent, var(--cf-frame-gold-bright), transparent); }
.cf-frame-quest__rules-vellum {
    position: absolute;
    inset: 0;
    /* bespoke: translucent vellum gradient (no --cf-* token equal) */
    background: linear-gradient(180deg, rgb(244 232 194 / 0.94) 0%, rgb(230 212 163 / 0.91) 100%);
    box-shadow: inset 0 0 0 1px var(--cf-frame-gold-warm), 0 -2px 10px rgb(0 0 0 / 0.4);
    border-radius: 2px;
}
.cf-frame-quest__rules-noise {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    mix-blend-mode: multiply;
    opacity: 0.3;
    border-radius: 2px;
    pointer-events: none;
}
.cf-frame-quest__rules-head {
    position: absolute;
    left: 22px; right: 22px; top: 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.cf-frame-quest__traits {
    font-family: 'IM Fell English SC', serif;
    font-size: calc(13px * var(--cf-text-scale, 1)); /* was 12 — matches portrait traits, clears the floor */
    letter-spacing: 0.14em; /* was 0.3em — see .cf-frame-body__traits */
    color: var(--cf-frame-trim);
    text-transform: uppercase;
}
.cf-frame-quest__rules-divider { position: absolute; left: 22px; right: 22px; top: 48px; height: 1px; background: linear-gradient(90deg, transparent, var(--cf-frame-trim), transparent); }
.cf-frame-quest__rules-body { position: absolute; inset: 60px 24px 18px; overflow: hidden; /* see .cf-frame__plate-body */ }
.cf-frame-quest__rules-body--flush { top: 16px; }

/* gold champlevé type plate */
.cf-frame-quest__type { position: absolute; left: 336px; right: 156px; bottom: 20px; height: 34px; filter: drop-shadow(0 3px 5px rgb(0 0 0 / 0.6)); z-index: 5; /* local: type plate over the painting */ }
