/*
 * FIELDSETS-CHAR.CSS - Character context theming
 * Sets local --accent, --primary, --secondary from --char-* variables
 * All children inherit these automatically via CSS cascade
 * Part of fieldsets split - see 009_FIELDSET_CSS_SPLIT.md
 */

/* ═══════════════════════════════════════════════════════════════════
   CHARACTER CONTEXT - Sets local accent variables
   ═══════════════════════════════════════════════════════════════════ */

.fieldset--char,
.cf-character,
.cf-char-row,
.cf-identity,
.character-fieldset {
    --accent: var(--neutral);  /* neutral grey (was --outfit-accent — neutralized) */
    --primary: var(--slot-1);
    --secondary: var(--slot-2);
}

/* ═══════════════════════════════════════════════════════════════════
   CHARACTER 3-COLOR GRADIENT BACKGROUND
   ═══════════════════════════════════════════════════════════════════ */

.fieldset--char {
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 20%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 15%, var(--card-base)) 50%,
        var(--card-base) 100%
    );
    border-color: rgba(255, 255, 255, 0.08);
}

.fieldset--char:hover {
    border-color: rgba(255, 255, 255, 0.1);
}

.fieldset--char h2 {
    /* Grey — base rule covers it; explicit here so future readers see
       this fieldset opted out of slot tinting on purpose. */
    color: var(--ui-text-medium);
}

/* ═══════════════════════════════════════════════════════════════════
   CARD FIELDSET - Chub V2 raw fields. Mirrors .fieldset--char's
   3-stop slot gradient (hair → eyes → tops) so it reads as part
   of the same character family rather than a foreign neutral panel.
   The titles/labels/icons inside still route through --ui-text-*, so
   readability holds even when the slot colors go dark.
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   CHUB CARD TAGS — display-only categorization bubbles in a full-width
   row below the avatar / mini-stack / description, above the card tabs.
   Mirrors .ckpt-popover__tag styling so the bubble look reads
   consistently with the dropdown hover popover.
   ═══════════════════════════════════════════════════════════════════ */

.chub-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 0.6rem;
}

.chub-tag {
    display: inline-block;
    font-size: 0.6rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 2px 6px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--primary) 18%, rgba(255, 255, 255, 0.06));
    color: color-mix(in srgb, var(--primary) 40%, rgba(255, 255, 255, 0.7));
    border: 1px solid color-mix(in srgb, var(--primary) 15%, transparent);
    white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════
   CARD TABS — horizontal strip at the bottom of the character
   fieldset. Inactive tabs sit flat on the fieldset surface; the
   active tab picks up the same slot-2/slot-1 bevel as the .card-pane
   below it and lifts its bottom edge by 1px to merge into the pane,
   so the selected tab visually IS an extension of the bevel.
   ═══════════════════════════════════════════════════════════════════ */

.card-tab-strip {
    display: flex;
    gap: 2px;
    margin-top: 0.6rem;
    position: relative;
    z-index: 2;
}

.card-tab-btn {
    flex: 1;
    min-width: 0;
    padding: 0.5rem 0.4rem;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-bottom: none;
    border-radius: 6px 6px 0 0;
    background: rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.45);
    font-family: inherit;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: color 0.12s ease, background 0.12s ease;
}

.card-tab-btn:hover {
    color: var(--ui-text-strong);
    background: rgba(0, 0, 0, 0.3);
}

.card-tab-btn.active {
    background: linear-gradient(
        225deg,
        color-mix(in srgb, var(--secondary) 16%, var(--card-base)) 0%,
        color-mix(in srgb, var(--primary) 16%, var(--card-base)) 100%
    );
    color: var(--ui-text-strong);
    box-shadow:
        inset 0 3px 6px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(0, 0, 0, 0.3);
    /* Lift over the pane's top border so the tab merges into the
       bevel below it — classic tabs-meet-pane trick. */
    margin-bottom: -1px;
    padding-bottom: calc(0.5rem + 1px);
    position: relative;
    z-index: 3;
}

/* Bevel pane — same recipe as .llm-prompt-block / .field--bevel.
   Holds all 6 textareas; the .visible one renders, others are hidden
   so the form still posts every Chub V2 field on save. */
.card-pane {
    position: relative;
    padding: 0.5rem 0.6rem 0.6rem;
    border-radius: 0 6px 6px 6px;
    background: linear-gradient(
        225deg,
        color-mix(in srgb, var(--secondary) 16%, var(--card-base)) 0%,
        color-mix(in srgb, var(--primary) 16%, var(--card-base)) 100%
    );
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        inset 0 3px 6px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(0, 0, 0, 0.3),
        0 1px 0 rgba(255, 255, 255, 0.04);
}

/* Rendered HTML content (chat_markdown server-side) — read-only.
   Hidden inputs alongside roundtrip the raw value on form save;
   re-import a card to update the prose. */
.card-pane-render {
    display: none;
    min-height: 100px;
    color: rgba(255, 255, 255, 0.88);
    font-family: inherit;
    font-size: 0.8rem;
    line-height: 1.45;
    word-wrap: break-word;
    white-space: normal;
}

.card-pane-render.visible {
    display: block;
}

/* Field title above the rendered prose — same uppercase grey label as
   ACTIVITY / DESCRIPTION in .field--bevel above. Ties each pane to
   its tab visually. */
.card-pane-render > label {
    display: block;
    margin: 0 0 0.4rem 0;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ui-text-soft);
}

/* Match .chat-msg em / strong / .chat-speech from chat-input.css so a
   card audit reads with the same voice tiers as the rendered chat —
   narration italic + slot-2 tint, speech slot-tinted heavier, bold
   just heavier weight (no color competition with narration). */
.card-pane-render em {
    font-style: italic;
    color: color-mix(in srgb, var(--secondary) 30%, currentColor);
}

.card-pane-render strong {
    font-weight: 600;
}

.card-pane-render .chat-speech {
    color: color-mix(in srgb, var(--secondary) 65%, currentColor);
}

/* ═══════════════════════════════════════════════════════════════════
   ENTITY NAME DISPLAY (static name in shoe cards)
   ═══════════════════════════════════════════════════════════════════ */

.fieldset--char .entity-name-display {
    padding: 0.5rem 0.75rem;
    background: linear-gradient(135deg, 
        color-mix(in srgb, var(--primary) 20%, rgba(0, 0, 0, 0.4)) 0%,
        color-mix(in srgb, var(--primary) 10%, rgba(0, 0, 0, 0.3)) 100%
    );
    border: 1px solid color-mix(in srgb, var(--primary) 40%, transparent);
    border-radius: 4px;
}

.fieldset--char .entity-name-static {
    color: color-mix(in srgb, var(--primary) 80%, white);
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
}

/* ═══════════════════════════════════════════════════════════════════
   CHARACTER NAME ROW - Recessed chrome tray, mirrors .chat-model-row.
   Name input + pawn/identity toggles ride in the same dark housing so
   the row reads as a single control panel instead of a label+input
   with stray buttons beside it.
   ═══════════════════════════════════════════════════════════════════ */

.char-name-row {
    display: flex;
    align-items: stretch;
    gap: 2px;
    padding: 3px;
    margin-bottom: 0.5rem;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--accent) 4%, rgba(0, 0, 0, 0.18)) 0%,
        color-mix(in srgb, var(--accent) 4%, rgba(0, 0, 0, 0.28)) 100%);
    border-radius: 7px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.04);
}

.char-name-row .character-name-input {
    flex: 1;
    min-width: 0;
    height: 28px;
    padding: 0 8px;
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 4px;
    color: #c0c0c0;
    font-family: inherit;
    font-size: 0.85rem;
    line-height: 1.2;
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}

.char-name-row .character-name-input::placeholder {
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.8rem;
}

.char-name-row .character-name-input:focus {
    border-color: color-mix(in srgb, var(--accent) 55%, transparent);
    box-shadow: inset 0 0 6px color-mix(in srgb, var(--accent) 20%, transparent);
    color: color-mix(in srgb, var(--accent) 60%, white);
}

/* Toggles inside the recessed row keep their base drawer-btn look —
   card-base bg already blends with the dark tray chrome, and the
   :hover / .active states from .fs-toggle-btn carry the slot glow. */
.char-name-row .fs-toggle-btn {
    align-self: center;
}

/* ═══════════════════════════════════════════════════════════════════
   BUTTON TRAY - Small recessed chrome for single buttons sitting in
   fieldset h2s (voice toggle, env toggle). Same recipe as
   .char-name-row / .chat-model-row, scoped for one-button houses.
   Accent comes from the surrounding fieldset's --accent.
   ═══════════════════════════════════════════════════════════════════ */

.fs-btn-tray {
    display: inline-flex;
    align-items: stretch;
    gap: 2px;
    padding: 3px;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--accent) 4%, rgba(0, 0, 0, 0.18)) 0%,
        color-mix(in srgb, var(--accent) 4%, rgba(0, 0, 0, 0.28)) 100%);
    border-radius: 7px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.04);
}

.fs-btn-tray--right {
    margin-left: auto;
}

/* ═══════════════════════════════════════════════════════════════════
   FIELDSET TOGGLE BUTTONS - icon-only, 32x28 to match chat-deck-btn /
   transport-bar--main drawer-btn dimensions. In field-rows they align
   to the input baseline via flex-end.
   ═══════════════════════════════════════════════════════════════════ */

.fs-toggle-btn,
/* Anchor variants (e.g. fs-toggle-btn--export = download link) — browser-default
   a:link / a:visited (spec 0,1,1) outranks the bare .fs-toggle-btn (0,1,0)
   and the icon ends up painted with the browser link color (blue/purple).
   Add :link/:visited at spec 0,2,0 to win. */
a.fs-toggle-btn:link,
a.fs-toggle-btn:visited {
    width: 32px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    border: 1px solid transparent;
    border-radius: 4px;
    background:
        linear-gradient(180deg,
            rgba(255, 255, 255, 0.06) 0%,
            rgba(0, 0, 0, 0.1) 100%),
        var(--card-base);
    color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: all 0.12s ease;
    font: inherit;
    flex-shrink: 0;
    text-decoration: none;
}

/* In a field-row, buttons sit at the input's baseline (not the label's) */
.field-row > .fs-toggle-btn {
    align-self: flex-end;
}

.fs-toggle-btn:hover {
    background:
        linear-gradient(180deg,
            rgba(255, 255, 255, 0.1) 0%,
            rgba(0, 0, 0, 0.05) 100%),
        var(--card-base);
    /* Grey icon — --accent can resolve to a near-black slot. Border + glow
       keep the accent. */
    color: var(--ui-text-strong);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
    box-shadow:
        0 0 8px color-mix(in srgb, var(--accent) 20%, transparent);
}

.fs-toggle-btn:active {
    transform: translateY(1px);
    background:
        linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
        var(--card-base);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

.fs-toggle-btn.active {
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--accent) 22%, rgba(255, 255, 255, 0.06)) 0%,
            color-mix(in srgb, var(--accent) 12%, rgba(0, 0, 0, 0.1)) 100%),
        var(--card-base);
    border-color: color-mix(in srgb, var(--accent) 45%, transparent);
    /* Grey icon, same reason as :hover. */
    color: var(--ui-text-strong);
    box-shadow:
        0 0 10px color-mix(in srgb, var(--accent) 30%, transparent),
        inset 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
}

.fs-toggle-btn-icon {
    font-size: 0.95rem;
    line-height: 1;
    font-weight: 700;
    filter: brightness(1.4);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.fs-toggle-btn-icon svg {
    display: block;
}

/* Pawn (Scene) button — uses hair slot (slot-1) as accent */
.fs-toggle-btn--enable {
    --accent: var(--primary);
}

.fs-toggle-btn--identity .fs-toggle-btn-icon {
    font-family: Georgia, "Times New Roman", serif;
    font-style: italic;
    font-size: 1rem;
}

/* Greyed-out fields when locked */
.identity-field.identity-locked {
    opacity: 0.35;
    pointer-events: none;
}

/* Character disabled — grey out fields, not titles or toggle buttons */
.character-disabled .fieldset-2col,
.character-disabled .builder-tags {
    opacity: 0.35;
    pointer-events: none;
}

.character-disabled > .char-name-row .character-name-input {
    opacity: 0.35;
    pointer-events: none;
}

/* Identity button dims (but stays clickable) when character disabled —
   identity toggle is moot without a character in scene. */
.character-disabled .fs-toggle-btn--identity {
    opacity: 0.5;
}

/* Generation / crystallize disable — surgical, per the deck philosophy.
   Row containers, labels, swatches and the management/toggle buttons
   stay fully lit; only the controls whose value feeds the next scene go
   inert — that's the single "system busy" read, not a washed panel.
   Editing them mid-flight is meaningless anyway (v10: the in-flight
   scene already snapshotted its params). `.generating` covers image-gen
   + chat-send (also dims chat-input via chat-input.css); `.crystallizing`
   is the reset-time variant. Read-only chub-card panes take the same
   soft grey as the frozen fields (rule at the end of this block) but
   stay readable and their tab strip still switches — prose to read
   during the wait, just joined to the busy read instead of stark-lit.
   The scene-control surface and chat deck are locked down surgically
   in their own stylesheets, not here.
   .fieldset-2col / .builder-tags were dropped from this rule — those
   classes no longer live inside #element-builder (bubbles moved to the
   chat overlay), so the old selectors were dead. opacity is the tuning
   knob. */

/* Identity / mood / activity / description: only the generation-input
   fields freeze. Select2 swaps <select> for .select2-container — cover
   both pre/post-init. The `I` identity toggle is a button, not in this
   list, so it stays live: a discrete state toggle that doesn't touch
   the in-flight snapshot and gives the panel something alive to do. */
:is(.generating, .crystallizing, .prompt-locked) #element-builder
    :is(.char-identity-row, .char-mini-stack, .char-description)
    :is(select, textarea, input, .select2-container) {
    opacity: 0.4;
    pointer-events: none;
}

/* Name row: every control freezes — the character switcher (switching
   mid-flight abandons the in-flight context) AND all management buttons.
   Renaming, deleting, or importing a card while a scene is generating is
   exactly the disruptive character-level mutation we don't want firing
   mid-pipeline. Each button is dimmed individually (.fs-toggle-btn
   covers pin / rename / delete / import / export) — the row container,
   labels and chrome stay lit, so it reads "locked" without a wash. */
:is(.generating, .crystallizing, .prompt-locked) #element-builder .char-name-row
    :is(#id_character_nav, .character-name-select, .select2-container, .fs-toggle-btn) {
    opacity: 0.4;
    pointer-events: none;
}

/* Chub card-tab prose joins the busy read by greying the TEXT only —
   NOT opacity on .card-pane (that washed its slot-tinted gradient bg +
   border, reading as a dead wash). What makes the activity/description
   effect feel intentional is the title staying full while the value
   greys; replicate that here: this overrides .card-pane-render's body
   colour, while the `> label` title keeps its own --ui-text-soft rule
   (out-specifies inheritance) and the .card-pane bg is untouched. em /
   strong / .chat-speech derive from currentColor so they fade with it.
   Read-only reference, so no pointer-events lock — scroll/select stays
   and the sibling .card-tab-strip still switches panes. 0.4 alpha
   mirrors the opacity-0.4 field effect on text only (same white channel
   as the base .card-pane-render colour); it's the tuning knob. */
:is(.generating, .crystallizing, .prompt-locked) #element-builder .card-pane-render {
    color: rgba(255, 255, 255, 0.4);
}